Qt3d QML:如何将文本作为覆盖添加到标准示例
Qt3d QML: how to add Text as overlay to a standard example
这里是资深程序员,但 QML nube。
我希望从示例开始一个 Qt 项目:“Qt 3D:Shadow Map QML 示例”,可以从 QtCreator 中列出的示例中轻松获得。这也是一个 link:https://doc.qt.io/qt-5/qt3d-shadow-map-qml-example.html
我想首先通过添加 2d 文本对其进行自定义,理想情况下,它会保留在屏幕上的固定位置,随着相机位置/角度的变化而保持在视野中。我愿意满足于以任何方式在屏幕上添加一些简单的文本!
从那个例子开始,我添加了一个文件:
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
}
}
然后,在 main.qml 的底部,我尝试合并:
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 {}
// -------------------------------------
}
我确定 Title
实体已包含在内。我已经为那个 onload 添加了一个声音效果和 console.logs() 来证明这一点(从这个 post 中删除)。我尝试过以各种方式操纵该实体,但它从未出现过。我认为其他组件必须隐藏它/阻止它/使其不兼容以显示...
text2D 实体旨在将文本放入您的 3D 场景中(例如在特定对象上放置一些文本标签)。我认为您只是想将文本作为叠加层放置在屏幕上。
这可以通过使用标准 QML 文本类型来完成。
我修改了您的代码并用 //ADDED 标记了新行。您不再需要的行标有 //REMOVED
专业文件:
您将需要 pro 文件中的 3dextras 模块
QT += 3dextras
main.cpp
通过使用 QQuickView 而不是 Qt3DQuickWindow 更改您的 main.cpp。这是因为scene3D和Qt3DQuickWindow的渲染机制不同。
Scene3D 使用 QML 的渲染器进行渲染,而 Qt3DQuickWindow 将创建一个专用的渲染线程。换句话说:如果您的程序只需要显示 3D 环境,那么坚持使用 Qt3DQuickWindow。
如果您想将文本和按钮放在 3D 环境之上,请使用 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
在下面的示例中,我使用矩形作为根,将 Scene3D 与文本(在左上角)和按钮放在同一级别,以展示如何组合标准 QML 类型。
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
}
}
编辑
这是 运行 在 Windows10 上使用 Qt5.13.2 MSVC2015 64 位的示例的打印屏幕,也适用于 Qt5.14.0 MSVC2015 64 位
这里是资深程序员,但 QML nube。
我希望从示例开始一个 Qt 项目:“Qt 3D:Shadow Map QML 示例”,可以从 QtCreator 中列出的示例中轻松获得。这也是一个 link:https://doc.qt.io/qt-5/qt3d-shadow-map-qml-example.html
我想首先通过添加 2d 文本对其进行自定义,理想情况下,它会保留在屏幕上的固定位置,随着相机位置/角度的变化而保持在视野中。我愿意满足于以任何方式在屏幕上添加一些简单的文本!
从那个例子开始,我添加了一个文件:
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
}
}
然后,在 main.qml 的底部,我尝试合并:
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 {}
// -------------------------------------
}
我确定 Title
实体已包含在内。我已经为那个 onload 添加了一个声音效果和 console.logs() 来证明这一点(从这个 post 中删除)。我尝试过以各种方式操纵该实体,但它从未出现过。我认为其他组件必须隐藏它/阻止它/使其不兼容以显示...
text2D 实体旨在将文本放入您的 3D 场景中(例如在特定对象上放置一些文本标签)。我认为您只是想将文本作为叠加层放置在屏幕上。
这可以通过使用标准 QML 文本类型来完成。
我修改了您的代码并用 //ADDED 标记了新行。您不再需要的行标有 //REMOVED
专业文件:
您将需要 pro 文件中的 3dextras 模块
QT += 3dextras
main.cpp
通过使用 QQuickView 而不是 Qt3DQuickWindow 更改您的 main.cpp。这是因为scene3D和Qt3DQuickWindow的渲染机制不同。 Scene3D 使用 QML 的渲染器进行渲染,而 Qt3DQuickWindow 将创建一个专用的渲染线程。换句话说:如果您的程序只需要显示 3D 环境,那么坚持使用 Qt3DQuickWindow。 如果您想将文本和按钮放在 3D 环境之上,请使用 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
在下面的示例中,我使用矩形作为根,将 Scene3D 与文本(在左上角)和按钮放在同一级别,以展示如何组合标准 QML 类型。
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
}
}
编辑
这是 运行 在 Windows10 上使用 Qt5.13.2 MSVC2015 64 位的示例的打印屏幕,也适用于 Qt5.14.0 MSVC2015 64 位