2010-03-03 14 views
5

ओपनजीएल ईएस (आईफोन) में काम करने के लिए बनावट मानचित्रों को प्राप्त करने में बहुत परेशानी हो रही है।मैं OpenGL ES में घन को कैसे बना सकता हूं?

यहाँ मैं क्या किया है:

  • vertexes की एक सरणी का निर्माण किया
  • चेहरे कि प्रत्येक चेहरा
  • के लिए vertexes की सरणी के सूचकांकों संदर्भ की एक सरणी बनाया रंग की एक सरणी का निर्माण तो मुझे यकीन है कि मुझे पता है कि घन पर कौन सा कशेरुका है।

यह सब Jeff Lamarche's tutorials के बाद। वस्तुओं को प्रतिपादन और स्थानांतरित करना एक समस्या नहीं है।

अब मैं घन (वास्तव में एक टाइल, ज़ेड एक्स या वाई में संकुचित) प्राप्त करने की कोशिश कर रहा हूं ताकि दो विपरीत चेहरे पर एक बनावट चिपक सके (अन्य बाद में आ सकें)। मैं एक चेहरा काम करने में सक्षम हूं, लेकिन मुझे किसी अन्य चेहरे पर व्यावहारिक परिणाम नहीं मिल रहे हैं।

OpenGL ES में किसी ऑब्जेक्ट को मानचित्र बनाने के लिए सबसे व्यवस्थित तरीका क्या है, और क्या कोई यह देख सकता है कि मेरे कोड में त्रुटियां कहां हैं?

#import "GLViewController.h" 
#import "ConstantsAndMacros.h" 
#import "OpenGLCommon.h" 
#import "Cube.h" 

@implementation GLViewController 

@synthesize initDone; 
@synthesize tileArray; 
@synthesize tileRows; 
@synthesize tileCols; 
@synthesize cubes; 
@synthesize gridOffsetX; 
@synthesize gridOffsetY; 
@synthesize gridOffsetZ; 
@synthesize tileSpacing; 

