2012-08-16 28 views
1

我正在嘗試製作一個Cocoa應用程序,用於呈現其中包含某些模型的房間。不正確順序的OpenGL繪圖模型

對於導入我使用的模型JEFF LAMARCHE's WavefrontOBJScene class,我修改了 以使用OSX而不是iOS。

問題是,當我嘗試渲染模型時,它們無法正確渲染。 我找不到解釋爲什麼發生這種情況。

[示例圖像] http://dl.dropbox.com/u/4556129/untitled%20folder%202/Untitled.jpg

正如你所看到的金字塔的內側面是可見的,即使立方體金字塔背後似乎是盈方。

繪圖代碼

- (BOOL) initGL 
{ 
    test = !test; 
    //glEnable(GL_CULL_FACE); 
    //glCullFace(GL_BACK); 
    glEnable(GL_TEXTURE_2D);    // Enable texture mapping 
    glShadeModel(GL_SMOOTH);    // Enable smooth shading 
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background 
    glClearDepth(1.0f);      // Depth buffer setup 
    glEnable(GL_DEPTH_TEST);    // Enable depth testing 
    glDepthFunc(GL_LEQUAL);     // Type of depth test to do 
    glDepthRange(0,1); 

    // Really nice perspective calculations 
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 
    glDisable(GL_BLEND); 


    return !test; 
} 
- (void)drawRect:(NSRect)rect 
{ 
    if (!test) [self initGL]; 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glClearColor(0.1f, 0.1f, 0.1f, 1); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

    [self setCamera]; 
    [self drawObjects]; 

    glFlush(); 
} 

- (void)drawObjects 
{ 
    glMatrixMode(GL_MODELVIEW); 
    glPushMatrix(); 
    [self drawAnObject]; 
    glPopMatrix(); 

    glPushMatrix(); 
    [[objects objectAtIndex:0] openGLDraw]; 
    glPopMatrix(); 

    glPushMatrix(); 
    [[objects objectAtIndex:1] openGLDraw]; 
    glPopMatrix(); 

} 

- (void)drawAnObject 
{  
    glBegin(GL_QUADS); 
    { 
     for (int x = -256; x < 256; ++x) { 
      for (int y = -256; y < 256; ++y) { 
       glColor3f(colorR[256+x][256+y], colorG[256+x][256+y], colorB[256+x][256+y]); 

       //glNormal3f(1.0, 1.0, 1.0); 

       glVertex3f(x , -1.0, y); 
       glVertex3f(x+1.0, -1.0, y); 
       glVertex3f(x+1.0, -1.0, y+1.0); 
       glVertex3f(x , -1.0, y+1.0); 
      } 
     } 
    } 
    glEnd(); 

    //glMatrixMode(GL_MODELVIEW); 
    //glLoadIdentity(); 
} 


- (void)setCamera 
{  
    //SET 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(60, (float)(self.frame.size.width/self.frame.size.height), 0.1, 1000.0); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glRotatef(-cameraRotationY, 1.0f, 0.0f, 0.0f); //ROT Y 
    glRotatef(cameraRotationX, 0.0f, 1.0f, 0.0f); //ROT X 
    glTranslatef(-cameraPositionX, -cameraPositionY, cameraPositionZ); // POS X Y Z 
} 

CSObject:

- (void)openGLDraw 
{  
    glPushMatrix(); 
    //glLoadIdentity(); 


    //Set Origin 
    glTranslatef(posX, posY, -posZ); // POS X Y Z 
    glRotatef(rotV, 1.0f, 0.0f, 0.0f); //ROT Y 
    glRotatef(rotH, 0.0f, 1.0f, 0.0f); //ROT X 

    glEnableClientState(GL_NORMAL_ARRAY); 
    glEnableClientState(GL_VERTEX_ARRAY); 

    //Draw objects 
    for(CSGroup *group in groups) {   
     if(TRUE) { 
      glShadeModel(GL_SMOOTH); 
     } else { 
      glShadeModel(GL_FLAT); 
     } 

     //VERTICES 
     GLuint verticesName = [group verticesName:GL_STATIC_DRAW]; 
     glBindBuffer(GL_ARRAY_BUFFER, verticesName); 
     glVertexPointer(3, GL_FLOAT, 0, 0); 

     //NORMALS 
     GLuint normalsName = [group normalsName:GL_STATIC_DRAW]; 
     glBindBuffer(GL_ARRAY_BUFFER, normalsName); 
     glNormalPointer(GL_FLOAT, 0, 0); 

     ColorRGBA color = group.material.ambientColor; 
     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat *)&color); 
     color = group.material.diffuseColor; 
     glColor4f(color.red, color.green, color.blue, color.alpha); 
     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (GLfloat *)&color); 
     color = group.material.specularColor; 
     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *)&color); 
     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, group.material.shine); 

     // load (if necessary) and bind the texture 
     if(group.textureCoordinatesIndexData.length > 0) { 
      glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
      GLuint textureCoordsName = [group textureCoordinatesName:GL_STATIC_DRAW]; 
      glEnable(GL_TEXTURE_2D); 
      glBindBuffer(GL_ARRAY_BUFFER, textureCoordsName); 
      glTexCoordPointer([group texCoordSize], GL_FLOAT, 0, 0); 
      GLuint texId = [group.material.diffuseTexture textureName]; 
      glBindTexture(GL_TEXTURE_2D, texId); 
     } 

     GLuint indexesName = [group indexesName:GL_STATIC_DRAW]; 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexesName); 
     glDrawElements(GL_TRIANGLES, (GLsizei)group.indexCount, GL_UNSIGNED_SHORT, NULL); 

     if(group.textureCoordinatesIndexData.length > 0) { 
      glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
     } 
    } 

    glDisableClientState(GL_NORMAL_ARRAY); 
    glDisableClientState(GL_VERTEX_ARRAY); 

    glPopMatrix(); 
} 
+1

你可以使用'glGet'來檢查'GL_DEPTH_BITS'的值嗎?它看起來像你的上下文沒有深度緩衝區。 – Tim 2012-08-16 15:41:01

+0

@Tim我照你說的做了,並在GLinit和drawRect(glClear之前和之後)中添加了以下幾行代碼: 'glGetIntegerv(GL_DEPTH_BITS,&testDepth); NSLog(@「BEFORE CLEAR:%d」,testDepth);' 它們全都返回0 – 2012-08-16 18:26:23

回答

3

您DEPTH_BITS將返回零,這意味着你沒有深度緩衝。因此,深度測試總是會通過,並且您將無法按深度排序。

我對Cocoa並不太熟悉,但基本上你必須做的是在創建opengl上下文的時候,你還必須要求創建深度緩衝區。 (這是在您請求彩色位數的時候)。

我不確切知道什麼命令控制着這個可可,但是如果你不知道(developer.apple.com - opengl_pixelformats),你可以在這裏找到它。請注意這裏提到的深度,並確保您請求深度緩衝區。

+1

只是爲了簡化未來的讀者。當你點擊你的OpenGLView時,你可以在InterfaceBuilder中設置DepthBuffer。 – 2012-08-16 18:45:15