问题描述
我在 QML (Qt 5.15/6.0.0) 中加载和显示 3D 模型 (.obj) 时遇到问题。我尝试了以下 3 种技术,但它们似乎都有独特的问题。
-
在我自己的 .obj 加载器中使用 QQuickItem 和 OpenGL。这可以工作,但我想利用 Qt 在质量渲染、简化模型加载和摆脱 OpenGL 特定绘制代码的潜力方面提供的强大功能。
-
来自 Qt3D 模块的 Scene3D。这有效,但它在退出时崩溃。我已经尝试了建议的解决方法,但它们都未能防止崩溃,或者如果我确实防止了崩溃,那么我的模型将无法正确加载或显示。
-
一个 来自 Quick 3D 的 View3D。这似乎是未来的最佳选择,但缺点似乎是我需要使用 balsam 预处理 obj 文件,以便将其转换为 qt .mesh 格式。我宁愿避免这一步,因为我希望用户能够加载他们自己的模型(obj、step 等)
需要能够设置网格和纹理源。使用带有网格的 Scene3D 可以做到这一点,但我没有看到使用带有模型对象的 View3D 的相同选项。
理想情况下,我可以使用 qml Qt3D.Render::Mesh 项或 Qt3DRender::QMesh 动态加载对象文件,然后使用该网格在 View3D 中进行渲染。或者使用自定义 QQuick3DGeometry 加载模型并可以添加为 QtQuick3D::Mode.geometry。
我是否在这里遗漏了什么,或者我是否试图混合两个不兼容的模块:Qt3D 和 Quick3D?模型可以动态加载到 View3D 中而不将其转换为 .mesh 文件吗?
解决方法
使用SceneLoader。
此代码是您可以在 Scene3d 中导入 .obj 文件的示例:
import QtQuick.Controls 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Scene3D 2.0
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
import QtQuick.Controls.Material 2.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("3D Viewer")
header: ToolBar
{
Material.theme: Material.Dark
ToolButton
{
text: "Open 3D Model"
onPressed:
{
fileDialog.open()
}
}
}
FileDialog
{
id: fileDialog
onAccepted:
{
sceneLoader.source = fileDialog.fileUrl
print(fileDialog.fileUrl)
mainScene3d.forceActiveFocus()
}
}
Scene3D
{
id:mainScene3d
anchors.fill: parent
focus: true
hoverEnabled: true
aspects: ["input","logic","render"]
cameraAspectRatioMode: Scene3D.AutomaticAspectRatio
Entity
{
id: sceneRoot
Camera
{
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 30
aspectRatio: 16/9
nearPlane : 0.1
farPlane : 100.0
position: Qt.vector3d( 10.0,0.0,10.0 )
upVector: Qt.vector3d( 0.0,1.0,0.0 )
viewCenter: Qt.vector3d( 0.0,0.0 )
}
OrbitCameraController
{
camera: camera
}
components: [
RenderSettings
{
activeFrameGraph: ForwardRenderer
{
clearColor:"#333333"
camera: camera
}
},InputSettings
{
}
]
Entity
{
id: monkeyEntity
components: [
SceneLoader
{
id: sceneLoader
}
]
}
}
}
}