- (void)drawView:(UIView *)theView 
{ 
    static GLfloat rot = 0.0; 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_COLOR_ARRAY); 
    glEnableClientState(GL_NORMAL_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    // This is the same result as using Vertex3D, just faster to type and 
    // can be made const this way 

    static const Vertex3D vertices[]= { 
     {1.0f, -1.0f, 0.2f}, 
     {1.0f, -1.0f, -0.2f}, 
     {1.0f, 1.0f, -0.2f}, 
     {1.0f, 1.0f, 0.2f}, 
     {-1.0f, -1.0f, 0.2f}, 
     {-1.0f, -1.0f, -0.2f}, 
     {-1.0f, 1.0f, -0.2f}, 
     {-1.0f, 1.0f, 0.2f} 
    }; 

    static const Color3D colors[] = { 
     {1.0, 0.0, 0.0, 20.0}, 
     {1.0, 1.0, 1.0, 20.0}, 
     {1.0, 1.0, 1.0, 20.0}, 
     {0.0, 0.0, 1.0, 20.0}, 
     {0.0, 1.0, 0.0, 20.0}, 
     {1.0, 1.0, 1.0, 20.0}, 
     {1.0, 1.0, 1.0, 20.0}, 
     {1.0, 1.0, 1.0, 20.0}, 
    }; 

    static const GLubyte cubeFaces[] = { 
     0, 1, 3,  
     2, 3, 1, 

     0, 3, 4, 
     3, 4, 7,  // first main face 

     2, 1, 6,  // second main face 
     1, 6, 5, 

     5, 6, 7, 
     5, 4, 7, 

     7, 6, 3, 
     6, 3, 2, 

     4, 0, 5, 
     1, 0, 5, 
    }; 

    static const Vector3D normals[] = { 
     {0.200000, -0.400000, 0.000000}, 
     {0.400000, -0.200000, -0.400000}, 
     {0.333333, 0.333333, -0.333333}, 
     {0.400000, 0.400000, -0.200000}, 
     {-0.333333, -0.333333, 0.333333}, 
     {-0.400000, -0.400000, -0.200000}, 
     {-0.200000, 0.400000, -0.400000}, 
     {-0.400000, 0.200000, 0.000000}, 
    }; 

    static const GLfloat texCoords[] = { 
     0.0, 0.0, // texture face 
     1.0, 1.0, 
     0.0, 1.0, 
     1.0, 1.0, 
     0.0, 0.0, 
     1.0, 0.0, 


     0.0, 0.0, // texture face 
     1.0, 1.0, 
     1.0, 0.0, 
     1.0, 0.0, 
     0.0, 1.0, 
     1.0, 1.0, 

     0.0, 0.0, // texture face 
     1.0, 1.0, 
     0.0, 1.0, 
     1.0, 1.0, 
     0.0, 0.0, 
     1.0, 0.0, 

     0.0, 0.0, // texture face 
     1.0, 1.0, 
     0.0, 1.0, 
     1.0, 1.0, 
     0.0, 0.0, 
     1.0, 0.0, 

     0.0, 0.0, // texture face 
     1.0, 1.0, 
     0.0, 1.0, 
     1.0, 1.0, 
     0.0, 0.0, 
     1.0, 0.0, 

     0.0, 0.0, // 
     1.0, 1.0, 
     0.0, 1.0, 
     1.0, 1.0, 
     0.0, 0.0, 
     1.0, 0.0, 

    }; 

     glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 


    glLoadIdentity(); 
    glClearColor(0.7, 0.7, 0.7, 1.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glVertexPointer(3, GL_FLOAT, 0, vertices); 
    glColorPointer(4, GL_FLOAT, 0, colors); 
    glNormalPointer(GL_FLOAT, 0, normals); 
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 

    NSMutableArray *tempRow; 
    Cube *tempCube; 
    for (int i = 1; i <= cubes.tileRows; i++) 
    { 
     tempRow = [cubes rowAtIndex:i-1]; 
     for (int j = 1; j <= cubes.tileCols; j++) 
     { 
      tempCube = [tempRow objectAtIndex:j-1]; 
      glLoadIdentity(); 
      glTranslatef(gridOffsetX + (tileSpacing * (GLfloat)i), gridOffsetY + (tileSpacing * (GLfloat)j), gridOffsetZ); 
      glRotatef(rot, 1.0, 0.0, 0); 
      glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, cubeFaces); 
     } 
    } 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_COLOR_ARRAY); 
    glDisableClientState(GL_NORMAL_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    static NSTimeInterval lastDrawTime; 
    if (lastDrawTime) 
    { 
     NSTimeInterval timeSinceLastDraw = [NSDate timeIntervalSinceReferenceDate] - lastDrawTime; 
     rot+=30 * timeSinceLastDraw;     
    } 
    //NSLog(@"rot is %f", rot); 
    lastDrawTime = [NSDate timeIntervalSinceReferenceDate];  
} 



-(void)setupView:(GLView*)view 
{ 
    initDone = NO; 

    tileRows = 5; 
    tileCols = 7; 
    gridOffsetX = 5.2f; 
    gridOffsetY = 6.9f; 
    gridOffsetZ = -14.0; 
    tileSpacing = -2.15f; 

    cubes = [[Cubes alloc] initWithRowCount:tileRows colCount: tileCols ]; 

    const GLfloat zNear = 0.01, zFar = 1000.0, fieldOfView = 50.0; 
    GLfloat size; 
    glEnable(GL_DEPTH_TEST); 
    glMatrixMode(GL_PROJECTION); 
    size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView)/2.0); 
    CGRect rect = view.bounds; 

