Extends

At it's core the ofFBO is a container for textures and an optional depth buffer. Kind of like, well, an OpenGL framebuffer, which is what you're normally rendering to. One way, conceptually correct but technically a bit loose, is that it's another renderer that you can write to. You can draw textures to it, draw 3D or 2D objects to it, render the view of cameras inside of it, all with one key difference: it's just an object stored on the graphics card that represents a rendered drawing pass. You can have multiple of them, draw all kinds of things inside of them, and then get all the textures out of them to play with in a shader or just draw them directly to the screen. They are, for most purposes, little render buffers that you can render to and store without needing to be drawing to the screen.

To start working with an ofFbo, you have to allocate it, the same way that you would with an ofTexture:

You can also use the ofFbo::Settings object to create a more customized FBO that allows you to set the internal format of the depth and stencil textures, create multiple textures to render to, and use different texture targets, among other things.

ofFbo can be a little confusing because it wraps two related, but distinct things in OpenGL: Textures and RenderBuffers. The difference conceptually isn't huge, but it's important if you're looking to understand deeply what's going on inside the ofFbo. RenderBuffers are good for rendering to, not drawing, whereas Textures are ok for both but slightly slower. More info on both here and here

ofFbo::ofFbo()

ofFbo::ofFbo(const ofFbo &mom)

ofFbo::~ofFbo()

void ofFbo::activateAllDrawBuffers()

This method allows you to render the results of a shading pass to all the textures inside the FBO. It's handy if you have many textures inside your FBO, for instance, a normals texture, a colored depth texture, a color texture, and you want to have a shader render to all of them at once. It calls glDrawBuffers() internally, which you can learn more about here.

Before you use the fbo you need to allocate it. This sets the width, height, and GL type of the fbo (i.e. whether it has alpha data or not) and the number of samples for MSAA. MSAA is sort of a big topic.
MSAA is what you typically have in hardware on a modern graphics card. The graphics card renders to a surface that is larger than the final image, but in shading each "cluster" of samples (that will end up in a single pixel on the final screen) the pixel shader is run only once. We save a ton of fill rate, but we still burn memory bandwidth.
This technique does not anti-alias any effects coming out of the shader, because the shader runs at 1x, so alpha cutouts are jagged. This is the most common way to run a forward-rendering game. MSAA does not work for a deferred renderer because lighting decisions are made after the MSAA is "resolved" (down-sized) to its final image size.

void ofFbo::begin(bool setupScreen=true)

Any drawing that you do after begin() is drawn into the fbo rather than the screen. This is how you draw things into your ofFbo instance.

Documentation from code comments

Sets up the framebuffer and binds it for rendering.

Warning: This is a convenience method, and is considered unsafe
in multi-window and/or multi-renderer scenarios.
If you use more than one renderer, use each renderer's
explicit void ofBaseGLRenderer::begin(const ofFbo & fbo, bool setupPerspective)
method instead.

Documentation from code comments

Bind OpenGL GL_FRAMEBUFFER target to this ofFbo

Warning: If you use this method, you need to manually keep track of the
currently bound framebuffer, if you ever want to restore state.
* use ofBaseGLRenderer::getCurrentFramebuffer() to query the current
framebuffer binding state within the renderer.
* Better, use the renderer's explicit method:
ofBaseGLRenderer::bind(const ofFbo & fbo) to bind the fbo, to allow
the renderer to keep track of any bound fbos.

void ofFbo::clear()

FBOs usually have two textures that are created inside of them: a color texture to hold all of the colors of objects that are rendered and a depth texture that represents all the depth values of objects that are rendered. While there are more esoteric reasons for generating a depth texture, a common one is that depth textures can be used in a vertex or fragment shader to figure out how far away from the camera (and possibly by extension a light) something is.

These are created with the default ofFbo::Settings, which means that unless you don't want one, you have a depth buffer to play with that you can access with:

fbo.getDepthTexture();

The attachment point is the index of the texture that you're going to be referring to within the FBO. By default this should just be GL_DEPTH_STENCIL but if you know what you're doing and don't want a stencil buffer you can use GL_DEPTH_ATTACHMENT or vice versa, GL_STENCIL_ATTACHMENT.

FBOs usually have two textures that are created inside of them: a color texture to hold all of the colors of objects that are rendered and a depth texture that represents all the depth values of objects that are rendered. While there are more esoteric reasons for generating a depth texture, a common one is that depth textures can be used in a vertex or fragment shader to figure out how far away from the camera (and possibly by extension a light) something is.

These are created with the default ofFbo::Settings, which means that unless you don't want one, you have a depth buffer to play with that you can access with:

fbo.getDepthTexture();

The attachment point is the index of the texture that you're going to be referring to within the FBO. By default this should just be GL_DEPTH_STENCIL but if you know what you're doing and don't want a stencil buffer you can use GL_DEPTH_ATTACHMENT or vice versa, GL_STENCIL_ATTACHMENT.

The extra parameters on this method allow you to set the type of depth buffer that you want to create, which is handy if you need particular fidelity for depth, for instance, GL_DEPTH32.

This creates a texture of the specified format and attaches it to the FBO at the index specified. Most of this can be handled for you by using the ofFbo::Settings object. RenderBuffers are slightly different than textures, more info can be found on the OpenGL Wiki.

int ofFbo::getNumTextures()

GLuint ofFbo::getStencilBuffer()

This gives you the OpenGL id of the stencil RenderBuffer that the fbo contains. The depthBuffer will only be created if you pass a Setting object with depthStencilAsTexture = false and settings.useStencil = true.

ofFbo & ofFbo::operator=(const ofFbo &fbo)

This allows you to get the pixels from an ofFbo and store it in an ofShortPixels instance. The attachmentPoint parameter allows you indicate which of the textures attached to the fbo you want to grab. The ofShortPixels instance is useful when you want your image as floating point values.

This allows you to get the pixels from an ofFbo and store it in an ofShortPixels instance. The attachmentPoint parameter allows you indicate which of the textures attached to the fbo you want to grab. The ofShortPixels instance is useful when you want your image at short ints, or non-floating point values.

void ofFbo::resetAnchor()

void ofFbo::setActiveDrawBuffer(int i)

This sets which texture within your FBO is going contain the results of any drawing method or shading pass, particularly useful if you have multiple color textures, for instance, a normals texture and a color value texture. Doing multiple rendering passes on different objects is called Deferred Shading and is a tricky but powerful technique.

void ofFbo::setActiveDrawBuffers(const vector &i)

This sets which texture within your FBO is going contain the results of any drawing method or shading pass, particularly useful if you have multiple color textures, for instance, a normals texture and a color value texture. Doing multiple rendering passes on different objects is called Deferred Shading and is a tricky but powerful technique.

void ofFbo::updateTexture(int attachmentPoint)

Documentation from code comments

Explicityl resolve MSAA render buffers into textures
\note if using MSAA, we will have rendered into a colorbuffer, not directly
into the texture call this to blit from the colorbuffer into the texture
so we can use the results for rendering, or input to a shader etc.
\note This will get called implicitly upon getTexture();

If you have any doubt about the usage of this module you can ask in the forum.

If you want to contribute better documentation or start documenting this section you can do so
here

If you find anything wrong with this docs you can report any error by opening an
issue