glReadPixels crashes using GL_FLOAT

I have a frustrating problem where my app crashes, when I designate my FBO greater than a given resolution and I call glReadPixels with GL_RGBA/GL_FLOAT. If I call glReadPixels with GL_RGBA/GL_UNSIGNED_BYTE the program doesn’t crash at any resolution (that I’ve tested at least) and the image I get back is what I’d expect.

My renderbuffers hold 32-bit floats because I’d like to store fairly large numbers greater than 1, but I don’t know why its causing a problem. If I can specify the renderbuffer to use RGBA32F and I can read it back correctly, I’d suspect everything is working as far as setup is concerned. However, glReadPixels just seems to consistenly crash trying to read floats out.

Can anyone spot anything that may cause the problem?


const int xres = 800; // crashes if > 843
const int yres = 600;

// create VBOs and FBOs for drawing out geometry
const int NUM_COLOR_ATTACHMENTS = 1;
GLuint fbo, depthBufferId;
GLuint colorBufferIds[NUM_COLOR_ATTACHMENTS];
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
GLuint vboId;
glGenBuffers(1, &vboId);


// Create depth renderbuffer
glGenRenderbuffers(1, &depthBufferId);
glBindRenderbuffer(GL_RENDERBUFFER, depthBufferId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, xres, yres);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBufferId);


// Create color renderbuffers
glGenRenderbuffers(NUM_COLOR_ATTACHMENTS, colorBufferIds);
for (int i = 0; i < NUM_COLOR_ATTACHMENTS; i++) {
  glBindRenderbuffer(GL_RENDERBUFFER, colorBufferIds[i]);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, xres, yres);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_RENDERBUFFER, colorBufferIds[i]);
 }
glBindRenderbuffer(GL_RENDERBUFFER, 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;
 }

glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// crashes regardless of whether I draw anything
// drawScene(); 

// read back buffer
//
GLfloat data[xres*yres*4];
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, xres, yres, GL_RGBA, GL_FLOAT, data); // GL_UNSIGNED_BYTE doesn't crash and gives correct (but clamped results)

you can’t normally allocate that much memory on the stack

use malloc or new and put the data on the heap

That was indeed my problem. I remember trying to use the heap to see if that was the problem, but maybe it didn’t compile or I was using the heap and still allocating something on the stack. Anyway, thanks.


GLfloat* data = new GLfloat[xres*yres*4];
...
delete[] data;

RGBA FLOAT is 16 bytes per pixel, not 4.

true, but he requests an array of xresyres4 GLfloats (not bytes, in which case using 16 instead of 4 would be correct).