GLCanvas flicker fixed with gl.setSwapInterval(1) - what fix for GLJPanel?

I’m using the absolute basic pattern to animate in JOGL, i.e. using an Animator and writing some gl commands in the display(GLAutoDrawable) interface method. Nothing beyond the introductory tutorial level.

Everything works aside from some horrible flicker/jitter - looks like lack of screen refresh synchronization (see later).

I started used a GLJPanel, tried a few tweaks assuming the double buffering wasn’t working right, then tried a GLCanvas. Same flicker. Then I stumbled on the gl.setSwapInterval() function (I am an OpenGL beginner, but this seems a relevant JOGL question hence the post here) and all of a sudden I get beautiful, smooth, flawless animation (I am using a bunch of gl.glDrawPixels to render a large scrolling off-screen image buffer).

I get the exact same results on ATI and Nvidia, for what that’s worth (i.e. flicker for every combination except GLCanvas + gl.setSwapInterval(1)).

setSwapInterval apparently synchronizes page flipping until the next screen refresh (sounds like a good idea to me). The flicker I see very much looks like it could be due to lack of such synchronization.

SO, my question is, how do I get this synchronization in a GLJPanel which is the drawing surface that I’d really like to use? setSwapInterval makes no difference when I change a GLCanvas for a GLJPanel (and the API docs suggest this would be the case as it apparently only has effect with heavyweight components).

Does anyone have the magic synchronization call to make my GLJPanel as beautiful as my GLCanvas?

Thanks (and thanks for JOGL!)

Coincidentally, Chris Campbell from the Java 2D team and I were just talking about this a couple of days ago. Apparently what is needed is true vsync support at the Swing / Java 2D level. From what I understand this is coming in the Direct3D pipeline for Java 2D, but I don’t think this will help in the case of the GLJPanel, since it’s necessary to turn off all DirectDraw- and Direct3D-related code paths in order to use OpenGL due to driver-level incompatibilities between the two different graphics libraries.

Maybe Chris will have more suggestions, but to be honest I think your most reliable approach will be to pull more functionality up into OpenGL and use the GLCanvas for more of your rendering.

Thanks Ken. My plan was to render some interactive Swing components (buttons, menus) on top of the GL rendering - which of course works fantastically with a GLJPanel (nice work!). I’ll probably get away with it because in the application it only makes sense to have the Swing components rendered when the GL rendering is not moving, i.e. immune from the artifact, so hopefully I can grab a Screenshot and switch between the GLCanvas and a GLJPanel or JPanel for this without too much visual artifact…I’ll see.

I tried using Overlay to paint some widgets, but couldn’t get them to respond no matter how much I tried to get them the focus. The API docs do say that this is really meant for text and images but I thought it was worth a try anyway.

I did try forcing the graphics driver to always vsync via the NVidia control panel (couldn’t find the equivalent on the ATI box although it was alluded to) and also by setting the __GL_SYNC_TO_VBLANK environment variable to 1. Must be a Swing/Java 2D thing as you say as this made no difference.

This is a strictly OpenGL question, but I assume that to write buttons and menus in OpenGL you have to do all the hard mouse interpretation and widget rendering work by hand? Are there any OpenGL libraries or extensions that have pre-canned widgets?

Thanks!

Check out FengGUI… If all you are looking for is some widgets this might help. http://www.fenggui.org

Wow. Thank you so much for the pointer - this looks too cool.

Just wanted to mention one thing on the Swing/Java 2D issue: I used to get the same flawless, seemingly-synchronized rendering doing the same task (panning a large off-screen image) with a page-flipping BufferStrategy in full screen exclusive mode (as per the Sun tutorial on that). Whatever this implementation is doing under the hood, it seems to have the vsync enabled nicely…

(The reason I moved to JOGL is because the off-screen image data is coming from a JPEG2000 decompression library written in C [Kakadu] so directly passing ByteBuffers wrapped around native malloc’d memory to JOGL is far more elegant and faster than copying the data into a RenderedImage. Been using the same approach to call Intel’s IPP from Java for years now just by passing pointers around. Beautiful.)