Using an FBO with two color attachments and a depth texture attachment, I can’t seem to read back the data from one of the color textures without crashing the application. This happens when I try to use either glReadPixels when the FBO is bound, or glGetTexImage on the texture directly.
I’ve checked the size of the texture, which seems to the be size I’d expect and I’ve also tried significantly expanding the allocated memory I’ve read into, which I’ve checked to make sure is correctly being allocated. I’ve also read that glReadPixels and glGetTexImage are affected by previous bind calls (I’m using VBOs, too) where it turns the pointer into an offset, so I tried to make sure I’m setting everything back to 0. Still either read function crashes.
I know the texture is getting the correct data. If I render my scene to the FBO and then render the texture to the screen, I get what I’d expect. Are there any other debugging tips I can use for working this out?
Looking at this example, it seems glReadPixels works without problem, so I don’t know if it’s my texture setup, messed up state, or something else.
http://www.mathematik.uni-dortmund.de/~goeddeke/gpgpu/tutorial.html
Here’s my code to setup the FBO, which works for rendering to the color attachments.
glGenFramebuffersEXT(1, &_fbo);
glGenTextures(1, &_beautyTexture);
glGenTextures(1, &_indexTexture);
glGenTextures(1, &_depthTexture);
glBindFramebufferEXT(GL_FRAMEBUFFER, _fbo);
// setup beauty texture
glBindTexture(GL_TEXTURE_2D, _beautyTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, _beautyTexture, 0);
// setup index texture
glBindTexture(GL_TEXTURE_2D, _indexTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, _indexTexture, 0);
// setup depth texture
glBindTexture( GL_TEXTURE_2D, _depthTexture);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, _depthTexture, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, _depthTexture, 0);
glBindTexture( GL_TEXTURE_2D, 0);
switch (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT" << std::endl;
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT" << std::endl;
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT" << std::endl;
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
std::cerr << "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT" << std::endl;
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
std::cerr << "GL_FRAMEBUFFER_UNSUPPORTED_EXT" << std::endl;
break;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
And here’s the code where I try to read back the data after I render out the scene.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _fbo);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
GLuint* ack = new GLuint(width()*height()*4*4);
//glBindTexture(GL_TEXTURE_2D, _beautyTexture);
GLint val;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &val);
std::cout << "Texture width: " << val << std::endl;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &val);
std::cout << "Texture height: " << val << std::endl;
std::cout << width() << std::endl;
std::cout << height() << std::endl;
//glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, ack);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, width(), height(), GL_RGBA, GL_UNSIGNED_BYTE, ack);
//glReadPixels(0, 0, width(), height(), GL_RGBA, GL_UNSIGNED_INT, _selectionBuffer.data());
delete ack;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);