glBlitFramebuffer
Copies a rectangle of pixels from the read framebuffer to the draw framebuffer, scaling and resolving MSAA on the way.
Signature
void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
How it works
Source and destination are the framebuffers bound to GL_READ_FRAMEBUFFER and GL_DRAW_FRAMEBUFFER (0 means the window). Three everyday uses:
MSAA resolve: copy a multisample framebuffer into a normal one of the same size; each pixel becomes the average of its samples. Copying depth: bring a G-buffer's depth into the window's framebuffer, so forward-rendered objects are hidden correctly behind deferred ones. Scaling: render at a lower resolution and stretch it to the window.
Parameters
Source rectangle corners (X1, Y1 exclusive).
Destination rectangle. A different size scales; swapped corners flip.
Which buffers to copy, combined with |.
Common values
- GL_COLOR_BUFFER_BIT
- The read buffer to every draw buffer.
- GL_DEPTH_BUFFER_BIT
- Depth (needs GL_NEAREST and matching formats).
- GL_STENCIL_BUFFER_BIT
- Stencil (needs GL_NEAREST).
GL_NEAREST or GL_LINEAR, used when the sizes differ. Depth and stencil allow only GL_NEAREST.
Tips & pitfalls
When the source is multisample, both rectangles must be the same size: resolve first, scale in a second blit.
The DSA form is glBlitNamedFramebuffer(readFbo, drawFbo, …), with no binds.
Errors
When the call is invalid it does nothing and sets an error, which glGetError returns:
- GL_INVALID_OPERATION
- Multisample source with different rectangle sizes, depth/stencil formats that differ, or GL_LINEAR with depth or stencil.
- GL_INVALID_FRAMEBUFFER_OPERATION
- The read or draw framebuffer is incomplete.
Example
1// resolve 4x MSAA into the post-processing framebuffer
2glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFbo);
3glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
4glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
5 GL_COLOR_BUFFER_BIT, GL_NEAREST);