Offscreen Rendering: Alternative for pbuffer/FBO?

Hi,

my MFC based application generates scenes based on a time code that is sent from an external device. For each frame in the time code a set of up to 4 plugins renders their content into a GDI memory device context. When all 4 are finished, the main thread merges the contents of all 4 memory device contexts into one and blits it into the device context of the output window.

The reason whey each plugin is rendering into its own memDC is, that they don’t know where on they screen their content shall go to. My application just tells them “render your content into a rectangle of cx width and cy height”.

Now I want to migrate from GDI to OpenGL for two reasons:

  1. More graphics power (i.e. better effects than in GDI)
  2. Portability (I plan porting to linux in the near future)

===================

Long introduction, here comes my problem: In order to do the offscreen rendering that I did with memDCs in GDI, I thought over using FBOs or pbuffers in OpenGL. But my graphics card does not support both of them! (ATI Radeon Mobility 9500). So I took another PC with a Radeon 7500, but same problem there!

I figured that after distributing my application, there will be many PCs withouf FBO/pbuffer support. That means, I need an alternative.

Here’s what I have tried so far.

  1. I tried using Mesa, but that’s really slow. Rendering into an offscreen area works, and I can access the data using glReadPixels and then blit it into my output window using glDrawPixels or creating a texture of it. But it’s really, really slow.

  2. Rendering into a second window, getting the contents using glReadPixels and then blitting into the ouput window using a texture. Good performance, but the second window must be visible! Otherwise, the pixels cannot be accessed. My application is actually supposed to run with one single window in fullscreen mode…

Any ideas how to solve this? My last option is to buy a new graphics card and tell all users without FBO/pbuffer support “Sorry, this application does not work on your PC, because it requires OpenGL 3.x… :(”

I wonder how game developers handle this…

PS: Another option would be to restrict the rendering area of each plugin. Say plugin 1 can only render into a rect of 100x100 at x=50, y=200. If that would be possible, I wouldn’t need offscreen rendering.

But my graphics card does not support both of them! (ATI Radeon Mobility 9500).

According to the OpenGL extension viewer, this does support WGL_ARB_pbuffer. You may need the latest supported drivers to get this support, however.

“Sorry, this application does not work on your PC, because it requires OpenGL 3.x… :(”

Neither FBO nor pbuffers requires OpenGL 3.x. What they do require are drivers that support those extensions. FBO has only been around for 3-4 years, so hardware older than that (like yours) likely won’t have an implementation.

The funny thing is that the non-mobility 9500 does support FBOs.

I wonder how game developers handle this…

OpenGL game developers generally don’t develop for cards of that age.

Hmm, have you considered using an Accumulation Buffer? it’s definitely more supported than a FBO.

EDIT: more info on it.

Hmm, have you considered using an Accumulation Buffer? it’s definitely more supported than a FBO.

I wouldn’t be too sure about that. Much accumulation buffer support is software-based.

If your certain that your 4 rects will always be smaller than your main window rect, you could always just render to your main window. The solution would be to render, read pixels, clear, then repeat. Because you won’t do the SwapBuffers until after you’ve rendered all 4 you won’t need to worry about them displaying on the main window during the rendering.

Thanks for all the answers!

That might be just the solution I was looking for! I’ll give it a try tonight.

I think my plugins render parallely, not sequentially. From what I know, only one thread at a time should use a context. I will try having the plugins render sequentially. Anyway, is there a way that several threads share one context?

EDIT: I stumbled on the topic “Clipping”. Could that be an alternative for me? Say, “Clip render area of back buffer to x,y,cx,cy, render plugin 1, clip next area, etc.”

Regarding my last EDIT above: I think glScissor could do the trick. I will try it today. Together with mhagain’s idea (use the backbuffer), it could be a solution. I’ll keep you guys posted.

Here’s my feedback: the glScissor is doing exactly what I want. Together with using the backbuffer, I have a solution that allows to control the output of my plugins without using offscreen rendering.

Thanks for all your comments.

If you’re rendering to the main window backbuffer, you need to be confident that your window is always going to be topmost. If a part of the window is covered by something else, rendering to that part isn’t guaranteed to draw anything.

The term to Google for is “pixel ownership test”.