Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL VAO's - Handling VAO's in multiple contexts

Tags:

c++

qt

opengl

I have run into an issue that I am afraid is going to be very hard to resolve, at least as far as google searching has show me.

I have an Editor utility using Qt which creates multiple OpenGL contexts for different tools in the editor, their is a 'World' editor which hosts a QGLWidget of my games scene, and a material editor which has a 'preview' QGLWidget which displays the currently built material.

I have been able to get context sharing working fine, I use gDEBugger to see the OpenGL contexts, and they are sharing Textures, VBO's, shaders etc. But one stipulation has me wondering how this will work, you can't share Vertex Array Objects between contexts. As I understand it, Vertex Array Objects are the standard now, and we should really be using them as opposed to using VBO's without VAO's.

I have thought of a 2 ways to get around this but I don't exactly think either are ideal

  1. Generate the VAO's before each render, but this seems to defeat the purpose of the VAO's
  2. use a std::map to map a GL context to a VAO, if the current context does not have this VAO, then generate one for the said context, this seems bad and may not even work.

What other solutions are there that I am overlooking? I have also considered somehow having everything in one context and using seperate viewports for each required opengl widget, which I hoped would be possible but I am having no luck figuring it out using Qt and it's QGLWidget.

Edit

Ok, so I have tried to get this working but it is giving me alot of grief, I tried 2 different ways and they are both causing me errors.

1) I create a QGLContext, and then pass it to my QGLWidgets when they are being created.

QGLFormat    fmt = QGLFormat();
QGLContext*  pContext = new QGLContext(fmt);

QGLWidget*   pWidget1 = new QGLWidget(pContext);
someLayout->addWidget(pWidget1);

QGLWidget*   pWidget2 = new QGLWidget(pContext);
anotherLayout->addWidget(pWidget2);

The error here is that as soon as I add the widget to a layout, or set it as the central widget for a Main Window, it deletes the context, really weird. If I then try to pass in the context from the first widget to the second

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);

I Get a Qt error saying QGLWidget::setContext: Context must refer to this widget

2) I create my first widget and use it's context for all the others

QGLWidget* pWidget1 = new QGLWidget();

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

This gives me the same error that I got from the end of my first method, it says QGLWidget::setContext: Context must refer to this widget.

Something is not right here and I feel I am missing something.

like image 831
user1294021 Avatar asked Nov 06 '12 19:11

user1294021


People also ask

Can the separate attribute format VAO setup interoperate with glvertexattribpointer?

The separate attribute format VAO setup can interoperate with glVertexAttribPointer (the latter is defined in terms of the former). But you must be careful when doing so. The separate attribute format version have direct state access (DSA) equivalents in 4.5.

What is glvertexattribpointer in OpenGL?

OpenGL context creation. The Vertex Array Object stores how opengl should interpret a set of VBOs. In essence it will let you avoid calling glVertexAttribPointer every time you want to render a new mesh. If you don't want to deal with VAOs you can simply create one and bind it during program initialization and pretend they don't exist.

What is the difference between a Vao and a vertex format?

So instead of having a VAO per mesh, you may have a VAO per vertex format. Each attribute is associated with a vertex format and a binding point. The vertex format consists of the type, component count, whether it is normalized, and the relative offset from the start of the data to that particular vertex.

What is the VBO in GL_array_buffer?

Each attribute is associated with a component count, type, normalized, offset, stride and VBO. The VBO is no passed explicitly as a parameter but is instead the buffer bound to GL_ARRAY_BUFFER at the time of the call.


1 Answers

You can't share VAOs for the same reason you can't share FBOs: They don't hold actual data, but are merely a collection of data holding buffer objects. BOs that hold data you can share.

However, why jump the hoops of context sharing at all? You can reuse a single OpenGL context for several windows, as long as the windows have the same visual format / FBConfig / PIXELFORMATDESCRIPTOR.

Have a look at the following QGLWidget constructor:

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

You can create a QGLWidget with an existing QGLContext. Either creates a stand-alone QGLContext and attach that to multiple windows, or create a main QGLWidget, and use the context created by that one. You can even destroy single QGLWidgets without loosing the context and the data within it, as long as there is at least one QGLWidget holding it.

like image 129
datenwolf Avatar answered Oct 05 '22 21:10

datenwolf