PDA

View Full Version : Reading FSAA with FBO and glReadPixels



devdept
12-01-2008, 07:10 AM
Hi All,


We have a perfect looking 4x FSAA viewport but when is the time to make a bitmap for it we get a strange result: a bitmap of the screne not antialiased but with some strange artifacts along the lines (simply wireframe GL_LINES drawing). Basically the image is the right one but during the glReadPixel the FSAA is working wrong.

We had no problem when using FBO texture to make the bitmap but recently we switched to glReadPixel as suggested on this forum and the problem arised.

What's wrong with this code:


fb = glGenFramebuffersEXT();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

uint cb = glGenRenderbuffersEXT();
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, cb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, posterWidth, posterHeight);

uint db = glGenRenderbuffersEXT();
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, db);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, posterWidth, posterHeight);

glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, cb);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, db);

int status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

DrawScene(...);

glReadPixels(0, 0, posterWidth, posterHeight, GL_BGR, GL_UNSIGNED_BYTE, scan0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(fb);


Why this code fails to get the antialising scene?


Thanks,

Alberto

mfort
12-01-2008, 08:57 AM
glReadPixel is not supported on antialiased FBO.

Make second FBO and use glBlitFramebufferEXT to copy data from FSAA FBO to non FSAA FBO.

BTW. Your code is not using FSAA.

Brolingstanz
12-01-2008, 09:12 AM
You need to use glRenderbufferStorageMultisampleEXT or glRenderbufferStorageMultisampleCoverageNV with say a 4 for the samples parameter.

devdept
12-01-2008, 02:31 PM
Hi Guys,


Is the glRenderbufferStorageMultisampleEXT() the best way to achieve it?

Where can I find an official usage sample?

What will happen if FSAA is not available? Will this call fail?


Thanks,

Alberto

V-man
12-01-2008, 07:11 PM
http://www.opengl.org/wiki/index.php/GL_EXT_framebuffer_multisample

devdept
12-02-2008, 07:30 AM
Thanks V-man,

I wanted to discuss the following more in details:


Since you can't read the multisample buffer directly with glReadPixels since it would raise an error flag (GL_INVALID_OPERATION), what should you do?
You need to blit to another surface so that the GPU can do a downsample. You could blit to the backbuffer, but there is the problem of the "pixel owner ship test". It is best to make another FBO.
Let's assume you made another FBO and now you want blit.
This requires GL_EXT_framebuffer_blit. Typically, when your driver supports GL_EXT_framebuffer_multisample, it also supports GL_EXT_framebuffer_blit, for example the nVidia Geforce 8 series.

Now I have FBO -> glReadPixel working perfectly without FSAA to add FSAA support I need:

1) create a new framebuffer_multisample in the case FSAA is available and active
2) make the blit between the framebuffer_multisample and the regular_framebuffer
3) use glReadPixel on the regular_multisample

In the case the FSAA is active go directly to point (3)

Is it everything right?


Thanks,

Alberto

devdept
12-19-2008, 07:39 AM
V-man,

In the sample you provided http://www.opengl.org/wiki/index.php/GL_EXT_framebuffer_multisample (http://www.opengl.org/wiki/index.php/GL_EXT_framebuffer_multisample) there is the following cleanup call:



//Delete resources
glDeleteTextures(1, &ColorBufferID);
glDeleteRenderbuffersEXT(1, &DepthBufferID);
//Bind 0, which means render to back buffer, as a result, fb is unbound
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &fboID);


But this line...


glDeleteTextures(1, &ColorBufferID);

... makes one texture in my app to disappear.

Why?


Thanks,

Alberto

mfort
12-19-2008, 08:05 AM
Because of bug in that example.
The clean up code should be:
glDeleteRenderbuffersEXT(1, &ColorBufferID);

devdept
12-19-2008, 08:07 AM
So there is a mistake in this official OpenGL reference?

Thanks,

Alberto

mfort
12-19-2008, 08:19 AM
It is a wiki, it's not any official source from ARB.

ColorBufferID is ID of render buffer so it must be destroyed by
glDeleteRenderbuffersEXT. But the author made a mistake and destroyed some texture with that ID.

It can happen, we are all humans.

devdept
12-19-2008, 01:50 PM
Ok, thanks.

Alberto