Easy3D 2.5.3
FramebufferObject Class Reference

An implementation of framebuffer object (FBO). More...

#include <easy3d/renderer/framebuffer_object.h>

Public Member Functions

 FramebufferObject (int w, int h, int samples=0)
 Default constructor.
 
virtual ~FramebufferObject ()
 Destructor.
 
bool add_color_texture (GLenum internal_format=GL_RGBA8, GLenum format=GL_RGBA, GLenum type=GL_UNSIGNED_BYTE, GLenum filter=GL_NEAREST)
 Add a color texture render buffer.
 
bool add_color_buffer (GLenum internal_format=GL_RGBA8, GLenum format=GL_RGBA, GLenum type=GL_UNSIGNED_BYTE)
 Add a color render buffer.
 
bool add_depth_texture (GLenum internal_format=GL_DEPTH24_STENCIL8, GLenum filter=GL_NEAREST, GLenum compare_mode=GL_NONE, GLenum compare_func=GL_LEQUAL)
 Add a depth texture render buffer.
 
bool add_depth_buffer (GLenum internal_format=GL_DEPTH24_STENCIL8)
 Add a depth render buffer.
 
bool attach_color_texture (GLenum target, GLuint texture_id, GLenum attachment)
 
bool attach_depth_texture (GLenum target, GLuint texture_id, GLenum attachment)
 
void ensure_size (int w, int h)
 
bool bind (GLenum target=GL_FRAMEBUFFER)
 
bool release (GLenum target=GL_FRAMEBUFFER)
 Switches rendering back to the default framebuffer.
 
bool is_valid () const
 Returns true if the framebuffer object is valid. More...
 
bool is_bound (GLenum target=GL_FRAMEBUFFER) const
 Check if the framebuffer object is currently bound to the current context.
 
void activate_draw_buffer (unsigned int index) const
 
void activate_draw_buffers (unsigned int num_buffers, const unsigned int indices[]) const
 
void activate_draw_buffers (unsigned int minId, unsigned int maxId) const
 
void deactivate_draw_buffers () const
 
void activate_read_buffer (unsigned int index) const
 
void deactivate_read_buffer () const
 Deactivates reading from the buffers.
 
GLuint handle () const
 
int width () const
 Returns the width of the render buffers.
 
int height () const
 Returns the height of the render buffers.
 
int samples () const
 
int num_color_attachments () const
 Returns the number of color attachments.
 
bool has_color_attachment (unsigned int index) const
 Does the fbo have color attachment at index?
 
bool has_depth_attachment () const
 Does the fbo have a depth attachment.
 
int depth_bits () const
 Returns the depth bits.
 
bool has_stencil () const
 Does the fbo have a stencil buffer.
 
GLenum texture_target () const
 Returns the texture target, i.e., GL_TEXTURE_2D or GL_TEXTURE_2D_MULTISAMPLE.
 
GLuint color_texture (unsigned int index=0, bool resolve=true) const
 
bool has_color_texture (unsigned int index) const
 Does the fbo have a color texture for color attachment index?
 
GLuint depth_texture (bool resolve=true) const
 
bool has_depth_texture () const
 Does the fbo have a depth texture?
 
bool copy_color_to_texture (GLuint &texture_handle, unsigned int index=0, int internalFormat=GL_RGBA8, GLenum format=GL_RGBA, GLenum type=GL_UNSIGNED_BYTE, GLenum filter=GL_NEAREST)
 Makes a copy of the current buffer into a texture (regardless the attachments already have textures). More...
 
bool copy_depth_to_texture (GLuint &texture_handle, unsigned int internal_format=GL_DEPTH24_STENCIL8, GLenum filter=GL_NEAREST)
 Makes a copy of the current depth buffer into a texture. More...
 
void print_attachments () const
 Print all the attachments of the current framebuffer object.
 
void print_draw_buffers () const
 Print the draw buffers.
 
void print_read_buffer () const
 Print the read buffer.
 
bool read_color (unsigned int index, unsigned char *buffer, unsigned int format, bool flip_vertically=true) const
 
bool read_color (unsigned int index, std::vector< unsigned char > &buffer, unsigned int format, bool flip_vertically=true) const
 
bool read_depth (float *buffer, bool flip_vertically=true) const
 Read the depth render buffer into a specified buffer.
 
bool read_depth (std::vector< float > &buffer, bool flip_vertically=true) const
 Read the depth render buffer into a specified buffer.
 
bool read_color (unsigned char rgba[4], int x, int y, int index=0) const
 
