LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: Icyene on March 10, 2013, 00:59:50

Title: LWJGL context instantiation problem
Post by: Icyene on March 10, 2013, 00:59:50
Hello!

I've wanted to create a simple tile-based game for a while, and recently I've had the time to do it. I originally wrote said game using Java2D, and then decided for performance reasons to switch to LWJGL. Since then, I've run across a problem which strikes me as exceedingly newbish, yet which I seem to be unable to solve.

I am trying to initialize a 480x320p frame, and paint an image of the same dimensions on it using LWJGL.

I am utilizing the following code:

public class TestApplet extends Applet {

   /**
    * The Canvas where the LWJGL Display is added
    */
   Canvas display_parent;

   /**
    * Thread which runs the main game loop
    */
   Thread gameThread;

   int width = 480;
   int height = 320;

   public TestApplet() {
       init();
   }

   /**
    * Once the Canvas is created its add notify method will call this method to
    * start the LWJGL Display and game loop in another thread.
    */
     public void startLWJGL() {
       try {
           Display.setParent(display_parent);

           // get modes
           Display.setTitle("Test");
           Display.setFullscreen(false);
           Display.create();
           // enable textures since we're going to use these for our sprites
           glEnable(GL_TEXTURE_2D);

           // disable the OpenGL depth test since we're rendering 2D graphics
           glDisable(GL_DEPTH_TEST);

           glMatrixMode(GL_PROJECTION);
           glLoadIdentity();

           glOrtho(0, width, height, 0, -1, 1);
           glMatrixMode(GL_MODELVIEW);
           glLoadIdentity();
           glViewport(0, 0, width, height);
       } catch (LWJGLException e) {
           e.printStackTrace();
       }

       gameThread = new Thread() {
           public void run() {
               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
               new TextureLoader().getSprite("Test.png").draw(0, 0);
           }
       };

       gameThread.start();
   }


   /**
    * Tell game loop to stop running, after which the LWJGL Display will be destoryed.
    * The main thread will wait for the Display.destroy() to complete
    */
   private void stopLWJGL() {
       // TODO some stopping code here
   }

   /**
    * Applet Destroy method will remove the canvas, before canvas is destroyed it will notify
    * stopLWJGL() to stop main game loop and to destroy the Display
    */
   public void destroy() {
       remove(display_parent);
       super.destroy();
       System.out.println("Clear up");
   }

   /**
    * initialise applet by adding a canvas to it, this canvas will start the LWJGL Display and game loop
    * in another thread. It will also stop the game loop and destroy the display on canvas removal when
    * applet is destroyed.
    */
   public void init() {
       setLayout(new BorderLayout());
       try {
           display_parent = new Canvas() {
               public void addNotify() {
                   super.addNotify();
                   startLWJGL();
               }

               public void removeNotify() {
                   stopLWJGL();
                   super.removeNotify();
               }
           };
           display_parent.setSize(getWidth(), getHeight());
           add(display_parent);
           display_parent.setFocusable(true);
           display_parent.requestFocus();
           display_parent.setIgnoreRepaint(true);
           setVisible(true);
       } catch (Exception e) {
           System.err.println(e);
           throw new RuntimeException("Unable to create display");
       }
   }
}


Essentially, it is the same as the example on LWJGL's Github example folder, yet with no logic but painting a screen constantly.

And yet, whenever I attempt to run the above snippet, I am hit with the following exceptions:

Exception in thread "Thread-5" java.lang.NullPointerException
at org.lwjgl.opengl.GL11.glClear(GL11.java:586)
at amber.TestApplet$1.run(TestApplet.java:69)
java.lang.RuntimeException: Unable to create display
at amber.TestApplet.init(TestApplet.java:135)
at sun.applet.AppletPanel.run(AppletPanel.java:424)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.IllegalStateException: From thread Thread[thread applet-amber.TestApplet,4,file:/a/path/-threadGroup]: Thread[Thread-3,4,] already has the context current
at org.lwjgl.opengl.ContextGL.checkAccess(ContextGL.java:184)
at org.lwjgl.opengl.ContextGL.makeCurrent(ContextGL.java:189)
at org.lwjgl.opengl.DrawableGL.makeCurrent(DrawableGL.java:110)
at org.lwjgl.opengl.Display.makeCurrent(Display.java:731)
at org.lwjgl.opengl.Display.makeCurrentAndSetSwapInterval(Display.java:1050)
at org.lwjgl.opengl.Display.setParent(Display.java:478)
at amber.TestApplet.startLWJGL(TestApplet.java:43)
at amber.TestApplet$2.addNotify(TestApplet.java:120)
at java.awt.Container.addImpl(Container.java:1068)
at java.awt.Container.add(Container.java:365)
at amber.TestApplet.init(TestApplet.java:129)
... 2 more


Googling for a solution has been useless so far: all the results point to an error involving LWJGL which the game MineCraft encountered at some point in time.

Needless to say, I am very confused and I would greatly appreciate any tidbit of light that could be shed on this beginner issue of mine.
Title: Re: LWJGL context instantiation problem
Post by: Cornix on March 10, 2013, 09:25:25
lwjgl has some problems with multi-threading since the openGl library is static.
Judging from this exception:
Quotejava.lang.IllegalStateException: From thread Thread[thread applet-amber.TestApplet,4,file:/a/path/-threadGroup]: Thread[Thread-3,4,] already has the context current
I'd say this is your problem.
Try it without creating a new thread in your code.
Title: Re: LWJGL context instantiation problem
Post by: quew8 on March 10, 2013, 11:20:11
I've never really understood the benefits of running your main game loop on anything but the main thread.
Title: Re: LWJGL context instantiation problem
Post by: Icyene on March 10, 2013, 14:23:16
That seemed to fix that issue, thanks!