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
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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With