Behaviour of glReadPixels outside viewport ?


I have noticed a strange behaviour in glReadPixels when trying to read outside any viewports or fbo.

There is just a note in the specif :
“Values for pixels that lie outside the window connected to the current GL context are undefined.”

And the second note is :
“If an error is generated, no change is made to the contents of data.”

But when I tried to read outside my window, glReadPixels doesn’t work as described in the notes above :

  1. There is no change in the output data (contradict the 1st note)
  2. glGetError gives GL_NO_ERROR (contradict the 2nd note).

Actually, in my case, the description should be :
“No change is made to the contents of data, when trying to read pixels that lie outside the window connected to the current GL context”.

I wonder if it depends on the implementation or not ? (my gpu is a Nvidia Quadro FX1700.)

Could anyone test to give me feedback about that ? (It’s very quick. With GLUT, it takes less than 2 min : just pay attention to initialize your pointer with noticeable values before calling glReadPixels). Thanks!

No change in the data is perfectly in line with undefined behaviour, so it doesn’t contradict the first point. Reading outside the viewport is not an error, so it doesn’t contradict the second note either.

What you experience is simply OpenGL’s pixelownership test failing.

The data not owned by the OpenGL context (for example because another window overlaps it, or because the window is moved off the desktop) return undefined data. Period.
What that data is is implementation dependent. Some implementations return garbage, some return black, some actually return the correct data. You’ll never know and must not rely on any behaviour you experience, that is the important fact, it’s undefined!

When glReadPixels throws an error (for example when you use a wrong parameter in the call) the read pixel is actually not done (just sets the error and returns early) and so the data you had in your destination buffer where the readpixels would have put it won’t change.
Since you got no error, the data has changed and failing pixelownership made parts undefined.

Everything worked as specifed and expected.
It’s your problem to make sure you pass the pixelownership test.

The only surfaces guaranteed to never fail the pixelownership test are FBOs and P-Buffers.

we did a readpixel of the GL_FRONT buffer on a winxp 32 bit / Quadro 1500FX system with some 162xxx drivers. In this config we were able to grab the screen content correctly, but its definitely not a wise solution to use this for application grabbing…

Why readback from front buffer? Have you tried readback from back buffer using PBO?

Again, pixelownership affects the whole OpenGL pixel vector: front, back, left, right, back, depth, stencil buffers and what else an implementaion might expose.
If the context doesn’t “own” a pixel (e.g. overlapped by another window or moved off the screen) the whole pixel vector is undefined (=> behaviour is implementation dependent).

Experiments to show that this isn’t working:
When reading from front under Windows XP, overlap your window with the Taskmanager which is topmost and see what you get.
When reading from back, overlap with another OpenGL application and see what you get. (That esp. won’t work on your workstation board which shares the back/depth/stencil buffers.)

Simple answer to all these problems: Use FBOs.