PDA

View Full Version : Clearing an INTEGER framebuffer



chrtom
02-20-2013, 01:44 PM
I'm implementing picking by rendering integer IDs into a framebuffer (FBO). As the buffer format, I'm using GL_RGBA32UI, which is an INTEGER format. My shaders correctly write the integer IDs into the buffer and I can read them back with glReadPixels. However, the problem is clearing the buffer with non-zero integer numbers using glClearBuffer. When I clear with 1, I would expect to read back 1. On NVIDIA cards clearing works as expected. However, on AMD, when I clear with 1, I read back 1065353216. Interestingly, bit-wise speaking 1065353216 INT corresponds to 1.0 FLOAT.

In any case, when I clear a buffer with 1 INT, I expect to read back 1 INT (and neither 1065353216 INT nor 1.0 FLOAT).

1. What is the correct way to clear an integer framebuffer?
2. Is the behavior on AMD cards a driver problem?

A corresponding test case is below. Tests have been made on Windows 7 and Ubuntu 12.10. It works correctly on NVIDIA, but fails on AMD.



#include <stdio.h>
#include <GL/glew.h>
#include <GL/freeglut.h>

GLuint fbo = 0;

void Display()
{
// Clear buffer
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
GLuint in[4] = {0, 1, 2, 3};
glClearBufferuiv(GL_COLOR, 0, in);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

// Read back from the buffer, expect to find the same values as used for clearing
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
unsigned int out[4] = {0, 0, 0, 0};
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &out);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);

printf("IN %d %d %d %d\n", in[0], in[1], in[2], in[3]);
printf("OUT %d %d %d %d\n", out[0], out[1], out[2], out[3]);

glutSwapBuffers();
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEP TH);
glutInitWindowSize(1024, 768);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL");
glutDisplayFunc(Display);

GLenum status = glewInit();
if (status != GLEW_OK) {
printf("Error: %s\n", glewGetErrorString(status));
return EXIT_FAILURE;
}

// Create the FBO
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

GLuint tex = 0;

// Create a texture object for the picking buffer
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32UI, 1024, 768, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);

// Create a texture object for the depth buffer
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 768, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);

// Verify that the FBO is correct
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
printf("Error: status 0x%x\n", status);
return EXIT_FAILURE;
}

// Restore the default framebuffer
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

glutMainLoop();

return 0;
}

debonair
02-20-2013, 09:43 PM
I am facing the same issue with AMD, when i clearcolor with integer texture fbo, everytime i get color values of max intensity. I am implementing render to texture and not using readpixels. I think that is probably a bug.

tonyo_au
02-25-2013, 09:10 PM
I have had several issues with the AMD driver - you may need to clear it with your own shader.

chrtom
02-27-2013, 01:46 AM
Thanks for the comments and suggestions.

So it appears there is a BUG on AMD when clearing and integerbuffer using glClearBuffer. Hopefully AMD recognizes this problem soon and corrects it.