hi, i’m trying to setup a framebuffer with several texture attachments
2 of those texture attachments should store some integer values (like materialID etc.), but i dont get it right
i want to read back to the application the current framebuffer values at the cursor position, that works if i use vec4 as fragment shader output and GL_RGBA as texture format
the problem is: how can i read back integer values correctly ???
the fragment shader is trivial:
layout (location = 0) out vec4 Fragment0;
layout (location = 1) out int Fragment1;
layout (location = 2) out int Fragment2;
void main(void)
{
Fragment0 = vec4(1, 0, 0, 1);
Fragment1 = 2; // any constant integer value, for testing
Fragment2 = 500;
}
the framebuffer setup:
i have 3 color attachments, the 1st is just a rgba texture for color
the 2nd/ 3rd texture are those integer textures
the 4th is a depth texture
// initialize 4 textures for framebuffer:
// set filter parameters
for (unsigned int i = 0; i < 4; i++)
{
glBindTexture(GL_TEXTURE_2D, framebuffer.textures[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
}
// allocate memory:
// color texture
glBindTexture(GL_TEXTURE_2D, framebuffer.textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// objectID texture
glBindTexture(GL_TEXTURE_2D, framebuffer.textures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_INT, 0);
// faceID texture
glBindTexture(GL_TEXTURE_2D, framebuffer.textures[2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_INT, 0);
// depth texture
glBindTexture(GL_TEXTURE_2D, framebuffer.textures[3]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// attach to framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, framebuffer.textures[0], 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, framebuffer.textures[1], 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, framebuffer.textures[2], 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, framebuffer.textures[3], 0);
when rendering:
i’m binding my framebuffer, set the drawbuffers, and render a simple triangle with the shader
when using for each color attacjment the same rgba format (aand vec4 as fragmentshader output), it works
but my problem is that i cant draw integers into those texture, i dont know what internal / external format to use and what arguments to pass to the function glReadPixels(…)
// render:
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
unsigned int drawbuffers[] = {
GL_COLOR_ATTACHMENT0, // color
GL_COLOR_ATTACHMENT1, // objectID
GL_COLOR_ATTACHMENT2, // faceID
};
glDrawBuffers(sizeof(drawbuffers) / sizeof(unsigned int), drawbuffers);
// clear buffers
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// render
glUseProgram(program);
glBindVertexArray(vertexarray);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
// read all 3 pixels from the color attachments
int pixel0 = 0, pixel1 = 0, pixel2 = 2;
int x = Main::Instance().cursor()->Position().x;
int y = Main::Instance().cursor()->Position().y;
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel0);
glReadBuffer(GL_COLOR_ATTACHMENT1);
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel1);
glReadBuffer(GL_COLOR_ATTACHMENT2);
glReadPixels(x, y, 1, 1, GL_RED, GL_INT, &pixel2);
std::cout << pixel0 << " " << pixel1 << " " << pixel2 << std::endl;