2014-03-19 155 views
1

我有一个我正在开发的OpenGL应用程序。所呈现的地形似乎没有遵循深度缓冲规则,所以我猜我搞砸了相当严重的地方OpenGL深度缓冲区溢出

我做我的代码

这里有GL11.glEnable(GL11.GL_CULL_FACE)就是平面外观就像在没有四分之一的情况下一样,所以即使在没有zbuffer的情况下,看起来也是正常的。请注意,这是一种“自上而下”的说法,这里的“摄像头”是平面的上方

enter image description here

enter image description here

而现在,从不同的观点角度的

enter image description here

距离场景最远的四边形被渲染在靠近计算机的四边形上。下面是我对glOrtho通话的样子,具体指定近端和远端剪切面,最远的平面是可见的,但是应该由上升平面

GL11.glOrtho(0, 1000, 0, 750, 50, -50); 

隐藏有趣的是,如果我删除我的电话给GL11。 glEnable(GL_DEPTH_TEST),zbuffer似乎只适用于几个角度

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

编辑2:添加代码,以显示渲染

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的代码,并常数值

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(); 
} 

回答

1

注:经过一番讨论后,使用glDepthFunc(GL_GREATER);和在清除深度缓冲区工作之前调用glClearDepth(0.0f);

看来正在发生的事情仅仅是剔除物体的背面。对于这些平面飞机,如果希望从后面看到它们,则必须完全禁用面部剔除。据我所知,没有任何东西被绘制在另一个上面。

编辑:我没有看到你的前面的文章关于面部剔除。这看起来像是面部剔除的正确结果;你只是从他们将被扑杀的一侧看着你的画面。

+0

在第一张照片中,飞机的中间升起,有点像山。在第二张照片中,即使中间四边形应位于最上方,也会显示右侧的四边形。 – dreadiscool

+0

设置glCullFace(GL_FRONT_AND_BACK)导致整个窗口变黑,没有任何渲染(或只是不可见) – dreadiscool

+1

我的道歉;我带领你走错了方向。为了渲染多边形的两侧,必须禁用脸部剔除。 – SDLeffler