tags:

views:

1044

answers:

3

I'm pretty much a newbie with opengl. I imagine glReadPixels is horrible so whats the best way to do this? I was thinking of having a function that locks a texture rect, do something like glTexSubImage2D to copy the pixels to RAM, modify it, then use glTexSubImage2D to copy the ram back into the texture. Is this a good way? I can think of optimizations like a flag saying not to copy the texture since you'll be overwriting it all and caching.

What other methods can I use? Can any of you tell me the names of the gl functions I may want (so I can read the manual) or point me to a tutorial? I tried googling but most of the results look like it was not doing what I had in mind.

+4  A: 

glReadPixels is the way to go.

Yes, it's slow - horrible slow. But that's the way it is. The DirectX counterparts (e.g. locking and reading the pixels) is not much faster either.

In general you want to avoid reading back pixels and doing something with the CPU on the data. You can do quite a bit processing using pixel-shaders, but that won't help you if you want to do screenshots (where the data must end up in the CPU).

Nils Pipenbrinck
A: 

The best idea would be to treat frame-buffer memory on the video card as write-only. I think the reason is that video memory is optimized for writing from the CPU side, at the expense of reading. (Obviously video memory can be read out quickly from the video-card side - it has to send it to the monitor in real-time)

The fastest solution will depend on what you're trying to do (care to elaborate?).

There's nothing stopping you keeping your own framebuffer in main memory, then copying that to a texture each frame and rendering it in OpenGL. I've done this before and it's a lot faster than glReadPixels, however you lose the ability to read back the results of other OpenGL rendering activity. Use that if all you need to do is keep frame-by-frame state of a part of your scene. eg: Generating a dynamic texture that cant be done via a pixel shader.

You may also be able to get away with reading back a much smaller set of data. I did that when I was playing around with non-realistic rendering. I took my scene, rendered it at 160x120,read that back into main memory, then re-rendered it as a collection of 2D sprites.

geofftnz