【问题标题】:Background object is drawn in front of foreground object in OpenGL?背景对象在OpenGL中的前景对象前面绘制?
【发布时间】:2011-03-16 19:26:46
【问题描述】:

出于测试目的,假设我用glutSolidTeapot() 画了两个茶壶,如下所示:

glColor3f(1.0f, 0.0f, 0.0f); // Red teapot
glutWireTeapot(1.0f);

glColor3f(0.0f, 1.0f, 0.0f); // Green teapot
glTranslatef(0.0f, 0.0f, 3.0f);
glutWireTeapot(1.0f);

相机最初位于(x,y,z) = (0.0f, 0.0f, 5.0f),我正在查看z = -1(这是相机位置#1)。我相信你知道绿色茶壶是离相机最近的物体,红色的在它后面。问题是红色的画得像在绿色的前面一样,看起来不正确:

示例:http://i.stack.imgur.com/8WoEn.png

现在,如果我也移动相机(x,y,z) = (0.0f, 0.0f, -5.0f) 并查看z = 1(这是相机位置#2),我会看到红色茶壶在绿色茶壶前面,这是正常行为。红色现在是离相机最近的物体,绿色在红色后面。一切都很好。

示例:http://i.stack.imgur.com/eJvPE.png

我知道这与订单有关,如果我切换上面的代码(首先是绿茶壶代码),它将解决相机位置 #1 的问题,但问题现在将在相机位置可见#2.

为什么会发生这种情况,我怎样才能防止其他对象后面的对象被绘制在前面,或者根本不绘制?

【问题讨论】:

    标签: opengl drawing z-index glut


    【解决方案1】:

    您需要分配一个深度缓冲区(您很可能已经这样做了),然后使用glEnable(GL_DEPTH_TEST)

    发生这种情况是因为没有深度测试,OpenGL 根本不会对相对于相机的不同深度做出反应。当您启用深度测试时,GL 将拒绝所有比当前最近点更远的新像素/片段。

    如果您想在场景中四处移动,您可能希望通过将GL_DEPTH_BUFFER_BIT 添加到glClear 来清除深度,否则它会记住上一帧中最近的片段。

    除此之外,您的透视矩阵可能格式不正确。这尤其有可能,因为红色茶壶被绘制在绿色茶壶前面,而您绘制它们时,绿色茶壶会通过正确的深度缓冲过度绘制红​​色茶壶。因此,深度值本身可能很糟糕。

    【讨论】:

    • 究竟什么是“分配深度缓冲区”?我已经启用了GL_DEPTH_TEST。如果它有所作为,我也在使用这个:glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);。那我错过了什么?
    • 我也在这样做,嗯...等等,让我发布完整的工作示例,这比继续猜测要好。
    • 在这种情况下,GLUT_DEPTH 应该确保分配了深度缓冲区。好吧,奇怪的是红色是在绿色上绘制的,即使你按顺序绘制它们。可能您的透视投影矩阵设置不正确 - 您可以发布执行此操作的代码吗?
    • 你说得对,我刚刚检查了三次并在gluPerspective() 上发现了问题,zNear 被设置为0.0f 而不是我通常的1.0f。没想到会出现这样的问题,只想减小近剪裁面。
    • @Nazgulled:阅读manpage 的注释部分。
    【解决方案2】:

    可能您还没有启用深度缓冲区(也称为 z 缓冲区)。 要在初始化部分执行此操作,请添加类似这样的内容

    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    

    在渲染每一帧之前,您还必须使用清除此缓冲区

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    

    您可以查看 OpenGL Nehe 教程以获取更多信息http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=01

    【讨论】:

    • 非常有帮助!谢谢。正是我需要的。
    • Metal有没有类似GL_DEPTH_TEST的功能?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 2013-03-25
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多