我使用两个 QGLWidget。一种用于加载纹理,一种用于渲染,但它不起作用。
我使用了以下解释http://blog.qt.digia.com/blog/2011/06/03/threaded-opengl-in-4-8/ http://blog.qt.digia.com/blog/2011/06/03/threaded-opengl-in-4-8/
纹理上传线程
由于推送到 GPU 的数据量很大,上传许多(或大型)纹理通常是一项昂贵的操作。同样,这是可能不必要地阻塞主线程的操作之一。在 4.8 中你可以通过创建一对共享的 QGLWidgets 来解决这个问题。其中一个小部件在单独的线程中变为当前状态,但永远不会在屏幕上可见。主线程通知上传线程要上传哪些图像,上传线程只需对每个图像调用bindTexture(),然后在每个图像完成时通知主线程,以便将其绘制到屏幕上。
使用 Qt 4.8 和 MinGW 可以正常工作,但现在我使用 Qt 5.1 和 MSVC。当我想让线程中的小部件成为当前小部件时,出现错误:
无法使 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);
}
EDIT:
当我将 myTextureWidget 的上下文移动到它的线程时,它可以工作,但是当 GUI 构建时,我从 API 收到 makeCurrent 错误(堆栈跟踪在 QT5Widgetsd 中的 QLineEdit::setPlaceHolderText 函数中表示)。当我在显示主窗口几秒钟后将 myTextureWidget 移动到线程时,一切正常。但是我怎么知道qt什么时候完成了所有GUI构建的东西呢?我将 GUI 绘制到带有 QGLWidget 视口的 QGraphicsView 上。
myTextureWidget->context()->moveToThread(myTextureLoadingThread);