如何获取可靠的QGLWidget快照

时间:2012-05-03 10:23:27

标签: c++ qt opengl qglwidget

在我的应用程序中,我将QGLWidget内容的快照用于两个目的:

  • 使用缓存的pixmap代替
  • 时,只重叠更改时不会重绘场景
  • 拉出用户截取特定情节(3D场景)的截图

我尝试的第一件事是grabFrameBuffer()。对于第一个应用程序使用此函数是很自然的,窗口小部件中当前可见的内容正是我想要缓存的内容。 问题:在某些硬件上(例如Intel integrade图形,带有GeForce图形的Mac OS X),获得的图像不包含当前屏幕内容,而是包含之前的内容。因此,如果场景将被绘制两次,在屏幕上你会看到第二张图,在图像中你看到第一张图(应该是后台缓冲区的内容?)。

我尝试的第二件事是renderToPixmap()。这使用paintGL()呈现,但不使用paint()。我在paint()中拥有所有内容,因为我使用Qt的绘画功能,只有一小部分代码使用原生GL(beginNativePainting()endNativePainting())。

我还尝试了常规QWidget的快照功能(QPixmap :: fromWidget()或它的名称),但是GL帧缓冲区是黑色的。

有关如何解决问题并获得当前绘制场景的可靠描述的任何想法?

4 个答案:

答案 0 :(得分:2)

  

如何拍摄可靠的QGLWidget快照

将当前场景渲染到帧缓冲区,将数据从帧缓冲区保存到文件。或者在glFlush之后抓住当前的后备缓冲区。其他任何东西都可能包含文物或不完整的场景。

答案 1 :(得分:2)

似乎QGLWidget :: grabFrameBuffer()在内部从OpenGL调用glReadPixels()。在双缓冲配置中,初始模式读取后缓冲区(GL_BACK),使用OpenGL调用glReadBuffer(GL_FRONT)切换到前缓冲区,然后使用QGLWidget :: grabFrameBuffer()在屏幕上显示图像。

答案 2 :(得分:1)

与所有其他OpenGL调用一样,QGLWidget::grabFrameBuffer()的结果取决于视频驱动程序。 Qt只是将您的呼叫转发给驱动程序并抓取它返回的图像,但图像的内容不受Qt的控制。除了确保为视频卡安装了最新的驱动程序之外,除了向视频卡制造商报告错误并祈祷之外,您无能为力。

答案 3 :(得分:0)

我使用paintGL();glFlush();在使用grabFrameBuffer()之前。 paintGL有助于在抓取帧缓冲区之前再次绘制当前帧,这样可以准确复制当前显示的内容。