我使用了两个QGLWidgets,一个用于加载纹理,另一个用于渲染,但是它没有起作用。我使用了来自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版本可以工作。当出现错误时,我可以按“忽略错误”按钮,程序仍然会加载纹理。
以下是一些示例代码:
加载纹理:
纹理上传线程: 上传许多(或较大)纹理通常是一项昂贵的操作,因为要将大量数据推入 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);