Search code examples
javaopengljoglorthographicopengl-compat

OpenGL 2D projection stretched by aspect ratio


I am currently trying to convert the drawing methods for my 2D java game to OpenGL by using JOGL, because native java seems rather slow for drawing high-res images in rapid succession. Now i want to use a 16:9 aspect ratio, but the problem is that my image is stretched to the sides. Currently i am only drawing a white rotating quad for testing this:

public void resize(GLAutoDrawable d, int width, int height) {

    GL2 gl = d.getGL().getGL2(); // get the OpenGL 2 graphics context
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL2.GL_PROJECTION);
    gl.glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);

}

public void display(GLAutoDrawable d) {

    GL2 gl = d.getGL().getGL2();  // get the OpenGL 2 graphics context
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    gl.glClear(GL.GL_COLOR_BUFFER_BIT);

    gl.glMatrixMode(GL2.GL_MODELVIEW);
    gl.glLoadIdentity();
    gl.glColor3f(1.0f,1.0f,1.0f);

    degree += 0.1f;

    gl.glRotatef(degree, 0.0f, 0.0f, 1.0f);

    gl.glBegin(GL2.GL_QUADS);
    gl.glVertex2f(-0.25f, 0.25f);
    gl.glVertex2f(0.25f, 0.25f);
    gl.glVertex2f(0.25f, -0.25f);
    gl.glVertex2f(-0.25f, -0.25f);
    gl.glEnd();

    gl.glRotatef(-degree, 0.0f, 0.0f, 1.0f);

    gl.glFlush();
}

I know that you can somehow adress this problem by using glOrtho() and I tried many different values for this now, but none of them achieved a unstretched image. How do I have to use this? Or is there another simple solution for this?


Solution

  • The projection matrix transforms all vertex data from the eye coordinates to the clip coordinates.

    Then, these clip coordinates are also transformed to the normalized device coordinates (NDC) by dividing with w component of the clip coordinates. The normalized device coordinates is in range (-1, -1, -1) to (1, 1, 1).

    With the orthographic projection, the eye space coordinates are linearly mapped to the NDC.

    If the viewport is rectangular this has to be considered by mapping the coordinates.

    float aspect = (float)width/height;
    gl.glOrtho(-aspect, aspect, -1.0f, 1.0f, -1.0f, 1.0f);