Search code examples
openglrenderinglwjgl

LWJGL 2.9 gluProject 3D to 2D


So I've been playing with LWJGL 3D object coordinates to 2D screen space coordinates using GLU.gluProject, however I'm finding there to be quite a problem when the xyz of the 3D object is behind the camera. The screen space coordinates seem to be on screen twice, once for the actual potion which works fine, but again for when the object is behind, and the positions are somewhat inverted of the objects true position (camera moves left, so do the screen coordinates twice as fast as the camera).

Here's the code I'm using for 3D to 2D:

public static float[] get2DFrom3D(float x, float y, float z) {
    FloatBuffer screen = BufferUtils.createFloatBuffer(3);
    IntBuffer view = BufferUtils.createIntBuffer(16);
    FloatBuffer model = BufferUtils.createFloatBuffer(16);
    FloatBuffer proj = BufferUtils.createFloatBuffer(16);

    GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, model);
    GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, proj);
    GL11.glGetInteger(GL11.GL_VIEWPORT, view);

    boolean res= GLU.gluProject(x, y, z, model, proj, view, screen);

    if (res) {
        return new float[] {screen.get(0), Display.getHeight() - screen.get(1), screen.get(2)};
    }
    return null;
}

Another query is what the screen.get(2) value is used for, as it majorly varies from 0.8 to 1.1, however occasionally reaches -18 or 30 when the position is just below the camera, and the camera pitch is sat just above or below the horizon.

Any help is appreciated.


Solution

  • Points behins the camera (or on the camera plane) can never be correctly projected. This case can only be handled for primitives like lines or triangles. During rendering, the primitives are clipped against the viewing frustum, so that new vertices (and new primitives) can be generated. But this is impossible to do for a single point, you always need lines or polygon edges to calculate any meaningful intersection point.

    Individual points, and this is all what gluProject handles, can either be inside or outside of the frustum. But gluProject does not care abnout that, it just applies the transformations, mirroring points behind the camera in front of the camera. It is the responsibilty of the caller to ensure that the points to project are actually inside of the viewing frustum.