从GPU获取完整的桌面屏幕截图

Ste*_* Lu 11 windows opengl screenshot fullscreen

我一直在使用Windows API的BitBlt功能来执行屏幕抓取.

但是有许多缺点:

  1. DWM和Aero导致大幅减速(3ms - > 35ms只是为了调用BitBlt) - 要解决这个问题需要禁用Aero,我只是不愿意这样做.屏幕闪烁,事物转移.
  2. 必须将数据重新传输到GPU才能将数据作为纹理加载
  3. 没有CAPTUREBLT标记,无法捕获分层Windows .启用后,捕获时鼠标光标会闪烁.这似乎是一个小问题,但当应用程序无其他错误时,它非常烦人.作为解决方法,我打算将分层窗口渲染为附加光标.

我已经在使用OpenGL来显示和操作捕获的屏幕数据.BitBlt给我像素数据,将其加载到纹理中相对容易.然而,这有点荒谬,因为我手动将数据重新发送回GPU,因为它应该可以在GPU上开始使用.数据肯定存在,但尝试访问它是另一回事.

我认为供应商的待办事项清单(或可能在任何清单上)的功能并不高,但我想问一下知道AMD(ATI)提供的任何条款或NVidia在其驱动程序中用于读取屏幕缓冲区(例如,进入OpenGL上下文).我对现代GPU架构知之甚少,不知道从哪里开始挖掘答案.

Nic*_*las 4

OpenGL 只能读取上下文帧缓冲区(窗口)以及您创建的任何帧缓冲区或 pbuffer。OpenGL 无法触摸桌面或任何其他窗口。

  • 正式来说你是对的。然而,在出现合成窗口管理器之前,顶层窗口将接收可见屏幕帧缓冲区内存的一部分。这样就可以通过创建全屏 OpenGL 窗口并在创建后立即执行 glReadPixels 来抓取屏幕截图。如今,对于合成窗口管理器,这不再起作用,因为每个窗口都有自己的屏幕外缓冲区。就像 @Ben Voigt 所说,那么你需要使用合成 API。在 X11 中,这有很好的记录:Composite X11 和 GLX_EXT_texture_from_pixmap GLX 扩展。 (2认同)