Some questions related to gl contexts and threads

The jogl user guide says that the AWT thread is the one that has the opengl context current. Does this means it’s ok to call gl methods from inside awt listeners?

Using jogl active rendering method similar to what is described in the Killer Game Programming book
http://fivedots.coe.psu.ac.th/~ad/jg2/ch15/index.html

suppose we want to use a different thread than AWT. If i understand correctly the rule is one drawable can have many contexts but one context per thread has to be associated to exactly one drawable. Also we have to make the context in each thread current before rendering one step and release it after. Is this correct?

What happens if we start messing with BufferStrategy in a canvas that is being used for opengl rendering? Just curious.

Although the AWT thread gets the context by default, it’s not always current. JOGL only makes the context current when it’s calling the GLEventListener methods; so it’s not okay to call gl methods from a KeyListener or MouseListener, etc.

As far as it goes for other threads, it sounds like you have the right rules. Keep in mind that JOGL by default forces everything onto the AWT thread internally, so you’ll have to call Threading.disableSingleThreading() to correctly get different threads to work.

I don’t exactly know what would happen with a BufferStrategy, but I believe a GLCanvas is double-buffered already because of opengl and I’m pretty sure the BS is unnecessary or could cause problems.

Thanks. That puts some light on this subject.

If you have a canvas that should always be looping and alot of gui around it. This forcing will make the gui slow (as for the application as a whole).

Can Jogl run on another thread? There was someting called worker thread in jogl 1.x but that was very buggy?

It’s possible to run it on another thread, but the worker thread was buggy. Although a GLCanvas will work reasonable well off of another thread, I’ve scene graphical glitches on Macs before. Also if the swing components are overlayed with the GLCanvas, I’d recommend keeping it single threaded.

Here’s a possible solution:

  1. Use the new Newt windowing for your primary GL window - it won’t contain any UI stuff
  2. Complex swing stuff can be in separate AWT windows around it

This setup would work best for an editor or utility and not a game. IMO a game should not be using swing components but instead use very simple widgets integrated with opengl (this should improve the consistency of the game’s LAF).

Im working on an application where the 3d scene is part of it showing the CAD model and all encapsulated in a jide layout. Having it a separate window wont do the trick for us!

[quote]As far as it goes for other threads, it sounds like you have the right rules. Keep in mind that JOGL by default forces everything onto the AWT thread internally, so you’ll have to call Threading.disableSingleThreading() to correctly get different threads to work.
[/quote]
Is this still required if you aren’t using a GLCanvas and building the GLDrawable directly?

I’m using the following code to associate a GLDrawable to a Frame. I’m actually surprised this is working.


private static Frame frame;
private static GLCapabilities capabilities;
private static GLDrawable drawable;
private static GLContext context;
private static GL gl;
private static GLU glu;

Part of a makeFrame method called from the main method.


capabilities = new GLCapabilities();
AWTGraphicsDevice dev = new AWTGraphicsDevice(null);
AWTGraphicsConfiguration awtConfig = (AWTGraphicsConfiguration) GLDrawableFactory.getFactory().chooseGraphicsConfiguration(capabilities, null, dev);
		
GraphicsConfiguration config = null;
if (awtConfig != null) config = awtConfig.getGraphicsConfiguration();
		
frame = new Frame(title, config);
		
frame.setSize(PWIDTH,PHEIGHT);
frame.setFocusable(true);
frame.requestFocus();
		
drawable = GLDrawableFactory.getFactory().getGLDrawable(frame, capabilities, null);
context = drawable.createContext(null);

// add listeners to frame
...

frame.setVisible(true);

The main method.


long period = (long)(1000.0 / DEFAULT_FPS) * 1000000L;
		
makeFrame("CubeGL (Active)", period);
		
while (!frame.isDisplayable()) Thread.yield();
		
drawable.setRealized(true); // can now be rendering into

stats = new FrameStatistics(period);
rot = new Rotator3D();
		
init();  // OpenGL initialization

loop();  // A while loop that calls simulUpdate and renderFrame

// Finalize
stats.printStats();
context.destroy();
System.exit(0);	

I didnt know you can have a drawable without a glcanvas :-\ . Will give it a try.

Thanks.

One question: Does this remove the drawable repaint from the awt thread?

You can use the setIgnoreRepaint(true) method but this is only a good idea if your window is a standalone window. If you want a GL window integrated with a gui then GLJPanel might be the best option.

but isnt glcanvas more performant than gljpanel

No idea, I’ve never tried. It’s pretty easy to tell if you debug and watch which thread the rendering is being conducted on.

It always go to the AWT-EventQueue thread