Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.

like image 656
viktorzeid Avatar asked Jul 17 '13 05:07

viktorzeid


People also ask

How many color attachments can a framebuffer have?

The minimum value for both these limits is 8 in OpenGL 3.

What is blit framebuffer?

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.


2 Answers

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.

like image 178
Nicol Bolas Avatar answered Sep 20 '22 23:09

Nicol Bolas


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

like image 22
neo-mashiro Avatar answered Sep 17 '22 23:09

neo-mashiro