OpenGL深度测试不按预期工作

3

我有一个使用深度测试的简单程序。但是它并没有按照我的期望工作。这个程序绘制了X轴、Y轴以及接近原点的一个球体。 如果我不开启GL_DEPTH_TEST,则球体会被绘制在轴上方。如果我开启GL_DEPTH_TEST,则轴会被绘制在球体上方,这不是我期望的结果。请问有人知道我做错了什么吗?

void  
glwid::initializeGL()  
{    
    glClearColor (0.0f, 0.0f, 0.0f, 1.0f);      
}  



void  
glwid::resizeGL(int width, int height)  
{  
    glViewport( 0, 0, (GLint)width, (GLint)height );  
    glMatrixMode( GL_PROJECTION );  
    glLoadIdentity();  

    gluPerspective ( 90, (GLint)width/ (GLint)height, 0.0, 200.0 );  
    glMatrixMode( GL_MODELVIEW );  
    glLoadIdentity();  
    glEnable (GL_DEPTH_TEST);  
}  


void  
glwid::paintGL()  
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  

    glMatrixMode (GL_MODELVIEW);  
    glLoadIdentity();  

    gluLookAt (0, 0, 100, 0, 0, 0, 0, 1, 0);  


    //  
    // X axis  
    //  
    glBegin( GL_LINES );  
    qglColor( green );  
    glVertex3f (-100.0,  0, 0. );  
    glVertex3f (100.0, 0, 0. );  
    glEnd();  


    //  
    // Y axis  
    //  
    glBegin( GL_LINES );  
    qglColor( red );  
    glVertex3f (0.0, 100.0, 0. );  
    glVertex3f (0.0, -100, 0. );   
    glEnd();  

    //  
    // sun  
    //  
    glTranslated (5, 0, 20);  
    GLUquadricObj *sphere_quadric = gluNewQuadric();  
    glColor3ub (255, 255, 0);  
    gluQuadricDrawStyle(sphere_quadric, (GLenum)GLU_SMOOTH);  
    gluSphere(sphere_quadric, 10, 36, 36);  
}  

没有人会像这样回答它。修复格式。 - orlp
1
你能发布带/不带深度测试的图片吗? - rotoglup
2个回答

13

我尝试了你的代码。问题在于 resizeGL() 函数。 问题出在你的写法

gluPerspective ( 90, (GLint)width/ (GLint)height, 0.0, 200.0 );  

将第三个参数设置为0.01(例如)即可,因为该参数应始终为正数:http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml

同时,将(GLint)width/ (GLint)height更改为(GLfloat)width/ (GLfloat)height,否则结果会很奇怪。

最好将glEnable(GL_DEPTH_TEST)放入initializeGL()函数中。


2
glEnable不应该放在初始化中。每个OpenGL状态都应该在需要时正确设置。glEnable(GL_DEPTH_TEST)应该放在paintGL中,在绘制几何图形之前。还有glViewport、设置投影矩阵和其他东西也应该放在那里,而不是其他地方。 - datenwolf
我的意思是resize()方法不是一个好的位置,对于这个程序来说,在初始化时将glEnable(GL_DEPTH_TEST)放入其中就足够了,因为它在其他地方没有被改变。但总体而言你是正确的。 - Andrew
谢谢你,安德鲁。透视参数是问题所在。 - tadpole

0

你的坐标轴从Z位置0开始。球体位于Z位置20(离“相机”更远),因此轴在球体前面并被显示。

目前设置为,随着Z值的增加,它们会远离屏幕。当它们向下移动时,它们靠近屏幕。

你有两个选择:在绘制轴时禁用深度测试(因此它将始终在所有物体后面)。或者将轴移动到Z位置100左右,并将其缩放以使其看起来相同大小。第一种选择可能更好。

只需在glDisable(GL_DEPTH_TEST);glEnable (GL_DEPTH_TEST);中包装您的轴绘图例程即可解决问题。


摄像机位于(0,0,100)。轴原点-(0,0,0)球心-(5,0,20)。轴更远。 - Andrew
我错过了相机放置的代码行。好发现。 - Timothy Baldridge
深度测试必须自动工作!当它应该工作时,您不应该启用/禁用!这与手动对象排序相同 - 深度测试应该执行的操作。 - Andrew
“当它应该工作时,你不应该启用/禁用!”这是正确的,但是在许多情况下,添加/禁用深度测试是正确的做法。 - Timothy Baldridge

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