qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记

qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记

文章目录

  • qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记
    • 1.例程运行效果
    • 2.例程缩略图
    • 3.项目文件列表
    • 4.main.qml
    • 5.main.cpp
    • 6.CMakeLists.txt

1.例程运行效果

在这里插入图片描述

运行该项目需要自己准备一个模型文件

2.例程缩略图

在这里插入图片描述

3.项目文件列表

runtimeloader/
├── CMakeLists.txt
├── main.cpp
├── main.qml
├── qml.qrc
└── runtimeloader.pro1 directory, 5 files

4.main.qml

// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clauseimport QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layoutsimport Qt.labs.platform
import QtCoreimport QtQuick3D
import QtQuick3D.Helpers
import QtQuick3D.AssetUtils// 创建一个窗口根节点,设置窗口大小和显示状态
Window {id: windowRootvisible: truewidth: 1280height: 720property url importUrl; // 用于导入模型的URL//! [base scene] 基础场景View3D {id: view3Danchors.fill: parent // 填充父窗口environment: SceneEnvironment {id: envbackgroundMode: SceneEnvironment.SkyBox // 背景模式为天空盒lightProbe: Texture {textureData: ProceduralSkyTextureData{} // 使用程序化天空纹理}InfiniteGrid {visible: helper.gridEnabled // 是否显示网格gridInterval: helper.gridInterval // 网格间隔}}camera: helper.orbitControllerEnabled ? orbitCamera : wasdCamera // 根据控制器选择相机// 设置方向光源DirectionalLight {eulerRotation.x: -35eulerRotation.y: -90castsShadow: true // 启用阴影}Node {id: orbitCameraNodePerspectiveCamera {id: orbitCamera // 轨道相机}}// 第一人称相机(WASD控制)PerspectiveCamera {id: wasdCameraonPositionChanged: {// 更新相机的近远裁剪面let distance = position.length()if (distance < 1) {clipNear = 0.01clipFar = 100} else if (distance < 100) {clipNear = 0.1clipFar = 1000} else {clipNear = 1clipFar = 10000}}}//! [base scene]// 重置视图的函数function resetView() {if (importNode.status === RuntimeLoader.Success) {helper.resetController()}}//! [instancing] 实例化RandomInstancing {id: instancinginstanceCount: 30 // 设置实例数量position: InstanceRange {property alias boundsDiameter: helper.boundsDiameterfrom: Qt.vector3d(-3*boundsDiameter, -3*boundsDiameter, -3*boundsDiameter); // 位置范围to: Qt.vector3d(3*boundsDiameter, 3*boundsDiameter, 3*boundsDiameter)}color: InstanceRange { from: "black"; to: "white" } // 颜色范围}//! [instancing]QtObject {id: helperproperty real boundsDiameter: 0 // 场景边界的直径property vector3d boundsCenter // 场景中心property vector3d boundsSize // 场景大小property bool orbitControllerEnabled: true // 是否启用轨道控制器property bool gridEnabled: gridButton.checked // 是否启用网格property real cameraDistance: orbitControllerEnabled ? orbitCamera.z : wasdCamera.position.length() // 相机与中心的距离property real gridInterval: Math.pow(10, Math.round(Math.log10(cameraDistance)) - 1) // 网格间隔计算// 更新场景边界信息function updateBounds(bounds) {boundsSize = Qt.vector3d(bounds.maximum.x - bounds.minimum.x,bounds.maximum.y - bounds.minimum.y,bounds.maximum.z - bounds.minimum.z)boundsDiameter = Math.max(boundsSize.x, boundsSize.y, boundsSize.z)boundsCenter = Qt.vector3d((bounds.maximum.x + bounds.minimum.x) / 2,(bounds.maximum.y + bounds.minimum.y) / 2,(bounds.maximum.z + bounds.minimum.z) / 2 )wasdController.speed = boundsDiameter / 1000.0 // 更新控制器速度wasdController.shiftSpeed = 3 * wasdController.speedwasdCamera.clipNear = boundsDiameter / 100wasdCamera.clipFar = boundsDiameter * 10view3D.resetView() // 重置视图}// 重置控制器function resetController() {orbitCameraNode.eulerRotation = Qt.vector3d(0, 0, 0)orbitCameraNode.position = boundsCenterorbitCamera.position = Qt.vector3d(0, 0, 2 * helper.boundsDiameter)orbitCamera.eulerRotation = Qt.vector3d(0, 0, 0)orbitControllerEnabled = true}// 切换控制器function switchController(useOrbitController) {if (useOrbitController) {let wasdOffset = wasdCamera.position.minus(boundsCenter)let wasdDistance = wasdOffset.length()let wasdDistanceInPlane = Qt.vector3d(wasdOffset.x, 0, wasdOffset.z).length()let yAngle = Math.atan2(wasdOffset.x, wasdOffset.z) * 180 / Math.PIlet xAngle = -Math.atan2(wasdOffset.y, wasdDistanceInPlane) * 180 / Math.PIorbitCameraNode.position = boundsCenterorbitCameraNode.eulerRotation = Qt.vector3d(xAngle, yAngle, 0)orbitCamera.position = Qt.vector3d(0, 0, wasdDistance)orbitCamera.eulerRotation = Qt.vector3d(0, 0, 0)} else {wasdCamera.position = orbitCamera.scenePositionwasdCamera.rotation = orbitCamera.sceneRotationwasdController.focus = true}orbitControllerEnabled = useOrbitController}}//! [runtimeloader] 运行时加载器RuntimeLoader {id: importNodesource: windowRoot.importUrl // 导入模型的URLinstancing: instancingButton.checked ? instancing : null // 实例化开关onBoundsChanged: helper.updateBounds(bounds) // 更新场景边界}//! [runtimeloader]//! [bounds] 场景边界Model {parent: importNodesource: "#Cube" // 默认使用立方体模型materials: PrincipledMaterial {baseColor: "red" // 设置基础颜色为红色}opacity: 0.2 // 设置模型透明度visible: visualizeButton.checked && importNode.status === RuntimeLoader.Success // 根据条件显示模型position: helper.boundsCenterscale: Qt.vector3d(helper.boundsSize.x / 100,helper.boundsSize.y / 100,helper.boundsSize.z / 100)}//! [bounds]//! [status report] 状态报告Rectangle {id: messageBoxvisible: importNode.status !== RuntimeLoader.Success // 如果导入失败,显示错误消息color: "red"width: parent.width * 0.8height: parent.height * 0.8anchors.centerIn: parentradius: Math.min(width, height) / 10opacity: 0.6Text {anchors.fill: parentfont.pixelSize: 36text: "Status: " + importNode.errorString + "\nPress \"Import...\" to import a model" // 显示错误信息color: "white"wrapMode: Text.WraphorizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenter}}//! [status report]}//! [camera control] 相机控制OrbitCameraController {id: orbitControllerorigin: orbitCameraNodecamera: orbitCameraenabled: helper.orbitControllerEnabled // 根据状态启用或禁用轨道控制器}WasdController {id: wasdControllercontrolledObject: wasdCameraenabled: !helper.orbitControllerEnabled // 根据状态启用或禁用WASD控制器}//! [camera control]// 界面控制面板Pane {width: parent.widthcontentHeight: controlsLayout.implicitHeightRowLayout {id: controlsLayoutButton {id: importButtontext: "Import..."onClicked: fileDialog.open() // 打开文件对话框focusPolicy: Qt.NoFocus}Button {id: resetButtontext: "Reset view"onClicked: view3D.resetView() // 重置视图focusPolicy: Qt.NoFocus}Button {id: visualizeButtoncheckable: truetext: "Visualize bounds" // 显示场景边界focusPolicy: Qt.NoFocus}Button {id: instancingButtoncheckable: truetext: "Instancing" // 开启实例化focusPolicy: Qt.NoFocus}Button {id: gridButtontext: "Show grid" // 显示网格focusPolicy: Qt.NoFocuscheckable: truechecked: false}Button {id: controllerButtontext: helper.orbitControllerEnabled ? "Orbit" : "WASD" // 切换控制器onClicked: helper.switchController(!helper.orbitControllerEnabled)focusPolicy: Qt.NoFocus}RowLayout {Label {text: "Material Override"}ComboBox {id: materialOverrideComboBoxtextRole: "text"valueRole: "value"implicitContentWidthPolicy: ComboBox.WidestTextonActivated: env.debugSettings.materialOverride = currentValue // 选择材质覆盖model: [{ value: DebugSettings.None, text: "None"},{ value: DebugSettings.BaseColor, text: "Base Color"},{ value: DebugSettings.Roughness, text: "Roughness"},{ value: DebugSettings.Metalness, text: "Metalness"},{ value: DebugSettings.Diffuse, text: "Diffuse"},{ value: DebugSettings.Specular, text: "Specular"},{ value: DebugSettings.ShadowOcclusion, text: "Shadow Occlusion"},{ value: DebugSettings.Emission, text: "Emission"},{ value: DebugSettings.AmbientOcclusion, text: "Ambient Occlusion"},{ value: DebugSettings.Normals, text: "Normals"},{ value: DebugSettings.Tangents, text: "Tangents"},{ value: DebugSettings.Binormals, text: "Binormals"},{ value: DebugSettings.F0, text: "F0"}]}}CheckBox {text: "Wireframe" // 启用或禁用线框模式checked: env.debugSettings.wireframeEnabledonCheckedChanged: {env.debugSettings.wireframeEnabled = checked}}}}// 文件对话框,允许用户选择glTF模型文件FileDialog {id: fileDialognameFilters: ["glTF files (*.gltf *.glb)", "All files (*)"]onAccepted: importUrl = file // 选择文件后导入Settings {id: fileDialogSettingscategory: "QtQuick3D.Examples.RuntimeLoader"property alias folder: fileDialog.folder}}// 调试视图切换按钮Item {width: debugViewToggleText.implicitWidthheight: debugViewToggleText.implicitHeightanchors.right: parent.rightLabel {id: debugViewToggleTexttext: "Click here " + (dbg.visible ? "to hide DebugView" : "for DebugView")anchors.right: parent.rightanchors.top: parent.top}MouseArea {anchors.fill: parentonClicked: dbg.visible = !dbg.visible // 切换调试视图可见性DebugView {y: debugViewToggleText.height * 2anchors.right: parent.rightsource: view3Did: dbgvisible: false}}}
}

