4

I have an existing OpenGL context that I would like to share with a new QOpenGLWidget.

I know I can do this:

  1. Create QOpenGLWidget
  2. Wait until initializeGL is called and save the context
  3. Create new QOpenGLContext, and make it shared with the saved context

However, I would like to do it in the other order:

  1. Create QOpenGLContext
  2. Create QOpenGLWidget, providing the existing context and making them shared

Is this possible?

8
  • You can also do the sharing in the initGL call Commented Nov 10, 2015 at 17:00
  • @ratchetfreak How? I think, when initGL is called, the OpenGL context is already created and cannot be set to share another context... Commented Nov 11, 2015 at 8:07
  • Where does it say you can't share a context after it is created? Commented Jan 7, 2016 at 22:38
  • I think that you don't need QOpenGLWidget at all. You may use QWindow with custom gl surface (or with your context) + QWidget::createWindowContainer to use it as a widget. Commented Jan 11, 2016 at 16:55
  • @SaZ: thanks for the idea. I actually tried to do this first. However, using a QWindow as WindowContainer brings other problems with layouts and stuff, since it is not a proper widget. So I would rather like to stay with the Widget instead... Commented Jan 12, 2016 at 7:23

1 Answer 1

3

Edit, I don't know much about QOpenGLFramebufferObject yet so ignore my previous answer content.

In the QOpenGLWidget it always sets its context to share with its closest top level window (or itself if it is a window). You are correct in your understanding that there is no way to change the QOpenGLWidget member context without subclassing it to totally change how it works. In the QOpenGLWidgetPrivate::initialize() function the context is initialized from the defaultFormat and from the top level shareContext. If you want to work with the context before you create the QOpenGLWidget then it must be through the global shared context. Qt::AA_ShareOpenGLContexts needs to be set before your QGuiApplication object is created.

You need to wait until QGuiApplication has initialized the global context before you try to access it. As the global_share_context is a static member of the QOpenGLContext class then you can just create any QOpenGLContext and access it via context.globalShareContext(). Then just delete your initial QOpenGLContext. Any QOpenGLWidget you create will share with that context automatically. If you can find a way of getting a pointer to the global shared context before you create() your special context then you can just share with the global context and you are good to go as the sharing goes both ways. The sharing is through the whole group of shared contexts that are shared with each other so any sharing with one context shares with the whole group.

Also, I don't know if this changes anything but The QOpenGLContext says it can share framebuffer objects too.

Sign up to request clarification or add additional context in comments.

16 Comments

Are you sure you can change the OpenGL context in initializeGL? On this page: doc.qt.io/qt-5/qopenglwidget.html#initializeGL it says "The QOpenGLWidget's associated OpenGL context is guaranteed to be current whenever initializeGL() and paintGL() are invoked." To be current, the context must already be created, however. And setShareContext has to be called before creating the context...
Just re create the context then and that should solve the problem.
@stevantatinger Ah, I could try that. I guess the disadvantage (from a performance reason) is, that the context is created twice, right?
@Jan Rüegg Yes the code I showed above would create the context twice on initialization. Have you tried just passing your existing context (making sure it is in the correct thread) and then calling makeCurrent()? If you re implemented initializeGL, paintGL and resizeGL to call makeCurrent at the beginning of each I don't see why you can't just use whatever context you want. Although it might be calling makeCurrent on two contexts each time which may affect performance a bit.
@stevantatinger I didn't try yet, but I think this will not work: As far as I know, paintGL draws into a framebuffer that is set up by the QOpenGLWidget. If this framebuffer is set up by the widgets context, and a different context tries to draw into the framebuffer, this would probably be undefined behaviour.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.