Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have implemented a lense flare for my game, and it looks great. The first draft used individual sprites each with its own draw call. This was very slow, so I reengineered it to use a single draw call, expecting it to be much faster. It's not.

I realise now that it is the call to glReadPixels that is the culprit. I have read that the function is slow, especially for reading the depth buffer, but I am reading only a single pixel. And my drawing goes from about 2ms to 15ms (although I'm not sure I trust my timings).

I know that glReadPixels stalls, because it has to wait for all previous operations to finish. Another point is that I would like to port my game to mobile devices at some point, and it's even worse there, perhaps impossible using the depth reading technique.

So my question is, is there a way to speed it up. For example, can I refactor things so that I only do the test at the very end, or perhaps use last frame's data. This is tricky because I have a splitscreen game and use offscreen buffers. Or should I just bite the bullet and implement raytracing. I can do this and my geomentry is simple and static, so fairly easy to use a kdtree or something, but I'd rather not if I don't need to. Thanks

share|improve this question
6  
What are you reading the pixel for? Is there an other way to get the same information? –  John McDonald May 13 '13 at 1:51
2  
The number of pixels you read doesnt matter as much as the stall, which you'll still get even with a 1x1 region and on the fastest modern hardware - better to use a method that doesnt involve reading back (e.g if you don't need the actual depth values but instead whether something is visible or not, use occlusion queries with a 3 frame delay between issuing a query & fetching it's result) –  Darth Satan May 13 '13 at 2:37
    
Occlusion queries. Perfect, that's exactly what I need. Never knew about them before. I will write it up as an answer soon. Cheers –  DaleyPaley May 13 '13 at 7:50
    
@DaleyPaley: Occlusion queries aren't going to be that much faster, since you're still going to have to synchronize to read the values back. –  Nicol Bolas May 13 '13 at 11:52
    
As soon as you're calling glReadPixels, it sounds like you're doing CPU processing instead of GPU processing. If you're doing 2 pass rendering, you need to render your scene first to an offscreen FBO. Consider the backing of that offscreen FBO as a "texture" and render again as a single TEXTURED QUAD (flat image), applying your per-pixel effects then in a pixel shader. –  bobobobo May 13 '13 at 13:40

1 Answer 1

You might want to use double buffering for the FBO and a Pixel Buffer Object to read the depth from the previous frames depth map to get rid of any CPU stall, as in your case it shouldn´t be a problem if it is a frame behind.

I currently have the same problem and I can´t use double buffering as it would mess everything up a lot, but from profiling and playing around with it, I am quite sure that the problem actually is the CPU stall, as for example simpler shaders will improve the performance a lot. I don´t know what is happening, but (at least with double buffering and multi threaded rendering) it seems as if rendering is usually a frame behind and the moment you call glReadPixels it has to finish rendering of the previous frame and then render the current frame while the CPU is waiting the whole time (I am probably completely wrong, but I didn´t find any usefull information for my issues and working on OSX I unfortunately don´t have any good OpenGL profiling tools available).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.