Using OpenGL to draw objects and also have my fragment shader outputting a scalar integer ID. For drawing the objects, I'm using multi-sampling for anti-aliasing, so when I create the buffer for the integer ID, I have to create it as an MSAA buffer as well for the FBO to be complete:
glBindRenderbuffer(GL_RENDERBUFFER, rboColorId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, GL_RGBA8,
cam.getWidth(), cam.getHeight());
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, GL_DEPTH_COMPONENT,
cam.getWidth(), cam.getHeight());
glBindRenderbuffer(GL_RENDERBUFFER, rboObjId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaaSamples, GL_R32UI,
cam.getWidth(), cam.getHeight());
glBindRenderbuffer(GL_RENDERBUFFER, rboColorNoMsaaId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8,
cam.getWidth(), cam.getHeight());
glBindRenderbuffer(GL_RENDERBUFFER, rboObjNoMsaaId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_R32UI,
cam.getWidth(), cam.getHeight());
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboColorId);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepthId);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rboObjId);
glBindFramebuffer(GL_FRAMEBUFFER, fboNoMsaaId);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboColorNoMsaaId);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rboObjNoMsaaId);
As you can see in the code above, I have 2 FBOs. The first is MSAA and has a buffer for drawing the scene, a depth buffer, and an integer buffer for the IDs. The second FBO is single sampled (non-MSAA) and has just the draw scene buffer and the integer buffer. After I draw everything (fragment shader sets indeces for each pixel), I read the integer ID buffer (GL_COLOR_ATTACHMENT1) by first blitting it to the single sampled FBO so I can glReadPixels from it. In this particular code, I'm just reading the 1 pixel where the mouse is pointing:
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId);
glReadBuffer(GL_COLOR_ATTACHMENT1);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboNoMsaaId);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glBlitFramebuffer(mouse_x_pos, cam.getHeight() - mouse_y_pos, mouse_x_pos+1, cam.getHeight() - mouse_y_pos + 1,
0, 0, 1, 1,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboNoMsaaId);
glReadBuffer(GL_COLOR_ATTACHMENT1);
GLuint objectId;
glReadPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_UNSIGNED_INT, &objectId);
My problem is that when I blit, the multi-samples for the pixel I want are interpolated into the single pixel I get to read. I want that for the color buffer I'm using to draw the scene, but I do not want that for the integer IDs I read. If I'm reading a pixel that contains fragments for both an ID of 50 and an ID of 100, I want to read either 50 or 100 (don't care which). But what I get is some value between 50 and 100, like 75. 75 may actually be a completely different pixel, so I don't want that at all.
Is there something I can do to read a single sample for the integer ID instead of the interpolation of multiple samples?