OpenGL GL_DEPTH_TEST不起作用

10

我刚刚将一个.obj文件加载器移植到Objective-C中,目前为止一切正常,我可以获取我的顶点、法线等信息。每个法线都很好,指向正确的方向,所有面都以逆时针顺序绕序,但是在深度测试方面存在一些问题。

float rotX = 0;
float rotY = 0;
objModel* o = [[objModel alloc] initWithPath:@"/model.obj"]

glClearColor(0,0,0,0);

glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW);
glCullFace(GL_BACK); 
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();   
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0, -1, 0);
glRotatef(90,0,0,1);
glRotatef(90,0,1,0);
glRotatef(rotX,0,0,-1);
glRotatef(rotY,0,1,0);

[o drawObjWithArrays]

glFlush();

我有两种不同的方式来绘制我的对象,一种使用glBegin() / glEnd(),另一种使用顶点和法线数组,并调用glDrawArrays()。两种方法都存在同样的问题:应该被前面的面遮挡的面被显示出来了,因为深度测试没有生效。这些面按照它们在.obj文件中的先后顺序进行绘制。

您可以在此处找到图像:http://img524.imageshack.us/img524/994/image2jgq.png

我对OpenGL和Objective-C相当新手,所以我想我的问题可能来自于我忘记的某个设置。这些设置如下:

-(id) initWithFrame:(NSRect) frame {
NSLog(@"INIT GL VIEW\n");

GLuint attributes[] = {
    NSOpenGLPFANoRecovery,
    NSOpenGLPFAWindow,
    NSOpenGLPFAAccelerated,
    NSOpenGLPFADoubleBuffer,
    NSOpenGLPFAColorSize, 24,
    NSOpenGLPFAAlphaSize, 8,
    NSOpenGLPFADepthSize, 24,
    NSOpenGLPFAStencilSize, 8,
    NSOpenGLPFAAccumSize, 0,
    0
};

NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:(NSOpenGLPixelFormatAttribute*) attributes];
if (!fmt)
    NSLog(@"No OpenGL pixel format");

GLfloat   mat_ambient[]     = {0.0, 0.0, 1.0, 1.0};
GLfloat   mat_flash[]       = {0.0, 0.0, 1.0, 1.0};
GLfloat   mat_flash_shiny[] = {50.0};
GLfloat   light_position[]  = {100.0,-200.0,-200.0,0.0};
GLfloat   ambi[]            = {0.1, 0.1, 0.1, 0.1};
GLfloat   lightZeroColor[]  = {0.9, 0.9, 0.9, 0.1};

/* set the material */
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);

glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);  
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);

return self = [super initWithFrame:frame pixelFormat:[fmt autorelease]]; 
}

有人能帮助我吗?我尝试了所有可能的glDepthFunc,glCullFace和glFrontFace组合,但都不起作用...

谢谢 ^^

4个回答

15

如果你将这个添加到你的绘制方法中,你会得到什么?

int depth;
glGetIntegerv(GL_DEPTH_BITS, &depth);
NSLog(@"%i bits depth", depth)

还有一些可以尝试的方法:

  • 确认调用了initWithFrame方法
  • 如果你正在使用从IB创建的NSOpenGLView子类,请在IB中设置深度缓冲区,并将所有的openGL初始化代码移动到- (void)prepareOpenGL方法中

已将其添加到drawRect函数中,返回“0位深度”。看起来不太对劲... - melka
2
哇,谢谢,它起作用了。 我不知道你必须在IB中设置参数。 现在我的视图有24位深度,没有问题了^^ - melka
如果您需要在没有NIB的情况下完成此操作,我在下面发布了代码(无法在评论中格式化代码)。 - Anna B
1
我曾经为这个问题苦苦挣扎,但最终找到了正确的解决方案。 - Daniel Wood

8
如果有人想知道如何在没有IB的情况下设置这个,请参考以下步骤:
NSOpenGLPixelFormatAttribute attrs[] = {
    // NSOpenGLPFADoubleBuffer,
    NSOpenGLPFADepthSize, 32,
    0
};
NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
NSOpenGLView *view = [[NSOpenGLView alloc] initWithFrame:frame pixelFormat:format];

1

请务必调用glDepthFunc()以设置深度缓冲比较函数。大多数应用程序使用GL_LEQUALGL_LESS作为深度函数。还要确保调用glClearDepth()以设置深度缓冲区被清除的值;您应该使用1.0参数来将其清除到最大深度。


我刚刚尝试了一下,使用不同的glDepthFunc参数,没有什么新的发现... :/ - melka

0

我不确定适当的AGL调用应该是什么样子的,但你应该确保为深度缓冲区实际分配位平面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接