glDrawBuffer(GL_FRONT_AND_BACK vs GL_BACK)

(We’re on Windows, but I presume this is not Windows-specific, so I’m posting here).

It seems, at least with my graphics card (nVidia GeForce 9500 GT), that glDrawBuffer(GL_FRONT_AND_BACK) will not draw in parts of the view obscured by another window (draws to neither front nor back). However glDrawBuffer(GL_BACK) does draw in those parts. Is there any way I can force it to always draw even where obscured, at least for the back buffer? (Without resorting to separate GL_FRONT and GL_BACK passes that is, and without just using GL_BACK and using SwapBuffers() after each change).

Let me explain what I’m trying to do…

Our app can have complex scenes which take time to render, so we want to avoid redrawing as much as possible.

I am looking into the behaviour of SwapBuffers. Apparently on some systems it actually swaps the front and back, but on others (most?) it just copies the back to the front. We can test for this behaviour, and if present, use the back buffer as a cache, calling SwapBuffers() again when the window needs refreshing if nothing has actually changed. That is, it instantly copies the back buffer to the front again, without us needing to redraw everything.

So far so good. Problems occur when we draw something on top of the scene without redrawing everything (sometimes we recognise that this is possible). In that case, we draw to the front buffer directly. That will mean the back buffer is out of date, so we solve that by drawing to both the front and back buffers. However, as described above, this causes the a problem if another window (or dialog) is covering part of the view).

Similarly, if rendering takes too long, we do SwapBuffers() and then continue rendering to the front buffer, so that at least they can see the scene building up. Again, if we render to front and back, then the back buffer misses out on any obscured parts so isn’t a good cache. We could just draw to the back buffer (which draws in the obscured parts) and use SwapBuffers(), but we’ve found this is annoyingly slow in some cases.

Any thoughts?
Thanks,
Rob.

Is there any way I can force it to always draw even where obscured, at least for the back buffer?

No. Pixels not owned by the window (owned by overlapping windows) fail the pixel ownership test, so rendering to them will produce undefined results.

However, all pixels of a framebuffer object pass the pixel ownership test, so you can render to that.

Apparently on some systems it actually swaps the front and back, but on others (most?) it just copies the back to the front.

At least on Windows, you can define the behavior you want using the pixel format. Just use WGL_ARB_pixel_format to get a pixel format whose WGL_SWAP_METHOD_ARB is WGL_SWAP_EXCHANGE_ARB or WGL_SWAP_COPY_ARB. Of course, implementations may not support these, so you may not get a valid pixel format back.

Alternatively, you can just render to a framebuffer object and have complete control over your rendering.