我使用两个 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);