QOpenglWidget and QML Quick - c++

Which is the best or right way to implement a QML overlay over an existing QOpenglWidget? QDeclarativeView is deprecated and works only with QtQuick 1.0. This is a general question for a widget use case.

This might be too late for you, but I was able to make a QOpenGLWidget as an underlay. This pointer from KDAB got me started. Basically, You have to make some public wrappers around the protected QOpenGLWidget functions, initializeGL() and paintGL() for the QQuickView sceneGraphInitialized and beforeRendering signals.

Related

QOpenGLWidget with QApplication?

We have a QWidget based application that was previously using a QWindow for OpenGL rendering. To fit that window in our application we had to use
QWidget QWidget::createWindowContainer(QWindow);
Previously we only used external to Qt OpenGL libraries for rendering.
We have a desire to switch from using QWindow to some kind of QWidget for compatibility with touch gestures, and generally better overall compatibility with the rest of our application. The latest recommended OpenGL compatible QWidget seems to be QOpenGLWidget, so we are trying to use that.
glContext is an OpenGLContext that we manage ourselves.
The problem now is that QOpenGLWidget is not a QSurface, so I cannot call
glContext->makeCurrent(this);
to make the context current on my custom QOpenGLWidget like we could before with our custom QWindow and our own OpenGLContext.
If I try to use QOpenGLWidget::makeCurrent(); then this uses the wrong context and tries to do stuff with some magical QT handled context or something I don't understand.
The result is that after creating our OpenGLContext when we try to call
glFunctions = glContext->versionFunctions<QOpenGLFunctions_3_3_Core>();
if(!glFunctions->initializeOpenGLFunctions())
printf("Could not initialize OpenGL functions.");
It always fails to initialize the OpenGL functions.
I have been reading over all the other resources I can find on the subject and came across this older Stack Overflow question that was similar:
QOpenGLWidget with shared OpenGL context?
The answer to that question did not solve my issue because we are using QApplication, not QGuiApplication as this is a QWidget based application.
QGuiApplicationPrivate::init() is never called and the QOpenGLContext::globalShareContext() returns a null pointer since it is not initialized.
Unfortunately I cannot wait for QOpenGLWidget::initializeGL() to be called to initialize the QT managed OpenGLContext since we already have lots of OpenGL resources over various classes that attempt to get initialized before that.
Has anyone else come across this same problem?
Any suggestions?
I am doing a little guess work here.
Probably your OpenGL is defaulting to ANGLE.
And your previous application OpenGL calls are platform specific OpenGL API.
try setting below attribute to your QApplication object.
appObject->setAttribute(Qt::AA_UseDesktopOpenGL, true);
then try calling
QOpenGLWidget::makeCurrent();
If things are still not working, configure your QT libraries for desktop OpenGL.
configure -opengl desktop
the below link gives you some information on Qt approach to OpenGL.
http://doc.qt.io/qt-5/windows-requirements.html
Put in comments, if this is not helping you, will delete the answer.

Qt QML draw in cpp subclass

so I am trying to understand drawing in Qt, but I dont get this one:
So first of all I had a qml file where I embedded a custom class called Game which has this constructor: Game::Game(QQuickItem *parent) : QQuickItem(parent)
Writing setFlag(ItemHasContents, true); in the constructor code was sufficient to being able to draw with QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *); using QSGGeometry (This worked). Now I tried to draw in a subclass, using the same procedure but now it does not work anymore: So what I did was create a class called qcurver, and in Game I create an instance of qcurver. QCurver has the same constructor like Game and I pass the parent of Game so that technically it has the same parent as Game, but now when I try to draw in this class, nothing happens. Does anyone know, how I can pass the QML object for drawing, so that I actually see the drawing?
You're creating a Game object from QML code, so it's registered correctly in the QML scene. But the QCurver isn't created there, so it won't work.
Yes, it has the same parent, but it only means that if the parent gets deleted - the QCurver will be deleted too. Qt doesn't revise all QObjects that are added as children to find out if they are of type QQuickItem and should be rendered.
Also, QML itself was added to be able to avoid doing widget hierarchies in C++. So, compose hierarchies in QML. Or, if you want some of them in C++ for the performance reasons - then it is possible to do QSGNode hierarchies inside a QQuickItem (that's useful for rendering complex scenes with OpenGL).

Moving from QGLWidget to QWindow

I have some code using Qt 4. I want to migrate it to Qt 5 and switch to QOpenGL stuff. I can't understand where the code from void paintGL() and void initializeGL() needs to go in a QWindow. Can anyone help me with an example?
I have created a simple example of using QWindow with OpenGL.
To simplify OpenGL development I have created an abstract class GLWindow, which contains the virtual functions initializeGL(), paintGL() and resizeGL(int w, int h). I believe the source code shows the relationship between the old style and the new style.
The example is available here:
https://github.com/mortennobel/QtOpenGLChapter/tree/master/OpenGL3xAlt
Qt has at least one example (Overpainting) of putting widgets over an OpenGL scene. By looking at that, it appears the easiest way would be to inherit from QGLWidget instead of QWidget and override the appropriate virtual functions for initialize and paint.
The standard example for using QWindow with OpenGL is hellowindow in qtbase/examples/opengl.
There is no direct replacement for initializeGL and paintGL. Instead you do something like this:
Have a QWindow with surface type OpenGLSurface.
Create a QOpenGLContext with a matching format.
When the window receives an expose event, start rendering (makeCurrent, your GL calls and finally swapBuffers).

What Qt classess use to make an animation?

I wrote almost every sort algorithm in C++ in console. Now I would like to make it look good, so what classes of Qt should I use to make an animation of sorting algorithms I implemented in pure C++? Im a newbie in Qt ;) tia
You can use QGraphicsItemAnimation to animate graphics displayed using QGraphicsScene and QGraphicsView.
Links:
Graphics View Framework
QGraphicsItemAnimation
Outside of the Graphics View Framework, you can use QVariantAnimation or QPropertyAnimation to drive properties or methods of any QObject derived class. See the Animation Framework docs for more info.
Conversely you can manually configure a QTimer to drive painting updates of a widget and use an increment to drive a QTimeLine.

Hosting QOpenGL widget inside QML

I have a library proving me a QGLWidget, and the interface allow me to only to resize/set size, and control some GL animation; but no GL command is exposed outside, all i do it initialize GLWidget, and then pass the context to library and later call swap buffer to show animation..
I want to integrate this QGLWidget library into QML, is it possible to hove a QGLWidget inside QML ? if yes how ?
It's totally possible! You can write a QML plugin that will define a new QML element to encapsulate the library.
Then you will import this plugin from the QML document and you'll be good to use the new element and harness the features that the library offers.
Tip: if the application that loads your QML document was setup to have it's on QGLWidget, then you won't need to create a new QGLWidget inside your plugin. I did this mistake once.
This blog post shows how to create a simple/new QML element from scratch and how to use it in a QML document.
QGLWidget derives from the QWidget while QML widgets are implemented as QDeclarativeItem which derives from QGraphicsObject and these two are to different worlds.
Possible way of doing OpenGL drawings in a QML item is to declare a new QDeclarativeItem, expose it to the QML system and then override the draw method of this QDeclarativeItem subclass to do native painting(by calling the beginNativePainting and endNativePainting of the QPainter instance provided in the draw method).
Have a look at these two links:
http://doc.qt.nokia.com/4.7-snapshot/qml-extending.html
http://developer.qt.nokia.com/forums/viewthread/4109