JOGL design issues

You can also take a look at FengGUI:
http://www.fenggui.org/doku.php

Good idea.

If you need a progress bar in JOGL, look at mine in the class “main.GLProgressBar”. I have a sort of menu in JOGL too, look at my class “main.GLMenu”. I use GLCanvas as it is more reliable as faster.

Since the above flurry of posts I’ve been modifying my engine to use AWLGLCanvas as a couple of posters suggested with mixed results - it forces the architecture of the engine to bend in a similar way to my gripe about the JOGL event listener, i.e. one has to get the canvas (or the listener in the JOGL case) to ‘call-back’ to the engine in order to do initialisation and drawing. The canvas should just refresh itself when it’s told to, not tell the application when to initialise itself or render a frame. Again this is fine if you’re putting together a simple demo but doesn’t scale well.

For example, the underlying LWJGL context is only setup in the paint() method (:slight_smile: once the rendering loop has started, i.e. you have to create the canvas and start a rendering thread before you can create your scene, upload textures, etc. Why? You don’t have to do this is you used to Display class, you just open the window and the GL APIs are immediately available, you don’t have to wait for the rendering loop to start.

I’m going to investigate writing my own canvas class based on the AWTGLCanvas code with the initialisation of LWJGL outside of the paint method. Ho hum.

IIRC this is due to how OpenGL deals with threading and contexts - a GL context can only be “current” in one thread at a time, and only that thread is allowed to make GL calls. Now when you’re using LWJGL’s native display you only have your main thread and so everything works nicely. When you using Swing then all the drawing has to be done in the AWT event thread, which the AWTGLCanvas manages for you.

If you want to do initialisation (like texture loading) in a thread other than the AWT event thread you can use Display.makeCurrent(). Obviously this comes with the usual threading cavets, so you’ll need suitable synchronization to make sure some other thread doesn’t currently have the context (eg. for drawing).

For drawing I don’t understand what your problem is - you do your drawing inside the paint callback so that it’s being done in the AWT event thread, and other code (like your main thread) just has to call canvas.repaint() when it wants the canvas to be redrawn.

OK cheers for that, I’ll check out the Display.makeCurrent() approach and see if that helps.

For drawing it isn’t a big deal as such, my only gripe is that the drawing code has to be invoked from paintGL(), so I have to set this in the canvas, invoke repaint() and then have the canvas ‘callback’ to the engine to do the rendering - this is a little irritating but hardly the end of the world. It’s the sort of dilemma you face whenever working with an AWT/SWING based application.

I’ll also try using Display.makeCurrent() in the existing rendering part of the engine so that the canvas is dumb and just gets told to repaint() at the end of the loop to update the scene and swap the buffers.

Incidentally I’ve started another thread on this specific issue in the LWJGL forums, apologies for multi-posting:

http://www.java-gaming.org/index.php/topic,19110.0.html

Can’t quite see what your issue is here… this is the correct, sensible and obvious way to do it??

Cas :slight_smile:

It might be the standard or most popular way of doing it, but that isn’t necessarily the best.

For a simple demo, it’s nice and quick and makes a lot of sense, e.g.

MyListener implements GLListener {
init() {
enable stuff
load textures etc
}

update() {
    render scene
    update stuff
}

...

}

But this does not scale, i.e. the more complex your application becomes, the more code you have to put in these methods. So the sensible approach is to move that code into other objects, which is what my engine does. So I’ve got classes for viewports, models, lights, textures, etc. that are wrappers around the JOGL or LWJGL APIs.

But the listener approach means that it has to invoke the engine to render the scene. i.e. what you get is the engine telling the canvas to update itself (in the rendering loop) which then has to tell the engine to do the actual repainting, which is daft.

The app contains contains the main thread and the various lights, models, instances, etc, so it should be its responsibility to render the scene and tell the canvas when its time to swap the buffers, not the other way around.

As an analogy, you don’t put the code for a button action inside an instance of the button class, you link an action with the button. It’s responsibilities are drawing itself and invoking the action on a click, not executing the actual action. (I know this is a rather trite simplification :wink: but you get the idea I hope).

Ah, I think you might want to look into active rendering for AWT. Maybe that’s what you want - that’s where you have your own rendering loop and tell AWT components precisely when to paint.

Cas :slight_smile:

Normally an engine is designed in a way, that the scenegraph just represents the data and logic of your game while it is rendered by a dedicated renderer, that has nothing to do with your scenegraph objects. It does not even get most of the scenegraph objects, because they converted to render primitives by some kind of preprocessor that can be depth and state sorted, so the render has nothing more to to than to iterate over a flat list of this primitives, changes the gl state and the modelview matrix from time to time and pushes the data to the card.

Yeah I think so, and someone else has also pointed me at this approach. Also the new Display.setParent() method in v2.0b1 looks like it will do something similar.

Yes you’re dead right, and this is the approach I’ve used. Bad choice of language when I described the engine doing the rendering above, I meant it was responsible for the scene graph data/logic (as you’ve described), but delegates to a ‘platform’-specific renderer to do the actual OpenGL stuff using LWJGL, JOGL, whatever. So I think the architecture is correct :persecutioncomplex: :wink: