0
votes

Background :

I have a Shader class in my c++/OpenGL3.1/GLSL/Qt program. My program uses several shaders based on different GLSL sources files.

My application can run many different 3D renderers based on the QGLWidget implementation and each one creates its own shaders.

When I create my first 3d renderer and initialize my shaders, shaders IDs are generated with the help of glCreateShader & glCreateProgram, without any problem.

Problem :

But when I create a second 3d renderer, the OGL functions retrieving the ID give exactly the same but I expect to have new ones. It means that my two renderers will send the data to the same GPU program...

It's obvious that in the GPU program, uniform variables are mixed and when running the second renderer, the first one displays a weird rendering.

Indeed, when I close one of the two renderer, all shaders are killed... and the second renderer cannot display anything.

Idea ?

I'm completely lost and my logical deduction is that glCreateShader & glCreateProgram give ID according to their own thread id. QGLWidget running probably its own thread to call the rendering functions, it may trouble the persistence...

Any idea of how to solve this problem ?

2
Are they QGLWidget or QOpenGLWidget ? You also wrote "QGLOpenGL". Most likely the former given the behavior you describe ... ? - Adrien Leravat
I'm currently using QGLWidget (it's what I meant, slip). I firstly called the 'with glFormat' ctor and then tried to create a context for both widgets and called QGLWidget ctor with their respective context and a different top-level parent (QWidget* dynamically instantiated). I still have the same problem. - Quentin Tealrod
I also tried to use 'QOpenGLWidget' instead of QGLWidget, still with two different parents. At this point, it seems that it works, but my openGL Widgets are in dockable widgets, and asa they are undocked, it turns weird. Seems unstable, the background turns black and it's not updated on mouse events. - Quentin Tealrod

2 Answers

3
votes

If both your QOpenGLWidget share the same parent window, then by default they share the same context. If you don't want that, the easier is probably to create a new top-level widget (any QWidget with no parent) with your second QOpenGLWidget.

Please note that this is different from the older QGLWidget class. From Qt documentation:

When multiple QOpenGLWidgets are added as children to the same top-level widget, their contexts will share with each other. This does not apply for QOpenGLWidget instances that belong to different windows.

This means that all QOpenGLWidgets in the same window can access each other's sharable resources, like textures, and there is no need for an extra "global share" context, as was the case with QGLWidget.

2
votes

There is no problem to solve.

Each QGLWidget has its own OpenGL context. And, unless you are explicitly sharing objects between them, each context has its own separate list of objects.

You can only use an OpenGL object with the OpenGL context that created it. So long as you keep the objects separate, and only use them with the context that created it, you should be fine.