PDA

View Full Version : Need help to take screenshot of openGL app in other app (C++)



Alex-cat
10-27-2015, 10:42 AM
I have openGL application.
I need to take screenshot of this application in my application (c++).
I know HWND of openGl application. If ::GetDC(hwnd); and then ::BitBlt, it works for winForm applications but doesn't work for openGL...
I take black picture.
May be somebody know how to openGl application window to HBITMAP or other...

GClements
10-27-2015, 11:01 AM
In cross-platform OpenGL applications, it's common to use glReadPixels() for screenshots.

glReadPixels() is affected by glReadBuffer(); the initial value is GL_BACK for double-buffered contexts. To read a frame which has already been rendered, you need to change it to GL_FRONT (the contents of the back buffer become undefined after a buffer swap, so reading from the back buffer only makes sense if you do it after rendering but before the buffer swap).

It is also affected by the GL_PACK_* settings for glPixelStore(). The default value for GL_PACK_ALIGNMENT is 4; change it to 1 unless the number of bytes per row is guaranteed to be a multiple of 4.

However: I don't know if or how glReadPixels() interacts with the "Aero" compositing in later versions of Windows (that may be related to getting a black screenshot for OpenGL programs). In the worst case, you may need to redraw the frame, reading the back buffer prior to the swap.

Alex-cat
10-27-2015, 11:13 AM
this is part of my code


HWND hwnd;
hwnd = FindWindow(L"some app", NULL);
RECT r;
::SetWindowPos(hwnd,HWND_TOP ,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
HDC dstDC = ::GetDC(NULL);
HDC srcDC;
::GetClientRect(hwnd, &r);
SIZE sz = { r.right - r.left, r.bottom - r.top };
if (sz.cx <= 0 || sz.cy <= 0)
return false;
srcDC = ::GetDC(hwnd);
HDC memDC = ::CreateCompatibleDC(srcDC);
HBITMAP bm = ::CreateCompatibleBitmap(dstDC, sz.cx, sz.cy);
HANDLE oldBM = ::SelectObject(memDC, bm);
::BitBlt(memDC, 0, 0, sz.cx, sz.cy, srcDC, 0, 0, SRCCOPY);

save_to_file(...)
::SelectObject(memDC, oldBM);
::SetWindowPos(hwnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOM OVE|SWP_NOSIZE);
::DeleteObject(bm);
::DeleteDC(memDC);


what I need to add for grab openGl window?

Aero - off

GClements
10-27-2015, 03:37 PM
Need help to take screenshot of openGL app in other app (C++)

Uh, I overlooked the fact that you're trying to do this to a different application's window. So ignore what I said.