如何共享OpenGL上下文或数据?

时间:2014-01-06 17:29:28

标签: c++ qt opengl qglwidget

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

以下代码无效:

我发现一些主要QGLWidget的解决方案和其他使用此主要小部件构建的解决方案。不幸的是,我不能使用这种方法,因为我的所有QGLWidgets都是相同的,几乎可以肯定第一个(主要)创建的QGLWidget将被破坏,而不是其他人。

可能的方法:

  • 所有QGLWidgets之间的单一共享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;
    

3 个答案:

答案 0 :(得分:3)

关于第一种方法,您没有设置共享,而是试图强制将相同的上下文用于不同的QGLWidgets。如上所述,这是错误的,不起作用。

相反,正常创建QGLWidgets并在创建其他参数时传递shareWidget参数中的第一个QGLWidget。这样,您将为每个QGLWidget获取单独的上下文,但它们将与第一个上下文共享(因此彼此共享)。见http://qt-project.org/doc/qt-4.8/qglwidget.html#QGLWidget

在其他人之前销毁第一个小部件应该不是问题,因为共享对象将会存在,直到任何共享上下文都存活。

答案 1 :(得分:1)

我意识到自问这个问题已经差不多一年了,但我相信上面的评论可能不准确。

更准确地说,虽然使用具有多个QGLWidgets的单个QGLContext可能确实无效,但这将限制Qt的OpenGL实现,而不是OpenGL或窗口系统的限制。使用相同的上下文渲染到多个窗口当然似乎是有效的。例如,函数wglMakeCurrent和SwapBuffers接受作为参数的设备句柄以及OpenGL上下文句柄。引用wglMakeCurrent文档:

  

hdc参数必须引用OpenGL支持的绘图表面。   它不一定是传递给wglCreateContext的hdc   hglrc已创建,但它必须位于同一设备上且具有相同的功能   像素格式。

我甚至不想解决SwapBuffers的问题,因为网络上有几个关于Qt5的错误报告,这似乎迫使在调用SwapBuffers之前不必要地使OpenGL上下文流动。

答案 2 :(得分:1)

自QT 5.4以来,这已经更新,您现在应该使用QOpenGLWidget而不是QGLWidget。全局共享上下文已经写入QOpenGLWidget,因此您不必自己编写代码。您只需在创建QGuiApplication之前启用共享标志Qt :: AA_ShareOpenGLContexts。