Magnum::GL::Framebuffer class

Framebuffer.

Unlike DefaultFramebuffer, which is used for on-screen rendering, this class is used for off-screen rendering, usable in windowless applications, for texture generation or for various post-processing effects.

Basic usage

A basic setup for rendering to a texture of a desired size might look like below. Apart from a color attachment, there's also a depth/stencil attachment in order to make depth test work properly. If you render 2D or don't need to use a depth/stencil test, you can have just a color attachment. It's possible to attach either a Texture or a Renderbuffer — a texture allows you to read the rendered output later from a shader, while a renderbuffer allows you to only read() or blit() from it. In modern desktop OpenGL there's not much reason to use Renderbuffer anymore, however in OpenGL ES and WebGL due to various texture format restrictions, renderbuffers are still the more flexible option if you don't need to use the result in a shader.

GL::Texture2D color;
GL::Renderbuffer depthStencil;
color.setStorage(1, GL::TextureFormat::RGBA8, size);
depthStencil.setStorage(GL::RenderbufferFormat::Depth24Stencil8, size);

GL::Framebuffer framebuffer{{{}, size}};
framebuffer.attachTexture(GL::Framebuffer::ColorAttachment{0}, color, 0);
framebuffer.attachRenderbuffer(
    GL::Framebuffer::BufferAttachment::DepthStencil, depthStencil);

Rendering then usually consists of switching between different framebuffers using bind() and reusing the rendered texture in subsequent draws:

framebuffer
    .clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth)
    .bind();

// draw to this framebuffer ...

/* Switch back to the default framebuffer */
GL::defaultFramebuffer
    .clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth)
    .bind();

// use the rendered texture in a shader ...
myShader.bindTexture(color);

Multisampled rendering

Another use case for custom framebuffers is multisampled rendering — as you're not always allowed to control the MSAA setting on a default framebuffer, or you might want your rendered texture to be multisampled as well:

Vector2i size = GL::defaultFramebuffer.viewport().size();

/* 8x MSAA */
GL::Renderbuffer color, depthStencil;
color.setStorageMultisample(8, GL::RenderbufferFormat::RGBA8, size);
depthStencil.setStorageMultisample(8,
    GL::RenderbufferFormat::Depth24Stencil8, size);

GL::Framebuffer framebuffer{{{}, size}};
framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, color);
framebuffer.attachRenderbuffer(
    GL::Framebuffer::BufferAttachment::DepthStencil, depthStencil);

framebuffer.clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth)
    .bind();

// draw to the multisampled framebuffer ...

/* Resolve the color output to a single-sampled default framebuffer */
GL::defaultFramebuffer.clear(GL::FramebufferClear::Color)
    .bind();
GL::Framebuffer::blit(framebuffer, GL::defaultFramebuffer,
    {{}, size}, GL::FramebufferBlit::Color);

Here Renderbuffer gets used for the color attachment as well. While it's possible to achieve the same with a MultisampleTexture2D, support for it is rather sparse on OpenGL ES and completely nonexistent on WebGL or macOS / iOS.

Multiple fragment shader outputs

In a deferred rendering setup for example, a shader usually has more than one output. That's finally where non-zero ColorAttachment and mapForDraw() gets used. In builtin shaders this is also how the Shaders::Flat::ColorOutput / Shaders::Flat::ObjectIdOutput etc. get used:

GL::Framebuffer framebuffer{GL::defaultFramebuffer.viewport()};
GL::Texture2D color, normal;
GL::Renderbuffer depthStencil;
// setStorage() ...

framebuffer.attachTexture(GL::Framebuffer::ColorAttachment{0}, color, 0);
framebuffer.attachTexture(GL::Framebuffer::ColorAttachment{1}, normal, 0);
framebuffer.attachRenderbuffer(
    GL::Framebuffer::BufferAttachment::DepthStencil, depthStencil);
framebuffer.mapForDraw({
    {MyShader::ColorOutput, GL::Framebuffer::ColorAttachment(0)},
    {MyShader::NormalOutput, GL::Framebuffer::ColorAttachment(1)}});

Performance optimizations

See also relevant section in AbstractFramebuffer.

If ARB_direct_state_access (part of OpenGL 4.5) is not available, functions checkStatus(), mapForDraw(), mapForRead(), invalidate(), attachRenderbuffer(), attachTexture(), attachCubeMapTexture(), attachTextureLayer() and detach() use DSA to avoid unnecessary calls to glBindFramebuffer(). See their respective documentation for more information.

Base classes

class AbstractFramebuffer
Base for default and named framebuffers.
class AbstractObject
Base for all OpenGL objects.

Public types

