OpenGL VAO - 在多种情况下处理VAO

时间:2012-11-06 19:52:27

标签: c++ qt opengl

我遇到了一个问题,我担心这个问题很难解决,至少就谷歌搜索向我展示而言。

我有一个使用Qt的Editor实用程序,它为编辑器中的不同工具创建多个OpenGL上下文,它们是一个“World”编辑器,它托管我游戏场景的QGLWidget,还有一个具有“预览”QGLWidget的材质编辑器。显示当前构建的材料。

我能够让上下文共享正常工作,我使用gDEBugger来查看OpenGL上下文,他们正在共享Textures,VBO,着色器等等。但有一条规定让我想知道这是如何工作的,你不能分享顶点数组上下文之间的对象。据我所知,Vertex数组对象现在已成为标准,我们应该使用它们而不是在没有VAO的情况下使用VBO。

我已经想到了两种方法来解决这个问题,但我并不认为这两种方法都是理想的

  1. 在每次渲染之前生成VAO,但这似乎打败了VAO的目的
  2. 使用std :: map将GL上下文映射到VAO,如果当前上下文没有此VAO,则为所述上下文生成一个,这看起来很糟糕,甚至可能无法正常工作。
  3. 我忽视了哪些其他解决方案?我还考虑过在某种情况下以某种方式拥有所有内容,并为每个必需的opengl小部件使用单独的视口,我希望这是可能的,但我没有运气使用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:Context必须引用这个小部件

    2)我创建了我的第一个小部件并使用它的所有其他小部件

    QGLWidget* pWidget1 = new QGLWidget();
    
    QGLContext* pContext = (QGLContext*)pWidget->context();
    QGLWidget* pWidget2 = new QGLWidget(pContext);
    

    这给了我与第一种方法结束时相同的错误,它说 QGLWidget :: setContext:Context必须引用此小部件。

    有些东西不在这里,我觉得我错过了什么。

1 个答案:

答案 0 :(得分:8)

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

然而,为什么要跳过上下文共享的箍?只要窗口具有相同的可视格式/ FBConfig / PIXELFORMATDESCRIPTOR,您就可以为多个窗口重用单个OpenGL上下文。

看看下面的QGLWidget构造函数:

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

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