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