AWYGLCanvas and threads

Started by lwjuggler, July 25, 2009, 21:57:37

Previous topic - Next topic

lwjuggler

Hi all,
     I am trying to write an application which contains an AWTGLCanvas with GUI around. I use the Canvas as a "java2d component" that means, i repaint() the component only when needed. The problem is that when i call functions concerning projections (like glGetEnv(), gluProject() etc) ) directly in a MouseActionListener's perform method, i get a NullPointerException, because I'm not in an opengl thread. So, what i do to get calculations of projections is to do them in the paintGL method of the Canvas, so it is not very proper. What do you advise me to do ?
I hope I was a minimum clear, if I wasn't I can post my code.

ey6es

Quote from: lwjuggler on July 25, 2009, 21:57:37
So, what i do to get calculations of projections is to do them in the paintGL method of the Canvas, so it is not very proper. What do you advise me to do ?

I believe you should be able to make the calls successfully by calling AWTGLCanvas.makeCurrent before invoking the methods and AWTGLCanvas.releaseContext after.

I'm curious, though, as to the rationale of releasing the context outside of the paint method.  For the tools I've been developing, which are largely single-threaded (with everything involving OpenGL happening in the event dispatch thread), I used some hacky workarounds to keep the context current at all times in the thread (bypassing AWTGLCanvas's attempts to release it).  You can see what I did in our Google Code repository at http://code.google.com/p/clyde/source/browse/trunk/src/java/com/threerings/opengl/GlCanvas.java.  That worked great until I recently upgraded to Ubuntu 9.04, Jaunty Jackalope.  Now I get frequent crashes (on window resize, for instance) that seem to be related to XWindows thread usage.  I would switch to using Display.setParent, but the tools rely heavily on AWT mouse and keyboard event processing.  Was there an X-specific reason why AWTGLCanvas was changed to release the context?

broumbroum

I think the most pratical approach is to leave the GLContext to Swing, though it can be make current-released. let's call it the Swing-OGLThread, here's how I have it like :

  • As Swing is using common ED-Threads (there may be to AWT-EventQueue), it shouldn't crash and you ensure that all rendering tasks are done within Swing (see SwingUtilities.invoke methods);
  • To capture events, it's worth trying in the JInput fashion, i.e. polling keyboard-mouse-pads events on the Swing-OGLThread, whereas Swing dispatchers would solely capture-and-enqueue in some Stack;
  • Last but not least, these two processes must be synchronized (on Stack's), so that it won't loop too long when Swing captures input-events.
Noticeable, is that getting-releasing context is done properly in the paint() process (thx ey6es!), but it's worth ignoring repaint() calls (it's difficult to know when it will occur exactly).

lwjuggler

Thank you ey6es for your fast answer, you saved my life ^_^, it's just what i needed for the moment, i'll take a look at your code later. I wish you lot of success on your projects. see you.