bool read_depth (float &depth, int x, int y) const
 
bool snapshot_color (unsigned int index, const std::string &file_name) const
 
bool snapshot_depth (const std::string &file_name) const
 

Static Public Member Functions

static bool is_supported ()
 Queries if FramebufferObject is supported.
 
static void blit_framebuffer (FramebufferObject *target, const FramebufferObject *source, GLbitfield buffers, GLenum filter=GL_NEAREST)
 Blit the whole sized buffer. More...
 
static void blit_framebuffer (FramebufferObject *target, const FramebufferObject *source, int target_color_attachment_index, int source_color_attachment_index, GLbitfield buffers, GLenum filter=GL_NEAREST)
 Blit the whole sized buffer of a specific color attachment.
 
static void blit_framebuffer (FramebufferObject *target, int tx0, int ty0, int tx1, int ty1, const FramebufferObject *source, int sx0, int sy0, int sx1, int sy1, GLbitfield buffers, GLenum filter=GL_NEAREST)
 Blit a specified region.
 
static void blit_framebuffer (FramebufferObject *target, int tx0, int ty0, int tx1, int ty1, const FramebufferObject *source, int sx0, int sy0, int sx1, int sy1, int target_color_attachment_index, int source_color_attachment_index, GLbitfield buffers, GLenum filter=GL_NEAREST)
 Blit a specified region of a specific color attachment.
 

Detailed Description

An implementation of framebuffer object (FBO).

A framebuffer object is conceptually a structure containing pointers to GPU memory. The memory pointed to is either an OpenGL texture or an OpenGL RenderBuffer. FBOs can be used to render to one or more textures, share depth buffers between multiple sets of color buffers/textures. http://oss.sgi.com/projects/ogl-sample/registry/EXT/framebuffer_object.txt for details.

Note that you need to create a FramebufferObject with more than one sample per pixel for primitives to be antialiased. To create a multisample framebuffer object you should set the sample property to a non-zero value. The default sample count of 0 represents a regular non-multisample framebuffer object. If the desired amount of samples per pixel is not supported by the hardware then the maximum number of samples per pixel will be used. The GL_EXT_framebuffer_multisample extension is required to create a framebuffer with more than one sample per pixel.

Note
  • A valid OpenGL context must be present when creating a FramebufferObject, otherwise initialization will fail.
  • GL_TEXTURE_2D textures must have a power of 2 width and height(e.g. 256x512), unless you are using OpenGL 2.0 or higher.
  • To create a multisample framebuffer object you should set the sample property to a non-zero value.
  • If you want to use a multisample framebuffer object a texture, you need to blit it to a regular framebuffer object using blit_framebuffer().
  • It is more efficient(but not required) to call bind() on an FBO before making multiple method calls. For example :
    fbo.bind();
    fbo.add_color_buffer();
    fbo.add_color_buffer();
    fbo.print_attachments();
    FramebufferObject(int w, int h, int samples=0)
    Default constructor.
    Definition: framebuffer_object.cpp:49
    To provide a complete encapsulation, the following usage pattern works correctly but is less efficient :
    // NOTE: No bind() call
    fbo.add_color_buffer();
    fbo.add_color_buffer();
    fbo.print_attachments();
    The first usage pattern binds the FBO only once, whereas the second usage binds/unbinds the FBO for each method call.

Example usage 1: draw to a fbo:

FramebufferObject fbo(w, h, 0);
fbo.add_color_texture();
fbo.add_depth_buffer();
fbo.bind();
fbo.activate_draw_buffer(0);
glClearDepth(1.0f); // optional, done by default
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // optional, done by default
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // optional, done by default
you draw code here...
fbo.release();
//... Now you can use fbo.color_texture() for other purposes.

Example usage 2: draw the depth map of an object or a scene:

FramebufferObject fbo(w, h, 0);
fbo.add_depth_texture();
fbo.bind();
glClearDepth(1.0f); // optional, done by default
glClear(GL_DEPTH_BUFFER_BIT); // optional, done by default
you draw code here...
fbo.release();
//... Now you can use the fbo.depth_texture().

For both the above examples, it's easy to enable MSAA by creating a multisample FBO and render to it. But do remember to blit to a normal FBO before using the texture.

Current implement support only GL_TEXTURE_2D (see the texture_target_ variable), and it does not manage externally created textures.

Todo:
  • add a class TextureFormat for flexible format specification and add related functions using the TextureFormat class.
  • modify the attach_color_texture() and attach_depth_texture() to use TextureFormat.
  • replace ColorAttachment by TextureFormat.
