2012-08-16 32 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