class BufferAttachment
Buffer attachment.
class ColorAttachment
Color attachment.
class DrawAttachment
Draw attachment.
class InvalidationAttachment
Invalidation attachment.
enum class Status: GLenum { Complete = GL_FRAMEBUFFER_COMPLETE, IncompleteAttachment = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, IncompleteMissingAttachment = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT, IncompleteDrawBuffer = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER, IncompleteReadBuffer = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER, Unsupported = GL_FRAMEBUFFER_UNSUPPORTED, IncompleteMultisample = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, IncompleteLayerTargets = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS }
Status.

Public static functions

static auto maxColorAttachments() -> Int
Max supported color attachment count.
static auto wrap(GLuint id, const Range2Di& viewport, ObjectFlags flags = {}) -> Framebuffer
Wrap existing OpenGL framebuffer object.

Constructors, destructors, conversion operators

Framebuffer(const Range2Di& viewport) explicit
Constructor.
Framebuffer(NoCreateT) explicit noexcept
Construct without creating the underlying OpenGL object.
Framebuffer(const Framebuffer&) deleted
Copying is not allowed.
Framebuffer(Framebuffer&&) defaulted noexcept
Move constructor.
~Framebuffer()
Destructor.

Public functions

auto operator=(const Framebuffer&) -> Framebuffer& deleted
Copying is not allowed.
auto operator=(Framebuffer&&) -> Framebuffer& defaulted noexcept
Move assignment.
auto id() const -> GLuint
OpenGL framebuffer ID.
auto release() -> GLuint
Release OpenGL object.
auto label() -> std::string
Framebuffer label.
auto setLabel(const std::string& label) -> Framebuffer&
Set framebuffer label.
template<std::size_t size>
auto setLabel(const char(&label)[size]) -> Framebuffer&
auto checkStatus(FramebufferTarget target) -> Status
Check framebuffer status.
auto clearColor(Int attachment, const Color4& color) -> Framebuffer&
Clear color buffer to specified value.
auto clearColor(Int attachment, const Vector4i& color) -> Framebuffer&
auto clearColor(Int attachment, const Vector4ui& color) -> Framebuffer&
auto mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments) -> Framebuffer&
Map shader output to attachments.
auto mapForDraw(DrawAttachment attachment) -> Framebuffer&
Map shader output to an attachment.
auto mapForRead(ColorAttachment attachment) -> Framebuffer&
Map given color attachment for reading.
void invalidate(std::initializer_list<InvalidationAttachment> attachments)
Invalidate framebuffer.
void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle)
Invalidate framebuffer rectangle.
auto attachRenderbuffer(BufferAttachment attachment, Renderbuffer& renderbuffer) -> Framebuffer&
Attach renderbuffer to given buffer.
auto attachTexture(BufferAttachment attachment, Texture1D& texture, Int level) -> Framebuffer&
Attach texture to given buffer.
auto attachTexture(BufferAttachment attachment, Texture2D& texture, Int level) -> Framebuffer&
Attach texture to given buffer.
auto attachTexture(BufferAttachment attachment, RectangleTexture& texture) -> Framebuffer&
auto attachTexture(BufferAttachment attachment, MultisampleTexture2D& texture) -> Framebuffer&
auto attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture& texture, CubeMapCoordinate coordinate, Int level) -> Framebuffer&
Attach cube map texture to given buffer.
auto attachTextureLayer(BufferAttachment attachment, Texture3D& texture, Int level, Int layer) -> Framebuffer&
Attach texture layer to given buffer.
auto attachTextureLayer(BufferAttachment attachment, Texture1DArray& texture, Int level, Int layer) -> Framebuffer&
auto attachTextureLayer(BufferAttachment attachment, Texture2DArray& texture, Int level, Int layer) -> Framebuffer&
auto attachTextureLayer(BufferAttachment attachment, CubeMapTextureArray& texture, Int level, Int layer) -> Framebuffer&
auto attachTextureLayer(BufferAttachment attachment, MultisampleTexture2DArray& texture, Int layer) -> Framebuffer&
auto attachLayeredTexture(BufferAttachment attachment, Texture3D& texture, Int level) -> Framebuffer&
Attach layered cube map texture to given buffer.
auto attachLayeredTexture(BufferAttachment attachment, Texture1DArray& texture, Int level) -> Framebuffer&
auto attachLayeredTexture(BufferAttachment attachment, Texture2DArray& texture, Int level) -> Framebuffer&
auto attachLayeredTexture(BufferAttachment attachment, CubeMapTexture& texture, Int level) -> Framebuffer&
auto attachLayeredTexture(BufferAttachment attachment, CubeMapTextureArray& texture, Int level) -> Framebuffer&
auto attachLayeredTexture(BufferAttachment attachment, MultisampleTexture2DArray& texture) -> Framebuffer&
auto detach(BufferAttachment attachment) -> Framebuffer&
Detach any texture or renderbuffer bound to given buffer.

