6
\$\begingroup\$

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
\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

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.
\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – labotsirc
    Sep 16, 2012 at 15:16
3
\$\begingroup\$

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.

\$\endgroup\$
4
  • \$\begingroup\$ 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? \$\endgroup\$
    – user827992
    Sep 15, 2012 at 14:39
  • \$\begingroup\$ 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. \$\endgroup\$
    – msell
    Sep 15, 2012 at 15:02
  • \$\begingroup\$ I forgot to mention that by ffmpeg I meant the library (libavcodec I guess), not the executable. \$\endgroup\$
    – msell
    Sep 16, 2012 at 5:53
  • \$\begingroup\$ msell, do you by any chance have some java source you could post for increasing glReadPixels the two pbo's? \$\endgroup\$ May 1, 2013 at 22:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .