opengldoublebufferedframe-ratemultisamplingwgl

WGL: No double buffering + multi sampling = FAIL?


I usually create a pixel format using wglChoosePixelFormatARB() with these arguments (among others):

WGL_DOUBLE_BUFFER_ARB = GL_TRUE
WGL_SAMPLE_BUFFERS_ARB = GL_TRUE
WGL_SAMPLES_ARB = 4

i.e. double buffering on and x4 multisampling. This works just fine.
But when I try to turn of the double buffering:

WGL_DOUBLE_BUFFER_ARB = GL_FALSE
WGL_SAMPLE_BUFFERS_ARB = GL_TRUE
WGL_SAMPLES_ARB = 4

The call to wglChoosePixelFormatARB() fails (or rather indicates it didn't create anything)
When I effectively turn multisampling off:

WGL_DOUBLE_BUFFER_ARB = GL_FALSE
WGL_SAMPLE_BUFFERS_ARB = GL_TRUE
WGL_SAMPLES_ARB = 1

I works fine again.

Is there something inherent that prevents a non-double buffered pixel format to work with multisampling?

The reason I'm turning double buffering off is to achieve unconstrained frame rate. with double buffering the frame rate I get is only up to 60 FPS (this laptop LCD works at 60Hz). But with double buffering off I can get up to 1500 FPS. Is there a way to achieve this with double buffering on?


Solution

  • In theory, drawing in a single-buffer mode means that you're directly modifying what is being presented to the screen (aka the front buffer). Since that memory is in a specific format already, you don't get to choose another one. (I'm saying in theory because the platform does however it pleases it in practice. Aero for example does not allow access to the front-buffer).

    Moreover, when doing multisampling, the step that converts the X samples/pixel to 1 pixel for drawing is when the back-buffer is copied to the front buffer (what is called the resolve step). In single buffer mode, there is no such step.

    As to your 60 fps locking, you might want to look atWGL_EXT_swap_control. The issue here is that you don't generally want to update what is being shown on screen while the screen refreshes the data; it creates tearing. So by default, Swap only updates while the screen is vertical syncing (aka vsync), so you end up locking to the refresh rate of the screen.

    If you don't mind your display showing parts of different frames, you can turn it off.

    For completeness, there is an alternative mode called triple buffering, that essentially has the GPU ping-pong rendering between 2 back-buffers while the front buffer is shown. It is up to the gpu to pick the last finished back-buffer when comes time to change what shows on screen (vsync). Sadly, I am not aware of a WGL method to ask for triple buffering.