Search code examples
opengltextures

glGetTexImage don't work with unsigned integer texture


I'm using integer texture and bind it to framebuffer to get render data.

I'v bind it to quad to display it on the screen and I'm sure the content of the texture is right.

But when I use glGetTexImage to get the content of the texture, I get random numbers.

here is the code to create the framebuffer:

glEnable(GL_TEXTURE_2D); 
glGenFramebuffers(1, &param.fbo);
glGenTextures(1,&param.triTex);
glBindTexture(GL_TEXTURE_2D, param.triTex); 

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); 

glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, param.fboSize, param.fboSize, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, param.fbo); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, param.triTex, 0);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);

The texture and framebuffer renders without problem.

here is the code of getting the content:

glBindTexture(GL_TEXTURE_2D, param.triTex);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
triTexData = (unsigned int *)malloc(param.fboSize * param.fboSize * sizeof(unsigned int));
memset(triTexData, 0, sizeof(unsigned int) * param.fboSize * param.fboSize);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, triTexData);
glBindTexture(GL_TEXTURE_2D,0);

Fragment shader and geometry shader

#version 330
flat in int color;
out vec4 fragColor;
void main(void)     
{
    fragColor = vec4(color,0.0,0.0,0.0);
}

#version 330
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
flat out int color;
void main(void)
{
gl_Position = gl_in[0].gl_Position;
color = gl_PrimitiveIDIn;
EmitVertex();
gl_Position = gl_in[1].gl_Position;
color = gl_PrimitiveIDIn;
EmitVertex();
gl_Position = gl_in[2].gl_Position;
color = gl_PrimitiveIDIn;
EmitVertex();
EndPrimitive();
};

Solution

  • Your fragment shader should actually be written this way to output to a GL_R32UI image:

    #version 330
    
    flat in  int  color;
         out uint fragColor;
    
    void main (void) {
      fragColor = color;
    }
    

    At present, you are not reading back "random" numbers, you are just seeing what happens when you interpret floating-point data as integers without the proper conversion. Not pleasant, is it?