3

It is possible to bind multiple framebuffers and renderbuffers in OpenGL ES? I'm rendering into an offscreen framebuffer/renderbuffer and would prefer to just use my existing render code.

Here's what I'm currently doing:

// create/bind framebuffer and renderbuffer (for screen display)

// render all content

// create/bind framebuffer2 and renderbuffer2 (for off-screen rendering)

// render all content again (would like to skip this)

Here's what I'd like to do:

// create/bind framebuffer and renderbuffer (for screen display)

// create/bind framebuffer2 and renderbuffer2 (for off-screen rendering)

// render all content (only once)

Is this possible?

MrDatabase
  • 43,245
  • 41
  • 111
  • 153

1 Answers1

4

You cannot render into multiple framebuffers at once. You might be able to use MRTs to render into multiple render targets (textures/renderbuffers) that belong the same FBO by putting out multiple colors in the fragment shader, but not into multiple FBOs, like an offscreen FBO and the default framebuffer. But if I'm informed correctly, ES doesn't support MRTs at the moment, anyway.

But in your case you still don't need to render the scene twice. If you need it in an offscreen renderbuffer anyway, why don't you just use a texture instead of a renderbuffer to hold the offscreen data (shouldn't make a difference). This way you can just render the scene once into the offscreen buffer (texture) and then display this texture to the screen framebuffer by drawing a simple textured quad with a simple pass-through fragment shader.

Though, in OpenGL ES it may make a difference if you use a renderbuffer or a texture to hold the offscreen data, as ES doesn't have a glGetTexImage. So if you need to copy the offscreen data to the CPU you won't get around glReadPixels and therefore need a renderbuffer. But in this case you still don't need to render the scene twice. You just have to introduce another FBO with a texture attached. So you render the scene once into the texture using this FBO and then render this texture into both the offsrceen FBO and the screen framebuffer. This might still be faster than drawing the whole scene twice, though only evaluation can tell you.

But if you need to copy the data to the CPU for processing, you can also just copy it from the screen framebuffer directly and don't need an offscreen FBO. And if you need the offscreen data for GPU-based processing only, then a texture is better than a renderbuffer anyway. So it might be usefull to reason if you actually need an additional offscreen buffer anyway, if it only contains the same data as the screen framebuffer. This might render the whole problem obsolete.

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
  • 1
    @MrDatabase Do you have FBOs in 1.1 (if not, the whole question would be invalid, anyway)? If yes, then this will just work. Instead of the simple pass-through fragment shader, you just render a standard textured quad, disabling anything unneccessary (like lighting) to speed things up. – Christian Rau Oct 25 '11 at 17:11
  • 1
    @MrDatabase And by the way, you shouldn't create the FBO and renderbuffer anew each frame. Create them at the start and just bind them each frame. – Christian Rau Oct 25 '11 at 17:13
  • Yes 1.1 has FBOs via an extension. Ok I'll try using a texture :-) – MrDatabase Oct 25 '11 at 17:22
  • 1
    @MrDatabase What do you want to do with the offscreen data? – Christian Rau Oct 25 '11 at 17:25
  • I'm using `glReadPixels` to transfer the data from GPU to CPU. The purpose of the offscreen rendering is to reduce the resolution on the GPU hence speeding up `glReadPixels`. – MrDatabase Oct 25 '11 at 17:26
  • 1
    @MrDatabase - Yes, it should work on iOS with 1.1, because FBOs are used even for rendering to the screen in the OS. I don't think you'll even need `glReadPixels()` for anything here, as you could just bind the render target texture as an input for the onscreen rendering and go. I've done this myself, and it worked great. The only way I'd think you'd need that would be if you wanted the rendered scene for something else on the CPU side (like saving out to disk as an image). – Brad Larson Oct 25 '11 at 17:27
  • 1
    @MrDatabase In this case you won't get around the solution in the third paragraph (be sure to make the texture full-resolution), but you should evaluate if it really gives a speed-up over rendering twice or even dropping the additional FBO and directly reading from the full-res screen (though the latter might really be a worse idea, performance-wise). – Christian Rau Oct 25 '11 at 17:35
  • 1
    @BradLarson It seems he really needs a CPU copy and therefore won't get around using a renderbuffer (as ES doesn't have `glGetTexImage` and using a low-res texture would be a bad idea anyway). So the first to high-res texture, then from texture to both high-res screen and low-res FBO, seems like the best idea (except for rendering twice, maybe). – Christian Rau Oct 25 '11 at 17:40
  • Thanks for all the feedback. Just fyi rendering again into the additional ("lower resolution") renderbuffer and bringing the data over to the CPU with `glReadPixels` performs well. – MrDatabase Oct 25 '11 at 17:50