Shaders and window resizing for GLJPanel

I’ve recently converted my jogl application from using a GLCanvas to using a GLJPanel. My application uses GLSL shaders and basic textures, and I never had any problems with this before the conversion. However, with the new GLJPanel version, I have an annoying problem that keeps occurring whenever I resize the window. Somehow, my shaders seem to get invalidated and are no longer active after the resize: my triangles get drawn using the GL color instead of the procedural texture. This never happened for the GLCanvas version.

My question is simple: What am I doing wrong? What do I have to do to make sure that my shaders will continue to work after the resize? Surely I do not have to rebuild them again?

This is my post to this forum and I am fairly new to jogl and shaders (although not new to OpenGL), so I apologize if this has been answered elsewhere. I am running Windows and JDK 1.6.0 and the jogl-1.0.0 release. Thanks in advance.

You are not doing anything wrong. GLJPanel renders to a pbuffer. Every time you resize your GLJPanel that pbuffer is destroyed and then created again to the correct size. Thats why your shaders and textures are disappearing. I believe that you can avoid this by creating a dummy pbuffer that you keep around to share resources with. Or you can try -Dsun.java2d.opengl=true in order to use the java2d/opengl pipeline and avoid all the destructive resizing.

As GKW says this is expected behavior for many of the operating modes of the GLJPanel. Creating and sharing textures and display lists with a 1x1 pbuffer can work around the problem. However, your GLEventListener should be written to recreate all of the necessary shaders, etc. in your init() method, and to support multiple calls to init(). Note, however, that if you share server-side objects with a 1x1 pbuffer, that you should not recreate them in your init() method, because the old ones won’t have been deleted by the OpenGL driver and doing so would cause a resource leak. This determination (of whether to recreate server-side objects in init()) is something only the application can know whether it needs to do.

I see, that makes sense. Many thanks for the replies so far, it is very much appreciated. After installing a DebugGL in my pipeline, I get the following exception whenever I am trying to use my shader program:

javax.media.opengl.GLException: This GL object is being incorrectly used with a different GLContext than that which created it

I guess that is consistent with what you are saying?

Might there be a related issue with textures? I am seeing something similar there. Any pointer on how to create and share these resources with a 1x1 pbuffer? I’m afraid that’s unknown territory to me.

No, this sounds like a bug in your code. You should re-fetch the GL object out of the GLAutoDrawable each time you enter your GLEventListener’s init(), display(), and reshape() methods. It sounds to me like you’ve cached the GL somewhere.

It’s simple:


  GLPbuffer oneByOne = GLDrawableFactory.getFactory().createGLPbuffer(new GLCapabilities(), null, 1, 1, null);
  // I think you need to forcibly display this once to get its OpenGL context created
  oneByOne.display();
  GLJPanel myPanel = new GLJPanel(new GLCapabilities(), null, oneByOne.getContext());

Take a look at demos.testContextSharing.TestContextSharing in the jogl-demos workspace.

Oh, I see. Thanks, I am going to look into it. This didn’t seem to happen for the GLCanvas, so I guess that’s what got me. Also, thank you for the code example, this will get me going.