class methods
- ofFbo()
- ~ofFbo()
- activateAllDrawBuffers()
- allocate()
- attachTexture()
- begin()
- bind()
- checkGLSupport()
- checkStatus()
- clear()
- clearColorBuffer()
- clearDepthBuffer()
- clearDepthStencilBuffer()
- clearStencilBuffer()
- copyTo()
- createAndAttachDepthStencilTexture()
- createAndAttachRenderbuffer()
- createAndAttachTexture()
- draw()
- end()
- flagDirty()
- getDefaultTextureIndex()
- getDepthBuffer()
- getDepthTexture()
- getHeight()
- getId()
- getIdDrawBuffer()
- getNumTextures()
- getStencilBuffer()
- getTexture()
- getWidth()
- isAllocated()
- isUsingTexture()
- maxColorAttachments()
- maxDrawBuffers()
- maxSamples()
- operator=()
- readToPixels()
- resetAnchor()
- setActiveDrawBuffer()
- setActiveDrawBuffers()
- setAnchorPercent()
- setAnchorPoint()
- setDefaultTextureIndex()
- setUseTexture()
- unbind()
- updateTexture()
Extends
This class extends others, you can call their methods on an instance of ofFbo too:
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:
fbo.allocate(400, 400, GL_RGBA); // with alpha, 8 bits red, 8 bits green, 8 bits blue, 8 bits alpha, from 0 to 255 in 256 steps
Often the FBO will contain artefacts from the memory that the graphics card has just allocated for it, so it's good to clear it before starting to draw it:
fbo.begin();
ofClear(255,255,255, 0);
fbo.end();
When you call begin() you're telling the framebuffer to store the rendered results of any drawing calls (or shaders for that matter) in the FBO:
float alpha = ofMap(ofGetMouseX(), 0, ofGetWidth(), 0, 255);
fbo.begin();
ofSetColor(255,255,255, alpha);
ofDrawRectangle(0,0,400,400);
fbo.end();
When it's time to draw your FBO, you can simply call draw:
void ofApp::draw()
{
fbo.draw(0,0);
}
If you want to pass the FBO to say, an ofShader, you do:
shader.setUniformTexture("fboTexture", fbo.getTextureReference(0), 0);
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
activateAllDrawBuffers()
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.
allocate(...)
void ofFbo::allocate(int width, int height, int internalformat, int numSamples=0)
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.
allocate(...)
void ofFbo::allocate(ofFboSettings settings)
You can also allocate the ofFbo using a Settings object
attachTexture(...)
void ofFbo::attachTexture(ofTexture &texture, GLenum internalFormat, GLenum attachmentPoint)
begin(...)
void ofFbo::begin(ofFboMode mode)
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.
The mode parameter indicates which defaults are set when binding the fbo.
The default OF_FBOMODE_PERSPECTIVE | OF_FBOMODE_MATRIXFLIP will set the screen perspective to the OF default for the fbo size, the correct viewport to cover the full fbo and will flip the orientation matrix in y so when drawing the fbo later or accesing it from a shader it's correctly oriented
Passing OF_FBOMODE_PERSPECTIVE will only set perspective and viewport
Passing OF_FBOMODE_MATRIXFLIP won't set the perspective but will flip the matrix.
Passing OF_FBOMODE_NODEFAULTS won't change anything and just bind the fbo and set it as current rendering surface in OF
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, ofFboMode mode) method instead.
See also: void ofBaseGLRenderer::begin(const ofFbo & fbo, ofFboMode mode)
bind()
void ofFbo::bind()
This function is internally called by ofFbo::begin() after setting up the viewport to draw things into your ofFbo instance.
To map the fbo to ofRectangle, ofMesh, or other vertex based drawing, call
fbo.getTextureReference().bind();
mesh.draw();
fbo.getTextureReference().unbind();
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.
See also: unbind()
See also: virtual void ofBaseGLRenderer::bind(const ofFbo & fbo)
checkGLSupport()
bool ofFbo::checkGLSupport()
This allows you quickly check whether your graphics card supports FBO objects.
clearColorBuffer(...)
void ofFbo::clearColorBuffer(const ofFloatColor &color)
Documentation from code comments
glClearBufferfv(GL_COLOR, 0...)
@see: https://www.opengl.org/wiki/GLAPI/glClearBuffer
clearColorBuffer(...)
void ofFbo::clearColorBuffer(size_t buffer_idx, const ofFloatColor &color)
Documentation from code comments
glClearBufferfv(GL_COLOR, buffer_idx...)
@see: https://www.opengl.org/wiki/GLAPI/glClearBuffer
clearDepthBuffer(...)
void ofFbo::clearDepthBuffer(float value)
Documentation from code comments
glClearBufferfv(GL_DEPTH...)
@see: https://www.opengl.org/wiki/GLAPI/glClearBuffer
clearDepthStencilBuffer(...)
void ofFbo::clearDepthStencilBuffer(float depth, int stencil)
Documentation from code comments
glClearBufferfi(GL_DEPTH_STENCIL...)
@see: https://www.opengl.org/wiki/GLAPI/glClearBuffer
clearStencilBuffer(...)
void ofFbo::clearStencilBuffer(int value)
Documentation from code comments
glClearBufferiv(GL_STENCIL...)
@see: https://www.opengl.org/wiki/GLAPI/glClearBuffer
copyTo(...)
void ofFbo::copyTo(ofBufferObject &buffer)
Documentation from code comments
Copy the fbo to an ofBufferObject.
Parameters:
buffer the target buffer to copy to.
createAndAttachDepthStencilTexture(...)
void ofFbo::createAndAttachDepthStencilTexture(GLenum target, GLint internalformat, GLenum 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.
createAndAttachDepthStencilTexture(...)
void ofFbo::createAndAttachDepthStencilTexture(GLenum target, GLint internalformat, GLenum attachment, GLenum transferFormat, GLenum transferType)
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.
createAndAttachRenderbuffer(...)
GLuint ofFbo::createAndAttachRenderbuffer(GLenum internalFormat, GLenum attachmentPoint)
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.
createAndAttachTexture(...)
void ofFbo::createAndAttachTexture(GLenum internalFormat, GLenum attachmentPoint)
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.
draw(...)
void ofFbo::draw(float x, float y)
This allows you draw everything that's in your fbo to the screen using its default height and width at the x, y indicated.
draw(...)
void ofFbo::draw(float x, float y, float width, float height)
This allows you draw everything that's in your fbo to the screen using any height and width. Any stretching is up to you to handle appropriately.
end()
void ofFbo::end()
Any drawing that you do after end() is drawn to the screen rather than into the fbo buffer. This is how you stop drawing things into your ofFbo instance.
Documentation from code comments
Ends the current framebuffer render context.
See also: void begin(bool setupScreen=true) const;
getDefaultTextureIndex()
int ofFbo::getDefaultTextureIndex()
If you've set the default texture reference, you can get access to it here.
getDepthBuffer()
GLuint ofFbo::getDepthBuffer()
This gives you the OpenGL id of the depth RenderBuffer that the fbo contains. The depthBuffer will only be created if you pass a Setting object with depthStencilAsTexture = false.
getDepthTexture()
ofTexture & ofFbo::getDepthTexture()
This gives you the OpenGL id of the depth Texture that the fbo contains. The depthBuffer will be created by default or if you pass a Setting object with depthStencilAsTexture = true.
getHeight()
float ofFbo::getHeight()
This returns the height of the fbo. This is just like height of a texture: it sets how many pixels wide the allocated memory on the graphics card is.
getId()
GLuint ofFbo::getId()
Documentation from code comments
returns id of the underlying GL object for advanced actions
getIdDrawBuffer()
GLuint ofFbo::getIdDrawBuffer()
Documentation from code comments
returns id of Fbo for texture attachments which is different when the fbo is using MSAA
getNumTextures()
int ofFbo::getNumTextures()
This returns the number of textures that the fbo contains.
getStencilBuffer()
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.
getWidth()
float ofFbo::getWidth()
This returns the width of the fbo that was set when it was allocated. This is just like width of a texture: it sets how many pixels wide the allocated memory on the graphics card is.
maxColorAttachments()
int ofFbo::maxColorAttachments()
This returns the max number of simultaneous max color attachments, i.e. textures that will just be used for color information.
maxDrawBuffers()
int ofFbo::maxDrawBuffers()
This returns the max number of simultaneous draw buffers that your graphics card supports, i.e. color buffers that can be drawn to simultaneously. This is usually 4 at present.
maxSamples()
int ofFbo::maxSamples()
This is the maximum number of MSAA samples that your graphic card supports.
operator=(...)
ofFbo & ofFbo::operator=(const ofFbo &fbo)
This overloaded operator allows you to set one fbo from another using the = operator. Very convenient.
readToPixels(...)
void ofFbo::readToPixels(ofFloatPixels &pixels, int attachmentPoint=0)
This allows you to get the pixels from an ofFbo and store it in an ofFloatPixels instance. The attachmentPoint parameter allows you indicate which of the textures attached to the fbo you want to grab. The ofFloatPixels instance is useful when you want your image as floating point values.
readToPixels(...)
void ofFbo::readToPixels(ofPixels &pixels, int attachmentPoint=0)
readToPixels(...)
void ofFbo::readToPixels(ofShortPixels &pixels, int attachmentPoint=0)
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.
setActiveDrawBuffer(...)
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.
setActiveDrawBuffers(...)
void ofFbo::setActiveDrawBuffers(const vector< 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.
setAnchorPercent(...)
void ofFbo::setAnchorPercent(float xPct, float yPct)
You can set the anchor position that the texture will be drawn at. This means that passing 0.5, 0.5 will draw the ofFbo center at the point you pass in to the draw() method.
setAnchorPoint(...)
void ofFbo::setAnchorPoint(float x, float y)
This allows you set the anchor position of the texture in the fbo when you draw it.
setDefaultTextureIndex(...)
void ofFbo::setDefaultTextureIndex(int defaultTexture)
This allows you set the default texture that your fbo will use. If you're using multiple textures, this will return the one that should be draw to, scaled, and positioned.
unbind()
void ofFbo::unbind()
After you bind the fbo and draw with it, call fbo to stop the fbo from being attached to vertices that are created.
Documentation from code comments
Unbinds OpenGL framebuffer target and restores the OpenGL framebuffer render target to whatever this ofFbo stores in previousFramebufferBinding.
See also: bind()
See also: void setPreviousFramebufferBinding(const GLuint& previousFramebufferBinding_) const
updateTexture(...)
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();
Last updated 星期二, 19 十一月 2024 17:25:13 UTC - 2537ee49f6d46d5fe98e408849448314fd1f180e
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