我需要在应用程序中的所有OpenGL小部件之间共享数据(纹理、顶点缓冲区…)。
以下代码不起作用:
我发现一些解决方案有一个主QGLWidget
,另一个是使用这个主小部件构建的。不幸的是,我不能使用这种方法,因为我所有的QGLWidget都是相等的,而且几乎可以肯定的是,第一个(主)创建的QGLWidget将在其他QGLWiget之前被销毁。
可能的方法:
- 所有QGLWidget之间的单个共享OpenGL上下文
- 不起作用:只有一个QGLWidget被正确渲染,其他的行为就像没有被渲染一样,损坏/随机数据
-
每个
QGLWidget
构造的错误,除了第一个:QGLWidget::setContext: Context must refer to this widget
另一种方法:
- 主OpenGL上下文并为每个QGLWidget创建子上下文
- 不工作:
context->isSharing()
返回false
-
我用于创建上下文的代码
context1
和context2
稍后传递给QGLWidgets:的构造函数QGLContext *mainContext = new QGLContext(format), *context1, *context2; mainContext->create(); context1 = new QGLContext(format); context1->create(mainContext); context2 = new QGLContext(format); context2->create(mainContext); cout << mainContext->isSharing() << " " << context1->isSharing() << endl;
关于第一种方法,您不是在设置共享,而是试图强制将相同的上下文用于不同的QGLWidget。如上所述,这是错误的,不会奏效。
相反,请正常创建QGLWidget,并在创建其他QGLWidgets时传递shareWidget参数中的第一个QGLWidget。通过这种方式,您将为每个QGLWidget获得一个单独的上下文,但它们都将与第一个的上下文共享(从而相互共享)。看见http://qt-project.org/doc/qt-4.8/qglwidget.html#QGLWidget
在其他小部件之前销毁第一个小部件应该不是问题,因为共享对象将一直存在,直到任何共享上下文都存在。
我知道这个问题已经被问了将近一年了,但我认为上面的评论可能不准确。
更准确地说,虽然将单个QGLContext与多个QGLWidget一起使用可能确实无效,但这将是Qt OpenGL实现的限制,而不是OpenGL或窗口系统的限制。使用相同的上下文渲染到多个窗口似乎是有效的。例如,函数wglMakeCurrent和SwapBuffers接受设备句柄和OpenGL上下文句柄作为参数。引用wglMakeCurrent文档:
hdc参数必须引用OpenGL支持的绘图曲面。当hglrc已经创建,但它必须在同一个设备上并且具有相同的像素格式。
我甚至不想讨论SwapBuffers的问题,因为网上到处都有关于Qt5的错误报告,这似乎迫使在调用SwapBuffer之前不必要地使OpenGL上下文成为当前上下文。
这是自QT 5.4以来更新的,现在应该使用QOpenGLWidget而不是QGLWidget。全局上下文共享现在已经写入QOpenGLWidget中,所以您不必自己编写代码。您只需要在创建QGuiApplication之前启用共享标志Qt::AA_ShareOpenGLContexts。