5.main.cpp

// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifdef HAS_MODULE_QT_WIDGETS
# include <QApplication>
#endif
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QtQuick3D/qquick3d.h>int main(int argc, char *argv[])
{
#ifdef HAS_MODULE_QT_WIDGETSQApplication app(argc, argv);
#elseQGuiApplication app(argc, argv);
#endifapp.setOrganizationName("The Qt Company");app.setOrganizationDomain("qt.io");app.setApplicationName("Runtime Asset Loading Example");const auto importUrl = argc > 1 ? QUrl::fromLocalFile(argv[1]) : QUrl{};if (importUrl.isValid())qDebug() << "Importing" << importUrl;QSurfaceFormat::setDefaultFormat(QQuick3D::idealSurfaceFormat(4));QQmlApplicationEngine engine;const QUrl url(QStringLiteral("qrc:/main.qml"));engine.load(url);if (engine.rootObjects().isEmpty()) {qWarning() << "Could not find root object in" << url;return -1;}QObject *topLevel = engine.rootObjects().value(0);QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);if (window)window->setProperty("importUrl", importUrl);return app.exec();
}

6.CMakeLists.txt

# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clausecmake_minimum_required(VERSION 3.16)
project(runtimeloader LANGUAGES CXX)set(CMAKE_AUTOMOC ON)find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick Quick3D Widgets)qt_add_executable(runtimeloadermain.cpp
)set_target_properties(runtimeloader PROPERTIESWIN32_EXECUTABLE TRUEMACOSX_BUNDLE TRUE
)target_link_libraries(runtimeloader PUBLICQt::CoreQt::GuiQt::QuickQt::Quick3D
)if(TARGET Qt::Widgets)target_compile_definitions(runtimeloader PUBLICHAS_MODULE_QT_WIDGETS)target_link_libraries(runtimeloader PUBLICQt::Widgets)
endif()qt_add_qml_module(runtimeloaderURI ExampleVERSION 1.0QML_FILES main.qmlNO_RESOURCE_TARGET_PATH
)install(TARGETS runtimeloaderBUNDLE  DESTINATION .RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)qt_generate_deploy_qml_app_script(TARGET runtimeloaderOUTPUT_SCRIPT deploy_scriptMACOS_BUNDLE_POST_BUILDNO_UNSUPPORTED_PLATFORM_ERRORDEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM
)
install(SCRIPT ${deploy_script})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/10858.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高性能消息队列Disruptor

