Multiple Contexts using QOpenGLWidget
-
In my application I create two QOpenGLWidgets, which are supposed to share a context. The second widget, is basically a preview for some visual properties that you can change in the main window. I had previously used QGLWidget and handed in the main widget as the share_widget parameter for
QGLWidget(QWidget * parent = 0, const QGLWidget * shareWidget = 0)
Calling makeCurrent() in initializeGL()/paintGL() and resizeGL() would then make it all work perfectly.
I now wanted to update my code to use QOpenGLWidget, so I tried to translate the QGLWIdget context sharing mechanism. Here is a function I implemented for that purpose:/* * Private function. * share_widget_ is a member variable of type QOpenGLWidget. **/ void MyGLWidget::setShareWidget() { QOpenGLContext* c = context(); c->setFormat(share_widget_->context()->format()); c->setShareContext(share_widget_->context()); c->create(); }
Calling this in the constructor will not work, since the widgets context is not initialized yet and context() will therefore return 0. I then added a call to the above function to the top of my overridden initializeGL() function, before calling makeCurrent() and proceeding with the rest of the initialization steps.
This will succeed to execute so I can see the new MyGLWidget instance. Nevertheless, I only get a black window (while setting glClearColor(1.0, 1.0, 1.0, 1.0) upon initialization).
Any suggestions, as to what I am doing wrong?
-
@Vagabond
Hello,
What isQOpenGLContext::areSharing
returning when used with your two contexts? You could also try creating a global shared context with QOpenGLContext::globalShareContext and try sharing both widget's context with that. Unfortunately, I'm by no means expert on the subject. After you create the context are you making your context current withQOpenGLContext::makeCurrent
before issuing theglClearColor
call?Kind regards.
-
This technique is useful for creating standalone shared contexts, but won't work in this case. QOpenGLWidget maintains its context internally and gives no way to provide it a manually set up context.
Here's a description of context sharing with QOpenGLWidget. Basically if the two QOpenGLWidgets are in the same window the sharing is already happening and you don't need to do anything special to enable it. If the widgets are in separate windows then the easiest way to make them share a context is to set the
Qt::AA_ShareOpenGLContexts
attribute on the application object right at the start of your app. -
@Chris-Kawa brilliant! The Qt::AA_ShareOpenGLContexts makes it really easy. Here is a little summary for everyone interested in how I solved the issue:
- 1.) In your main, call:
int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QApplication a(argc, argv); doOtherStuff(); return a.exec(); }
This will force every context to share resources. It should only be done if your sharing contexts reside in different windows, since QOpenGLContext automatically share resources if they are children of the same parent window. As can be seen above, make sure you call setAttribute before constructing QApplication.
- 2.) All classes used for instancing a resource sharing QOpenGLWidget should override the following functions and start them with a call to QOpenGLWidget::makeCurrent()
void MyGLWidget::initializeGL() { QOpenGLWidget::makeCurrent(); doOtherStuff(); } void MyGLWidget::paintGL() { QOpenGLWidget::makeCurrent(); doOtherStuff(); } void MyGLWidget::resizeGL(int width, int height) { QOpenGLWidget::makeCurrent(); doOtherStuff(); }
-
There's no need to call
makeCurrent()
in the virtual GL methods. It's already done for you before they are called anddoneCurrent()
is called for you after they finish. See the docs for these methods.