我有一个用 Qt 编写的MDI应用程序。一些子窗口包括QGLWidget
s,即OpenGL 上下文。其中最突出的是使用 OpenGL 顶点和片段着色器来可视化他们的数据。
我需要以编程方式捕获应用程序主窗口的屏幕截图,当然包括所有碰巧可见的子窗口。起初听起来很容易(“肯定被问过很多次,所以让我们用谷歌搜索吧!”),但仔细观察后似乎有点棘手......
现在这是我到目前为止所尝试的:
QPixmap::grabWidget
不适用于使用着色器程序的子窗口,显然是因为重定向上下文似乎不支持必要的 OpenGL 扩展。(渲染代码检查关联的上下文是否支持所需的扩展,如果不支持则拒绝继续。)QPixmap::grabWindow
默默地让所有 OpenGL 上下文为空——即使是那些只使用基本原语的上下文。QGLWidget::grabFrameBuffer
有效,但仅捕获特定子窗口的 OpenGL 上下文,而我想获取整个应用程序(基本上是Alt+PrtScr
在 Windows 中执行的操作)。
我还尝试先执行#2,然后为所有子窗口迭代#3,只需将#3 的结果复制到#2 中图像的正确位置。这工作得很好,直到我让一些子窗口重叠——在这种情况下,来自#3 的图像会覆盖子窗口框架等。所以这种方法可能需要更多的代码来处理所有令人讨厌的极端情况......
一些额外的背景:一旦我得到截图,我将把其中的几个放在一个序列中以创建一个视频——可能使用ffmpeg。这使得这个问题成为我上一个问题(第一部分)的延续;只是该应用程序已从单上下文独立 OpenGL 程序演变为使用 Qt 进行整体窗口和 UI 小部件的东西,并将图形嵌入子窗口中。
虽然我当然更喜欢一个不错的 Qt-ish 跨平台解决方案,但我也愿意考虑使用 Windows 特定的 hack。(这应该是可能的,因为我可以看到Alt+PrtScr
做非常正确的事情。)
那么,有什么建议吗?