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 need a way to capture what is rendered on screen, i have read about glReadPixels but it looks really slow.

Can you suggest a more efficient or just an alternative way for just copying what is rendered by OpenGL 3.0+ to the local RAM and in general to output this in a image or in a data stream?

How i can achieve the same goal with OpenGL ES 2.0 ?

EDIT:

i just forgot: with this OpenGL functions how i can be sure that

  • I'm actually reading a complete frame, meaning that there is no overlapping between 2 frames or any nasty side effect
  • I'm actually reading the frame that comes right next to the previous one so i do not lose frames
share|improve this question
add comment

2 Answers 2

You can boost the performance of glReadPixels a lot by using Pixel Buffer Objects. This tutorial gives an example on how to do it. The idea is to use two PBOs. After a frame is rendered (either to the screen or to an FBO), bind one PBO and read the pixels to the PBO. This starts an asynchronous data transfer. In the next frame the data has been transferred and you can map the buffer for reading the data from it fast and also issue another read command for reading the current data to another PBO. Note that PBO itself doesn't speed up the transfer, but it allows asynchronous data transfer.

With this approach I can capture HD-video from OpenGL with 60 FPS without noticing any performance penalty. With ffmpeg I can also encode it realtime as an .mp4 video in another thread.

share|improve this answer
    
my doubts are about how to connect ffmpeg with this data stream, this PBO returns a pixel array or a complete image? And in what format? It's encoded? Can you explain more the ffmpeg part? –  user827992 Sep 15 '12 at 14:39
    
I'm not using ffmpeg directly. Instead I use Java wrapper library called Xuggler: xuggle.com/xuggler. Anyway the idea should be the same. glReadPixels gives RGB(A) byte array, which is given to ffmpeg for encoding. It may need to be converted to YUV-format before encoding, which ffmpeg can also do. –  msell Sep 15 '12 at 15:02
    
I forgot to mention that by ffmpeg I meant the library (libavcodec I guess), not the executable. –  msell Sep 16 '12 at 5:53
    
msell, do you by any chance have some java source you could post for increasing glReadPixels the two pbo's? –  Bill Gockeler May 1 '13 at 22:37
add comment

The OpenGL 3.3 way:

The OpenGL ES 2.0 way:

  • I'm not sure how to achieve the same in OpenGL ES 2.0, but there are probably OGL extensions which allow you to do the renderbuffer/framebuffer part as described in the OGL 3+ way.
share|improve this answer
    
i support this answer since the best one can do is just one transfer through PCI express using a common GPU. However in modern CPU+GPU chips the same texture could be shared in a productor/consumer way, simulating the stream. –  labotsirc Sep 16 '12 at 15:16
add comment

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.