main.cpp
#include#include #include int main(int argc, char **argv) { //QSurfaceFormat格式包括颜色缓冲区的大小,红色、绿色和蓝色; //alpha 缓冲区的大小; //深度和模板缓冲区的大小; //以及用于多重采样的每个像素的样本数。 //此外,该格式还包含表面配置参数,例如用于渲染的 //OpenGL 配置文件和版本、是否启用立体缓冲区以及交换行为。 QSurfaceFormat format; format.setSamples(4); QSurfaceFormat::setDefaultFormat(format); #if !QT_CONFIG(qt3d_rhi_renderer) qputenv("QSG_RHI_BACKEND", "opengl"); #endif QGuiApplication app(argc, argv); //QQuickView 类提供了一个用于显示 Qt Quick 用户界面的窗口 QQuickView view; view.resize(520, 500); //此枚举指定如何调整视图大小。 //QQuickView::SizeRootObjectToView //视图将自动将根项目的大小调整为视图的大小。 view.setResizeMode(QQuickView::SizeRootObjectToView); view.setSource(QUrl("qrc:/main.qml")); view.show(); return app.exec(); }
main.qml
import QtQuick 2.14
import QtQuick.Scene3D 2.14
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.2
Item {
id: main
property real rotationValue: 0
//与 GridLayout 相同,但只有一列
ColumnLayout {
id: colorLayout
anchors.left: parent.horizontalCenter
anchors.leftMargin: parent.width * 0.25
anchors.right: parent.right
anchors.rightMargin: 15
anchors.top: scene3D.top
spacing: 5
Text { text: "Appearance"; font.bold: true }
Text { text: "Ambient color RGB" }
RowLayout {
Text { text: "R" }
Slider {
id: color_r
Layout.fillWidth: true
from: 0
to: 255
value: 128
}
}
RowLayout {
Text { text: "G" }
Slider {
id: color_g
Layout.fillWidth: true
from: 0
to: 255
value: 195
}
}
RowLayout {
Text { text: "B" }
Slider {
id: color_b
Layout.fillWidth: true
from: 0
to: 255
value: 66
}
}
Text { text: "Shininess" }
Slider {
id: shining
Layout.fillWidth: true
from: 30
to: 90
value: 50
}
}
ColumnLayout {
id: transformLayout
anchors.left: colorLayout.left
anchors.right: colorLayout.right
anchors.top: colorLayout.bottom
anchors.topMargin: 10
spacing: 5
Text { text: "Item transform"; font.bold: true }
Text { text: "Rotation" }
RowLayout {
Text { text: "X" }
Slider {
id: rotation_x
Layout.fillWidth: true
from: -45
to: 45
value: rotationValue
}
}
RowLayout {
Text { text: "Y" }
Slider {
id: rotation_y
Layout.fillWidth: true
from: -45
to: 45
value: rotationValue
}
}
RowLayout {
Text { text: "Z" }
Slider {
id: rotation_z
Layout.fillWidth: true
from: -45
to: 45
value: rotationValue
}
}
RowLayout {
CheckBox {id: animation; text: "Animation"; checked: false}
}
}
ColumnLayout {
id: cameraLayout
anchors.left: colorLayout.left
anchors.right: colorLayout.right
anchors.top: transformLayout.bottom
anchors.topMargin: 10
spacing: 5
Text { text: "Camera"; font.bold: true }
Text { text: "View Ctr Z: " + watch.cameraZ.toFixed(2) }
Slider {
id: viewCenter_z
Layout.fillWidth: true
from: 4
to: 12
value: 7.5
onValueChanged: watch.setPositionZ(value)
}
Button {
id: viewAll
Layout.fillWidth: true
text: "View All"
onClicked: watch.viewLogo()
}
}
// 在 QML 文件中的位置和 Scene3D 的大小
//在Underlay模式下没有实际效果:
// 3D 内容将在任何 QtQuick 内容之前绘制
// 并假设一个全屏视口
Scene3D {
id: scene3D
focus: true
aspects: "input"
//适用于使用 FBO 可能过于占用资源的全屏 3D 场景。
//Scene3D 表现为 QtQuick 底图。
//请注意,使用此模式时,Scene3D 的大小及其变换将被忽略,渲染将占据整个屏幕。
//QML 文件中 Scene3D 的位置也不会有任何影响。
//Qt 3D 内容将在任何 Qt Quick 内容之前绘制。
//必须注意不要通过重叠 Qt Quick 内容来过度绘制和隐藏 Qt 3D 内容。
//此外,使用此模式时,窗口 clearBeforeRendering 将自动设置为 false。
compositingMode: Scene3D.Underlay
Logo {
id: watch
}
}
SequentialAnimation {
running: true
paused: !animation.checked
loops: Animation.Infinite
NumberAnimation {
target: main
property: "rotationValue"
easing.type: Easing.OutQuad
duration: 1000
from: 0
to: 45
}
NumberAnimation {
target: main
property: "rotationValue"
easing.type: Easing.InOutQuad
duration: 1000
from: 45
to: -45
}
NumberAnimation {
target: main
property: "rotationValue"
easing.type: Easing.InQuad
duration: 1000
from: -45
to: 0
}
}
}
Logo.qml
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import QtQuick 2.0
import Qt3D.Extras 2.0
//实体本身是空的。
//Entity 对象的行为由它引用的 Component3D 对象定义。
//每个 Qt3D 后端方面都能够通过识别实体由哪些组件组成来解释和处理实体。
//一个方面可能决定只处理由单个 Transform 组件组成的实体,
//而另一个方面可能专注于 MouseHandler。
Entity {
id: sceneRoot
readonly property double cameraZ: camera.position.z
//旋转和移动相机,使其 viewCenter 成为场景边界体积的中心,并且整个场景适合视口。
//注意:仅当镜头处于透视或正交投影模式时才有效。
function viewAll() {
camera.viewAll()
}
//旋转并移动相机,使其 viewCenter 成为实体边界体积的中心,并且整个实体适合视口。
//注意:仅当镜头处于透视或正交投影模式时才有效。
function viewLogo() {
camera.viewEntity(logoEntity)
}
function setPositionZ(z) {
camera.position = Qt.vector3d( 0.0, 0.0, z )
}
//定义将渲染场景的视点。
Camera {
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 40
aspectRatio: 4/3
nearPlane : 0.1
farPlane : 1000.0
position: Qt.vector3d( 0.0, 0.0, 7.5 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
}
//RenderSettings 类型保存与渲染过程相关的设置并托管活动的 frameGraph。
components: [
RenderSettings {
activeframeGraph: ForwardRenderer {
camera: camera
clearColor: "white"
}
//保存当前的渲染策略。
//Qt3DRender::QRenderSettings::OnDemand
//frameGraph 仅在发生变化时呈现。
renderPolicy: RenderSettings.onDemand
}
]
PhongMaterial {
id: material
diffuse: Qt.rgba( color_r.value/255, color_g.value/255, color_b.value/255, 1.0 )
ambient: Qt.rgba( 0.1, 0.1, 0.1, 1.0 )
shininess: shining.value
}
Transform {
id: logoTransform
rotation: fromEulerAngles( rotation_x.value, rotation_y.value, rotation_z.value )
}
Mesh {
id: logoMesh
source: "Qt_logo.obj"
}
Entity {
id: logoEntity
components: [ logoMesh, material, logoTransform ]
}
//以由 Qt3DCore::QEntity 实例聚合为组件的场景节点的基类
//Qt3DCore::QComponent 提供了一个垂直的行为切片,
//可以分配给 Qt3DCore::QEntity 实例,有时也可以在它们之间共享。
//Qt3DCore::QComponent 子类通常聚合成组,将有用的行为传递给聚合实体。
//例如,要拥有一个由 Qt3D 渲染器方面绘制的实体,一个实体很可能会聚合
//Qt3DCore::QTransform、Qt3DRender::QMesh 和 Qt3DRender::QMaterial 组件。
Entity {
components: [
PointLight {
color: "white"
intensity: 0.6
},
Transform {
translation: Qt.vector3d(0, 0, 10)
}
]
}
}



