获取运行OpenGL的子窗口的屏幕截图(Windows)

时间:2010-01-27 00:56:01

标签: winapi opengl screenshot

我有一个带孩子的主窗口。我需要以编程方式截取屏幕截图以在我的主窗口上裁剪并绘制它们。我这样做的方式是:

HDC hDC = GetWindowDC(hWnd);
HDC memDC = CreateCompatibleDC(hDC);
HBITMAP memBM = CreateCompatibleBitmap(hDC, Width, Height);
HBITMAP OldBM = (HBITMAP)::SelectObject(memDC, memBM );
BitBlt(memDC, 0, 0, Width, Height , hDC, BEGINX, BEGINY, SRCCOPY);
int Bpp = GetDeviceCaps(hDC,BITSPIXEL);
int size = Bpp/8 * ( Width * Height );
BYTE *lpBits = new BYTE[size];
GetBitmapBits(memBM, size, lpBits);

但是这不会捕获子窗口的OpenGL部分,而只是在OGL渲染应该是的区域中绘制空白。

4 个答案:

答案 0 :(得分:0)

我记得几年前当我试图屏幕抓取一个视频并且只是获得视频的黑色区域时,我遇到了类似的问题。通过减少视频驱动程序上的硬件加速设置(在XP上:右键单击桌面>属性>设置>高级>疑难解答)来解决它。

对于基于代码的解决方案,您可能需要参考以下的帖子:

Blank Screenshots In Vista and Win7 when gaming

Saving a screenshot of a window using C#, WPF, and DWM

答案 1 :(得分:0)

可能是NQR,但您可以将场景渲染为位图并将其BLT放入空白区域。

答案 2 :(得分:0)

我假设你在胜利平台上。

即使您没有子窗口的源代码,也可以渲染到位图。

  1. 首先获取正确句柄到子窗口
    • 正确的句柄搜索非常棘手,因为win中的几乎所有内容都是一个窗口(因此有数百个句柄......)
  2. 创建位图
  3. 将屏幕截图窗口的渲染/设备上下文句柄更改为您的位图。
    • 并非所有的窗户都能做到这一点!!!
  4. 强行重画
    • 最小化/恢复胜利或其他什么
  5. 存储新的位图
  6. 恢复屏幕截图窗口的渲染/设备上下文。
  7. 注意这不是一个非常稳定的过程(OpenGL可以在上下文句柄更改期间发生冲突),在某些情况下甚至无法将句柄更改为上下文

    更安全的是自己截取桌面。

    TCanvas *scr=new TCanvas();
    scr->Handle=GetDC(GetDesktopWindow());
    // copy scr to your bitmap (do not forget to resize bitmap)
    

    警告不要经常获取/创建/释放上下文或获取句柄因为它有点小错误(有时候winapi函数会停止返回正确的处理程序值)更好的方法是获取句柄一次并希望没有人关闭窗口...为你的child胜利你知道什么时候得到新的处理程序)对于IsWindow()函数也是如此。

    有关详细信息,请查看:

答案 3 :(得分:0)

OpenGL可能会呈现为分层上下文;尝试

BitBlt(memDC, 0, 0, Width, Height , hDC, BEGINX, BEGINY, SRCCOPY | CAPTUREBLT);

代替。