Search code examples
openglglewfreeglut

Freeglut: glReadPixels() does not work when minimizing (iconify) window


I use freeglut to display OpenGL renderings in a Windows window. The last step of my pipeline is to grab the pixels from my buffer using glReadPixels() for later processing (e.g. storing in a video file). However, as soon as I minimize the window using the standard Windows minimize button, the call to glReadPixels() does not read any data and as soon as I restore the window to its visible state, it works again.

How can I continue rendering even if the window is minimized?

This is how I fetch the image data:

GLint viewPortParams[4];
glGetIntegerv(GL_VIEWPORT, viewPortParams);
const int width = viewPortParams[2];
const int height = viewPortParams[3];
// outImage is a cv::Mat* which stores image data as matrix
outImage->create(height, width, CV_8UC3);
// Set it to all grey for debugging - if image stays grey, data has not been fetched.
outImage->setTo(145);

const size_t step = static_cast<size_t>(renderParameters.outImage->step);
const size_t elemSize = renderParameters.outImage->elemSize();

//Set the byte alignment
glPixelStorei(GL_PACK_ALIGNMENT, (step & 3) ? 1 : 4);
//set length of one complete row
glPixelStorei(GL_PACK_ROW_LENGTH, step / elemSize);
glFlush();  //the flush before and after are to prevent unintentional flipping
glReadBuffer(GL_BACK);
glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, outImage->data);

/*
 * Now, outImage->data does contain the desired image if window is normal
 * but stays grey (i.e. the value 145 set above) if minimized
 */

glFlush();
glutSwapBuffers();

Interesting side note: using a completely offscreen pipeline (using glutHideWindow()) does work - the image data is correctly retrieved


Solution

  • However, as soon as I minimize the window using the standard Windows minimize button, the call to glReadPixels() does not read any data and as soon as I restore the window to its visible state, it works again.

    Yes, that's how it works. Rendering happens only to pixels that pass the pixel ownership test (i.e. pixels that are part of an off-screen buffer, of pixels of an on-screen window that are actually visible to the user).

    How can I continue rendering even if the window is minimized?

    Render to a framebuffer object (that gives you an off-screen buffer), then read from that.