If I am copying pixels from one FBO to another and each of them have multiple (not necessary the same number) of color attachments, and if my mask is GL_COLOR_BUFFER_BIT
, which color attachments (GL_COLOR_ATTACHMENT0
, GL_COLOR_ATTACHMENT1
, ...., GL_COLOR_ATTACHMENTi
) does it copy? All of them? If yes, what if these FBOs have different number of color buffers attached to them?
Assume that there are 2 FBOs that are bound in this way:
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo1);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo2);
Note that fbo1
has 2 color attachments and fbo2
has 4 color attachments.
So how does the glBlitFrameBuffer
blit color attachments in this case?
I could not find this anywhere in the OpenGL documentation.
The minimum value for both these limits is 8 in OpenGL 3.
A blit operation is a special form of copy operation; it copies a rectangular area of pixels from one framebuffer to another. This function also has some very specific properties with regard to multisampling. Framebuffer blitting commands are considered Rendering Commands.
A framebuffer color blitting operation will only read from the current glReadBuffer
for the GL_READ_FRAMEBUFFER
, and it will only write to the glDrawBuffers
specified for the GL_DRAW_FRAMEBUFFER
. So it's not about the attachments; it's about the read and draw buffers of the two framebuffers.
This is an old topic but I recently came across the same problem. The previously accepted answer still works, but you have to restore the read/write buffers after the blit operation as that's part of the framebuffer state.
For those who are using OpenGL version 4.5 and above, you can take advantage of the new Direct State Access feature that uses glBlitNamedFramebuffer
instead, this will give us a much cleaner solution. With NamedFramebuffer
at our disposal, we can access and modify the read/write buffers without having to bind the framebuffers, so that no state will be changed.
// transfer pixels data between color attachments
glNamedFramebufferReadBuffer(in, GL_COLOR_ATTACHMENT0 + in_buff_id);
glNamedFramebufferDrawBuffer(out, GL_COLOR_ATTACHMENT0 + out_buff_id);
glBlitNamedFramebuffer(in, out, 0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
// transfer pixels data between depth buffers
glBlitNamedFramebuffer(in, out, 0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
// transfer pixels data between stencil buffers
glBlitNamedFramebuffer(in, out, 0, 0, width, height, 0, 0, width, height, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
I haven't tested the performance though but the difference should be trivial (hopefully).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With