PDA

View Full Version : Screen capture problems



gtada
07-23-2001, 06:05 AM
I'm trying to implement a screen capture feature in an OpenGL program.

...
GLubyte* ssBuffer;

ssBuffer = new GLubyte[pixelCount * 3];

glReadPixels(0, 0, windowInfo.actualWidth, windowInfo.actualHeight, GL_RGB, GL_UNSIGNED_BYTE, ssBuffer);

for (int i = 0; i < pixelCount * 3; i+=3) {
outfile << ssBuffer[i + 2]; // B
outfile << ssBuffer[i + 1]; // G
outfile << ssBuffer[i]; // R
}
...

The problem is that part of whatever is behind the OpenGL window is captured in the file. For example, part of Visual C++'s screen is in the screen capture, when the OpenGL window should take up all of it.

Thanks,
Greg

Eric
07-23-2001, 06:10 AM
I think the OpenGL specs state that the contents of the frame buffer is unknown where the GL window is covered by another window... And there is no workaround about this.

Your best bet is to render offscreen (in a DIB).

Regards.

Eric

gtada
07-23-2001, 06:14 AM
The problem is that it's capturing part of whatever is BEHIND the OpenGL window, not what's over it. Weird, ain't it? I have no idea what is going on with it. Any other ideas?

Eric
07-23-2001, 06:17 AM
Oops sorry: I should read more carefully !

Can you e-mail me a sample app that demonstrates the bug ?

One or two things to check: is your rendering context correctly set up when calling glReadPixels (check wglMakeCurrent) ?

As a side question: what type of hardware/drivers are you using ?

Regards.

Eric

gtada
07-23-2001, 06:21 AM
LOL don't worry, I do it ALL the time. http://www.opengl.org/discussion_boards/ubb/wink.gif

I'll email the code, but one thing is that I have no idea what wglMakeCurrent is. Hmmm.

I'm running two machines, an SGI 540 with 1 gig of RAM and the Cobalt graphics chipset(latest drivers) and an SGI/Intergraph Zx10 with 1.5 gigs of RAM and a Wildcat 4210 (also latest drivers).

Thanks Eric,
Greg

gtada
07-23-2001, 06:42 AM
I looked at the wglMakeCurrent function, and the only thing is that I'm using GLUT, and I don't know how to get the window handle. Also, I'd like to keep this as cross-platform as possible. Isn't there a cross-platform way to do a screen capture?

Thanks,
Greg

Deiussum
07-23-2001, 09:01 AM
This is just a thought, but when do you do your screen capture, and are you using double buffering?

More specifically, are you doing something like so?

RenderScene();
glutSwapBuffers();
GetScreenCapture();

or

RenderScene();
GetScreenCapture();
glutSwapBuffers();

You should be using the second method. If you use the first, then that could be what is causing your problem.

gtada
07-23-2001, 10:56 AM
Deiussum,
I don't know exactly when the screen capture occurs. I'm using GLUT, and I have it set to screen capture when the user presses the "s" key. Any idea when it happens?

Deiussum
07-23-2001, 12:06 PM
Are you using double buffering then? If so, you are probably running into the problem where you are grabbing from a backbuffer that hasn't had a scene drawn to it yet, thus there is no telling what may be on it. Perhaps you could set a global boolean to say that next frame you need to take a screenshot, then reset that boolean after you've taken it. Just one possible solution, but it should work.

zed
07-23-2001, 01:10 PM
how about

keyboard_callback()
{
case 's': s_pressed=true;
}

btw the following 2 are standard for doublebuffed windows
glReadBuffer( GL_BACK )
glDrawBuffer( GL_BACK )

RenderScene();
glFlush();
if ( s pressed )
GetScreenCapture();
glutSwapBuffers();

gtada
07-24-2001, 05:18 AM
Got it working! Big thanks to Eric, Deiussum, and Zed. I placed a call to glReadBuffer(GL_FRONT) before glReadPixels, and that fixed it.

gtada
07-24-2001, 11:05 AM
Continued challenges on the screen capture I'm afraid. It works fine when my OpenGL window is small, but if it's say larger than 600 pixels in any direction, it barfs. The resulting image is skewed, like there's an extra pixel in each row. I don't know if my screen resolution has anything to do with it, but it's at 1920 x 1200. Too much for it to handle?

zed
07-24-2001, 12:29 PM
perhaps check out the glPixelStore(..) operations eg glPixelStore( GL_PACK_ALIGNMENT, 1 )

gtada
07-26-2001, 05:54 AM
Thanks for the tip, Zed. Now it really does work great! Now for the little nitty-gritty detail: it takes a LONG time to finish. When I do a print screen, it takes maybe two seconds. What gives?

Eric
07-26-2001, 07:04 AM
Have you checked whether the slow bit is glReadPixels or your output code to the PIX file ? If it is the former, there's really nothing you can do about it...

Regards.

Eric