首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenGL深度缓冲区混乱

问OpenGL深度缓冲区混乱
EN

Stack Overflow用户
提问于 2014-03-19 00:53:44
回答 1查看 407关注 0票数 1

我正在开发一个OpenGL应用程序。正在呈现的地形似乎不遵循深度缓冲规则,所以我猜我在某个地方搞砸了。

我的代码中确实有GL11.glEnable(GL11.GL_CULL_FACE)

这是飞机在没有四边形的情况下的样子,所以即使在没有zbuffer的情况下,事情看起来也很正常。请注意,这是一个“自上而下”的视图,其中“照相机”在飞机上方。

​

​

​

​

现在,从另一个角度看

​

​

离现场最远的四边形被渲染在离电脑更近的四边形上。下面是我对glOrtho的调用,具体地指定了近和远的裁剪平面,当它被上升的平面隐藏时,最远的平面是可见的。

代码语言:javascript
复制
GL11.glOrtho(0, 1000, 0, 750, 50, -50);

有趣的是,如果我删除对GL11.glEnable(GL_DEPTH_TEST)的调用,zbuffer似乎只工作几个角度

编辑:我认为这个问题与我叫glOrtho的地方有关。它只被调用一次,以及代码开始时的glEnable。应该在循环中在GL11.glLoadIdentity() (在循环期间反复调用)之后重复调用它吗?

编辑2:添加代码以显示呈现

代码语言:javascript
复制
public void render() {
    for (int y = 0; y <  mapHeight - 1; y++) {
        for (int x = 0; x < mapWidth - 1; x++) {
            drawTile(x, y, rawMap[y][x], rawMap[y][x + 1], rawMap[y + 1][x + 1], rawMap[y + 1][x]);
        }
    }

}

private void drawTile(double xPos, double zPos, double height1, double height2, double height3, double height4) {
    GL11.glColor3ub((byte) 255, (byte) 255, (byte) 255);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
    GL11.glBegin(GL11.GL_QUADS);
    Point3D normal = faceNormals[(int) zPos][(int) xPos];
    GL11.glNormal3d(normal.getX(), normal.getY(), normal.getZ());
    double xIn = xPos * 0.15;
    double xOut = xIn + 0.15;
    double zIn = zPos * 0.15;
    double zOut = zIn + 0.15;


    /* Original First */
    GL11.glTexCoord2d(xPos * textureFactorX, zPos * textureFactorY);
    GL11.glVertex3d(xIn, height1, zIn);

    GL11.glTexCoord2d(xPos * textureFactorX, (zPos + 1) * textureFactorY);
    GL11.glVertex3d(xIn, height4, zOut);

    GL11.glTexCoord2d((xPos + 1) * textureFactorX, (zPos + 1) * textureFactorY);
    GL11.glVertex3d(xOut, height3, zOut);

    GL11.glTexCoord2d((xPos + 1) * textureFactorY, zPos * textureFactorY);
    GL11.glVertex3d(xOut, height2, zIn);

    GL11.glEnd();
}

下面是设置所有glEnables和常量值的代码

代码语言:javascript
复制
public static void main(String[] args) {
    try {
        Display.setDisplayMode(new DisplayMode(1000, 750));
        Display.create();
        Display.setResizable(true);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    GL11.glMatrixMode(GL11.GL_PROJECTION);

    // GL11.glEnable(GL11.GL_CULL_FACE);
    GL11.glCullFace(GL11.GL_FRONT_AND_BACK);
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glEnable(GL11.GL_LIGHTING);
    GL11.glEnable(GL11.GL_LIGHT0);

    // Enable lighting
    FloatBuffer lightFloatBuffer = (FloatBuffer) BufferUtils.createFloatBuffer(4).put(5f).put(5f).put(1f).put(0f).flip();
    FloatBuffer ambientFloatBuffer = (FloatBuffer) BufferUtils.createFloatBuffer(4).put(2f).put(2f).put(2f).put(2f).flip();
    FloatBuffer diffuseFloatBuffer = (FloatBuffer) BufferUtils.createFloatBuffer(4).put(1f).put(1f).put(1f).put(1f).flip();
    FloatBuffer specularFloatBuffer = (FloatBuffer) BufferUtils.createFloatBuffer(4).put(1f).put(1f).put(1f).put(1f).flip();

    GL11.glLightModeli(GL11.GL_LIGHT_MODEL_LOCAL_VIEWER, GL11.GL_TRUE);
    GL11.glShadeModel(GL11.GL_FLAT);

    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, ambientFloatBuffer);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_DIFFUSE, diffuseFloatBuffer);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_SPECULAR, specularFloatBuffer);
    GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, lightFloatBuffer);

    System.out.println("Resource Directory: " + RESOURCE_DIR.toString());

    new Game().start();
    Display.destroy();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-19 01:06:28

注意:经过一些讨论,在清除深度缓冲区之前,使用glDepthFunc(GL_GREATER);并调用glClearDepth(0.0f);是有效的。

看起来正在发生的仅仅是你在剔除对象的背面。对于这些平面,如果你想让它们从背面可见,必须完全禁止对脸的剔除。据我所知,没有任何东西是画在另一个上面的。

编辑:我确实看到了你早些时候关于选脸的帖子。这看起来就像面部剔除的正确结果;你只是从你的画出的脸的侧面去看,它们将被剔除。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22494126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档