• 6277阅读
  • 2回复

Qt 4.8 中的线程相关OpenGL [复制链接]

上一主题 下一主题
离线ka1980
 
只看楼主 倒序阅读 楼主  发表于: 2011-12-17
— 本帖被 XChinux 设置为精华(2011-12-17) —
关键词: QT4.8threadopengl
简单翻译了一下:http://labs.qt.nokia.com/2011/06/03/threaded-opengl-in-4-8/
Qt 4.8 中OPenGl的线程特性,大家一起学习吧:


如果你曾经在Qt模块中使用过OpenGL,那么在某些情况下,你可能想在一个单独的线程中执行一些OpenGL命令,底层的OpenGL实现其自身是可重入的,所以没有什么能阻止你。事实上,waaay back 在第6期的 Qt 季刊中甚至有一篇文章描述了如何来实现它。这是人们花时间写纯OpenGL的代价,但是如果你想在一个单独的线程中使用一些Qt的便利类会怎么样呢?不幸的是这是不可能的,因为这些Qt类不是线程安全的。在Qt 4.8 中,这些都改进了,我们现在已经增加了几种最常见的情况支持。要在x11系统中使用这些新的函数,你应该开启Qt::AA x11InitThreads 应用程序的属性,确保底层调用的GLX是线程安全的,但是对于windows 和 Macox来说,直接使用就可以了。

缓冲区交换线程
根据您的驱动程序和GPU,函数swapBuffers()的调用有时很费时(特别是在嵌入式处理器)。在许多情况下,这是告诉GPU去接受你所有的渲染命令,并执行它们以渲染当前帧。如果该操作是同步的,那么在GPU做工作的时候,你的主线程就被阻塞了。很不幸,因为你当前的线程有比等待GPU更重要的事情去做。例如,它可以返回到事件循环中来处理一些用户的输入,网络通讯或提前处理下一个动画场景。Qt 4.8的解决方案是提供一个单独的线程,其执行周期的唯一目的是通过调用swapBuffers等待GPU。在具体使用中,你可以像通常一样在主线程中绘制所有的物体,而不调用swapBuffers(),你可以在当前GL上下文中调用doneCurrent()。通知交换线程你已经完成了渲染工作,它接着会调用makeCurrent()激活当前上下文,然后调用swapBuffers(),然后调用doneCurrent()并通知主线程它已经完成了。应该注意的是,这里有一个上下文切换开销,实际上可能会比等待GPU执行完更慢一些,所以,你应该自己测试一下做出取舍和选择。

纹理上传线程
上传许多(或大的)纹理数据通常是一个昂贵的操作,因为有许多数据需要传递给GPU。这同样也是不必要阻塞主线程的操作 。在Qt 4.8中,你可以创建一对共享QGLWidgets来解决改该问题。在单独的线程中创建一个从不在屏幕上显示Widget,主线程通知上传线程哪些图像需要上传,上传线程调用每一个图像的bindTexture(),都完成后然后通知主线程时,就可以在屏幕上进行绘制了。

QPainter的线程
在Qt 4.8中可以在一个单独的线程中使用QPainter绘制到QGLWidget,QGLPixelBuffer和QGLFrameBufferObject假设您正在使用OpenGL[ ES] 2.0绘图引擎 。重要的是要注意,QGLWidget并不是移动到辅助线程中(它毕竟是一个QWidget)。而是它的上下文被用在别的地方,这就需要调用QGLWidget的 doneCurrent(),在主线程中释放上下文 。接下来,你应该创建一个单独的QObject子类,并可以移动到辅助的绘制线程中。这个QObject会在绘制线程中关联QGLWidget的上下文为当前上下文,并可以打开一个QPainter开始绘制。如果您正在使用QGLWidget作为绘制目标,那么你需要在QGLWidget中额外设置“QT::WA_PaintOutsidePaintEvent:”的属性 。此外,您将需重载该类,并重新实现QGLWidget resizeEvent()和paintEvent()函数 。这些默认实现将尝试使QGLWidget的上下文为当前上下文,因为这些功能都在主线程上(创建widget的地方),我们不希望这样的事情发生,因为我们正在使用的线程上下文调用 。在您重新实现这些功能,你应该通知QObject子类,它的渲染,这样可以调整视口或重绘现场,如果需要的话。这一切的结果可以看出以下称为一个新的演示 glhypnotizer运行的MDI子窗口包含一个单独的线程QGLWidget渲染 。
  
离线dbzhang800

只看该作者 1楼 发表于: 2011-12-18
恩,不错,

建议你和老大齐亮联系一下,然后放置到 http://labs.qt.nokia.com.cn/ 上面去

可以在 irc://freenode/#qt-cn 找到他
离线ka1980
只看该作者 2楼 发表于: 2011-12-18
多谢指点!!
快速回复
限100 字节
 
上一个 下一个