How can I store the contents of an FBO?


#1

Hey all,

I’m trying to store the Color texture of an Fbo into a gl::TextureRef but with no luck. I’m wondering if it’s possible at all.

My first idea was to do something like this:
mTexture = gl::Texture::create( mFbo->getColorTexture() );
But there is no matching constructor…

And doing:
mTextureA = mFbo->getColorTexture();
just passes the underling reference so whenever the fbo get’s updated the texture also changes, some that I don’t want

I did manage to store the data by rendering it’s texture into another fbo, but I was wondering if there was a more straight forward / less hackish way…

thanks!


#2

An FBO’s colour attachment can outlive it, so there’s no problem with creating a temporary fbo and then keeping around a reference to what’s returned by gl::Fbo::getColorTexture().

If, for some reason, performance isn’t a concern, you can always synchronously pull down the pixels of the color attachment and reupload as a new texture, but this is horribly slow.

gl::TextureRef copiedTexture = gl::Texture::create( fbo->getColorTexture()->createSource() );


#3

hey lithium, thanks for the quick reply.

yeah, I’m trying to keep things in the GPU side


#4

In that case, assuming you’re not on mac (that is to say have OpenGL 4.3+), you may be able to use glCopyImageSubData. Not sure if cinder supports it natively though, so you may need to drop into raw opengl calls to get it done.


#5

Alternatively, you can create a texture first and use it in an Fbo later. As @lithium.snepo mentioned, the Fbo can be temporary and you can throw it away once you’re done, leaving you with a texture you can keep using.

Here’s a code snippet:

auto texture = gl::Texture2d::create( getWindowWidth(), getWindowHeight() );
auto fmt = gl::Fbo::Format().attachment( GL_COLOR_ATTACHMENT0, texture );
auto fbo = gl::Fbo::create( texture->getWidth(), texture->getHeight(), fmt );

-Paul


#6

ah! somehow I did read that suggestion! thanks for the examples Paul!


#7

I’m not sure about your use case, but you can also try creating an Fbo with multiple attachments, and you only switch between the attachments when you want to store the texture. Then you render to the other attachment, while the stored content remains intact.