Problems with QML with OpenGL view
-
hi guys :)
I'm writing a 3d model viewer, so basically I want to pass my glview to QML to use it as an element and add the rest of the UI with QML...
My current problem is that only the element which represents my glview (a custom QDeclarativeItem with reimplemented paint() with OpenGLES 2.0 calls) is shown, the rest (2 toolbars and some more) is all black.
But when I hit the buttons on the (black) toolbar (or scroll a listview) those elements are shown, flickering with black, as if they were trying to get the top view but the black layer was trying to cover them again.
I have tried changing the setViewportUpdateMode, and that doesn't help (I have tried all values)...unless I set it to FullViewportUpdate, in which case the UI is always repainted and FPS goes from 36 (with the 3D model viewer and all the rest under the black layer) to 22!!
So what I'd like to accomplish is: get what is inside my custom QML element (QDeclarativeItem) repainted (i.e. the 3D Model), without repainting the rest of the elements of the UI (toolbars, etc) because that is useless and eats a lot of FPS...but without painting black over all the UI elements (as it currently does)!
can you guys help me out? :)
Here's the setup of my app
@ QApplication::setGraphicsSystem("opengl");
Q_INIT_RESOURCE(common);
qmlRegisterType<modelviewer>("Test", 1, 0, "Viewer");
QScopedPointer<QApplication> app(createApplication(argc, argv));
QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());viewer->setResizeMode(QDeclarativeView::SizeRootObjectToView); QGLWidget* renderer = new QGLWidget(); //if setAutoFillBackground is true I get the 3D model painted, and the rest is all WHITE, if it is false, the 3D Model is painted, and the rest is all BLACK renderer->setAutoFillBackground(false); viewer->setViewport(renderer); viewer->setAttribute(Qt::WA_OpaquePaintEvent); viewer->setAttribute(Qt::WA_NoSystemBackground); viewer->viewport()->setAttribute(Qt::WA_OpaquePaintEvent); viewer->viewport()->setAttribute(Qt::WA_NoSystemBackground); viewer->setMainQmlFile(QLatin1String("qml/main2.qml"));
@
-
I think I had the same problem "here":http://developer.qt.nokia.com/forums/viewthread/11273/, and the solution was to set the the viewportUpdateMode to FullViewportUpdate.
I haven't found any other solutions, but I would also be interested. -
Hello. I'm trying to do pretty much the same thing. Did you ever get this to work? If so I would love to have a peek at the code related to getting the OpenGL viewer running inside of QML.
Using the method described "here":http://qt-project.org/forums/viewthread/4109/P15/, (another thread on this forum),I was able to get an OpenGL window embedded in my QML layout, HOWEVER, because it is only instantiated in the QML I have no way of accessing the OpenGL viewer object or passing any arguments to it, because it does not exist on the C++ side...
I'm going to try and figure out what you are doing here anyway. It sure would be nice to know that it actually works (without the blackness bug) and to have some more information on this method of implementation.
If ANYONE can point me to some clear documentation concerning embedding a fully functional OpenGL context inside of a QML layout, please do!
Thanks!
Cheers!
-
Hi ultramanjones,
It's not something I've tried to do.
But, with your example:@
import QtQuick 1.0
import MDEPlugins 1.0MDE{
width:200
height:200
}
@Just add some Q_INVOKABLE functions to it, if you want to call those functions from QML.
Why can you not access the MDE object from C++? Alternatively, from C++, just qobject_cast (actually, there may be a qgraphics_cast or similar, for graphics-view based stuff, I can't remember) the pointer returned by view.rootObject() as an MDE and access it that way.
Or am I misunderstanding what you're trying to do?
In general, if you have an Item in QML, you can pass it back to C++ as an argument. Just give it an id, and then pass that id as a QObject* argument to a Q_INVOKABLE function of a helper item.
eg:
@
// assume that I have a QDeclarativeItem-derived class called
// Helper which is installed into the Helper 1.0 namespace
// where that class has a Q_INVOKABLE void doStuffWithObject(QObject* arg) { /whatever/ } function
import Helper 1.0Item {
id: rootMDE { id: mde width: 200; height: 200 } Helper { id: helper } Component.onCompleted: { helper.doStuffWithObject(mde); }
}
@