0

I tried to make a off-screen rendering using frame buffer object. When in non-multi-sampling, everything is okay; but when I turned it into multi-sampling, I just got a blank image. My code is as follows:

GLuint textureId, rboId, fboId;
int err;
// 1. Create a texture.
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureId);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, w, h, GL_TRUE);
err = glGetError(); // <== err = 0, no error.

// 2. Create depth render buffer: (Optional)
glGenRenderbuffers(1, &rboId);
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT, w, h);
err = glGetError(); // <== err = 0, no error.

// 3. Create and bind the frame buffer
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
err = glGetError(); // <== err = 0, no error.

// 4. Attach the texture to FBO color attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureId, 0);
err = glGetError(); // <== err = 0, no error.

// 5. Attach the depth info to FBO depth attachment point
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);
err = glGetError(); // <== err = 0, no error.

// check FBO status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); // status = GL_FRAMEBUFFER_COMPLETE

Then, I draw the scene and read the pixels:

draw();
cv::Mat Img(h,w,CV_8UC4);
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, Img.data); // <== Img contains nothing.

Where did I go wrong?

Update: I tried the following code to read pixels, but problem remains, Why?

...
draw(); 
// then I tried "blit" the multisampled fbo to a normal fbo for reading.
GLuint normalFboId;
glGenFramebuffers(1, &normalFboId);
glBindFramebuffer(GL_FRAMEBUFFER, normalFboId);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, normalFboId);
glDrawBuffer(GL_BACK);
glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, normalFboId);

cv::Mat Img(h, w, CV_8UC4, cv::Scalar(0,0,255,255));
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, Img.data);
C. Wang
  • 2,516
  • 5
  • 29
  • 46
  • possible duplicate of [glReadPixels from FBO fails with multisampling](http://stackoverflow.com/questions/765434/glreadpixels-from-fbo-fails-with-multisampling) – derhass Aug 15 '15 at 20:46
  • @derhass, see my updated question. Thanks! – C. Wang Aug 15 '15 at 21:08
  • Your `nomalFboID` does not have any color buffer to blit into. And `glDrawBuffer(GL_BACK)` is completely invalid when an FBO is bound. – derhass Aug 15 '15 at 21:08
  • @derhass, Could you help me fix my newly-added code? Since I am quite new to it. Thanks! – C. Wang Aug 15 '15 at 21:10
  • Why are you using an FBO for the destination in the first place? `glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);` (instead of using `normalFboId`) would draw directly to the screen (assuming you have a screen). The default framebuffer has a front-buffer, and probably a back-buffer too; FBOs do not. If you are completely offscreen, then `glDrawBuffer (...)` needs to be `GL_COLOR_ATTACHMENT0` and you need to attach an RBO to that location to hold the results. – Andon M. Coleman Aug 16 '15 at 01:52

0 Answers0