带有OpenGL的Qt MDI应用程序:如何获取有效的屏幕截图? [英] Qt MDI app with OpenGL: how to grab a valid screenshot?

查看:340
本文介绍了带有OpenGL的Qt MDI应用程序:如何获取有效的屏幕截图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用Qt编写的 MDI 应用.某些子窗口包含QGLWidget,即OpenGL上下文.其中最突出的是使用OpenGL顶点和片段着色器来可视化其数据.

我需要以编程方式捕获应用程序主窗口的屏幕截图,当然包括所有碰巧可见的子窗口.一开始听起来很简单(肯定被问过很多次,所以让我们用谷歌搜索吧!"),但仔细看后似乎有点棘手...

现在这是到目前为止我尝试过的事情:

  1. QPixmap::grabWidget 不适用于使用着色器的子窗口程序,显然是因为重定向上下文似乎不支持必要的OpenGL扩展. (呈现代码检查关联的上下文是否支持所需的扩展,如果不支持,则拒绝继续.)
  2. QPixmap::grabWindow 默默地将所有OpenGL上下文留空-甚至那些仅使用基本图元.
  3. QGLWidget::grabFrameBuffer 有效,但仅捕获特定的子窗口,而我想抓取整个应用程序(基本上是Alt+PrtScr在Windows中的工作).

我还尝试先执行#2,然后对所有子窗口重复执行#3,只是将#3的结果复制到#2中图像的正确位置.这非常有效,直到我重叠了一些子窗口-在这种情况下,#3的图像会覆盖子窗口框架,依此类推.因此,此方法可能需要更多代码才能处理所有讨厌的极端情况...

一些其他背景:一旦获得了屏幕截图,我将按顺序放置其中的几个以创建视频-可能使用 ffmpeg .这使该问题成为我之前的问题;仅仅是该应用程序已从单上下文的独立OpenGL程序演变为使用Qt进行整体窗口和UI窗口小部件内容并将图形嵌入子窗口中的东西.

虽然我当然希望使用一种不错的,具有Qt风格的跨平台解决方案,但我也愿意考虑诉诸Windows特定的黑客. (应该有可能,因为我看到Alt+PrtScr做得非常正确.)

那么,有什么建议吗?

解决方案

非常黑,但是确实捕获了桌面(不隐藏窗口),就像MDI app written in Qt. Some of the subwindows include QGLWidgets, i.e., OpenGL contexts. The most salient of these use OpenGL vertex and fragment shaders to visualize their data.

I need to programmatically capture a screenshot of the application's main window, including of course all the subwindows that happen to be visible. Sounds easy at first ("definitely been asked many times, so let's just google it!"), but after a closer look it seems to be getting a bit tricky...

Now here's what I've tried so far:

  1. QPixmap::grabWidget doesn't work for the subwindows that use shader programs, apparently because the redirection context does not seem to support the necessary OpenGL extensions. (The rendering code checks that the associated context supports the required extensions, and refuses to continue if not.)
  2. QPixmap::grabWindow silently leaves all OpenGL contexts empty -- even those that use basic primitives only.
  3. QGLWidget::grabFrameBuffer works, but captures only the OpenGL context of the specific subwindow, whereas I'd like to grab the whole application (essentially what Alt+PrtScr does in Windows).

I also tried doing first #2 and then iterating #3 for all subwindows, just copying the result of #3 into the right location of the image from #2. This worked very well, until I made some subwindows overlap -- in which case the images from #3 overwrite the subwindow frames, etc. So this approach would probably require much more code in order to handle all the nasty corner cases...

Some additional background: Once I get the screenshot, I'm going to put several of them in a seqence in order to create a video -- probably using ffmpeg. That makes this question a kind of continuation to (the first part of) my previous question; it's just that the app has evolved from a single-context standalone OpenGL program to something that uses Qt for the overall windowing and UI widget stuff, and embeds the graphics in subwindows.

While I would of course prefer a nice, Qt-ish cross-platform solution, I'm willing to consider resorting to a Windows-specific hack, too. (Which ought to be possible, as I can see Alt+PrtScr doing very much the right thing.)

So, any suggestions?

解决方案

Very hackish, but does capturing the desktop (without hiding your window) like in this tutorial and cropping everything but your window work?

More generally, I'm not even sure that the OpenGL spec demands that output has to be placed in the front buffer: an implementation could just use video overlays (or Voodoo2-esque VGA pass-through shenanigans) for output.

这篇关于带有OpenGL的Qt MDI应用程序:如何获取有效的屏幕截图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