I started a topic http://www.java-gaming.org/index.php/topic,19099.0.html in the newbies forum which pointed me towards AWTGLCanvas. Having had a play with this canvas class I’ve got a couple of further questions which are probably best raised in this forum:
First a little background: I’m designing and implementing an engine that is OpenGL agnostic, i.e. it handles the generic side of a 3D application: models, texture blending, vector maths, etc. The engine defines a set of interfaces that a specific OpenGL library implements to handle rendering, lighting, texturing, etc. I’ve got two implementations, one for JOGL (largely incomplete) and another for LWJGL (largely done :)).
The LWJGL implementation initially used the Display class to create the window and Keyboard/Mouse to handle input. Once I started on the JOGL version I realised that I’d been re-inventing the wheel to some extent - it would much nicer to use standard Java APIs for creating the frame and keyboard/mouse handling, which is why I ended up looking at AWTGLCanvas.
But having altered the LWJGL library to use AWTGLCanvas I’ve realised that it’s screwing the engine architecture and I don’t like it.
Like most applications, the engine sets everything up then starts a rendering loop that redraws the scene, updates the game and swaps the buffers:
- open the display
- init the application (build the scene-graph, load models, texture images, etc)
- setup input devices handlers
- rendering loop:
- update context (timing, etc)
- render scene
- swap buffers
- update game
But this approach won’t work with the AWTGLCanvas. I (perhaps naively) expected I could just leave the engine as it is and change step 3 above to invoke repaint() on the canvas. Oh no - null-pointers all over the place. It appears that the LWJGL context is only created in the paint() method ( :-!) of the canvas, and is not valid outside of that method. Why? You don’t need to be concerned with this context notion when using the Display approach, the GL APIs are globally available.
This forces me to sub-class the canvas, put the initialisation code in initGL() and the scene code in paintGL(), or at least call back to the engine to do it. I can understand why this is as it is, the developer followed the AWT/SWING paradigm. It’s bad design but that’s the way the AWT/SWING developers decided to do things - deal with it you might say.
But I’m not giving in just yet, so:
-
Is what I’ve written above correct? i.e. the GL APIs are not available outside of this loop.
-
If so, why? It works when you use the Display approach.
-
Is there anyway I can get access to the GL APIs outside of the painting loop such that my engine remains largely as it is? Or am I going to have to start the rendering loop and then wait for the initialisation and painting ‘callbacks’ from the canvas?
-
As a small aside - should I be using AWTGLCanvas and standard Java APIs for display modes, input devices, etc. in a real-world LWJGL application anyway, or should I be using the Display/Keyboard/Mouse approach? What is the general approach used out there?
I hope this makes some sense. Cheers in advance for any suggestions.
The only drawback is that you can have only one Display at once.