PDA

View Full Version : FBO mulltisampling



Maire Nicolas
10-29-2010, 06:51 AM
Hello :)

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

mfort
10-29-2010, 08:57 AM
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).

Maire Nicolas
10-29-2010, 11:45 AM
Ok, I did not understand this like that. Thank you for your help !

Maire Nicolas
10-30-2010, 12:37 AM
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 ?

Alfonse Reinheart
10-30-2010, 02:38 AM
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?

mfort
10-30-2010, 02:51 AM
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

Maire Nicolas
10-30-2010, 03:56 AM
Thank you for your replies :)

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 ?

mfort
10-30-2010, 04:56 AM
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

Maire Nicolas
10-30-2010, 11:04 AM
Wow, FBOs are'nt so much flexible, actually :sick: I think I am rather going to use glCopyTexImage2D :whistle:
Thank you for the help !

Alfonse Reinheart
10-30-2010, 02:57 PM
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.

Maire Nicolas
10-31-2010, 04:58 AM
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.

Alfonse Reinheart
10-31-2010, 11:30 AM
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 (http://www.opengl.org/wiki/Framebuffer_Object) 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).

Maire Nicolas
10-31-2010, 12:23 PM
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 ?

mfort
10-31-2010, 01:15 PM
Yes, the code outline is correct.
On the other hand I think the FBO and glCopySubTexImage will have equal performance in this case.

Alfonse Reinheart
10-31-2010, 03:03 PM
-- 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.

Maire Nicolas
11-01-2010, 05:17 AM
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 ?

mfort
11-01-2010, 06:45 AM
I think this is already the fastest way. FBO is not a magic wand to make things faster.

Maire Nicolas
11-02-2010, 11:35 PM
Ok, then I will stick to that.
Thank you both for your help :)