文章目录
一、Mutiviewport 效果
demo是一个qml窗口从多个视口来渲染场景图
代码阅读
代码结构如上图。
QuadViewportFrameGraph.qml
提供了五个viewport ,一个大的包含和其平分的上下左右四个子viewport
import Qt3D.Core 2.0
import Qt3D.Render 2.0
RenderSettings {
id: quadViewportFrameGraph
property alias topLeftCamera: cameraSelectorTopLeftViewport.camera;
property alias topRightCamera: cameraSelectorTopRightViewport.camera;
property alias bottomLeftCamera: cameraSelectorBottomLeftViewport.camera;
property alias bottomRightCamera: cameraSelectorBottomRightViewport.camera;
property alias window: surfaceSelector.surface
activeFrameGraph: RenderSurfaceSelector {
id: surfaceSelector
Viewport {
id: mainViewport
normalizedRect: Qt.rect(0, 0, 1, 1)
ClearBuffers {
buffers: ClearBuffers.ColorDepthBuffer
clearColor: Qt.rgba(0.6, 0.6, 0.6, 1.0)
}
Viewport {
id: topLeftViewport
normalizedRect: Qt.rect(0, 0, 0.5, 0.5)
CameraSelector { id: cameraSelectorTopLeftViewport }
}
Viewport {
id: topRightViewport
normalizedRect: Qt.rect(0.5, 0, 0.5, 0.5)
CameraSelector { id: cameraSelectorTopRightViewport }
}
Viewport {
id: bottomLeftViewport
normalizedRect: Qt.rect(0, 0.5, 0.5, 0.5)
CameraSelector { id: cameraSelectorBottomLeftViewport }
}
Viewport {
id: bottomRightViewport
normalizedRect: Qt.rect(0.5, 0.5, 0.5, 0.5)
CameraSelector { id: cameraSelectorBottomRightViewport }
}
}
}
}
SimpleCamera.qml
对此文件有些不太明白,该文件提供了Entity中 components中包含了一个CameraLens 和Transform ,这样难道就等同于Camera了吗?
import Qt3D.Core 2.0
import Qt3D.Render 2.0
Entity {
id: root
property vector3d position: Qt.vector3d(0.0, 0.0, 10.0)
property vector3d viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
property vector3d upVector: Qt.vector3d(0.0, 1.0, 0.0)
property CameraLens lens: null
components: [lens, transform]
Transform {
id: transform
matrix: {
var m = Qt.matrix4x4();
m.translate(root.position)
var zAxis = root.position.minus(root.viewCenter).normalized()
var xAxis = root.upVector.crossProduct(zAxis).normalized();
var yAxis = zAxis.crossProduct(xAxis);
var r = Qt.matrix4x4(xAxis.x, yAxis.x, zAxis.x, 0,
xAxis.y, yAxis.y, zAxis.y, 0,
xAxis.z, yAxis.z, zAxis.z, 0,
0, 0, 0, 1)
return m.times(r);
}
}
}
main.qml
import QtQuick 2.0
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
Entity {
id: rootNode
components: [quadViewportFrameGraph, inputSettings]
QuadViewportFrameGraph {
id: quadViewportFrameGraph
topLeftCamera: cameraSet.cameras[0]
topRightCamera: cameraSet.cameras[1]
bottomLeftCamera: cameraSet.cameras[2]
bottomRightCamera: cameraSet.cameras[3]
}
// Event Source will be set by the Qt3DQuickWindow
InputSettings { id: inputSettings }
Entity {
id: cameraSet
property var cameras: [camera1, camera2, camera3, camera4]
CameraLens {
id: cameraLens
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: 16/9
nearPlane: 0.01
farPlane: 1000.0
}
CameraLens {
id: cameraLens2
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 15
aspectRatio: 16/9
nearPlane: 0.01
farPlane: 1000.0
}
CameraLens {
id: cameraLens3
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 5
aspectRatio: 16/9
nearPlane: 0.01
farPlane: 1000.0
}
SimpleCamera {
id: camera1
lens: cameraLens2
position: Qt.vector3d(10.0, 1.0, 10.0)
viewCenter: Qt.vector3d(0.0, 1.0, 0.0)
}
SimpleCamera {
id: camera2
lens: cameraLens
position: Qt.vector3d(0.0, 0.0, 5.0)
viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
}
SimpleCamera {
id: camera3
lens: cameraLens2
position: Qt.vector3d(30.0, 30.0, 20.0)
viewCenter: Qt.vector3d(0.0, 0.0, -8.0)
}
SimpleCamera {
id: camera4
lens: cameraLens3
position: Qt.vector3d(100.0, 0.0, -6.0)
viewCenter: Qt.vector3d(0.0, 0.0, -6.0)
}
}
Entity {
id: sceneRoot
property real rotationAngle: 0
SequentialAnimation {
running: true
loops: Animation.Infinite
NumberAnimation { target: sceneRoot; property: "rotationAngle"; to: 360; duration: 4000; }
}
Entity {
components: [
Transform {
rotation: fromAxisAndAngle(Qt.vector3d(0, 0, 1), -sceneRoot.rotationAngle)
},
SceneLoader {
source: "qrc:/Gear_scene.dae"
}
]
}
} // sceneRoot
} // rootNode
二、涉及组件学习
CameraLens
定义3D场景中摄影机的投影矩阵,下面的属性是不是似曾相识,跟Camera很类似
Properties
aspectRatio : real
bottom : real
farPlane : real
fieldOfView : real
left : real
nearPlane : real
projectionMatrix : matrix4x4
projectionType : enumeration
right : real
top : real
CameraSelector
CameraSelector可用于选择相机,FrameGraph使用该相机来绘制实体。
Properties
camera : Entity
RenderSurfaceSelector
RenderSurface选择器可用于选择serface,Qt3D在其中渲染内容。表面可以是window surface 或 offscreen surface。externalRenderTargetSize用于指定offscreen surface渲染目标的实际大小。
当系统使用DPI缩放时,鼠标事件使用的逻辑曲面大小和曲面的实际“物理”大小可能会有所不同。surfacePixelRatio是将逻辑大小转换为物理大小的因子。
Properties
externalRenderTargetSize : size
surface : QSurface
surfacePixelRatio : real
Viewport
场景的视口指定Qt3D渲染到渲染曲面的哪个部分。视口外的区域保持不变。它还控制该视口中渲染的全局参数,如gamma
Properties
gamma : rect //gamma因子,默认2.2
normalizedRect : rect
指定视口的规格化矩形,即相对于渲染曲面大小指定视口矩形。整个曲面大小的视口指定为[0.0,0.0,1.0,1.0],这是默认值。
SceneLoader
给定一个3D源文件,SceneLoader将尝试对其进行解析,并用适当的GeometryRenderer、Transform和Material组件构建实体对象树。
loader 将根据模型文件的属性尝试确定要使用的最佳材料。如果希望使用自定义材质,则必须遍历树,并将默认关联材质替换为您的材质。
顾名思义,SceneLoader加载一个完整的场景子树。如果希望加载单个几何体,则应改用网格。
SceneLoader内部依靠插件的使用来支持各种各样的3D文件格式。以下是Qt3D支持的格式列表。http://assimp.sourceforge.net/main_features_formats.html
注意:此组件不应在多个实体实例之间共享。将导致未定义的行为。
三、总结
上节的simple-qml 中提供的场景是RenderSettings->Camera结构,
本文提供的场景是 RenderSettings -> viewport -> CameraLens 结构