main.cpp
#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include <QGuiApplication>
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Quick::Qt3DQuickWindow view;
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return app.exec();
}
main.qml
import QtQuick 2.0 as Quick
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
//Entity 是一个 Node 子类,它可以聚合多个 Component3D 实例,这些实例将指定其行为
//Qt3DCore::QComponent 提供了一个垂直的行为切片,可以分配给 Qt3DCore::QEntity 实例,有时也可以在它们之间共享。
//Qt3DCore::QComponent 子类通常聚合成组
//将有用的行为传递给聚合实体
//例如,要拥有一个由 Qt3D 渲染器方面绘制的实体
//一个实体很可能会聚合 Qt3DCore::QTransform、Qt3DRender::QMesh 和 Qt3DRender::QMaterial 组件
Entity
{
//[read-only] components : list<Component3D>
//保存定义实体行为的 Component3D 实例列表。
components: [
//RenderSettings 类型保存与渲染过程相关的设置并托管activeFrameGraph
RenderSettings {
//保存当前活动的 FrameGraph。
activeFrameGraph: SimpleForwardRenderer {
clearColor: Qt.rgba(0, 0, 0, 1)
camera: camera
}
},
//InputSettings 组件必须设置为场景根实体的组件。
//它存储一个指向对象的指针,该对象充当要由各种输入类处理的输入事件的源。
//例如,一个 Window 实例可以是一个事件源。
InputSettings { }
]
Camera {
id: camera
//保存相机投影的类型。 默认值为 CameraLens.PerspectiveProjection。
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
position: Qt.vector3d( 0.0, 40.0, 300.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
viewCenter: Qt.vector3d( 0.0, -10.0, -1.0 )
}
//FirstPersonCameraController 允许从第一人称视角控制场景相机
FirstPersonCameraController {
camera: camera
linearSpeed: 1000.0
acceleration: 0.1
deceleration: 1.0
}
Entity {
id: sun
components: [
//定向光是一种行为类似于太阳光的光源。
//来自定向光的光从同一方向以相同的强度照射所有对象,无论它们在场景中的哪个位置。
DirectionalLight {
color: Qt.rgba(0.8, 0.8, 0.8, 1.0)
//指定平行光的世界方向。
//注意:此属性的确切含义和用途取决于材料实现。
worldDirection: Qt.vector3d(-1, -1, 0)
}
]
}
Entity {
id: redLight
components: [
SphereMesh {
radius: 2
},
Transform {
translation: Qt.vector3d(2.0, 8.0, -2.0)
Quick.SequentialAnimation on translation.y {
loops: Quick.Animation.Infinite
Quick.NumberAnimation { from: 8.0; to: 40.0; duration: 3000 }
Quick.NumberAnimation { from: 40.0; to: 8.0; duration: 3000 }
}
},
PhongMaterial {
diffuse: "red"
},
PointLight {
color: Qt.rgba(1, 0, 0, 1)
}
]
}
Entity {
id: greenLight
components: [
SphereMesh {
radius: 2
},
Transform {
translation: Qt.vector3d(0.0, 3.0, 4.0)
Quick.SequentialAnimation on translation.z {
loops: Quick.Animation.Infinite
Quick.NumberAnimation { from: 4.0; to: 40.0; duration: 5000 }
Quick.NumberAnimation { from: 40.0; to: 4.0; duration: 5000 }
}
},
PhongMaterial {
diffuse: "green"
},
PointLight {
color: Qt.rgba(0, 1, 0, 1)
}
]
}
Entity {
id: spotLight
components: [
SphereMesh {
radius: 2
},
Transform {
translation: Qt.vector3d(-20.0, 40.0, 0.0)
Quick.SequentialAnimation on translation {
loops: Quick.Animation.Infinite
running: true
Quick.Vector3dAnimation { from: Qt.vector3d(-40.0, 40.0, 0.0); to: Qt.vector3d(40.0, 40.0, 0.0); duration: 5000 }
Quick.Vector3dAnimation { from: Qt.vector3d(40.0, 40.0, 0.0); to: Qt.vector3d(-40.0, 40.0, 0.0); duration: 5000 }
}
},
PhongMaterial {
diffuse: "white"
},
SpotLight {
localDirection: Qt.vector3d(0.0, -4.0, 0.0)
Quick.SequentialAnimation on localDirection {
loops: Quick.Animation.Infinite
running: true
Quick.Vector3dAnimation { from: Qt.vector3d(0.0, -4.0, -4.0); to: Qt.vector3d(0.0, -4.0, 4.0); duration: 1000 }
Quick.Vector3dAnimation { from: Qt.vector3d(0.0, -4.0, 4.0); to: Qt.vector3d(0.0, -4.0, -4.0); duration: 1000 }
}
color: "white"
cutOffAngle: 30
constantAttenuation: 1
intensity: 2.5
}
]
}
PlaneEntity {
id: floor
width: 600
height: 600
resolution: Qt.size(20, 20)
position: Qt.vector3d(0, -30, 0)
material: NormalDiffuseMapMaterial {
ambient: Qt.rgba( 0.2, 0.2, 0.2, 1.0 )
diffuse: TextureLoader {
source: "assets/textures/ceramic_small_diamond/ceramic_small_diamond_basecolor.png"
format: Texture.SRGB8_Alpha8
generateMipMaps: true
}
normal: TextureLoader {
source: "assets/textures/ceramic_small_diamond/ceramic_small_diamond_normal.png"
generateMipMaps: true
}
textureScale: 10
shininess: 10
}
}
Entity {
components: [
PhongMaterial {
diffuse: "white"
shininess: 50
},
Mesh {
source: "assets/obj/toyplane.obj"
}
]
}
}
PlaneEntity.qml
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Extras 2.0
Entity {
id: root
property alias position: transform.translation
property alias scale: transform.scale
property alias width: mesh.width
property alias height: mesh.height
property alias resolution: mesh.meshResolution
property Material material
components: [ transform, mesh, root.material ]
Transform { id: transform }
//方形平面网格
PlaneMesh {
id: mesh
width: 1.0
height: 1.0
//保持平面分辨率。 此属性的宽度和高度值指定了在相应维度中为网格生成的顶点数。
meshResolution: Qt.size(2, 2)
}
}
SimpleForwardRenderer.qml
import Qt3D.Core 2.0
import Qt3D.Render 2.0
//TechniqueFilter 指定 FrameGraph 在呈现实体时使用哪些技术。
//TechniqueFilter 指定了 FilterKey 对象和 Parameter 对象的列表。
//当 FrameGraph 中存在 TechniqueFilter 时,仅使用与列表中的键匹配的技术进行渲染。
//列表中的参数可用于设置着色器参数的值。
//TechniqueFilter 中的参数会覆盖 Material、Effect、Technique 和 RenderPass 中的参数,但会被 RenderPassFilter 中的参数覆盖。
TechniqueFilter {
// 暴露相机以允许用户选择用于渲染的相机
property alias camera: cameraSelector.camera
property alias clearColor: clearBuffer.clearColor
property alias viewportRect: viewport.normalizedRect
property alias window: surfaceSelector.surface
property alias externalRenderTargetSize: surfaceSelector.externalRenderTargetSize
property alias frustumCulling: frustumCulling.enabled
// 选择任何使用过的Effect的前向渲染技术
//matchAll保存 TechiqueFilter 使用的过滤键列表
matchAll: [ FilterKey { name: "renderingStyle"; value: "forward" } ]
//RenderSurfaceSelector 可用于选择表面 Qt3D 在此渲染内容。
//表面可以是窗口表面或屏幕外表面。
//externalRenderTargetSize 用于在使用离屏表面时指定渲染目标的实际大小。
RenderSurfaceSelector {
id: surfaceSelector
// 使用整个视口
Viewport {
id: viewport
normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
// 使用指定的相机
CameraSelector {
id : cameraSelector
//为 FrameGraph 启用视锥体剔除
FrustumCulling {
id: frustumCulling
//Qt3DRender::QClearBuffers FrameGraph 节点可以清除具有特定值的特定渲染目标缓冲区。
ClearBuffers {
id: clearBuffer
clearColor: "white"
buffers : ClearBuffers.ColorDepthBuffer
}
}
}
}
}
}