如何共享OpenGL上下文或数据



我需要在应用程序中的所有OpenGL小部件之间共享数据(纹理、顶点缓冲区…)。

以下代码不起作用:

我发现一些解决方案有一个主QGLWidget,另一个是使用这个主小部件构建的。不幸的是,我不能使用这种方法,因为我所有的QGLWidget都是相等的,而且几乎可以肯定的是,第一个(主)创建的QGLWidget将在其他QGLWiget之前被销毁。

可能的方法:

  • 所有QGLWidget之间的单个共享OpenGL上下文
  • 不起作用:只有一个QGLWidget被正确渲染,其他的行为就像没有被渲染一样,损坏/随机数据
  • 每个QGLWidget构造的错误,除了第一个:

    QGLWidget::setContext: Context must refer to this widget
    

另一种方法:

  • 主OpenGL上下文并为每个QGLWidget创建子上下文
  • 不工作:context->isSharing()返回false
  • 我用于创建上下文的代码context1context2稍后传递给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。

相关内容

  • 没有找到相关文章

最新更新