问题
I need to shared data (textures, vertex-buffers,... ) across all OpenGL widgets in a application.
The following code isn't working:
I've found some solutions that have one main QGLWidget
and other are constructed using this main widget. Unfortunately, I can't use this approach, because all my QGLWidgets are equal and almost certainly the first(main) created QGLWidget will be destroyed before others are.
Possible approach:
- single shared OpenGL context between all QGLWidgets
- not working: just one QGLWidget gets rendered correctly, others behave as they weren't rendered, corrupted/random data
error for each
QGLWidget
construction except first one:QGLWidget::setContext: Context must refer to this widget
Another approach:
- main OpenGL context and create sub-context for each QGLWidget
- not working:
context->isSharing()
returnsfalse
code that I use for context creation,
context1
andcontext2
are later passed to constructors of QGLWidgets:QGLContext *mainContext = new QGLContext(format), *context1, *context2; mainContext->create(); context1 = new QGLContext(format); context1->create(mainContext); context2 = new QGLContext(format); context2->create(mainContext); cout << mainContext->isSharing() << " " << context1->isSharing() << endl;
回答1:
With regards to the first approach, you are not setting up sharing but trying to force the same context to be used with different QGLWidgets. As pointed out above, this is wrong and will not work.
Instead, create the QGLWidgets normally and pass the first QGLWidget in the shareWidget parameter when creating the others. This way you will get a separate context for each QGLWidget but they will all share with the context of the first one (and thus with each other). See http://qt-project.org/doc/qt-4.8/qglwidget.html#QGLWidget
Destroying the first widget before the others should not be an issue since the shared objects will be around until any of the sharing contexts are alive.
回答2:
I realize that it has been almost a year since this question has been asked, but I believe the comment above may be inaccurate.
To be more precise, while it may be indeed invalid to use a single QGLContext with multiple QGLWidgets, this would be a limitation of Qt's OpenGL implementation rather than a limitation of OpenGL or the windowing system. It certainly seems valid to use the same context to render to multiple windows. For example, the functions wglMakeCurrent and SwapBuffers accept as parameters device handles alongside OpenGL context handles. To quote the wglMakeCurrent documentation:
The hdc parameter must refer to a drawing surface supported by OpenGL. It need not be the same hdc that was passed to wglCreateContext when hglrc was created, but it must be on the same device and have the same pixel format.
I do not even want to go into problems with SwapBuffers, since there are several bug reports all over the web regarding Qt5, which seems to force making the OpenGL context current unnecessarily before SwapBuffers is called.
回答3:
This has been updated since QT 5.4 and you should now use QOpenGLWidget instead of QGLWidget. Global sharing of contexts has been written into QOpenGLWidget now so you don't have to code it yourself. You just need to enable the sharing flag Qt::AA_ShareOpenGLContexts before you create QGuiApplication.
来源:https://stackoverflow.com/questions/20955669/how-to-share-opengl-context-or-data