2

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...

BuvinJ
  • 10,221
  • 5
  • 83
  • 96

1 Answers1

3

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

Eddy Alleman
  • 1,096
  • 2
  • 10
  • 21
  • This looks like a perfect solution to an irritating problem. I haven't gotten a chance to confirm this yet, but I will get to it in the coming days. Thanks for the help! – BuvinJ Jan 29 '20 at 22:41
  • I know the feeling. I have been in the same situation...So what you want is just putting text on top of a Qt3D scene? In that case it would. Be good to change the title of your first post accordingly. – Eddy Alleman Jan 30 '20 at 06:08
  • Yes, this is very close to what I want. I would have liked to preserve the ability to move the camera around the 3d world. I'm not sure this method allows that? If not, I'll live with that loss. Unfortunately, this is not quite working for me. The text appears, but the QtQuick.Scene3D is not rendering. I updated my question to include the exact QML I'm using. When possible, please test that for me? If it works for you, perhaps there is another factor in play. I'm hoping, that I just have glitch that code. – BuvinJ Jan 30 '20 at 13:38
  • I added the complete source code of a working example in my previous answer. I hope this helps in learning Qt3D. – Eddy Alleman Jan 31 '20 at 12:55
  • Thanks for al the help! To be sure I understand, you literally ran this with success, right? Well, I've tried your exact code and it doesn't work on my machine. Just TITLE over a blue screen. I checked the cpp, qml, and pro, repeatedly. I can use the examples for both the original question and the standard one for a QML 3d scene. I've deleted and recreated the build folder... Totally baffled here. I ultimately need this to work cross platform (windows, linux, mac) and cross Qt version to a reasonable extent. I'm starting on Linux (Ubuntu) using Qt 5.14 in case that possibly means anything. – BuvinJ Feb 01 '20 at 16:06
  • This works for me if I make my scene that from the QML 3d scene example, but not this one with the plane etc using the .obj resources. Could it be related to : `components: [ ShadowMapFrameGraph { ... // Event Source will be set by the Qt3DQuickWindow InputSettings { } ]` ? – BuvinJ Feb 01 '20 at 16:41
  • I added a print screen to my answer of the example running on Windows10 with Qt5.13.2 MSVC2015 64bit and works also on Qt5.14.0 MSVC2015 64bit Did you run the example in it’s original location? Or did you copy it elsewhere? I would suggest testing on the original example location first. As you mention, you want your program to run your program on Windows, Ubuntu and Mac. Have you compiled on Windows10 ? What are the results? I’ve seen differences while using the same Qt3D program on Debian and Windows. Due to MESA driver restrictions. – Eddy Alleman Feb 02 '20 at 06:12
  • I'm again back logged, but I'll test this in some other environments e.g. Windows. I've upvoted for your time. When I figure out whatever my hangup is here, I will mark this as solved. Thank you! – BuvinJ Feb 06 '20 at 13:26
  • Thanks for the appreciation. If you can upload your test application, i can do some tests here to help pinpoint the problem. could be opengl related. What version of opengl have your devices? – Eddy Alleman Feb 07 '20 at 17:43
  • Confirmed on Windows. Marked as solved! I tested both MSVC and MinGW. I have no idea why this doesn't work on my Linux machine, when all the components do by themselves. I'll revisit this cross platform when I can get back to it. Thanks, again! – BuvinJ Feb 08 '20 at 15:03
  • Can you check the driver of your ubuntu machine? What opengl version does it support? I think that is the cause. – Eddy Alleman Feb 08 '20 at 17:02
  • I'll look when I have that machine up and running again in the next day or two. I'm not, however, sure how that can be the problem. Remember, all of the examples work. The original version of this and Scene3d example. It was just the (conceptual) "merging" of them which didn't. If there were an underlying opengl issue, I don't see how those originals would function? – BuvinJ Feb 08 '20 at 17:14
  • Ok i missed that part of your adventurë. Good luck ! – Eddy Alleman Feb 08 '20 at 17:20
  • Thanks, Eddy. Feel free to hit me up directly if you ever have an SO question. I usually have more answers than questions! I'm weak on QML, but quite strong on programming in general - especially when it comes to Qt (or Python). – BuvinJ Feb 08 '20 at 17:29
  • Thx. Good to know! – Eddy Alleman Feb 09 '20 at 07:26