Reading FSAA with FBO and glReadPixels

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


int status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

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

Why this code fails to get the antialising scene?



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.

You need to use glRenderbufferStorageMultisampleEXT or glRenderbufferStorageMultisampleCoverageNV with say a 4 for the samples parameter.

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 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?




In the sample you provided 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.




Because of bug in that example.
The clean up code should be:
glDeleteRenderbuffersEXT(1, &ColorBufferID);

So there is a mistake in this official OpenGL reference?



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.

Ok, thanks.