【发布时间】:2013-10-12 16:45:32
【问题描述】:
我使用了两个 QGLWidget。一种用于加载纹理,一种用于渲染,但它不起作用。
我使用了以下解释 http://blog.qt.digia.com/blog/2011/06/03/threaded-opengl-in-4-8/
纹理上传线程 上传许多(或大)纹理通常是一项昂贵的操作,因为要推送到 GPU 的数据量很大。同样,这是可能不必要地阻塞主线程的操作之一。在 4.8 中你可以通过创建一对共享的 QGLWidgets 来解决这个问题。其中一个小部件在单独的线程中成为当前的,但永远不会在屏幕上显示。主线程通知上传线程要上传哪些图片,上传线程只需对每张图片调用 bindTexture(),然后在每张图片完成后通知主线程,以便将其绘制到屏幕上。
使用带有 MinGW 的 Qt 4.8 可以正常工作,但现在我使用带有 MSVC 的 Qt 5.1。当我想让线程中的小部件成为当前小部件时出现错误:
不能使 QOpenGLContext 在不同的线程中成为当前的
我了解错误,但我该如何解决。当我不将小部件设置为当前时,我无法加载纹理(在 bindTexture() 函数处冻结)。我也想知道,为什么它适用于我的旧 QT 版本。当错误出现时,我可以按“忽略错误”,程序无论如何都会加载纹理。
这里是一些示例代码:
加载纹理:
GLContext::GLContext(QWidget *parent, QGLWidget *myDisplayWidget) :
QGLWidget(parent,myDisplayWidget)
{
}
...
GLContext* myTextureWidget = new GLContext(this,myDisplayWidget);
...
void TextureLoadingThread::run()
{
makeCurrent(); //Here is the bug!
QImage *im = new QImage(filename);
GLuint textid = myTextureWidget->bindTexture(*im, GL_TEXTURE_2D, GL_RGBA);
}
编辑:
当我将 myTextureWidget 的上下文移动到它工作的线程时,但是当 GUI 将构建时我从 API 获得 makeCurrent 错误(堆栈跟踪在 QT5Widgetsd 中的 QLineEdit::setPlaceHolderText 函数中说)。当我在显示主窗口几秒钟后将 myTextureWidget 移动到线程时,一切正常。但是我怎么知道qt什么时候完成了所有的GUI构建东西?我将 GUI 绘制到带有 QGLWidget 视口的 QGraphicsView。
myTextureWidget->context()->moveToThread(myTextureLoadingThread);
【问题讨论】:
-
Qt 4.8 中没有“QOpenGLContext”,所以我不确定“它工作正常”是什么意思。也许您的意思是使用 QtOpenGL 进行不同的设计和实现?
-
我的程序代码没有太大变化,除了移植到 QT 5.1 的一些行。我使用 QT OpenGL 版本(不是 ANGLE)和两个 QGLWidgets 来共享上下文。我想我今天会做一些调试。我昨天尝试将 myTextureWidget 的上下文移动到 TextureLoadingThread。然后我只在开始时得到 makeCurrent 错误,尽管在错误发生之前我从未在我的源代码中调用过 makeCurrent 。但是当我忽略错误时,我可以根据需要经常调用 makeCurrent 并且错误不再发生。
-
您找到解决方案了吗?我也有同样的问题...
标签: c++ qt qthread qtgui qtcore