我遇到了一个问题,我担心这将很难解决,至少就Google搜索显示给我的问题而言。

我有一个使用Qt的Editor实用程序,它为编辑器中的不同工具创建了多个OpenGL上下文,它们是一个“世界”编辑器,它承载了我的游戏场景的QGLWidget,而一个 Material 编辑器具有一个“preview” QGLWidget,它显示了当前的场景。建筑 Material 。

我已经能够使上下文共享正常工作,我使用gDEBugger查看OpenGL上下文,并且它们正在共享纹理,VBO,着色器等。但是有一项规定让我想知道这将如何工作,您无法共享顶点数组对象在上下文之间。据我了解,顶点数组对象是现在的标准,我们应该真正使用它们,而不是使用不带VAO的VBO。

我想过两种解决方法,但我不完全认为这两种方法都是理想的

  • 在每次渲染之前生成VAO,但这似乎违反了VAO的
  • 的目的。
  • 使用std::map将GL上下文映射到VAO,如果当前上下文不具有该VAO,则为所述上下文生成一个VAO,这似乎很糟糕,甚至可能无法正常工作。

  • 我还有什么其他解决方案可以忽略?我还考虑过将所有内容都放在一个上下文中,并为每个必需的opengl小部件使用单独的视口(viewport),我希望这是可能的,但是我没有运气使用Qt和它的QGLWidget来解决它。

    编辑

    好的,所以我尝试使此工作正常进行,但是这使我感到非常悲伤,我尝试了两种不同的方法,它们都导致我出错。

    1)我创建一个QGLContext,然后在创建它们时将其传递给我的QGLWidgets。
    QGLFormat    fmt = QGLFormat();
    QGLContext*  pContext = new QGLContext(fmt);
    
    QGLWidget*   pWidget1 = new QGLWidget(pContext);
    someLayout->addWidget(pWidget1);
    
    QGLWidget*   pWidget2 = new QGLWidget(pContext);
    anotherLayout->addWidget(pWidget2);
    

    这里的错误是,一旦我将小部件添加到布局中或将其设置为主窗口的中央小部件,它就会删除上下文,这确实很奇怪。如果然后我尝试将上下文从第一个小部件传递到第二个小部件
    QGLFormat    fmt = QGLFormat();
    QGLContext*  pContext = new QGLContext(fmt);
    
    QGLWidget*   pWidget1 = new QGLWidget(pContext);
    someLayout->addWidget(pWidget1);
    
    pContext = (QGLContext*)pWidget1->context();
    QGLWidget*   pWidget2 = new QGLWidget(pContext);
    anotherLayout->addWidget(pWidget2);
    

    我收到一个Qt错误,说QGLWidget::setContext:上下文必须引用此小部件

    2)我创建了我的第一个小部件,并将其上下文用于所有其他小部件
    QGLWidget* pWidget1 = new QGLWidget();
    
    QGLContext* pContext = (QGLContext*)pWidget->context();
    QGLWidget* pWidget2 = new QGLWidget(pContext);
    

    它给了我从第一种方法结束时得到的相同错误,它说
    QGLWidget::setContext:上下文必须引用此窗口小部件。

    此处不正确,我觉得我缺少了一些东西。

    最佳答案

    您无法共享VAO的原因与您无法共享FBO的原因相同:它们不保存实际数据,而仅仅是数据保存缓冲区对象的集合。 BO包含您可以共享的数据。

    但是,为什么要完全跳过上下文共享呢?您可以将单个OpenGL上下文重用于多个窗口,只要这些窗口具有相同的可视格式/FBConfig/PIXELFORMATDESCRIPTOR。

    看一下下面的QGLWidget构造函数:

    QGLWidget::QGLWidget (
        QGLContext * context,
        QWidget * parent = 0,
        const QGLWidget * shareWidget = 0,
        Qt::WindowFlags f = 0 )
    

    您可以使用现有的QGLContext创建一个QGLWidget。创建一个独立的QGLContext并将其附加到多个窗口,或者创建一个主QGLWidget并使用由该窗口创建的上下文。您甚至可以销毁单个QGLWidget,而不会丢失上下文和其中的数据,只要至少有一个QGLWidget可以保存它即可。

    10-06 14:33