moving GLPanel from one to other AWT container

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

moving GLPanel from one to other AWT container

Ondrej
Is it good idea to remove GLPanel from one AWT container and add it other container? It would be useful in our application design but we could find alternative if you guys don't recommend it. I tried to add existing instance of GLPanel to other AWT container (JPanel) . First dispose and then init method (GLEventListener) were called. The GLAutoDrawable instance stays the same but getContext() method returns different instance. This must be the reason why all textures and probably all other resources allocated under the first context (before moving GLPanel) are lost.
Reply | Threaded
Open this post in threaded view
|

Re: moving GLPanel from one to other AWT container

Sven Gothel
Administrator
On Wednesday, March 23, 2011 21:48:23 Ondrej [via jogamp] wrote:
>
> Is it good idea to remove GLPanel from one AWT container and add it other
> container? It would be useful in our application design but we could find
> alternative if you guys don't recommend it. I tried to add existing instance
> of GLPanel to other AWT container (JPanel) . First dispose and then init
> method (GLEventListener) were called. The GLAutoDrawable instance stays the
> same but getContext() method returns different instance. This must be the
> reason why all textures and probably all other resources allocated under the
> first context (before moving GLPanel) are lost.

correct analysis ..

you may utilize a 'parent' shared context
holding your resources (textures ..).

then you can create your GLCanvas one passing he shared one.

we have to call dispose on removeNotify(), since this is the only chance
to release the GL stuff before passing the 'signal' to super,
which frees the native peer.

You could also use NewtCanvasAWT (see junit tests),
where a removeNotify() only reparents the NEWT window (child -> top window).
This is demonstrated in the many unit tests.

~Sven
Reply | Threaded
Open this post in threaded view
|

Re: moving GLPanel from one to other AWT container

Ondrej
Sven thanks for you hints. I still wonder how to create parent shared context. I tried to get it from "parent" GLCanvas:

GLProfile.initSingleton(false);
GLProfile glp = GLProfile.getDefault();
GLCapabilities caps = new GLCapabilities(glp);
parentCanvas = new GLCanvas(caps);
frame.add(parentCanvas);
frame.setVisible(true);

then created movable "child" GLCanvas:

canvas = new GLCanvas(parentCanvas.getChosenGLCapabilities(), parentCanvas.getContext());
canvas.addGLEventListener(glEventListener);
jPanel1.add(canvas);
frame.validate();
FPSAnimator animator = new FPSAnimator(canvas, 60);
animator.add(canvas);
animator.start();

after some user moves the canvas to second panel:

jPanel2.add(canvas);

also changed glEventListener to check if parent context is used:

@Override
public void init(GLAutoDrawable drawable) {
    System.out.println("init: context #" + System.identityHashCode(drawable.getContext()) + "  parent context #" + System.identityHashCode(parentCanvas.getContext()));
   
    if(drawable.getContext() != parentCanvas.getContext()) {
        drawable.setContext(parentCanvas.getContext());
    }
}

When init() is called for the first time context and parentContext are not the same. Is it correct to call drawable.setContext() from init()? I am getting this exception:

init: context #17303670  parent context #6533862
Exception in thread "Timer-0" javax.media.opengl.GLException: java.lang.NullPointerException
        at com.jogamp.opengl.impl.awt.AWTThreadingPlugin.invokeOnOpenGLThread(AWTThreadingPlugin.java:98)
        at com.jogamp.opengl.impl.ThreadingImpl.invokeOnOpenGLThread(ThreadingImpl.java:197)
        at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:164)
        at javax.media.opengl.awt.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:709)
        at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:361)
        at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:74)
        at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:140)
        at com.jogamp.opengl.util.FPSAnimator$1.run(FPSAnimator.java:125)
        at java.util.TimerThread.mainLoop(Timer.java:512)
        at java.util.TimerThread.run(Timer.java:462)
Caused by: java.lang.NullPointerException
        at com.jogamp.opengl.impl.GLDrawableHelper.reshape(GLDrawableHelper.java:193)
        at com.jogamp.opengl.impl.GLDrawableHelper.reshape(GLDrawableHelper.java:202)
        at javax.media.opengl.awt.GLCanvas$DisplayAction.run(GLCanvas.java:789)
        at com.jogamp.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:355)
        at javax.media.opengl.awt.GLCanvas$DisplayOnEventDispatchThreadAction.run(GLCanvas.java:810)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

This is just the first init, still didn't get to the second init, when moving canvas to other panel.

Maybe it would be better to use GLPBuffer for parent context instead of GLCanvas.

I will also try with NewtCanvasAWT. Can you please recommend which unit test to look at. I expect it will be some of these jogl/src/test/com/jogamp/opengl/test/junit/newt

Ondrej
Reply | Threaded
Open this post in threaded view
|

Re: moving GLPanel from one to other AWT container

Ondrej
I guess this piece of code:

@Override
public void init(GLAutoDrawable drawable) {
    if(drawable.getContext() != parentCanvas.getContext()) {
        drawable.setContext(parentCanvas.getContext());
    }
}

was nonsense.

I got it work just by passing shared parent context to GLCanvas constructor. If such canvas is moved into other AWT container, context instance changes but textures created with previous context (before the movement) are still usable.

But I still can not use textures created directly in parent context. Any idea?

OpenGL documentation (http://www.opengl.org/resources/faq/technical/texture.htm) says:
If you're using multiple rendering contexts and need to share texture objects between contexts, you must explicitly enable texture object sharing. This is done with the wglShareLists() function in Microsoft Windows and glXCreateContext() under X Windows.
Reply | Threaded
Open this post in threaded view
|

Re: moving GLPanel from one to other AWT container

Sven Gothel
Administrator
On Saturday, March 26, 2011 20:49:10 Ondrej [via jogamp] wrote:

>
> I guess this piece of code:
>
> @Override
> public void init(GLAutoDrawable drawable) {
>     if(drawable.getContext() != parentCanvas.getContext()) {
>         drawable.setContext(parentCanvas.getContext());
>     }
> }
>
> was nonsense.
>
> I got it work just by passing shared parent context to GLCanvas constructor.
> If such canvas is moved into other AWT container, context instance changes
> but textures created with previous context (before the movement) are still
> usable.
>
> But I still can not use textures created directly in parent context. Any
> idea?
>

http://jogamp.org/git/?p=jogl.git;a=tree;f=src/test/com/jogamp/opengl/test/junit/jogl/acore

2 unit tests for shared context AWT and NEWT

~Sven
Reply | Threaded
Open this post in threaded view
|

Re: moving GLPanel from one to other AWT container

Ondrej
This post was updated on .
Thanks Sven. I have seen the unit test. Now I also use PBuffer for parent context. Moving of GLCanvas between AWT containers works. Textures created in parent context are shared but after some number of moves I get exception:

javax.media.opengl.GLException: Unable to create temp OpenGL context for device context 0x69010309
        at jogamp.opengl.windows.wgl.WindowsWGLContext.createImpl(WindowsWGLContext.java:296)

The number of successful moves (before exception) differs from 5 to aprox. 50. Tested on notebook with ATI Catalyst 9.12.

Ondrej