PDA

View Full Version : glReadPixels OR glGetTexImage crash application



strattonbrazil
09-24-2011, 05:13 PM
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, &amp;val);
std::cout << "Texture width: " << val << std::endl;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &amp;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);

Dan Bartlett
09-24-2011, 06:33 PM
Do you have a buffer object bound to PIXEL_PACK_BUFFER? If so it will be reading into that buffer (likely at a huge offset) instead of into client memory.
Try:


glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

strattonbrazil
09-24-2011, 07:14 PM
I don't actually do anything iwth PIXEL_PACK_BUFFER anywhere in my code. Adding that code in just in case still crashes my app.

Dan Bartlett
09-25-2011, 12:31 AM
I'm not fluent in c/c++, but looking at http://en.wikipedia.org/wiki/New_(C%2B%2B) should:


GLuint* ack = new GLuint(width()*height()*4*4);

be


GLuint* ack = new GLuint[width()*height()*4*4];

Alfonse Reinheart
09-25-2011, 03:32 AM
Also, use `delete[]` when you use `new[]`.

strattonbrazil
09-26-2011, 05:33 PM
That indeed was my problem.