Examples
Tutorial_404_VirtualScanner, and Tutorial_506_DepthMaps.

Member Function Documentation

◆ activate_draw_buffer()

void activate_draw_buffer ( unsigned int  index) const

Choose the buffers to render into. This command lets you select which attachments are written to.

Note
The default buffer is the 0. In such a case calling to this function is optional.

◆ activate_read_buffer()

void activate_read_buffer ( unsigned int  index) const

Choose the buffers to read from. This command lets you select which attachment to read from.

Note
The default buffer is the 0. In such a case calling to this function is optional.

◆ attach_color_texture()

bool attach_color_texture ( GLenum  target,
GLuint  texture_id,
GLenum  attachment 
)

Attach an existing color texture to the framebuffer

Parameters
targetGL_TEXTURE_2D, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_ARRAY
attachmentGL_COLOR_ATTACHMENTi

◆ attach_depth_texture()

bool attach_depth_texture ( GLenum  target,
GLuint  texture_id,
GLenum  attachment 
)

Attach an existing depth texture to the framebuffer

Parameters
targetGL_TEXTURE_2D, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_ARRAY
attachmentGL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT or GL_DEPTH_STENCIL_ATTACHMENT.

◆ bind()

bool bind ( GLenum  target = GL_FRAMEBUFFER)

Bind FBO to FRAMEBUFFER, DRAW_FRAMEBUFFER, or READ_FRAMEBUFFER The current binding is saved for later release.

Note
bind() and release() should be called in pair.

◆ blit_framebuffer()

void blit_framebuffer ( FramebufferObject target,
const FramebufferObject source,
GLbitfield  buffers,
GLenum  filter = GL_NEAREST 
)
static

Blit the whole sized buffer.

Blits from the source rectangle in the source framebuffer object to the target rectangle in the target framebuffer object. If source or target is 0, the default framebuffer will be used instead of a framebuffer object as source or target respectively. The buffers parameter should be a mask consisting of any combination of GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, and GL_STENCIL_BUFFER_BIT. Any buffer type that is not present both in the source and target buffers is ignored.

The source and target rectangles may have different sizes; in this case buffers should not contain GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT. The filter parameter should be set to GL_LINEAR or GL_NEAREST specifying whether linear or nearest interpolation should be used for scaling. For GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT, the filter parameter must be GL_NEAREST.

If source equals target a copy is performed within the same buffer. Results are undefined if the source and target rectangles overlap and have different sizes. The sizes must also be the same if any of the framebuffer objects are multisample framebuffers.

When multiple render targets are in use, source_color_attachment_index and target_color_attachment_index specify the index of the color attachments in the source and destination framebuffers.

Note
The scissor test will restrict the blit area if enabled.

◆ color_texture()

GLuint color_texture ( unsigned int  index = 0,
bool  resolve = true 
) const

Returns the texture id attached to the color attachment index of this framebuffer object.

Parameters
indexThe index of the color attachment.
resolveIf a multisample framebuffer object is used, the function blits and returns the resolved non-multisample texture when resolve is true.
Returns
The ID of the color texture.

◆ copy_color_to_texture()

bool copy_color_to_texture ( GLuint &  texture_handle,
unsigned int  index = 0,
int  internalFormat = GL_RGBA8,
GLenum  format = GL_RGBA,
GLenum  type = GL_UNSIGNED_BYTE,
GLenum  filter = GL_NEAREST 
)

Makes a copy of the current buffer into a texture (regardless the attachments already have textures).

Internally it creates a texture and uses glCopyTexSubImage2D() to directly copy the buffer in it.

Parameters
texture_handleThe target texture (will be created if it does not exist).
indexThe index of the color attachment.
internalFormat,format,typeUsed to define the texture format and hence which and how components of the buffer are copied into the texture. See the glTexImage2D() documentation for details.
filterSpecifies how the texture minifying and magnification function work.

The typical internalFormat/format/type combinations are: For depth: GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT24 / GL_DEPTH_COMPONENT / GL_UNSIGNED_BYTE GL_DEPTH_COMPONENT32F / GL_DEPTH_COMPONENT / GL_FLOAT For color: GL_RGBA8 / GL_RGBA / GL_UNSIGNED_BYTE internalFormat mus be GL_[components][size][type], e.g., GL_RG8, GL_RGBA16, GL_R16F, GL_RG16, GL_RGBA32F ... format must be one of the GL_RED, GL_RG, GL_RGB, GL_BGR, GL_BGRA ... type can be GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT ... Use GL_LUMINANCE as the internalFormat and GL_RED, GL_GREEN or GL_BLUE as format to capture a single color component as a luminance (gray scaled) value.

