【问题标题】:Quads appear in front of others while they're not四边形出现在其他人面前,而他们却没有
【发布时间】:2014-03-12 01:28:33
【问题描述】:

我正在尝试编写一个简单的 Doom 风格游戏,为此我决定编写一个块型引擎(与 Minecraft 非常相似),但是我遇到了一个问题:块的渲染非常奇怪,部分街区像什么都没有一样穿过。

当您从左看四边形时会发生这种情况: 然而,当你从右边看时,一切看起来都很好:

让我们来看看代码,好吗? 这就是我初始化 OpenGL 的方式:

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(fov, (float) Display.getWidth() / (float) Display.getHeight(), 0, -2);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

我使用显示列表渲染块的面。我尝试使用 VBO,但更改为显示列表,因为我认为它们导致了问题。每个显示列表看起来大致相同:

        glNewList(listTop, GL_COMPILE);
        glBegin(GL_QUADS);
        tex.bind();
            glTexCoord2f(0, 0);
        glVertex3f(x+0.0f, y+1.0f, z-1.0f); 
            glTexCoord2f(0, 1);
        glVertex3f(x+0.0f, y+1.0f, z+0.0f); 
            glTexCoord2f(1, 1);
        glVertex3f(x+1.0f, y+1.0f, z+0.0f); 
            glTexCoord2f(1, 0);
        glVertex3f(x+1.0f, y+1.0f, z-1.0f); 
        glEnd();
    glEndList();

然后是渲染:

glClearColor(0, .5f, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);

            glPushMatrix();

          if(rTo)glCallList(listTop);
          if(rBt)glCallList(listBot);
          if(rFr)glCallList(listFront);
          if(rBk)glCallList(listBack);
          if(rLe)glCallList(listLeft);
          if(rRi)glCallList(listRight);

            glPopMatrix();

    glLoadIdentity();
    //Display.update() etc here

那么,是什么导致了这个错误?有人遇到过类似问题吗?

【问题讨论】:

  • 您是否启用并初始化了深度缓冲区?
  • 你在哪里请求你的 OpenGL 上下文?

标签: java opengl lwjgl


【解决方案1】:

我没有看到您正在启用深度测试,

glEnable(GL_DEPTH_TEST);

此外,您必须清除每一帧的深度缓冲区。

尝试在渲染场景之前执行此操作,因为它看起来对象被错误地覆盖。另外,我认为您不应该将投影矩阵中的 near 值设置为零,因为这可能会在以后给您带来一些麻烦。

【讨论】:

  • 我也说了“近乎价值”的东西!但无论如何,很高兴知道它现在工作正常:)
  • 哦,抱歉,没注意到 :D
【解决方案2】:

好的,事实证明我没有启用 GL_DEPTH_TEST。虽然这是问题所在,但它并不是唯一的问题。最大的问题是在 gluPerspective 方法中,zNear 被设置为 0,我知道它需要高于 0。所以,改变这一行:

gluPerspective(fov, (float) Display.getWidth() / (float) Display.getHeight(), 0, -2);

到这里:

gluPerspective(fov, (float) Display.getWidth() / (float) Display.getHeight(), 0.1f, -2);

并启用 GL_DEPTH_TEST 修复了所有问题 :)

【讨论】:

  • gluLookAtzNear 无关。你的问题是gluPerspective。您不能使用 0 因为这与用于计算透视深度的数学相混淆;如果你有一个正交投影矩阵,你可以使用0
  • 我还应该补充一点,单独启用深度测试通常是不够的。您可能会遇到帧缓冲区实际上没有地方存储深度的情况,因此在选择像素格式时,您需要确保深度位具有非零值。同样,如果您使用深度测试,您应该在代码中的某处清除深度缓冲区。
猜你喜欢
  • 1970-01-01
  • 2022-01-21
  • 2022-01-12
  • 1970-01-01
  • 2012-05-18
  • 2016-06-22
  • 1970-01-01
  • 2011-09-15
  • 2014-07-26
相关资源
最近更新 更多