How do I properly render an integer ID of an object to an integer texture buffer?
Say I have a texture2D with internal format GL_LUMINANCE16 and i attach it as color attachment to my FBO.
When rendering an object, i pass an integer ID to the shader and would like to render this id into my integer texture.
fragmentshader output is of type vec4 however. How do I properly transform my ID to four component float and avoid conversion inaccuracies such that in the end the integervalue in my integer texture target corresponds to the integer ID i wanted to render?
I still don't think that there is a clear answer here. So here is how I made it work through a 2D texture:
// First, create a frame buffer:
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// Then generate your texture and define an unsigned int array:
glGenTextures(1, &textureid);
glBindTexture(GL_TEXTURE_2D, textureid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, w, h, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Attach it to the frame buffer object:
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, textureid, 0);
// Before rendering
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
GLuint buffers[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; // this assumes that there is another texture that is for the render buffer. Color attachment1 is preserved for the element ids.
glDrawBuffers(2, buffers);
// Clear and render here
glFlush(); // Flush after just in case
glBindFramebuffer(GL_FRAMEBUFFER, 0);
On the GLSL side the fragment shader should have (4.3 core profile code here):
layout(location = 0) out vec4 colorOut; // The first element in 'buffers' so location 0
layout(location = 1) out uvec4 elementID; // The second element in 'buffers' so location 1. unsigned int vector as color
// ...
void main()
{
//...
elementID = uvec4( elementid, 0, 0, 0 ); // Write the element id as integer to the red channel.
}
You can read the values on the host side:
unsigned int* ids = new unsigned int[ w*h ];
glBindTexture(GL_TEXTURE_2D, textureid);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, ids);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With