easy-gl › Framebuffer

Framebuffer

Manages an OpenGL Framebuffer Object (FBO). Used for offscreen rendering, shadow maps, post-processing, etc. Non-copyable, movable, RAII.

Simple offscreen FBO with a texture color attachment

// Create a color texture
easygl::Texture colorTex;
colorTex.create();
colorTex.bind(easygl::TextureTarget::Texture2D);
colorTex.set_storage_2d(easygl::TextureTarget::Texture2D, 1,
                          easygl::InternalFormat::Rgba8, width, height);

// Create a depth renderbuffer
easygl::Renderbuffer depthRbo;
depthRbo.create();
depthRbo.bind();
depthRbo.set_storage(easygl::InternalFormat::DepthComponent24, width, height);

// Assemble the FBO
easygl::Framebuffer fbo;
fbo.create();
fbo.bind();

fbo.attach_texture_2d(
    easygl::FramebufferTarget::Framebuffer,
    easygl::FramebufferAttachment::Color0,
    easygl::TextureTarget::Texture2D,
    colorTex.native_handle(),
    0); // mip level

fbo.attach_renderbuffer(
    easygl::FramebufferTarget::Framebuffer,
    easygl::FramebufferAttachment::Depth,
    depthRbo.native_handle());

if (!fbo.is_complete()) {
    std::cerr << "FBO incomplete!\n";
}

MRT — multiple render targets

// Attach two color textures
fbo.attach_texture_2d(target, easygl::FramebufferAttachment::Color0, ..., albedoTex.native_handle(), 0);
fbo.attach_texture_2d(target, easygl::FramebufferAttachment::Color1, ..., normalTex.native_handle(), 0);

const easygl::DrawBuffer bufs[] = {
    easygl::DrawBuffer::ColorAttachment0,
    easygl::DrawBuffer::ColorAttachment1
};
fbo.set_draw_buffers({bufs, 2});

Shadow map FBO (depth-only)

easygl::Texture shadowTex;
shadowTex.create();
shadowTex.bind(easygl::TextureTarget::Texture2D);
shadowTex.set_storage_2d(easygl::TextureTarget::Texture2D, 1,
                           easygl::InternalFormat::DepthComponent24,
                           shadowSize, shadowSize);

easygl::Framebuffer shadowFbo;
shadowFbo.create();
shadowFbo.bind();
shadowFbo.attach_texture_2d(
    easygl::FramebufferTarget::Framebuffer,
    easygl::FramebufferAttachment::Depth,
    easygl::TextureTarget::Texture2D,
    shadowTex.native_handle(), 0);

// No color — tell GL explicitly:
const easygl::DrawBuffer none[] = { easygl::DrawBuffer::None };
shadowFbo.set_draw_buffers({none, 1});
shadowFbo.set_read_buffer(easygl::ReadBuffer::None);

Blitting (resolve MSAA, copy regions)

msFbo.bind(easygl::FramebufferTarget::Read);
resolveFbo.bind(easygl::FramebufferTarget::Draw);

easygl::Framebuffer::blit(
    0, 0, width, height,   // src rect
    0, 0, width, height,   // dst rect
    easygl::ClearBufferBit::Color,
    easygl::TextureFilter::Nearest);

Restore default framebuffer

easygl::Framebuffer::unbind(); // static — binds FBO 0

Method reference

MethodDescription
create()Allocate GL FBO handle.
destroy()Free handle. Noexcept.
bind(target)Bind to Framebuffer, Read or Draw target.
unbind(target) [static]Bind FBO 0.
attach_texture_2d(target, attachment, texTarget, texture, level)Attach a 2D texture.
attach_texture_layer(target, attachment, texture, level, layer)Attach a layer of a 3D or array texture.
attach_renderbuffer(target, attachment, renderbuffer)Attach a renderbuffer.
check_status(target)Returns FramebufferStatus enum.
is_complete(target)True if status == Complete.
set_draw_buffers(span)Set draw buffer targets for MRT.
set_read_buffer(src)Set read buffer source.
invalidate(target, attachments)Hint that attachment data is no longer needed.
blit(...) [static]Copy/resolve between read and draw framebuffers.
is_created()True if GL handle allocated.
native_handle()Raw GL integer ID.
reset_handle_no_gl()Context-loss recovery.