FBO mulltisampling

Hello :slight_smile:

I would like to enable MSAA with my FBO but I do not manage to make it work. I tried to follow the official Opengl sample code, but no luck either. Here is my FBO initialisation :


  // Initialising part
  
  // Creation of the multisampled FBO
  glGenFramebuffers(1, @MultisampledFBOId);
  glBindFramebuffer(GL_FRAMEBUFFER, MultisampledFBOId);

  // Color render buffer
  glGenRenderbuffers(1, @ColorBufferId);
  glBindRenderbuffer(GL_RENDERBUFFER, ColorBufferId);
  glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA, MultisampledFBOWidth, MultisampledFBOHeight);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ColorBufferId);
  
  // Color buffer texture attachment
  glGenTextures(1, @ColorBufferTextureId);
  glBindTexture(GL_TEXTURE_2D, ColorBufferTextureId);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MultisampledFBOWidth, MultisampledFBOHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorBufferTextureId, 0);

  // Depth render buffer
  glGenRenderbuffers(1, @DepthBufferId);
  glBindRenderbuffer(GL_RENDERBUFFER, DepthBufferId);
  glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT32, MultisampledFBOWidth, MultisampledFBOHeight);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DepthBufferId);

  // Depth buffer texture attachment
  glGenTextures(1, @DepthBufferTextureId);
  glBindTexture(GL_TEXTURE_2D, DepthBufferTextureId);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, MultisampledFBOWidth, MultisampledFBOHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nil);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, DepthBufferTextureId, 0);

  glBindFramebuffer(GL_FRAMEBUFFER, 0);
  
  ...
  ...// Creation of the non-multisampled FBO
  ...
  
  // Drawing Part
  
  glEnable(GL_MULTISAMPLE);
  glBindFramebuffer(GL_FRAMEBUFFER, MultisampledFBOId);
  glPushAttrib(GL_VIEWPORT_BIT);
  glViewport(0, 0, MultisampledFBOWidth, MultisampledFBOHeight);
  
  ...
  ...// Render the scene
  ...
  
  glPopAttrib;
  glBindFramebuffer(GL_FRAMEBUFFER, 0);
  glDisable(GL_MULTISAMPLE);
  

  // Copy the Multisampled FBO into the other
  glBindFramebuffer(GL_READ_FRAMEBUFFER, MultisampledFBOId);
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, NonMultisampledFBOId);

  glBlitFramebuffer(0, 0, MultisampledFBOWidth, MultisampledFBOHeight, 0, 0, NonMultisampledFBOWidth, NonMultisampledFBOHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);

  glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
  
  ...
  ...// Display the non multisampledFBO Color texture
  ...

The non-multisampled FBO is created the same way as the other, just with “glRenderbufferStorage” instead of “glRenderbufferStorageMultisample”.
I also found that if I change the two “GL_TEXTURE_2D” in “glFramebufferTexture2D” with “GL_TEXTURE_2D_MULTISAMPLE”, it appears to work, but according to the OpenGL sample code, it should also work without.

Thank you for your help, and sorry for my poor English :slight_smile:

First you attached render buffer (correct) but then you changed that to texture 2d (incorrect).

You cannot attach both texture 2d and multi sampled render buffer to the same attachment points (0 is your case).

Ok, I did not understand this like that. Thank you for your help !

I tried to change the GL_COLOR_ATTACHMENT0 of the color texture to 1, but now I get a GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE. Any idea ?

All images in an FBO must have the same number of samples. If they do not, then you get GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE.

I tried to change the GL_COLOR_ATTACHMENT0 of the color texture to 1

What does that mean? Change what of the color texture to 1?

You probably want to render your scene with multisampling and have the result in texture. Right? This is not directly supported.

First render your scene to multisampled renderbuffer.
Then create second FBO with texture 2D and “blit” the content from 1st FBO to 2nd FBO. This blit operation resolves the multisampling buffer to plain texture.

more info here: http://www.opengl.org/registry/specs/EXT/framebuffer_blit.txt

Thank you for your replies :slight_smile:

Alfonse Reinheart : Sorry, I mean change the color attachment of the texture from 0 to 1.

mfort : Yes, I would like to have the color buffer in a texture. I tried to remove both color and depth texture attachment in the multisampled FBO creation, and now it works, with the blitting operation.

I had one more question : I would like to get a texture from the color buffer while rendering my scene. Is it possible with a non-multisampled FBO ? Is the attached texture of a FBO constantly updated when rendering into it ?

It is not possible to render to texture and use the texture at the same time. NVIDIA provides extension to allow this operation under certain conditions: http://www.opengl.org/registry/specs/NV/texture_barrier.txt

Wow, FBOs are’nt so much flexible, actually :sick: I think I am rather going to use glCopyTexImage2D :whistle:
Thank you for the help !

Wow, FBOs are’nt so much flexible, actually I think I am rather going to use glCopyTexImage2D

Good luck with your performance. I’ll stick to using FBOs and not doing extra copies.

I would really like to use FBOs, but is it possible with that ? : I would like to render some objects using an image of the current scene, and also get the image of the scene fully rendered for post processing.
I’m really confused about how to achieve that with FBOs. It’s quite easy with glCopyTexImage, but I agree that it is not really performance-friendly.

I would really like to use FBOs, but is it possible with that ?

Anything you could possibly do with glCopyTex(Sub)Image can be done with FBOs. It’s all a question of exactly what it is you are trying to do.

From your code, it seems like you need a refresher in how to set up an FBO. Read this for details.

As for the multisample issue, you could use GL_ARB_texture_multisample (part of GL 3.2 and above). But if you’re using this as a texture for an object in a scene, I wouldn’t recommend it. Multisample textures do not support filtering, which you’ll probably want.

Instead, render to multisampled renderbuffers, then use a framebuffer blit to an FBO containing a texture. You then use that texture to do what you need to (post-processing, etc).

If I just “replace” the glCopyTexImage with FBOs operation, it would give me something like that :

– Bind multisampled FBO –

  • Render part of the scene -

– Unbind multisampled FBO –
– Blit to the other FBO –
– Get the color texture from that FBO –

– Rebind multisampled FBO –

  • Render the rest of the scene : objects that need the scene image (using the color texture) -

– Unbind multisampled FBO –
– Blit to the other FBO –
– Get the color texture from that FBO –

  • Do post processing using the color texture -

Is that a correct way of using (efficiently) FBOs instead of glCopyTexImage ?

Yes, the code outline is correct.
On the other hand I think the FBO and glCopySubTexImage will have equal performance in this case.

– Bind multisampled FBO –

  • Render part of the scene -

– Unbind multisampled FBO –
– Blit to the other FBO –
– Get the color texture from that FBO –

– Rebind multisampled FBO –

You cannot blit from or to a buffer object if it is not bound. So the “Unbind multisampled FBO” step is wrong.

Alfonse Reinheart : That’s true, I was implicitly including the bindings of both FBOs (read and write) in the “–Blit to the other FBOs–”

mfort : if it does not give more performance that with CopyTexImage, how should I modify my code outline ?

I think this is already the fastest way. FBO is not a magic wand to make things faster.

Ok, then I will stick to that.
Thank you both for your help :slight_smile: