user34537
user34537

Reputation:

Best way to access pixel in OpenGL?

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.

Upvotes: 7

Views: 3675

Answers (3)

user473816
user473816

Reputation: 356

As stated previously glReadPixels is the way to go. One way to make reading the framebuffer or accessing pixels faster is to use the ARB_pixel_buffer_object extension. This will let you do glReadPixels asynchronously and the performance can be much faster when you need to read large amount of pixels. The performance can be much faster because if you use the "right" format the transfer is done using DMA and does not consume precious CPU cycles.

Upvotes: 6

geofftnz
geofftnz

Reputation: 10092

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.

Upvotes: 0

Nils Pipenbrinck
Nils Pipenbrinck

Reputation: 86323

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).

Upvotes: 6

Related Questions