Setting same context name in multiple contexts.
-
#include <Qt3DQuickExtras> #include <Qt3DQuickExtras/qt3dquickwindow.h> #include <QGuiApplication> #include <QApplication> std::vector<Qt3DExtras::Quick::Qt3DQuickWindow*> views; void generateViews(QApplication &app, int viewcount){ QSurfaceFormat format; format.setAlphaBufferSize(8); for(int count=0; count<viewcount; count++){ Qt3DExtras::Quick::Qt3DQuickWindow* view = new Qt3DExtras::Quick::Qt3DQuickWindow(); view->setFlag(Qt::SplashScreen); view->setFormat(format); view->engine()->qmlEngine()->rootContext()->setContextProperty("_window", view); // problems //view->engine()->qmlEngine()->rootContext()->setContextObject(view); // problems /* // all objects are different, why interaction between objects? qInfo() << count; qInfo() << view->engine(); qInfo() << view->engine()->qmlEngine(); qInfo() << view->engine()->qmlEngine()->rootContext(); */ view->setSource(QUrl("qrc:/main.qml")); view->show(); //QObject::connect(view->engine()->qmlEngine(), SIGNAL(quit()), &app, SLOT(quit())); views.push_back(view); } } int main(int argc, char* argv[]) { QApplication app(argc, argv); generateViews(app, 2); return app.exec(); }
This code is based upon the simple-qml example that comes with Qt-Creator.
The version of Qt is 5.9.7.The problems is that when I call setContextProperty with "_window" as the name for all contexts then the application locks up. If I don't set this, or set the context to something unique like _window0, _window1, etc. then it will run. I have checked the contexts that are created and they are all unique. I am very confused as to why the context of each window would care about the others.
Is there some sort of global context I should be aware of? Even though the pointers for each windows' contexts are unique?
I need the object as reported to each context to be the same name so I only have to write one QML file that is used on all windows created. If I generate a unique name for each window then I will have to somehow determine what that name is on the QML side.
-
Hi and welcome to devnet,
Just a wild guess, I would check whether there's only one engine/rootContext that is created.
-
Hello!
qInfo() << count; qInfo() << view->engine(); qInfo() << view->engine()->qmlEngine(); qInfo() << view->engine()->qmlEngine()->rootContext();
When I ran this code it produced all unique pointers:
0 Qt3DCore::Quick::QQmlAspectEngine(0x25780d68) QQmlEngine(0x25790e98) QQmlContext(0x257b0348) 1 Qt3DCore::Quick::QQmlAspectEngine(0x25832fd0) QQmlEngine(0x2583ff78) QQmlContext(0x611f4f28)
That is what is stumping me. What is common to the contexts?
-
I don't know. Can you also provide the QML file so I can test it on my end ?
-
I should have posted this in the first place:
import QtQuick 2.2 as QQ2 import Qt3D.Core 2.0 import Qt3D.Render 2.0 import Qt3D.Input 2.0 import Qt3D.Extras 2.0 Entity { id: sceneRoot Camera { id: camera projectionType: CameraLens.PerspectiveProjection fieldOfView: 45 aspectRatio: 16/9 nearPlane : 0.1 farPlane : 1000.0 position: Qt.vector3d( 0.0, 0.0, -40.0 ) upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) } /* OrbitCameraController { camera: camera } */ KeyboardDevice { id: keyboardSourceDevice } KeyboardHandler { sourceDevice: keyboardSourceDevice focus: true onEscapePressed: { Qt.quit() } onUpPressed: { _window.setY(_window.y - 25) } onDownPressed: { _window.setY(_window.y + 25) } } components: [ RenderSettings { activeFrameGraph: ForwardRenderer { //clearColor: Qt.rgba(0, 0.5, 1, 1) clearColor: Qt.rgba(0, 0, 0, 0) camera: camera } }, // Event Source will be set by the Qt3DQuickWindow InputSettings { } ] PhongMaterial { id: material } TorusMesh { id: torusMesh radius: 5 minorRadius: 1 rings: 100 slices: 20 } Transform { id: torusTransform scale3D: Qt.vector3d(1.5, 1, 0.5) rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45) } Entity { id: torusEntity components: [ torusMesh, material, torusTransform ] } SphereMesh { id: sphereMesh radius: 3 } Transform { id: sphereTransform property real userAngle: 0.0 matrix: { var m = Qt.matrix4x4(); m.rotate(userAngle, Qt.vector3d(0, 1, 0)); m.translate(Qt.vector3d(20, 0, 0)); return m; } } QQ2.NumberAnimation { target: sphereTransform property: "userAngle" duration: 10000 from: 0 to: 360 loops: QQ2.Animation.Infinite running: true } Entity { id: sphereEntity components: [ sphereMesh, material, sphereTransform ] } }
-
I don't have 5.9.7 at hand currently but I just tested with 5.12 (self-built) and the two windows are created. Can you test a more recent version of Qt ?
-
Hmmm, I just ran it under 5.11.2 and it fails to run if I set it to create 2 windows. It doesn't matter if I expose the view object via setcontextproperty or not.
It puts out this error a bunch of times:
QThread::start: Failed to create thread (The operation completed successfully.) -
On what OS are you running that ?
-
I tested the same code on:
Windows 7 Pro
mingw 5.3.0
Qt 5.11.2
GeForce 460I was able to get 5 instances running at the same time before it started having problems. The more I look at this the more I think a QML based 3D rendering pipeline is going to be heavy handed for what I want to do. I need light weight windows to do 3D in lots of windows. I also think part of the issue on the Windows 10 machine is it has 2 video cards. I think the 3D app was running on the Intel GPU rather than the Nvidia GPU. So GPU affinity I think it partially to blame for it not running more than one instance very well.
So I had a look at QOpenGLWindow. I was able get a simple rotating cube scene running in that window. Then I tested it with 50 windows. It opened all 50 on my geforce 460 just fine. They all ran and could rotate the cube. This first test is for a proof of concept and I needed to know if Qt 3D rendering contexts could scale. Running 50 at the same time tells me it can scale well. I didn't even tell the windows to share resources yet.
SGaist,
Thanks for testing this. For now I am going the route of QOpenGLWindow. It fills my needs. I just won't be able to use the convenience of QML for now. I kind of thought that might be the case so it doesn't surprise me.Thanks