3

I've the following problem :

I want to get an application composed of many view which render a common OpenGL scene from a different point of view, illumination, and others options.

Basically, my question is what is the best way to do that with qt ?

My first attempt was to create multiple QOpenGLWidget and get a common QOpenGLContext where I stored the textures but also the meshes and shaders. But it didn't work for meshes because Vertex Array Objects seem to not be shareable. After lot of tries, a possible solution is to store one VAO for each widget that need the mesh but this look really awful.

So, I wonder if there is a good alternative for this kind of problem, or maybe a good documentation to understand how these QOpenGLContext work.

The simplest idea that I've imagined is to create only one QOpenGLContext and use it in the different widgets. But I don't know how to just create a QOpenGLContext alone nor what kind of QWidgets is able to display these renderings.

It's my first post so I don't know if it's clear enough or if I need to describe my whole architecture.

2
  • 1
    The QOpenGLContext wraps the OpenGL context. Its limitations have everything to do with how OpenGL contexts work. Qt has nothing much to do with it. The documentation you want is OpenGL documentation and tutorials, not QOpenGLContext documentation. Commented Aug 23, 2016 at 13:29
  • I know the liminations of OpenGL context, that why I want to use only one for my whole application but the point is to know how to do that with qt. Commented Aug 23, 2016 at 14:00

2 Answers 2

-1

You already tried, so I pass the word about shared contexts.

An OpenGL context is bound to a window: if you want only one context, the straight answer is to have only one window.

Using the widgets module, you can have multiple views of a same scene using multiple viewports in a same QOpenGLWidget. Something like:

void myWidget::paintGL() {
    //...

    glViewport(
        0, 0,
        this->width()/2, this->height()/2
    );

    // draw scene from one point of view

    glViewport(
        this->width()/2, this->height()/2,
        this->width()/2, this->height()/2
    );

    // draw scene from an other point of view

    //...
}

You should probably design a viewport class to store and manage the rendering parameters for each viewport.

The drawback is that you will have to detect in which viewport the user is clicking to handle interactions: some kind of if event.pos.x is between 0 and this->width()/2 ....


An other way could be to let down the widgets module and use Qt Quick and QML: a quick window declares a unique OpenGL context, where each quick item is like a viewport, but encapsulated in its own object so you don't have to think about where the user is interacting.

Inherit QQuickItem instead of QOpenGLWidget and export your class to QML using the qmlRegisterType() macro. You can then create a QQuickView in your program to load a QML code where you declare your items. An example from Qt's documentation here.

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

8 Comments

I've never consider this solution because I thought that is better to not reinvent the wheel. But actually it's probably the simplest solution to keep the control of my resources and renderings.
I guess that by reinventing the wheel, you speak of the multiple viewport solution. You should really consider using the QML solution: it's the same with a wheel already invented
Ok, I've look a bit of what is qt quick and it look really easier to use than the old method. Nethertheless, before I go a step further in my documentation step, can you already tell me if the qml will permit me to dynamically change the size or the number of viewport ?
To dynamically change the size of viewports, you can take a look at SplitView which is the QML version of QSplitter. Changing the number of viewport can be achieved with buttons and signals and slots as in C++. If you want a more complex layout, e.g. to make a tile-based UI, it's also possible. I made something like that last year. It was a bit more difficult, but it can be done in a clean way (unfortunately, the code is not open source, so I can't show you the result)
@Harish That's because you didn't understand the question is an XY problem
|
-1

I think since multiple views/surfces can update independently, unfortunately its not possible to have one single QOpenGLContext that does the job. And sharing contexts have the limitation you already point out in your question.

QOpenGLContext can be moved to a different thread with moveToThread(). Do not call makeCurrent() from a different thread than the one to which the QOpenGLContext object belongs. A context can only be current in one thread and against one surface at a time, and a thread only has one context current at a time.

Link : http://doc.qt.io/qt-5/qopenglcontext.html

So one way you can get it working is have independent updates to your views in a sequential order and make the context current one by one and render before moving on to the next view. This will guarantee that the context is current in only one view at any given time. Perhaps use a QMutex to serialize the updates.

Alternatively you can also pass the context around among threads and serialize their updates, but this is a bad approach.

6 Comments

If the updates are sequential, what is the point of using threads?
If there is some cpu side stuff that needs to be done pre rendering that part can be parallel, only the rendering needs to be synchronized.
FYI, I use a classical SIGNAL/SLOT combo to refresh my displays. I don't know if it's sequential or not.
Its sequential if both are on the same thread. I am guessing both are on the GUI thread so in that case they are sequential.
I'm not really confortable with this kind of multi threading but I'm afraid that it yield a huge pain in the ass to maintain this, isn't it ?
|

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.