Using the JOGLDisplaySystem wih and existing GLAutodrawable

The following change allows the JOGLDisplaySystem to use a window (a GLAutodrawable) that was created outside of JME.  This is used within jMirrorWorld to allow JME to interact with the window created by World Wind.


### Eclipse Workspace Patch 1.0
Index: src/com/jme/system/jogl/JOGLDisplaySystem.java
===================================================================
--- src/com/jme/system/jogl/JOGLDisplaySystem.java   (revision 4479)
+++ src/com/jme/system/jogl/JOGLDisplaySystem.java   (working copy)
@@ -562,6 +562,62 @@
         gl.setSwapInterval(0);
     }
 
+    public GLContext createContext(GLAutoDrawable currentDrawable) {
+        if (autoDrawable != null)
+            throw new IllegalStateException();
+
+        width = currentDrawable.getWidth();
+        height = currentDrawable.getHeight();
+
+        autoDrawable = currentDrawable;
+
+        // Create the context reusing the existing surface. This creates a
+        // context just like the construction of a GLAutoDrawable such as
+        // a GLCanvas.
+        GLContext existingContext = currentDrawable.getContext();
+        GLContext context = autoDrawable.createContext(existingContext);
+        logger.info("AutoDrawable.createContext(" + existingContext + "): Error Code = "
+                + currentDrawable.getGL().glGetError());
+       
+        // Make the new context current so that OpenGL operations will use
+        // this context.
+        while (context.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {
+            logger.info("GLContext.makeCurrent(): Error Code = "
+                    + currentDrawable.getGL().glGetError());
+           
+            try {
+                logger.info("Waiting for the GLContext to initialize...");
+                Thread.sleep(500);
+            } catch (InterruptedException interrupted) {
+                logger.log(Level.WARNING, "Interrupted", interrupted);
+            }
+        }
+
+        // Enable automatic checking for OpenGL errors.
+        // TODO Make this configurable, possibly from a system property.
+        // TODO Can this be centralized in createGLCanvas?
+        context.setGL(new DebugGL(context.getGL()));
+
+        // TODO Move this into the canvas, instead of grabbing the current
+        // current GLAutoDrawable, since this precludes multiple canvases.
+        // TODO UPDATE: Switch to context-based scenario.
+        JOGLContextCapabilities caps = new JOGLContextCapabilities(autoDrawable);
+        renderer = new JOGLRenderer(this, caps, width, height);
+
+        // This renderer is "headless" because someone else will be responsible
+        // for displaying back buffers, etc.
+        renderer.setHeadless(true);
+
+        // TODO switching to GLAutoDrawable as the key would allow this to be
+        // centralized. The other option is to move the context into the surface
+        // where it belongs.
+        currentContext = new RenderContext<GLContext>(context);
+        currentContext.setupRecords(renderer);
+        updateStates(renderer);
+
+        return context;
+    }
+
     @Override
     public boolean isActive() {
         // TODO Auto-generated method stub return false;

Is a so long sleep necessary?

Thread.sleep(500);

The length of time to wait before checking again for the GLContext to initialize could be changed.  I just looked, and found that the same basic code appears 3 times in JOGLDisplaySystem:


    while (contextKey.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {
        try {
            logger.info("Waiting for the GLContext to initialize...");
            Thread.sleep(500);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }



We could consolidate the code into a single internal method, and consider shortening the delay between checks.

cylab makes the same kind of call in ensureContextCurrent(). We will have to factorize this code.

You can submit the code as it is, we will do something cleaner later.

gouessej said:

You can submit the code as it is, we will do something cleaner later.
Are you sure that is a good idea?.. How will you assure that 'doing something cleaner later will ever happen?
erlend_sh said:

gouessej said:

You can submit the code as it is, we will do something cleaner later.
Are you sure that is a good idea?.. How will you assure that 'doing something cleaner later will ever happen?

We will factorize the source code once cylab will have finished his fixes. I will write a method that performs the operations common with cylab's and woody's fixes and I will replace the duplicated source code by a call of this method.