Enum documentation

enum class Magnum::GL::Framebuffer::Status: GLenum

Status.

Enumerators
Complete

The framebuffer is complete

IncompleteAttachment

Any of the attachment points are incomplete

IncompleteMissingAttachment

The framebuffer does not have at least one image attached to it

IncompleteDrawBuffer

No object attached to any draw color attachment points

IncompleteReadBuffer

No object attached to read color attachment point

Unsupported

Combination of internal formats of the attached images violates an implementation-dependent set of restrictions.

IncompleteMultisample

Sample count or locations are not the same for all attached images.

IncompleteLayerTargets

Mismatched layered color attachments

Function documentation

static Int Magnum::GL::Framebuffer::maxColorAttachments()

Max supported color attachment count.

The result is cached, repeated queries don't result in repeated OpenGL calls. If neither EXT_draw_buffers nor NV_fbo_color_attachments extension is available in OpenGL ES 2.0 and WEBGL_draw_buffers is not available in WebGL 1.0, returns 0.

static Framebuffer Magnum::GL::Framebuffer::wrap(GLuint id, const Range2Di& viewport, ObjectFlags flags = {})

Wrap existing OpenGL framebuffer object.

Parameters
id OpenGL framebuffer ID
viewport Viewport to use with this framebuffer
flags Object creation flags

The id is expected to be of an existing OpenGL framebuffer object. Unlike framebuffer created using constructor, the OpenGL object is by default not deleted on destruction, use flags for different behavior.

Magnum::GL::Framebuffer::Framebuffer(const Range2Di& viewport) explicit

Constructor.

Generates new OpenGL framebuffer object. If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is created on first use.

Magnum::GL::Framebuffer::Framebuffer(NoCreateT) explicit noexcept

Construct without creating the underlying OpenGL object.

The constructed instance is equivalent to moved-from state. Useful in cases where you will overwrite the instance later anyway. Move another object over it to make it useful.

This function can be safely used for constructing (and later destructing) objects even without any OpenGL context being active.

Magnum::GL::Framebuffer::~Framebuffer()

Destructor.

Deletes associated OpenGL framebuffer object.

GLuint Magnum::GL::Framebuffer::release()

Release OpenGL object.

Releases ownership of OpenGL framebuffer object and returns its ID so it is not deleted on destruction. The internal state is then equivalent to moved-from state.

std::string Magnum::GL::Framebuffer::label()

Framebuffer label.

The result is not cached, repeated queries will result in repeated OpenGL calls. If OpenGL 4.3 / OpenGL ES 3.2 is not supported and neither KHR_debug (covered also by ANDROID_extension_pack_es31a) nor EXT_debug_label desktop or ES extension is available, this function returns empty string.

Framebuffer& Magnum::GL::Framebuffer::setLabel(const std::string& label)

Set framebuffer label.

Returns Reference to self (for method chaining)

Default is empty string. If OpenGL 4.3 / OpenGL ES 3.2 is not supported and neither KHR_debug (covered also by ANDROID_extension_pack_es31a) nor EXT_debug_label desktop or ES extension is available, this function does nothing.

template<std::size_t size>
Framebuffer& Magnum::GL::Framebuffer::setLabel(const char(&label)[size])

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Status Magnum::GL::Framebuffer::checkStatus(FramebufferTarget target)

Check framebuffer status.

Parameters
target Target for which check the status

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

The target parameter is ignored on OpenGL ES 2.0 if none of APPLE_framebuffer_multisample, ANGLE_framebuffer_blit or NV_framebuffer_blit is available and also on WebGL 1.0.

Framebuffer& Magnum::GL::Framebuffer::clearColor(Int attachment, const Color4& color)

Clear color buffer to specified value.

Parameters
attachment Color attachment index
color Value to clear with
Returns Reference to self (for method chaining)

Framebuffer& Magnum::GL::Framebuffer::clearColor(Int attachment, const Vector4i& color)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::clearColor(Int attachment, const Vector4ui& color)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::mapForDraw(std::initializer_list<std::pair<UnsignedInt, DrawAttachment>> attachments)

Map shader output to attachments.

Returns Reference to self (for method chaining)

attachments is list of shader outputs mapped to framebuffer color attachment IDs. Shader outputs which are not listed are not used, you can achieve the same by passing Framebuffer::DrawAttachment::None as color attachment ID. Example usage:

