views:

816

answers:

2

What is eligible way to implement double buffering in JOGL (Java OpenGL)?

I am trying to do that by the following code:

...    

/** Creating canvas. */
GLCapabilities capabilities = new GLCapabilities();
capabilities.setDoubleBuffered(true);
GLCanvas canvas = new GLCanvas(capabilities);

...

/** Function display(…), which draws a white Rectangle on a black background. */
public void display(GLAutoDrawable drawable) {
    drawable.swapBuffers();

    gl = drawable.getGL();

    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    gl.glColor3f(1.0f, 1.0f, 1.0f);

    gl.glBegin(GL.GL_POLYGON);
    gl.glVertex2f(-0.5f, -0.5f);
    gl.glVertex2f(-0.5f, 0.5f);
    gl.glVertex2f(0.5f, 0.5f);
    gl.glVertex2f(0.5f, -0.5f);
    gl.glEnd();
}

...

/** Other functions are empty. */

Questions:

— When I'm resizing the window, I usually get flickering. As I see it, I have a mistake in my double buffering implementation.

— I have doubt, where I must place function swapBuffers — before or after (as many sources says) the drawing? As you noticed, I use function swapBuffers (drawable.swapBuffers()) before drawing a rectangle. Otherwise, I'm getting a noise after resize. So what is an appropriate way to do that?

Including or omitting the line capabilities.setDoubleBuffered(true) does not make any effect.

+1  A: 

Here's an example of double-buffered animation using JOGL:

http://www.java-tips.org/other-api-tips/jogl/how-to-implement-a-simple-double-buffered-animation-with-mouse-e.html

Try instead of calling swapBuffers(), at the end of display(...) call:

gl.glFlush();

It's been a while since I've done anything with JOGL; hope this helps.

RMorrisey
You need both. glFlush flushes the polygon pipeline, drawing everything to the video buffer. But you still need to swap buffers to make the result visible on the screen.
finnw
+2  A: 

If JOGL is like the C/C++ version:

RMorrisey and the sample code is incorrect in stating the use of glFlush.

The swapBuffers function must go at the end of the drawing.

To confirm this: have the shapes do animation very quickly and watch for tearing. If you get tearing then you are doing a single draw, if you don't then you are using double buffering.

monksy
If you get tearing it may just be that the buffer swapping is not synchronized with the screen refresh.
finnw
Double buffering is designed to intentionally avoid that. Rather directly draw onto the screen, the results are cached in the background and then the new memory segment is shown on the screen.
monksy
What Steven says is true... but only if you do what finnw says. In JOGL, this is accomplished by the (default: on) AutoSwapBufferMode in GLDrawable (in case the OP manually shut it off elsewhere in code).
Dave
that sounds like something that the Java version would do. You should be double bufferring anyways
monksy