QOpenGLWidget with shared context
-
In a nutshell, my goal is to have an OpenGL surface that has ownership of a group of QWidgets. The OpenGL surface will display a texture generated by a QOffscreenSurface. The child QWidgets act as UI elements that allow the user to change certain areas of this texture (similar to the concept of a mask).
I tried doing this with a QWindow to make the OpenGL side of things a bit easier but there were problems with z order since a QWindow is not a widget and has to be packaged using a window container.
I'm now trying to do this using a QOpenGLWidget. This looks promising; the child QWidgets are correctly shown on top of the background OpenGL texture. The issue is that I cannot share the QOpenGLWidget's context correctly.
This is my current InitializeGL code:
void GLWidget::initializeGL() { //In order to share OpenGL resources, the context has to be recreated if(!initialized){ QOpenGLContext* openGLContext = context(); if(openGLContext) delete openGLContext; //Allocate memory for the context object and prepare to create it openGLContext = new QOpenGLContext(this); openGLContext->setFormat(openGLFormat); if(shareContext) openGLContext->setShareContext(shareContext); //Make sure the context is created & is sharing resources with the shared context bool contextCreated = openGLContext->create(); assert(contextCreated); if(shareContext){ bool sharing = QOpenGLContext::areSharing(openGLContext,shareContext); assert(sharing); } makeCurrent(); } //Other initialization code if needed }
This class is a subclass of QOpenGLWidget and QOpenGLFunctions. I pass the OpenGL surface format and shared context to the QOpenGLWidget constructor and recreate its context in the InitializeGL method.
I get a crash when calling QOpenGLFunctions::initializeOpenGLFunctions() which seems to suggest that even though I'm recreating the context, the widget's surface has a format that is compatible with the original context and not the new one.
My stack trace:
1 QOpenGLFunctions_4_0_Compatibility::glVertexAttrib4ubv Qt5Guid 0x7ffa2732ee2d 2 QOpenGLFunctions_4_0_Compatibility::glVertexAttrib4ubv Qt5Guid 0x7ffa2732f129 3 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282efbcd 4 GLWidget::initializeGL glwidget.cpp 135 0x7ff6e1b16286 5 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282f1a0a 6 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282efef5 7 QTreeWidget::findItems Qt5Widgetsd 0x7ffa28295a31 8 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282f01c2 9 QTreeWidget::findItems Qt5Widgetsd 0x7ffa28232c4f 10 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282302a8 11 QStateMachinePrivate::processedPendingEvents Qt5Cored 0x7ffa26982aa0 12 QStateMachinePrivate::processedPendingEvents Qt5Cored 0x7ffa269809d2 13 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282a592e 14 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282a5c90 15 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282a5c26 16 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282a41ff 17 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282a5cb1 18 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282a5c26 19 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282a41ff 20 QTreeWidget::findItems Qt5Widgetsd 0x7ffa282a5cb1 ... <More>
Is what I'm doing completely wrong? Any ideas on how to do this correctly?
Note: I can't wait for the QOpenGLWidget to get created and take its context to share with the other OpenGL surfaces. This is because of the order in which the object are created.
Cheers!
-
If sharing all OpenGL contexts is an option for you then you can set the global Qt::AA_ShareOpenGLContexts application attribute before instantiating QApplication. This way you won't have to do anything else to have all your contexts shared.
-
@Chris-Kawa That would work for multiple QOpenGLWidgets in the same application. My use case involves sharing the context of one QOpenGLWidget with that of a QOffscreenSurface