framebuffer.mapForDraw({
    {MyShader::ColorOutput, GL::Framebuffer::ColorAttachment(0)},
    {MyShader::NormalOutput, GL::Framebuffer::DrawAttachment::None}});

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Framebuffer& Magnum::GL::Framebuffer::mapForDraw(DrawAttachment attachment)

Map shader output to an attachment.

Parameters
attachment Draw attachment
Returns Reference to self (for method chaining)

Similar to above function, can be used in cases when shader has only one (unnamed) output.

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Framebuffer& Magnum::GL::Framebuffer::mapForRead(ColorAttachment attachment)

Map given color attachment for reading.

Parameters
attachment Color attachment
Returns Reference to self (for method chaining)

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

void Magnum::GL::Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments)

Invalidate framebuffer.

Parameters
attachments Attachments to invalidate

If extension ARB_invalidate_subdata (part of OpenGL 4.3), extension EXT_discard_framebuffer in OpenGL ES 2.0 or OpenGL ES 3.0 is not available, this function does nothing. If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

void Magnum::GL::Framebuffer::invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle)

Invalidate framebuffer rectangle.

Parameters
attachments Attachments to invalidate
rectangle Rectangle to invalidate

If extension ARB_invalidate_subdata (part of OpenGL 4.3) is not available, this function does nothing. If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Framebuffer& Magnum::GL::Framebuffer::attachRenderbuffer(BufferAttachment attachment, Renderbuffer& renderbuffer)

Attach renderbuffer to given buffer.

Parameters
attachment Buffer attachment
renderbuffer Renderbuffer
Returns Reference to self (for method chaining)

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Framebuffer& Magnum::GL::Framebuffer::attachTexture(BufferAttachment attachment, Texture1D& texture, Int level)

Attach texture to given buffer.

Parameters
attachment Buffer attachment
texture Texture
level Mip level
Returns Reference to self (for method chaining)

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Framebuffer& Magnum::GL::Framebuffer::attachTexture(BufferAttachment attachment, Texture2D& texture, Int level)

Attach texture to given buffer.

Parameters
attachment Buffer attachment
texture Texture
level Mip level
Returns Reference to self (for method chaining)

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Framebuffer& Magnum::GL::Framebuffer::attachTexture(BufferAttachment attachment, RectangleTexture& texture)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachTexture(BufferAttachment attachment, MultisampleTexture2D& texture)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture& texture, CubeMapCoordinate coordinate, Int level)

Attach cube map texture to given buffer.

Parameters
attachment Buffer attachment
texture Texture
coordinate Cube map coordinate
level Mip level
Returns Reference to self (for method chaining)

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Framebuffer& Magnum::GL::Framebuffer::attachTextureLayer(BufferAttachment attachment, Texture3D& texture, Int level, Int layer)

Attach texture layer to given buffer.

Parameters
attachment Buffer attachment
texture Texture
level Mip level
layer Layer
Returns Reference to self (for method chaining)

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Framebuffer& Magnum::GL::Framebuffer::attachTextureLayer(BufferAttachment attachment, Texture1DArray& texture, Int level, Int layer)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachTextureLayer(BufferAttachment attachment, Texture2DArray& texture, Int level, Int layer)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachTextureLayer(BufferAttachment attachment, CubeMapTextureArray& texture, Int level, Int layer)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachTextureLayer(BufferAttachment attachment, MultisampleTexture2DArray& texture, Int layer)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachLayeredTexture(BufferAttachment attachment, Texture3D& texture, Int level)

Attach layered cube map texture to given buffer.

Parameters
attachment Buffer attachment
texture Texture
level Mip level
Returns Reference to self (for method chaining)

Attaches whole texture with all layers addressable using gl_Layer in geometry shader. If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Framebuffer& Magnum::GL::Framebuffer::attachLayeredTexture(BufferAttachment attachment, Texture1DArray& texture, Int level)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachLayeredTexture(BufferAttachment attachment, Texture2DArray& texture, Int level)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachLayeredTexture(BufferAttachment attachment, CubeMapTexture& texture, Int level)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachLayeredTexture(BufferAttachment attachment, CubeMapTextureArray& texture, Int level)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::attachLayeredTexture(BufferAttachment attachment, MultisampleTexture2DArray& texture)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Framebuffer& Magnum::GL::Framebuffer::detach(BufferAttachment attachment)

Detach any texture or renderbuffer bound to given buffer.

Parameters
attachment Buffer attachment
Returns Reference to self (for method chaining)

If ARB_direct_state_access (part of OpenGL 4.5) is not available, the framebuffer is bound before the operation (if not already).

Debug& operator<<(Debug& debug, Framebuffer::Status value)

Debug output operator.