PDA

View Full Version : Reading the entire sceen using glReadPixels



Laughing Rice
04-03-2009, 02:32 PM
I'm trying to find out how to read the entire screen into a PBO (for transfering int cuda for post processing if it matters). I managed to find how to do it under linux (X windows) with GLX but I can't seem to find out how to do it with WGL.

Under linux something like this works:

Display *dpy = XOpenDisplay(NULL);
Window root = DefaultRootWindow(dpy);
GLint att[] = {GLX_RGBA, None};
XVisualInfo *vis = glXChooseVisual(dpy, 0, att);
GLXContext glc = glXCreateContext(dpy, vis, NULL, true);
glXMakeCurrent(dpy, root, glc);
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, WIDTH, HEIGHT, GL_BGRA, UNSIGNED_BYTE, NULL);

I tried the following under windows but all it gets me is a blank buffer

HDC hdc;
HGLRC hglrc;
hdc = GetDC(hWnd);
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, /* version */
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24, /* 24-bit color depth */
0, 0, 0, 0, 0, 0, /* color bits */
0, /* alpha buffer */
0, /* shift bit */
0, /* accumulation buffer */
0, 0, 0, 0, /* accum bits */
32, /* z-buffer */
0, /* stencil buffer */
0, /* auxiliary buffer */
PFD_MAIN_PLANE, /* main layer */
0, /* reserved */
0, 0, 0 /* layer masks */
};
int iPixelFormat;
iPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, iPixelFormat, &pfd);
hglrc = wglCreateContext (hdc);
wglMakeCurrent (hdc, hglrc);
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGB, UNSIGNED_BYTE, NULL);

Laughing Rice
04-03-2009, 04:24 PM
I tried to see the return of the glReadPixels and apparently it returns invalid operation.
I saw some references for doing this by creating an undisplayed window and capturing it but it's apparently undocumented and thus not guaranteed to work.
There are also suggestions to use bitblt, but if I understand correctly this will pass the data through the CPU and I would like to leave it on the gpu so as not to create a communication overhead.

chris2718
04-04-2009, 08:39 AM
As far as I know there are 3 ways to capture the screen in windows.
Win32 calls. BitBlt(_hCaptureDC,x,y,_width,_height,_hDesktopDC, x,y,SRCCOPY);

DirectX.

Windows Media Player extensions or Windows Multimedia. This is for video capture of the desktop.

They may all go through the CPU, I'm unsure.