定义一个事件模型 之后创建一个java类来使用这个数据模型。 /* <h1>事件模型工程类&#xff0c;用于生产事件消息</h1> */ no usages public class EventMessageFactory implements EventFactory<EventMessage> { Overridepublic EventMessage newInstance(…

Spring Boot项目如何使用MyBatis实现分页查询

写在前面&#xff1a;大家好&#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正&#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是&#xff1a;https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油&#xff0c;冲鸭&#x…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.27 线性代数王国:矩阵分解实战指南

1.27 线性代数王国&#xff1a;矩阵分解实战指南 #mermaid-svg-JWrp2JAP9qkdS2A7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-JWrp2JAP9qkdS2A7 .error-icon{fill:#552222;}#mermaid-svg-JWrp2JAP9qkdS2A7 .erro…

EasyExcel使用详解

文章目录 EasyExcel使用详解一、引言二、环境准备与基础配置1、添加依赖2、定义实体类 三、Excel 读取详解1、基础读取2、自定义监听器3、多 Sheet 处理 四、Excel 写入详解1、基础写入2、动态列与复杂表头3、样式与模板填充 五、总结 EasyExcel使用详解 一、引言 EasyExcel 是…

FIDL:Flutter与原生通讯的新姿势,不局限于基础数据类型

void initUser(User user); } 2、执行命令./gradlew assembleDebug&#xff0c;生成IUserServiceStub类和fidl.json文件 3、打开通道&#xff0c;向Flutter公开方法 FidlChannel.openChannel(getFlutterEngine().getDartExecutor(), new IUserServiceStub() { Override void…

DIFY源码解析

偶然发现Github上某位大佬开源的DIFY源码注释和解析&#xff0c;目前还处于陆续不断更新地更新过程中&#xff0c;为大佬的专业和开源贡献精神点赞。先收藏链接&#xff0c;后续慢慢学习。 相关链接如下&#xff1a; DIFY源码解析

87.(3)攻防世界 web simple_php

之前做过&#xff0c;回顾 12&#xff0c;攻防世界simple_php-CSDN博客 进入靶场 <?php // 显示当前 PHP 文件的源代码&#xff0c;方便调试或查看代码结构 // __FILE__ 是 PHP 的一个魔术常量&#xff0c;代表当前文件的完整路径和文件名 show_source(__FILE__);// 包含…

x86-64数据传输指令

关于汇编语言一些基础概念的更详细的介绍&#xff0c;可移步MIPS指令集&#xff08;一&#xff09;基本操作_mips指令 sw-CSDN博客 该指令集中一个字2字节。 该架构有16个64位寄存器&#xff0c;名字都以%r开头&#xff0c;每个寄存器的最低位字节&#xff0c;低1~2位字节&…

网络工程师 (8)存储管理

一、页式存储基本原理 &#xff08;一&#xff09;内存划分 页式存储首先将内存物理空间划分成大小相等的存储块&#xff0c;这些块通常被称为“页帧”或“物理页”。每个页帧的大小是固定的&#xff0c;例如常见的页帧大小有4KB、8KB等&#xff0c;这个大小由操作系统决定。同…

全程Kali linux---CTFshow misc入门(25-37)

第二十五题&#xff1a; 提示&#xff1a;flag在图片下面。 直接检查CRC&#xff0c;检测到错误&#xff0c;就直接暴力破解。 暴力破解CRC的python代码。 import binascii import struct def brute_force_ihdr_crc(filename): # 读取文件二进制数据 with open(filen…

MySQL数据库(二)- SQL

目录 ​编辑 一 DDL (一 数据库操作 1 查询-数据库&#xff08;所有/当前&#xff09; 2 创建-数据库 3 删除-数据库 4 使用-数据库 (二 表操作 1 创建-表结构 2 查询-所有表结构名称 3 查询-表结构内容 4 查询-建表语句 5 添加-字段名数据类型 6 修改-字段数据类…

Android记事本App设计开发项目实战教程2025最新版Android Studio

平时上课录了个视频&#xff0c;从新建工程到打包Apk&#xff0c;从头做到尾&#xff0c;没有遗漏任何实现细节&#xff0c;欢迎学过Android基础的同学参加&#xff0c;如果你做过其他终端软件开发&#xff0c;也可以学习&#xff0c;快速上手Android基础开发。 Android记事本课…

STM32调试手段:重定向printf串口

引言 C语言中经常使用printf来输出调试信息&#xff0c;打印到屏幕。由于在单片机中没有屏幕&#xff0c;但是我们可以重定向printf&#xff0c;把数据打印到串口&#xff0c;从而在电脑端接收调试信息。这是除了debug外&#xff0c;另外一个非常有效的调试手段。 一、什么是pr…

如何使用 ChatBox AI 简化本地模型对话操作

部署模型请看上一篇帖子&#xff1a;本地部署DeepSeek教程&#xff08;Mac版本&#xff09;-CSDN博客 使用 ChatBox AI 简化本地模型对话操作&#xff1a; 打开 ChatBox AI 官网&#xff1a;Chatbox AI官网&#xff1a;办公学习的AI好助手&#xff0c;全平台AI客户端&#xf…

C++ Primer 自定义数据结构

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

鸿蒙物流项目之基础结构

目录&#xff1a; 1、项目结构2、三种包的区别和使用场景3、静态资源的导入4、颜色样式设置5、修改项目名称和图标6、静态包基础目录7、组件的抽离8、在功能模块包里面引用静态资源包的组件 1、项目结构 2、三种包的区别和使用场景 3、静态资源的导入 放在har包中&#xff0c;那…

RK3568使用QT搭建TCP服务器和客户端

文章目录 一、让RK3568开发板先连接上wifi二、客户端代码1. `widget.h` 文件2. `widget.cpp` 文件**详细讲解**1. **`Widget` 类构造函数 (`Widget::Widget`)**2. **UI 布局 (`setupUI`)**3. **连接按钮的槽函数 (`onConnectClicked`)**4. **发送消息按钮的槽函数 (`onSendMess…

Redis|前言

文章目录 什么是 Redis&#xff1f;Redis 主流功能与应用 什么是 Redis&#xff1f; Redis&#xff0c;Remote Dictionary Server&#xff08;远程字典服务器&#xff09;。Redis 是完全开源的&#xff0c;使用 ANSIC 语言编写&#xff0c;遵守 BSD 协议&#xff0c;是一个高性…

【算法设计与分析】实验8:分支限界—TSP问题

目录 一、实验目的 二、实验环境 三、实验内容 四、核心代码 五、记录与处理 六、思考与总结 七、完整报告和成果文件提取链接 一、实验目的 掌握分支界限求解问题的思想&#xff1b;针对不同的问题&#xff0c;能够利用分支界限法进行问题拆分和求解以及时间复杂度分析…

2025年大年初一篇,C#调用GPU并行计算推荐

C#调用GPU库的主要目的是利用GPU的并行计算能力&#xff0c;加速计算密集型任务&#xff0c;提高程序性能&#xff0c;支持大规模数据处理&#xff0c;优化资源利用&#xff0c;满足特定应用场景的需求&#xff0c;并提升用户体验。在需要处理大量并行数据或进行复杂计算的场景…