Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Scene3D vs Qt3DQuickWindow: pictures differ



  • I tried to combine QtQuick and Qt3D using Scene3D component which is basically a window to Qt3D from within QtQuick. I was surprised not everything works the same as in the pure Qt3D application.

    I believe the shaders don't work as expected because Scene3D is embedded into QtQuick window repaint procedure thus sharing some objects with its GL context. Is that right?

    Are there ways to fix that? Any other ways to combine QtQuick and Qt3D still staying in QML and not going to C++?

    Thanks guys, your responses are highly appreciated!

    Here are the screen shots and the sources:
    Scene3D: https://drive.google.com/open?id=0BxC-DMpqMeoKSkFJR0t0NFNXWXM
    Pure Qt3D: https://drive.google.com/open?id=0BxC-DMpqMeoKNHM1VGJ2T1diQlU
    Sources: https://drive.google.com/open?id=0BxC-DMpqMeoKdWM1dEVBMXZLQ00



  • I read all the qt3d samples and got the solution:

    1. use Qt3DQuickWindow for pure Qt3D application window, with or without shaders (example: simple-qml/wave)
          Qt3DExtras::Quick::Qt3DQuickWindow view;
          view.setSource(QUrl("qrc:/main.qml"));
          view.show();
    
    1. use scene3d for QtQuick mixed with simple Material (example: scene3d)
        QQuickView view;
        view.setResizeMode(QQuickView::SizeRootObjectToView);
        view.setSource(QUrl("qrc:/main.qml"));
        view.show();
    
    1. change QuickView gl context to be same with qt3d shaders (example: planet-qml)
        QSurfaceFormat format;
        if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
            format.setVersion(3, 2);
            format.setProfile(QSurfaceFormat::CoreProfile);
        }
        format.setDepthBufferSize(24);
        format.setStencilBufferSize(8);
        format.setSamples(4);
    
        QQuickView view;
        view.setFormat(format);
        view.setResizeMode(QQuickView::SizeRootObjectToView);
        view.setSource(QUrl("qrc:/PlanetsMain.qml"));
        view.show();
    
    1. set default window gl context with QML ApplicationWindow x QmlAppEngine (I tried and it works)
    	QSurfaceFormat format;
    	......
    	QSurfaceFormat::setDefaultFormat(format);
    
    	QQmlApplicationEngine engine;
    	engine.load(QUrl(QLatin1String("qrc:/qml/main.qml")));
    
    

    in my application if graphicsApiFilter in Technique is not specified there is nothing need to be done to make scene3d works perfectly.



  • @Midori-Yakumo Thanks Midori, now I've got it working. I should have looked at planets example more carefully.

    I'm wondering why they didn't implement solution #4 as a default Qt behavior?

    Thanks again! Here's the demo code of all four solutions in case someone needs it:

    #include <Qt3DQuickExtras/qt3dquickwindow.h>
    #include <Qt3DQuick/QQmlAspectEngine>
    #include <QGuiApplication>
    #include <QQmlEngine>
    #include <QQmlContext>
    #include <QOpenGLContext>
    
    #include <QQuickView>
    
    int main(int argc, char* argv[])
    {
        QGuiApplication app(argc, argv);
    
    // Set to 1 to use Qt3DQuickWindow only
    // Set to 2 to use default QQuickView+Scene3D
    // Set to 3 to set a custom format to QtQuickView and use QQuickView+Scene3D
    // Set to 4 to set a custom format as a default and use QQuickView+Scene3D
    #define MODE 3
    
    #if MODE == 1
    
        Qt3DExtras::Quick::Qt3DQuickWindow view;
    
        // Expose the window as a context property so we can set the aspect ratio
        view.engine()->qmlEngine()->rootContext()->setContextProperty("_window", &view);
        view.setSource(QUrl("qrc:/WireMain.qml"));
        view.show();
    
    #endif
    #if MODE == 2
    
        QQuickView view;
    
        view.resize(800, 600);
        view.setResizeMode(QQuickView::SizeRootObjectToView);
        view.setSource(QUrl("qrc:/main.qml"));
        view.show();
    
    #endif
    #if MODE == 3
    
        QSurfaceFormat format;
        if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
            format.setVersion(3, 2);
            format.setProfile(QSurfaceFormat::CoreProfile);
        }
        format.setDepthBufferSize(24);
        format.setStencilBufferSize(8);
        format.setSamples(4);
    
        QQuickView view;
        view.setFormat(format);
        view.setResizeMode(QQuickView::SizeRootObjectToView);
        view.setSource(QUrl("qrc:/main.qml"));
        view.setColor("#000000");
        view.show();
    
    #endif
    #if MODE == 4
    
        QSurfaceFormat format;
        if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
            format.setVersion(3, 2);
            format.setProfile(QSurfaceFormat::CoreProfile);
        }
        format.setDepthBufferSize(24);
        format.setStencilBufferSize(8);
        format.setSamples(4);
        QSurfaceFormat::setDefaultFormat(format);
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QLatin1String("qrc:/qml/main.qml")));
    
    #endif
    
        return app.exec();
    }
    


  • @sylc solution 4 is a simple but global workaround, on ther other hand QtQuick should be kept in a lower profile for better compatibility



  • Moderator, why can't I mark this post as solved? Thanks!


  • Lifetime Qt Champion

    Hi,

    @sylc because you didn't "asked it as a question". Click on the "Topic Tools" button, you should have a "Ask as question" option at the bottom. After you clicked that, re-click the "Topic Tools" button and you should have the mark as solved option available.



  • @SGaist many thanks!


Log in to reply