Initialization steps...

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Initialization steps...

ThomasR
Hi,

I'm having trouble establishing a clean Jogamp Ardor3D initialization using AWT or Swing unless there's a visible window on the screen to which I've added a JoglAwtCanvas or JoglSwingCanvas, before FrameHandler.init().

I've played with the order a bit, whether FrameHandler.init() is called before or after the canvas is added to the FrameHandler. But it doesn't matter, the problem is that in the JoglAwtInitializerRunnable JoglAwtCanvas.getDelegatedDrawable() returns null and a NPE is thrown.

I need a generic way to initialize that doesn't depend on the order that components are created, or added to one another. We can't really force applications to do this. Do I have something wrong here? I created a workaround which starts another thread and checks if canvas.getDelegatedDrawable() is null in a loop. When its not null, I do FrameHandler.init() and start the runner thread which does FrameHandler.updateFrame(). It's actually works, but seems very problematic and infrequently fails. Could this be more tightly integrated into the Jogamp Ardor3D framework?

Tom
Reply | Threaded
Open this post in threaded view
|

Re: Initialization steps...

gouessej
Administrator
This post was updated on .
Hey

GLAutoDrawable.getDelegatedDrawable() can legally return null when the delegated drawable isn't ready and the implementation uses delegation instead of always returning the caller. I don't understand your problem, the examples work, what more can we do? Moreover, JogAmp's Ardor3D Continuation 1.0 should have been released last year, I'm quite late, some strong problems of design have to be fixed but the public API should remain mostly frozen and I should refrain myself from implementing new features now except if you want me to release a stable version in 2030...

Finally, maybe you're asking something impossible to do as there are some constraints when initializing the canvases except if you prefer working around the various weirdnesses of OpenGL drivers under Windows by yourself.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Initialization steps...

ThomasR
Hi Julien,

Jogamp Ardor3D is wonderful, and the examples are great!

Finally, maybe you're asking something impossible to do as there are some constraints when initializing the canvases except if you prefer working around the various weirdnesses of OpenGL drivers under Windows by yourself.
Yes, quite likely! I'm afraid we've become accustomed to bad and sloppy practice at times.

The problem is order of initialization and realization of components. I tool a look at ExampleBase and JoglBasicExample, and if you can, verify this is the proper initialization sequence:

frame = new JFrame()
canvas = new JoglAwt/Swing/NewtCanvas()
frame.setContentPane(canvas)
frame.setVisible(true)
canvas.init() // Also done by the FrameHandler.init()

I think this is the only order that will work.

We've become used to just creating and JFrames and Java3D Canvas3D in any order. So I think my workaround stated earlier is really "Don't canvas.init() until it has a visible, heavyweight ancestor". Perhaps there's a much better approach? I would just force the steps above, but there's already quite a bit of user and application code out there. I'm not sure if I'm making sensor or not.

I don't think my question is unreasonable considering that in JoglAwtInitializerRunnable:
        if (_joglAwtCanvas.getDelegatedDrawable().isRealized())
since getDelagatedDrawable() can be null, isRealized() will possibly throw a NPE (which it does, if above steps are not followed)

As to JogAmp's Ardor3D Continuation 1.0, that would be fantastic whenever you feel it's ready. Of course, entirely up to you. Perhaps, it could be branch on the Jogamp git repo? Whatever you think.

Is the version currently on the Jogamp git repo now the official version to use, it's what I'm running with now.


Thanks again,
Tom
Reply | Threaded
Open this post in threaded view
|

Re: Initialization steps...

gouessej
Administrator
Maybe you're not waiting for the right thing. Have you tried to wait for the realization of the drawable?

I have to clarify the initialization sequence in the documentation. When the frame handler calls canvas.init(), it will initialize the canvas only if it hasn't already been done. I don't use a frame handler in my game, that's why I always call canvas.init(). Java3D Canvas3D is very different, it's closer to an AWT canvas than something OpenGL related whereas it doesn't make sense to realize a non visible onscreen drawable without visible top level container.

isRealized() doesn't throw a NullPointerException:
https://github.com/sgothel/jogl/blob/master/src/jogl/classes/com/jogamp/opengl/awt/GLCanvas.java#L483

I have to throw Guava out of our engine, switch to Java 1.8 and fix a very few issues before releasing the version 1.0.

Yes, the "eviction" takes some time, be patient.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Initialization steps...

ThomasR
just to summarize quickly, I'm essentially correct regarding the initialization steps stated above, and my waiting solution should be workable? i'm thinking about an api change in our stuff as well.
Reply | Threaded
Open this post in threaded view
|

Re: Initialization steps...

gouessej
Administrator
I just fear that you do something more complicated than it should. If your waiting solution is poorly implemented, it will have some nasty side effects. Why not using GLAutoDrawable.invoke()? When it runs your stuff, you're sure that the drawable has been realized.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Initialization steps...

ThomasR
Do you mean something like this:

canvas = new JoglAwt/Swing/NewtCanvas()

call safeStart (see below)

safeStart = {
   canvas.invoke(true, GLRunnable)  // what is the GLRunnable in this case
   canvas.init()
}

frame = JFrame()
frame.setContentPane(canvas)

frame.setVisible(true)  //once this is done, then invoke would return? safeStart would still have to be called on separate thread though?

Tom

Reply | Threaded
Open this post in threaded view
|

Re: Initialization steps...

gouessej
Administrator
Rather call GLAutoDrawable.invoke(false, GLRunnable) and you can use a listener or a property change support in this GLRunnable to tell you when the initialization has ended:
http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/com/jogamp/opengl/GLAutoDrawable.html#invoke(boolean,%20com.jogamp.opengl.GLRunnable)

I don't know what you do but there is probably something deeply wrong if you really need such a mechanism. I remember that even the drawing methods try to trigger the initialization if necessary.

The problem is that the (onscreen) canvas can't become realized when its parent isn't visible.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Initialization steps...

ThomasR
For now, I will just require a visible component as input for the canvas or a separate start method that must be called after adding to a visible component (it would throw an exception otherwise)... a much bigger problem for us is Ardor3D running in separate Frames.