// glOrthof(-5.0,           // Left 
//   5.0,           // Right 
//    -5.0/(rect.size.width/rect.size.height), // Bottom 
//   5.0/(rect.size.width/rect.size.height), // Top 
//   0.01,           // Near 
//   10000.0);          // Far 

    glFrustumf(-size, size, -size/(rect.size.width/rect.size.height), size/
       (rect.size.width/rect.size.height), zNear, zFar); 

    glViewport(0, 0, rect.size.width, rect.size.height); 
    glMatrixMode(GL_MODELVIEW); 

    glEnable(GL_COLOR_MATERIAL); 
    // Enable lighting 
    glEnable(GL_LIGHTING); 

    // Turn the first light on 
    glEnable(GL_LIGHT0); 

    // Define the ambient component of the first light 
    const GLfloat light0Ambient[] = {0.5, 0.5, 0.5, 1.0}; 
    glLightfv(GL_LIGHT0, GL_AMBIENT, light0Ambient); 

    // Define the diffuse component of the first light 
    const GLfloat light0Diffuse[] = {0.7, 0.7, 0.7, 1.0}; 
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light0Diffuse); 

    // Define the specular component and shininess of the first light 
    const GLfloat light0Specular[] = {0.7, 0.7, 0.7, 1.0}; 
    const GLfloat light0Shininess = 0.4; 
    glLightfv(GL_LIGHT0, GL_SPECULAR, light0Specular); 


    // Define the position of the first light 
    const GLfloat light0Position[] = {0.0, 10.0, 10.0, 0.0}; 
    glLightfv(GL_LIGHT0, GL_POSITION, light0Position); 

    // Define a direction vector for the light, this one points right down the Z axis 
    const GLfloat light0Direction[] = {0.0, 0.0, -1.0}; 
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0Direction); 

    // Define a cutoff angle. This defines a 90° field of vision, since the cutoff 
    // is number of degrees to each side of an imaginary line drawn from the light's 
    // position along the vector supplied in GL_SPOT_DIRECTION above 
    glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0); 


    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE, GL_SRC_COLOR); 

    glGenTextures(1, &texture[0]); 
    glBindTexture(GL_TEXTURE_2D, texture[0]); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

    NSString *path = [[NSBundle mainBundle] pathForResource:@"a-tile-64" ofType:@"png"]; 
    NSData *texData = [[NSData alloc] initWithContentsOfFile:path]; 
    UIImage *image = [[UIImage alloc] initWithData:texData]; 
    if (image == nil) 
     NSLog(@"Do real error checking here"); 

    GLuint width = CGImageGetWidth(image.CGImage); 
    GLuint height = CGImageGetHeight(image.CGImage); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    void *imageData = malloc(height * width * 4); 
    CGContextRef context = CGBitmapContextCreate(imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 
    CGContextClearRect(context, CGRectMake(0, 0, width, height)); 
    CGContextTranslateCTM(context, 0, height - height); 
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); 

    CGContextRelease(context); 

    free(imageData); 
    [image release]; 
    [texData release]; 

    glLoadIdentity(); 
}; 

- (void)dealloc 
{ 
    [tileArray release]; 
    [cubes release]; 

    [super dealloc]; 
} 
@end 
+0

क्या रंग ठीक से प्रदर्शित होते हैं? जेफ लैमर के ट्यूटोरियल के लिंक के लिए –

+0

+1। यह वही है जो मुझे चाहिए था। – Bogatyr

उत्तर

2

मैंने जेफ के ट्यूटोरियल का उपयोग करके ओपनजीएल ईएस भी शुरू किया।

मैं आपको जो करने की कोशिश कर रहा हूं उसे सरल बनाने का सुझाव दूंगा।उदाहरण के लिए:

  • नॉर्मल्स
  • भूल जाओ भूल जाओ रंग
  • सूचकांक भूल जाओ
  • एक संरचना है कि उनकी विशेषताओं के कोने बांधता

जेफ एक उपयोगी TexturedVertexData3D Struct प्रदान करता बनाएं कि क्या ये। यदि आप नहीं चाहते हैं तो आपको सामान्य भाग को भरना नहीं है।

glVertexPointer(3, GL_FLOAT, sizeof(TexturedVertexData3D), &vertices[0]); 
glTexCoordPointer(2, GL_FLOAT, sizeof(TexturedVertexData3D), &vertices[0].texCoords); 

और अपने वस्तु आकर्षित करने के लिए glDrawArrays का उपयोग करें::

glDrawArrays(GL_TRIANGLES, 0, nVertices); 

बार जब आप इस काम की है, आगे जाना है और में normals और रंग भी जोड़

फिर, अपने कदम उचित रूप से सेट TexturedVertexData3D संरचना, और उचित रूप से अपने बनावट और रंग पॉइंटर्स सेट करें। फिर फिर से परीक्षण करें, या चीजें काम नहीं करते हैं तो एक अद्यतन पोस्ट करें।

इस बिंदु पर आप सूचकांक का उपयोग करने के बारे में सोचना शुरू कर सकते हैं। इंडेक्स वास्तव में तब तक समझ में नहीं आता जब तक आप हजारों शिखर प्रतिपादन नहीं कर रहे हों। लेकिन, जब समय आता है, तो आप उनका उपयोग करके एक अच्छा प्रदर्शन बढ़ा सकते हैं।

+0

ठीक --- यह जानना अच्छा है। मैंने ब्रूट-फोर्स स्पष्ट शिखर का उपयोग करके प्रोजेक्ट का पुनर्निर्माण किया, और चीजें अच्छी तरह से काम कर रही हैं, जैसा कि आपने GLDrawArrays का उपयोग करने का सुझाव दिया था। बनावट के नक्शे एक समझदार तरीके से काम कर रहे हैं, और अब मुझे लगता है कि मैं कर सकता हूं, जैसा कि आप कहते हैं, जो काम कर रहा है, वह बढ़ता जा रहा है। – omnivore

0

मैं इस सवाल को देख रहा हूं क्योंकि मैं इस समय ओपनजीएल सीख रहा हूं और ओपनजीएल ईएस पर जा रहा हूं। जैसा कि किसी ने अभी तक जवाब नहीं दिया है, मैं आपको अपने विचार दूंगा, हालांकि यह एक विशेषज्ञ राय पर विचार न करें।

कुछ विचार करना है कि यह आपके वर्टेक्स, रंग & सामान्य सरणी में 8 'आइटम' होते हैं, हालांकि आपके TexCoord सरणी में 36 'आइटम' होते हैं। मुझे यकीन है कि जब आप इंडेक्स की सूची के साथ glDrawElements का उपयोग करते हैं, तो यह उन सभी इंडेक्स का उपयोग करता है जो सभी सक्रिय एरे से आइटम चुनते हैं। तो आपके TexCoord सरणी के अंतिम 28 आइटम कभी भी उपयोग नहीं किए जाएंगे, उन्हें cubeFaces द्वारा निर्दिष्ट सूचकांक के अनुसार चुना जाएगा। आपके द्वारा लिंक किए गए ट्यूटोरियल में, सभी सरणी में चार आइटम हैं, जो ऑब्जेक्ट के एक ही चेहरे के लिए अच्छी तरह से काम करता है।

हालांकि यह 3 डी ऑब्जेक्ट्स के लिए सूचकांक का उपयोग करने के साथ एक मुद्दा है, क्योंकि यद्यपि कई क्यूबों का एक घन में फिर से उपयोग किया जाता है, उनके बनावट समन्वय के लिए अलग-अलग त्रिकोणों के लिए आवश्यक नहीं होगा । असल में न तो उनके आदर्श होंगे, ताकि ऑब्जेक्ट को प्रकाश देने के लिए आपके कोड के साथ एक और समस्या हो सकती है।

मुझे नहीं पता कि इसका सबसे अच्छा समाधान क्या है, यही कारण है कि मुझे इस प्रश्न के किसी भी अन्य उत्तर में दिलचस्पी है ... वर्टेक्स द्वारा क्यूब वर्टेक्स को चित्रित करना एक विकल्प है। मैं यह भी सोच रहा हूं कि घन के प्रत्येक चेहरे को अलग से खींचना संभव है, और प्रत्येक बार TexCoord सरणी को बदलना संभव है। या शायद इस तरह की चीज करने का कुछ आसान या मानक तरीका है जिसे मैं अभी तक नहीं जानता!

+0

मैं इसी तरह के निष्कर्षों पर आ रहा हूं। मूल समस्या तब उत्पन्न हो सकती है जब आप किसी इंडेक्स को सरणी के सरणी में उपयोग करते हैं: यह स्पष्ट नहीं है कि वही इंडेक्स का उपयोग बनावट वर्टेक्स सरणी में मान प्राप्त करने के लिए किया जाता है। मुझे इस पर कोई दस्तावेज नहीं मिल रहा है। अब मैं मूल त्रिकोणों पर वापस जाने पर विचार कर रहा हूं। मैं केवल साधारण ज्यामिति से निपट रहा हूं, इसलिए एक चरम सूचक सूचक के साथ अंतरिक्ष की बचत शायद परेशानी के लायक नहीं है। इसके अलावा: मैं जो कर रहा हूं, उसके लिए आवश्यक है कि मैं वस्तुओं को विभिन्न तरीकों से बनावट में मैप करने में सक्षम हूं: त्रिकोण का उपयोग करना ऐसा करने का एकमात्र तरीका हो सकता है। – omnivore

संबंधित मुद्दे