Search code examples
qtqmlqt3d

Qt3d QML: how to add Text as overlay to a standard example


Longtime programmer here, but QML nube.

I wish to start a Qt project from the example: "Qt 3D: Shadow Map QML Example", which is readily available from the examples listed in QtCreator. Here's a link to it as well: https://doc.qt.io/qt-5/qt3d-shadow-map-qml-example.html

I want to first customize it by adding 2d text, which would ideally remain in a fixed position on the screen, remaining in view as the camera position / angle changed. I would settle for just being able to add some simple text to the screen in any fashion!

Starting with that example, I added a file:

Title.qml

import Qt3D.Core 2.12
import Qt3D.Extras 2.13

Entity {
    id: titleText
    components: [ Transform { translation: Qt.vector3d(0.0, 10.0, 30.0) } ]

    Text2DEntity {
        font.family: "Sans Serif"
        font.pointSize: 100
        color: "white"
        text: "MY TITLE"
        width: text.length * font.pointSize*2
        height: font.pointSize * 4
    }
}

Then, at the bottom of main.qml, I attempt to incorporate that:

import QtQuick 2.1 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: _window.width / _window.height
        nearPlane: 0.1
        farPlane: 1000.0
        position: Qt.vector3d(0.0, 10.0, 20.0)
        viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
        upVector: Qt.vector3d(0.0, 1.0, 0.0)
    }

    FirstPersonCameraController { camera: camera }

    ShadowMapLight {
        id: light
    }

    components: [
        ShadowMapFrameGraph {
            id: framegraph
            viewCamera: camera
            lightCamera: light.lightCamera
        },
        // Event Source will be set by the Qt3DQuickWindow
        InputSettings { }
    ]


    AdsEffect {
        id: shadowMapEffect

        shadowTexture: framegraph.shadowTexture
        light: light
    }


    // Trefoil knot entity
    Trefoil {
        material: AdsMaterial {
            effect: shadowMapEffect
            specularColor: Qt.rgba(0.5, 0.5, 0.5, 1.0)
        }
    }

    // Toyplane entity
    Toyplane {
        material: AdsMaterial {
            effect: shadowMapEffect
            diffuseColor: Qt.rgba(0.9, 0.5, 0.3, 1.0)
            shininess: 75
        }
    }

    // Plane entity
    GroundPlane {
        material: AdsMaterial {
            effect: shadowMapEffect
            diffuseColor: Qt.rgba(0.2, 0.5, 0.3, 1.0)
            specularColor: Qt.rgba(0, 0, 0, 1.0)
        }
    }

    // -------------------------------------
    // Title entity
    Title {}
   // -------------------------------------
}

I know for certain the Title entity is being included. I've add a sound effect to that onload and console.logs() to prove such (removed from this post). I have tried manipulating the entity in various ways, but it never appears. I think other components must be hiding it / blocking it / rendering it incompatible from being displayed...


Solution

  • A text2D Entity is aimed at putting text into your 3D scene (like putting some text tags on specific objects). I think you just want to put text on your screen as an overlay.

    This can be done by using the standard QML Text type.

    I adapted the your code and marked new lines with //ADDED. Lines you don't longer need are marked with //REMOVED

    pro file:

    You will need the 3dextras module in your pro file

    QT += 3dextras

    main.cpp

    Change your main.cpp by using a QQuickView instead of Qt3DQuickWindow. the reason for this is that the rendering mechanisms between scene3D and Qt3DQuickWindow are different. Scene3D uses the renderer of QML to do its rendering, while Qt3DQuickWindow will create a dedicated render thread. To put it in another way : if your program only needs to show the 3D environment then stick with Qt3DQuickWindow. If you want to put text and buttons on top of your 3D environment use QQuickView.

    #include <Qt3DQuickExtras/qt3dquickwindow.h>
    #include <Qt3DQuick/QQmlAspectEngine>
    #include <QGuiApplication>
    #include <QQmlContext>
    #include <QQmlEngine>
    #include <QQuickView>//ADDED
    
    int main(int argc, char* argv[])
    {
        QGuiApplication app(argc, argv);
    
    //ADDED:
        QQuickView view;
    
        view.rootContext()->setContextProperty("_window", &view);
        view.setSource(QUrl("qrc:/main.qml"));
        view.setWidth(1600);
        view.setHeight(900);
        view.show();
    
    //REMOVED:
    //    Qt3DExtras::Quick::Qt3DQuickWindow view;
    //    view.resize(1600, 800);
    //    view.engine()->qmlEngine()->rootContext()->setContextProperty("_window", &view);
    //    view.setSource(QUrl("qrc:/main.qml"));
    //    view.show();
    
        return app.exec();
    }
    

    main.qml

    In the following example I use a Rectangle as the root and the Scene3D on the same level as a Text (in the top left corner) and a Button to show how you can combine standard QML types.

    Rectangle {
        anchors.fill: parent
    
        Scene3D{
            anchors.fill: parent
            focus: true
            aspects: ["input", "logic"]
            Entity {
                id: sceneRoot
    
                    Camera {
                        id: camera
                        projectionType: CameraLens.PerspectiveProjection
                        fieldOfView: 45
                        aspectRatio: _window.width / _window.height
                        nearPlane: 0.1
                        farPlane: 1000.0
                        position: Qt.vector3d(0.0, 10.0, 20.0)
                        viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
                        upVector: Qt.vector3d(0.0, 1.0, 0.0)
                    }
    
                    FirstPersonCameraController { camera: camera }
    
                    ShadowMapLight {
                        id: light
                    }
    
                    components: [
                        ShadowMapFrameGraph {
                            id: framegraph
                            viewCamera: camera
                            lightCamera: light.lightCamera
                        },
                        // Event Source will be set by the Qt3DQuickWindow
                        InputSettings { }
                    ]
    
    
                    AdsEffect {
                        id: shadowMapEffect
    
                        shadowTexture: framegraph.shadowTexture
                        light: light
                    }
    
    
                    // Trefoil knot entity
                    Trefoil {
                        material: AdsMaterial {
                            effect: shadowMapEffect
                            specularColor: Qt.rgba(0.5, 0.5, 0.5, 1.0)
                        }
                    }
    
                    // Toyplane entity
                    Toyplane {
                        material: AdsMaterial {
                            effect: shadowMapEffect
                            diffuseColor: Qt.rgba(0.9, 0.5, 0.3, 1.0)
                            shininess: 75
                        }
                    }
    
                    // Plane entity
                    GroundPlane {
                        material: AdsMaterial {
                            effect: shadowMapEffect
                            diffuseColor: Qt.rgba(0.2, 0.5, 0.3, 1.0)
                            specularColor: Qt.rgba(0, 0, 0, 1.0)
                        }
                    }
                }
            }
    
        Text {
            id: title
            text: qsTr("TITLE")
            font.family: "Arial"
            font.pointSize: 30
            color: "black"
    
            anchors.top:parent.top
            anchors.left:parent.left
            anchors.leftMargin: 20
            anchors.topMargin: 20
        }
    }
    

    EDIT

    Here is a print screen of the example running on Windows10 with Qt5.13.2 MSVC2015 64bit and works also on Qt5.14.0 MSVC2015 64bit enter image description here