0

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

PhilLab
  • 4,777
  • 1
  • 25
  • 77

1 Answers1

3

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.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • okay, I understand why this is as it is. Why does it work if I hide the window, though? Is this actually unintended? – PhilLab Oct 14 '16 at 14:41
  • 2
    @PhilLab: It's undefined behavior, anything might happen. Most likely you're runniung on a system that uses window compositing and hiding a window simply omits the final compositing step. It will probably not work if compositing is disabled (OS compositing mechanisms are as following: Windows Vista onward DWM/Aero. X11: XRender+Composite + {xcompmgr,compiz,emerald,Gnome Shell,etc.}. MacOS X: Quartz Extreme). – datenwolf Oct 14 '16 at 14:58