Reading the entire sceen using glReadPixels

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);

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.

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.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.