Returns
true on success.
Note
  • GL_STENCIL is not supported as a format.
  • The GL_DEPTH_COMPONENT format may not be supported by all hardware. It may sometimes be emulated in software, resulting in poor performances.
  • You need to release the texture when you're done.

◆ copy_depth_to_texture()

bool copy_depth_to_texture ( GLuint &  texture_handle,
unsigned int  internal_format = GL_DEPTH24_STENCIL8,
GLenum  filter = GL_NEAREST 
)

Makes a copy of the current depth buffer into a texture.

Parameters
texture_handleThe target texture (will be created if it does not exist).
internalFormatUsed to define the texture format.
filterSpecifies how the texture minifying and magnification function work.
Returns
true on success.
Note
  • You need to release the texture when you're done.

◆ depth_texture()

GLuint depth_texture ( bool  resolve = true) const

Returns the texture id for the texture attached to the depth attachment of this framebuffer object.

Parameters
resolveIf a multisample framebuffer object is used, the function blits and returns the resolved non-multisample texture if resolve is true.
Returns
The ID of the depth texture.

◆ ensure_size()

void ensure_size ( int  w,
int  h 
)

Ensure the size of the buffers is (w, h). If its size matches the required size, i.e, (w, h), it does nothing. If doesn't match, it clears and reallocate memory in the GPU.

◆ handle()

GLuint handle ( ) const
inline

Returns the OpenGL framebuffer object handle for this framebuffer object (returned by the glGenFramebuffers() function). This handle can be used to attach new images or buffers to the framebuffer. If you attach images or buffers, you are responsible for cleaning up and destroying these objects.

◆ is_valid()

bool is_valid ( ) const

Returns true if the framebuffer object is valid.

Returns true if the framebuffer object is valid.

The framebuffer can become invalid if the initialization process fails, the user attaches an invalid buffer to the framebuffer object, or a non-power of two width/height is specified as the texture size if the texture target is {GL_TEXTURE_2D}. The non-power of two limitation does not apply if the OpenGL version is 2.0 or higher, or if the GL_ARB_texture_non_power_of_two extension is present.

The framebuffer can also become invalid if the OpenGL context that the framebuffer was created within is destroyed and there are no other shared contexts that can take over ownership of the framebuffer.

◆ read_color() [1/3]

bool read_color ( unsigned char  rgba[4],
int  x,
int  y,
int  index = 0 
) const

Reads the color at pixel (x, y) from the color render buffer attached to color attachment index. Returns false if the color attachment index does not exist.

Note
(x, y) are in the OpenGL coordinate system.

◆ read_color() [2/3]

bool read_color ( unsigned int  index,
std::vector< unsigned char > &  buffer,
unsigned int  format,
bool  flip_vertically = true 
) const

Read the color render buffer attached to color attachment index.

Parameters
formatThe format of the pixel data. The following formats are accepted: GL_RGB, GL_BGR, GL_RGBA, and GL_BGRA.

◆ read_color() [3/3]

bool read_color ( unsigned int  index,
unsigned char *  buffer,
unsigned int  format,
bool  flip_vertically = true 
) const

Read the color render buffer attached to color attachment index.

Parameters
formatThe format of the pixel data. The following formats are accepted: GL_RGB, GL_BGR, GL_RGBA, and GL_BGRA.

◆ read_depth()

bool read_depth ( float &  depth,
int  x,
int  y 
) const

Reads the depth at pixel (x, y). Returns false if the depth attachment does not exist.

Note
(x, y) are in the OpenGL coordinate system.

◆ samples()

int samples ( ) const
inline

The returned value can be greater than the requested value since the typically supported values are 0, 4, 8, ..., and the requests are mapped to the next supported value.

◆ snapshot_color()

bool snapshot_color ( unsigned int  index,
const std::string &  file_name 
) const

Snapshots the color render buffer attached to color attachment index into an image file.

Note
Only png, jpg, bmp, tga, ppm are supported. File format is determined by the given extension.

◆ snapshot_depth()

bool snapshot_depth ( const std::string &  file_name) const

Snapshots the color render buffer into an image file.

Note
Only png, jpg, bmp, tga, ppm are supported. File format is determined by the given extension.

The documentation for this class was generated from the following files: