1
votes

I have an OpenGL application that I'm developing. The terrain being rendered seems to not follow depth buffer rules, so I'm guessing I messed up pretty badly somewhere

I do have GL11.glEnable(GL11.GL_CULL_FACE) in my code

Here's what the plane looks like in a scenario where no quad is behind another, so that even in the absence of a zbuffer things look normal. Please note that this is from a "top-down" view, where the "camera" is above the plane

enter image description here

enter image description here

And now, angled from a different view

enter image description here

The quads furthest from the scene are being rendered on top of the quads closer to the computer. Here's what my call to glOrtho looks like, specifying the near and far clipping planes Specifically, The furthest plane is visible when it should be hidden by the ascending plane

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

Interestingly enough, if I remove my call to GL11.glEnable(GL_DEPTH_TEST), the zbuffer seems to work for only a few angles

Edit: I think the problem has something to do with where I called glOrtho. It is only called once, along with my glEnable's at the beginning of the code. Should I call it repeatedly in my loop, after GL11.glLoadIdentity() (which is repeatedly called during the loop)?

Edit 2: Adding code to display rendering

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

Here is the code that sets up all of my glEnables, and constant values

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

1 Answers

1
votes

NOTE: After some discussion, using glDepthFunc(GL_GREATER); and calling glClearDepth(0.0f); before clearing the depth buffer worked.

What appears to be occurring is simply that you are culling the back faces of the objects. For these flat planes, if you wish them to be visible from the back, face culling must be disabled altogether. Nothing is being drawn on top of the other as far as I can see.

EDIT: I did see your earlier post about face culling. This looks like the correct outcome of face culling; you are simply looking at your drawn faces from the side where they will be culled.