Does glBlitFramebuffer copy all color attachments if GL_COLOR_BUFFER_BIT mask is specified?
Asked Answered
O

2

23

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.

Oversexed answered 17/7, 2013 at 5:20 Comment(0)
S
24

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.

Sallust answered 17/7, 2013 at 5:31 Comment(5)
Thanks Nicol. I was aware of that. My question still holds. For the sake of making question more clear, here are the 2 FBOs that are bound in this way: glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo1); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo2); fbo1 has 2 color attachments and fbo2 has 4 color attachments. So how does the glBlitFrameBuffer copy color attachments in this case?Oversexed
@kvikram: "I was aware of that." No, you were not and you still are not. What you fail to grasp is the difference between "the current glReadBuffer" and "the framebuffer bound to GL_READ_FRAMEBUFFER". As I said, it's not about the attachments; it's about the read and draw buffers within the framebuffers.Sallust
Thanks Nicol. I think you cleared my understanding. The first step is to choose the FBOs for read/draw: glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo1); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo2); and then mention explicitly the color buffers for read/draw glReadBuffer(GL_COLOR_ATTACHMENT0); glDrawBuffer(GL_COLOR_ATTACHMENT3); and then do the blit operation: glBlitFramebuffer..? This will copy buffer in color attachment 0 from fbo1 to buffer in color attachment3 in fbo2?Oversexed
@kvikram Exactly, feel free to accept this answer. And by the way, if you have multiple draw buffers, the read buffer will be copied into all of those. In fact you can even use the same framebuffer for read and draw and copy one attachment into another one this way.Virnelli
Thanks Christian. This clears my understanding. You guys rock!Oversexed
P
2

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).

Popup answered 30/9, 2021 at 6:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.