【发布时间】:2020-11-19 00:29:33
【问题描述】:
我创建了一个带有 800x600 窗口的 C++ 应用程序,它使用 Qt Quick 2 元素以及 Qt 3D 对象成功地在 QML 中绘制了一些对象:
QML 代码使用 Qt Quick 2 Rectangle 元素在 Scene2D 内绘制几个绿色/黄色矩形。然后将 2D 场景传送到 3D 立方体的其中一个表面以进行渲染并在 3D 世界中显示。最后,来自 Qt 3D 的蓝色 SphereMesh 被渲染在中心,如上面的屏幕截图所示。
我一直在尝试调整 3D 立方体(2D UI 被渲染到的位置)的大小,使其与窗口的大小相同,但我找不到以编程方式执行此操作的方法:
所以问题是如何调整或缩放 3D 立方体,使其自动调整为与窗口大小相同?
我正在寻找一种解决方案,允许立方体具有与窗口相同数量的像素。例如,在一个 800x600 的窗口上,我希望看到一个 800x600 的绿色矩形。
这是我尝试过的:我可以手动调整camZ 的值,即Camera 与3D 世界中心的距离,有点眼花缭乱,但这不是一个精确的解决方案:如果窗口稍后更改为不同的尺寸,我需要再次进行大量测试以确定camZ 的新值必须是什么。
有什么想法吗?
main.cpp:
#include <QGuiApplication>
#include <QQmlContext>
#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include <Qt3DQuick/QQmlAspectEngine>
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
Qt3DExtras::Quick::Qt3DQuickWindow view;
view.setSource(QUrl("qrc:/main.qml"));
auto rootContext = view.engine()->qmlEngine()->rootContext();
rootContext->setContextProperty("_window", &view);
view.resize(800, 600);
view.show();
return app.exec();
}
main.qml:
import Qt3D.Core 2.12
import Qt3D.Render 2.12
import Qt3D.Extras 2.12
import Qt3D.Input 2.12
import QtQuick 2.0
import QtQuick.Scene2D 2.9
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2
Entity
{
id: sceneRoot
property int w: _window.width
property int h: _window.height
property real camZ: 1000
/* setup camera */
Camera {
id: mainCamera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: _window.width / _window.height
nearPlane: 0.01
farPlane: 1000000.0
position: Qt.vector3d( 0.0, 0.0, sceneRoot.camZ )
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
}
components: [
RenderSettings {
activeFrameGraph: ForwardRenderer {
camera: mainCamera
clearColor: "white"
}
pickingSettings.pickMethod: PickingSettings.TrianglePicking
},
InputSettings {}
]
/* setup a 3D cube to be used as the 2D drawing surface for all Qt Quick 2 stuff */
Entity {
id: drawingSurface
CuboidMesh {
id: planeMesh
}
Transform {
id: planeTransform
translation: Qt.vector3d(0, 0, 0)
scale3D: Qt.vector3d(sceneRoot.w, sceneRoot.h, 1)
}
TextureMaterial {
id: planeMaterial
texture: offscreenTexture // created by qmlTexture below
}
// picked up by Scene2D’s "entities" property and used as a source for events
ObjectPicker {
id: planePicker
hoverEnabled: false
dragEnabled: false
}
components: [ planeMesh, planeMaterial, planeTransform, planePicker ]
}
/* setup Scene2D offscreen texture to be used as canvas by Qt Quick 2 */
Scene2D {
id: qmlTexture
output: RenderTargetOutput {
attachmentPoint: RenderTargetOutput.Color0
texture: Texture2D {
id: offscreenTexture
width: sceneRoot.w
height: sceneRoot.h
format: Texture.RGBA8_UNorm
generateMipMaps: true
magnificationFilter: Texture.Linear
minificationFilter: Texture.LinearMipMapLinear
wrapMode {
x: WrapMode.ClampToEdge
y: WrapMode.ClampToEdge
}
}
}
mouseEnabled: false
entities: [ drawingSurface ]
/* Qt Quick 2 rendering */
Rectangle {
width: offscreenTexture.width
height: offscreenTexture.height
x: 0
y: 0
border.color: "red"
color: "green"
Component.onCompleted: {
console.log("Outter rectangle size: " + width + "x" + height + " at " + x + "," + y);
}
Rectangle {
id: innerRect
height: parent.height*0.6
width: height
x: (parent.width/2) - (width/2)
y: (parent.height/2) - (height/2)
border.color: "red"
color: "yellow"
transform: Rotation { origin.x: innerRect.width/2; origin.y: innerRect.height/2; angle: 45}
Component.onCompleted: {
console.log("Inner rectangle size: " + width + "x" + height + " at " + x + "," + y);
}
}
}
} // Scene2D
/* add light source at the same place as the camera */
Entity {
PointLight {
id: light
color: "white"
intensity: 1
constantAttenuation: 1.0
linearAttenuation: 0.0
}
Transform {
id: lightTransform
translation: Qt.vector3d(0.0, 0.0, sceneRoot.camZ)
}
components: [ light, lightTransform ]
}
/* display 3D object */
Entity {
SphereMesh {
id: mesh
radius: 130
}
PhongMaterial {
id: material
ambient: "blue"
}
Transform {
id: transform
translation: Qt.vector3d(0, 0, 0)
}
components: [ mesh, material, transform ]
}
} // sceneRoot
将这些模块添加到您的 .pro 文件中:
QT += qml quick 3dquick 3dquickextras
【问题讨论】: