Search code examples
javaopenglrenderinglwjgl

Same openGL calls yield different results in LWJGL


We're supposed to use LWJGL 2.9.3 to create a simple application that displays a wireframe object. I created a test class based off of the first example code from http://www.glprogramming.com/red/chapter01.html What I end up with is a program that flashes a white square for a brief moment and then disappears. I'm not sure what I'm doing wrong.

Here's the test code:

package Test.LWJGL;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import static CS355.LWJGL.LWJGLSandbox.DISPLAY_HEIGHT;
import static CS355.LWJGL.LWJGLSandbox.DISPLAY_WIDTH;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL11.glFlush;


public class LWJGLTest {
    public static void render() {
        glClear(GL_COLOR_BUFFER_BIT);
        glColor3f(1.0f, 1.0f, 1.0f);
        glOrtho(0, 1.0, 0.0, 1.0, -1.0, 1.0);
        glBegin(GL_POLYGON);
            glVertex3f(0.25f, 0.25f, 0.0f);
            glVertex3f(0.75f, 0.25f, 0.0f);
            glVertex3f(0.75f, 0.75f, 0.0f);
            glVertex3f(0.25f, 0.75f, 0.0f);
        glEnd();
        glFlush();
    }

    public static void main(String[] args)  {
        try {
            Display.setDisplayMode(new DisplayMode(DISPLAY_WIDTH,DISPLAY_HEIGHT));
            Display.setFullscreen(false);
            Display.create();

            glClearColor(0.0f,0.0f,0.0f,0.0f);

            while(!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
                if(Display.isVisible()) {
                    render();
                }
                else {
                    if(Display.isDirty()) {
                        render();
                    }
                    try {
                        Thread.sleep(100);
                    }
                    catch(InterruptedException ex) {}
                }
                Display.update();
                Display.sync(60);
            }
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        finally {
            Mouse.destroy();
            Keyboard.destroy();
            Display.destroy();
        }
    }
}

Solution

  • OpenGL is a state machine. This means, there are lots of states which you can set, and which will influence the final rendering result in some well-defined way. These states are never automatically reset, they just stay as you set them, until you change them. There are no such things as "frames" or "scene objects", just a stream of state-setting or drawing commands.

    OpenGL's matrix stack is also just a state. The function glOrtho will multiply the current top element of the currently selected matrix stack with that ortho matrix, and will replace the top element by that result.

    Assume the Ortho matrix is called O. Initially, all of GL's matrices will be identiy. So when you call render for the first time, you'll get: M = M * O = I * O = O. However, the second time, you will get M = M * O = O * O. And so on.

    You have to explicitely reset your matrix back to identity at the beginning of the frame:

    glLoadIdentity();
    glOrtho(...);
    

    You should be aware that the code you are using is not very good. It uses the MODELVIEW stack for projection matrices, which is meant to go to GL_PROJECTION. But before you try to learn about that staff, be warned that all of that is completely deprecated in the GL since a decade. Modern core versions of OpenGL do not support these functions at all.