1
votes

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();
};
1
Why not use calloc (...) instead of zeroing your memory after allocation? Onto things that actually matter though, can you add the fragment shader you are using to output to the unsigned integer texture attachment? - Andon M. Coleman
@AndonM.Coleman In my fragment shader I output information as float to Red channel and I can garantee the output is correct because I bind it onto a quad and show it on screen - Wood
@AndonM.Coleman I've pasted my fragment shader and geometry shader. check the updates :-) - Wood
I can guarantee you that if you output as a float, then the output is not correct. You do not write floating-point outputs to integer textures, there is implicit conversion from uint to float and this is probably why you are sort of getting away with this. You actually need to write to a uint output. - Andon M. Coleman

1 Answers

3
votes

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?