2

I'm starting to play with LWJGL. I have taken this sample code, which works fine. Then, I wanted to change the way the loop is stopped. Here is my new code for the "while" loop:

while (true) {
        // Clear the screen and depth buffer
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);  

        // set the color of the quad (R,G,B,A)
        GL11.glColor3f(0.5f,0.5f,1.0f);

        // draw quad
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(100,100);
        GL11.glVertex2f(100+200,100);
        GL11.glVertex2f(100+200,100+200);
        GL11.glVertex2f(100,100+200);
        GL11.glEnd();

        Display.update();

        if(Display.isCloseRequested()) {
            Display.destroy();
            throw new Exception("Normal termination");
        }
  }

This time an exception is thrown to get out of the loop. The "start" method throws Exception, and my "main" is as follows:

public static void main(String[] argv) {
        QuadExample quadExample = new QuadExample();
        try {
            quadExample.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

With this new structure, the program crashes with the error:

Invalid memory access of location 0x0 rip=0x7fff86d8cf0c

instead of terminating properly when I close it.

For information, I'm running that on Mac OS X 10.6.7, with JavaSE-1.6. I saw a similar issue here and tried with -Xint. It solves the problem. Any idea what can go wrong without -Xint?

Community
  • 1
  • 1
sunmat
  • 6,976
  • 3
  • 28
  • 44
  • Not sure, but most likely some optimization by the compiler gone wrong.I could not find reliable info on how java optimizes for speed(branch prediction or early fetching of data) But it shows that using exceptions where it is not really needed is sub-optimal design. – Dawnkeeper Sep 15 '14 at 20:11
  • I agree that the design is not the best, but this is something I need if I want to integrate LWJGL as graphic backend for a game engine that I already have without deep modifications in the game engine's code. – sunmat Sep 17 '14 at 08:46

2 Answers2

0

While I can't answer the question what exactly going wrong I can suggest a workaround:

boolean continue = true;
while (continue ) {
   //GL code
    Display.update();
    if(Display.isCloseRequested()) {
      continue = false;
    }
}
Display.destroy();
throw new Exception("Normal termination");

This should hopefully prevent optimization of the loop to call GL-commands for a destroyed display.

Dawnkeeper
  • 2,844
  • 1
  • 25
  • 41
  • I guess you meant to put the "continue" variable as condition of the while loop. This is what is done in the original example, in fact. I aim to leave the loop through an exception. – sunmat Sep 17 '14 at 15:46
0

I still don't know what precisely goes wrong with my code, but I found a workaround: putting Display.destroy(); after the exception is caught instead of before throwing it. So the main function becomes as follows:

public static void main(String[] argv) {
    QuadExample quadExample = new QuadExample();
    try {
        quadExample.start();
    } catch (Exception e) {
        Display.destroy(); // destroying the display here now
        e.printStackTrace();
    }
}

I don't know the internals of the Display class or how LWJGL works, but my guess is that Display.destroy does something asynchronously that is not finished when the exception is thrown, leading to bad memory accesses later.

sunmat
  • 6,976
  • 3
  • 28
  • 44