Qt Quick 3D 入门:QML 3D场景详解

随着 Qt 6 的发布,QtQuick3D 模块带来了新的 3D 渲染和交互能力,使得在 Qt 中创建 3D 场景变得更加简单和直观。本文将带您从一个简单的 QML 3D 应用开始,详细讲解各个相关领域的概念、代码实现以及功能特点。

什么是 Qt Quick 3D?

Qt Quick 3D 是 Qt 6 中引入的一个模块,旨在为用户提供便捷的 3D 场景管理和渲染工具。与 Qt 5 中的 Qt 3D 模块相比,QtQuick3D 更加简化,且集成了 Qt Quick 的能力,让 2D 和 3D 内容的结合更加自然。

QML 3D 应用的基本结构

QtQuick3D 中,您可以通过 QML 来定义 3D 场景、物体、灯光、摄像机等。这些内容与 Qt Quick 2D 界面元素可以并存和协作,允许在同一个窗口中同时渲染 2D 和 3D 元素。

以下是我们将要分析的 QML 代码示例,这个例子展示了如何通过 QML 创建一个简单的 3D 场景,并与用户交互。

代码示例程序:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN) && QT_VERSION_CHECK(5, 6, 0) <= QT_VERSION && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endifQGuiApplication app(argc, argv);QQmlApplicationEngine engine;engine.load(QUrl(QStringLiteral("qrc:/qt/qml/qtquickapplication2/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}
main.qml
import QtQuick.Window
import QtQuick3D
import QtQuick
Window {width: 640height: 480visible: truetitle: qsTr("Hello World")View3D {//显示3D的舞台(摄影棚)id: _viewanchors.fill: parentenvironment: SceneEnvironment {//environment设置渲染场景//SceneEnvironment为场景的渲染方式定义了一组全局属性。clearColor: "red"//环境颜色backgroundMode: SceneEnvironment.ColorantialiasingMode: SceneEnvironment.MSAAantialiasingQuality: SceneEnvironment.High}camera: cameraPerspectiveCamera {//定义用于查看三维场景内容的透视摄影机(摄像机)。id: cameraposition: Qt.vector3d(0, -900, 800)//摄像机位置eulerRotation.x: 45//x轴旋转45度}MouseArea {anchors.fill: parentonClicked: (mouse)=> {let ret = _view.pick(mouse.x, mouse.y)if(ret.objectHit !== null)ret.objectHit.materials[0].diffuseColor =Qt.rgba(Math.random(),Math.random(), Math.random(), 1.0)}}DirectionalLight {//场景灯光eulerRotation: Qt.vector3d(1, 0, 0)castsShadow: truebrightness: 3}Model {//物体(拍照对象)id: _spheresource: "#Sphere"//球z: 300pickable: truescale: Qt.vector3d(2, 2, 2)materials: DefaultMaterial {//定义三维材质材质diffuseColor: Qt.rgba(0.6, 0.5, 0.2, 1.0)//着色diffuseLightWrap:0//}}Model {source: "#Rectangle"pickable: truescale: Qt.vector3d(10, 10, 1)materials: DefaultMaterial {diffuseColor: Qt.rgba(0.7, 0.2, 0.2, 1.0)}}}}

运行结果:

代码分析
1. 创建主窗口

首先,我们需要一个窗口来容纳 3D 内容。这里我们使用 Window 元素,并设置基本的窗口属性,例如宽度、高度和标题。

Window {width: 640height: 480visible: truetitle: qsTr("Hello World")
  • Window:定义一个窗口,宽度为 640,高度为 480,并设置标题为“Hello World”。
  • qsTr("Hello World"):Qt 的国际化功能,便于将文本翻译成不同语言。
2. 定义 3D 视图

要显示 3D 内容,首先需要创建一个 View3D,这是 QtQuick3D 中的主要容器,类似于 2D 场景中的 ItemView3D 是一个 3D 场景的承载体,所有 3D 内容都将在这个视图中渲染。

 

qml

View3D {id: _viewanchors.fill: parent
  • View3D:这是一个 3D 视图容器,用于渲染 3D 场景。anchors.fill: parent 将其大小设置为充满整个窗口。
  • id: _view:为 3D 视图定义一个 ID 以便后续引用。
3. 设置场景环境

为了优化 3D 渲染效果,我们可以通过 SceneEnvironment 来设置全局的渲染环境。例如,可以定义背景颜色、抗锯齿模式等。

environment: SceneEnvironment {clearColor: "red"backgroundMode: SceneEnvironment.ColorantialiasingMode: SceneEnvironment.MSAAantialiasingQuality: SceneEnvironment.High
}

environment: SceneEnvironment { clearColor: "red" backgroundMode: SceneEnvironment.Color antialiasingMode: SceneEnvironment.MSAA antialiasingQuality: SceneEnvironment.High }

  • SceneEnvironment:定义了 3D 场景的渲染环境。
    • clearColor:设置场景背景为红色。
    • backgroundMode:指定背景填充模式为颜色填充。
    • antialiasingModeantialiasingQuality:启用多重采样抗锯齿(MSAA)并设置其质量为高。
4. 添加摄像机

3D 场景的观察依赖于摄像机。PerspectiveCamera 是一种常用的透视摄像机,它能产生与现实世界类似的透视效果。

 
camera: camera
PerspectiveCamera {id: cameraposition: Qt.vector3d(0, -900, 800)eulerRotation.x: 45
}
  • PerspectiveCamera:定义了一个透视摄像机,用于观察 3D 场景。
    • id: camera:为摄像机设置 ID。
    • position:设置摄像机的位置,x、y 和 z 坐标为(0, -900, 800)。
    • eulerRotation.x: 45:将摄像机绕 X 轴旋转 45 度,使其向下倾斜以获得俯视视角。
5. 添加光照

光照是 3D 渲染中不可或缺的一部分,它决定了物体的明暗和阴影效果。这里使用 DirectionalLight 来模拟来自特定方向的光源。

DirectionalLight {eulerRotation: Qt.vector3d(1, 0, 0)castsShadow: truebrightness: 3
}

DirectionalLight { eulerRotation: Qt.vector3d(1, 0, 0) castsShadow: true brightness: 3 }

  • DirectionalLight:定义了场景中的一个方向光源。
    • eulerRotation:设置光源的旋转方向。
    • castsShadow:启用阴影投射效果。
    • brightness:设置光源亮度为 3。
6. 创建 3D 模型

3D 模型是场景中的核心部分。在 QtQuick3D 中,通过 Model 元素定义 3D 物体,并使用 source 属性加载预定义的形状(例如球体、矩形等)。

Model {id: _spheresource: "#Sphere"z: 300pickable: truescale: Qt.vector3d(2, 2, 2)materials: DefaultMaterial {diffuseColor: Qt.rgba(0.6, 0.5, 0.2, 1.0)}
}
  • Model:创建了一个 3D 模型,源为一个球体(source: "#Sphere")。
    • z: 300:将球体沿 z 轴平移。
    • pickable:模型是可拾取的,也就是说可以用鼠标进行选择和交互。
    • scale:将球体按比例放大 2 倍。
    • materials:指定了球体的材质,diffuseColor 定义了其漫反射颜色为金黄色。

再创建一个矩形模型:

Model {source: "#Rectangle"pickable: truescale: Qt.vector3d(10, 10, 1)materials: DefaultMaterial {diffuseColor: Qt.rgba(0.7, 0.2, 0.2, 1.0)}
}

此模型定义了一个矩形,并设置了红色的材质。

7. 交互:鼠标点击事件

通过 MouseArea,可以捕捉鼠标点击事件,并与 3D 模型进行交互。通过调用 pick 函数,可以检测鼠标点击的模型,并修改其颜色。

MouseArea {anchors.fill: parentonClicked: (mouse)=> {let ret = _view.pick(mouse.x, mouse.y)if(ret.objectHit !== null)ret.objectHit.materials[0].diffuseColor = Qt.rgba(Math.random(), Math.random(), Math.random(), 1.0)}
}
  • MouseArea:定义了一个鼠标区域,覆盖整个 3D 视图。
    • onClicked: 当点击时,调用 _view.pick(mouse.x, mouse.y) 检测点击到的物体,若成功选中物体,则将其材质的漫反射颜色随机改变。
C++ 代码入口

为了启动 QML 应用,我们还需要一个 C++ 程序入口。main.cpp 文件提供了应用程序的启动逻辑,并加载 QML 文件。

#include <QGuiApplication>
#include <QQmlApplicationEngine>int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN) && QT_VERSION_CHECK(5, 6, 0) <= QT_VERSION && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endifQGuiApplication app(argc, argv);QQmlApplicationEngine engine;engine.load(QUrl(QStringLiteral("qrc:/qt/qml/qtquickapplication2/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}
  • QGuiApplication:负责应用程序的基本设置和生命周期管理。
  • QQmlApplicationEngine:用于加载和执行 QML 文件。在这里,加载了 main.qml,该文件定义了 3D 场景和其所有组件。
  • app.exec():进入应用程序的事件循环,保持应用程序持续运行。

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

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

相关文章

git维护【.gitignore文件】

在工程下添加 .gitignore 文件【git忽略文件】 *.class .idea *.iml *.jar /*/target/

订阅ROS2中相机的相关话题并保存RGB、深度和点云图

系统&#xff1a;Ubuntu22.04 ROS2版本&#xff1a;ROS2 humble 1.订阅ROS2中相机的相关话题并保存RGB图、深度图和点云图 ros2 topic list/stellar_1/rgb/image_raw /camera/depth/image_raw /stellar_1/points2CMakeLists.txt cmake_minimum_required(VERSION 3.15) projec…

Docker安装人大金仓(kingbase)关系型数据库教程

人大金仓数据库(KingbaseES)是由中国人民大学金仓公司研发的一款自主知识产权的关系型数据库管理系统。 官网地址:https://www.kingbase.com.cn/ 本章教程,主要介绍如何用Docker安装启动人大金仓(kingbase)关系型数据库。 一、下载镜像 下载地址:https://www.kingbase.c…

螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习04(环境准备)

4 创建docker容器 4.1创建网络 [rootlocalhost wutool]# docker network create -d macvlan --subnet192.168.137.0/24 --gateway192.168.137.2 --ip-range192.168.137.0/24 -o parentens33 nat 52af11381bfd655d175e4168265b2a507793e8fe48f119db846949ffd4dd27de [rootlocal…

​IAR全面支持国科环宇AS32X系列RISC-V车规MCU

全球领先的嵌入式系统开发软件解决方案供应商IAR与北京国科环宇科技股份有限公司&#xff08;以下简称”国科环宇”&#xff09;联合宣布&#xff0c;最新版本IAR Embedded Workbench for RISC-V将全面支持国科环宇AS32X系列RISC-V MCU&#xff0c;双方将共同助力中国汽车行业开…

文件上传之%00截断(00截断)以及pikachu靶场

pikachu的文件上传和upload-lab的文件上传 目录 mime type类型 getimagesize 第12关%00截断&#xff0c; 第13关0x00截断 差不多了&#xff0c;今天先学文件上传白名单&#xff0c;在网上看了资料&#xff0c;差不多看懂了&#xff0c;但是还有几个地方需要实验一下&#…

自然语言处理问答系统技术

自然语言处理问答系统技术 随着人工智能的不断发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术已成为推动智能问答系统发展的核心技术。问答系统是利用NLP来解析用户提出的问题&#xff0c;并从知识库中找到最相关的答案。在许多应用中&#xff0c;如智能客服、…

使用python基于DeepLabv3实现对图片进行语义分割

DeepLabv3 介绍 DeepLabv3 是一种先进的语义分割模型&#xff0c;由 Google Research 团队提出。它在 DeepLab 系列模型的基础上进行了改进&#xff0c;旨在提高图像中像素级分类的准确性。以下是 DeepLabv3 的详细介绍&#xff1a; 概述DeepLabv3 是 DeepLab 系列中的第三代…

开启AI新篇章:探索GPT-4与大模型!订阅方案!简单支付!

开启AI新篇章&#xff1a;探索GPT-4的无限可能 随着人工智能技术的飞速发展&#xff0c;我们正处于一个前所未有的变革时代。作为人工智能领域的领导者&#xff0c;OpenAI 推出的GPT-4&#xff0c;以其卓越的自然语言处理能力和强大的计算潜力&#xff0c;引发了行业内外的广泛…

【Android 14源码分析】WMS-窗口显示-流程概览与应用端流程分析

忽然有一天&#xff0c;我想要做一件事&#xff1a;去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

创建Vue项目的时出现:无法加载文件 E:\software\node\node_global\vue.ps1,因为在此系统上禁止运行脚本

创建Vue项目的时出现的问题:出现&#xff1a;无法加载文件 E:\software\node\node_global\vue.ps1&#xff0c;因为在此系统上禁止运行脚本 解决方法&#xff1a; .PowerShelll的执行政策阻止了该操作,用 get-ExecutionPolicy 查看执行策略的状态为受限 输入Set-ExecutionPo…

【STM32开发之寄存器版】(二)-USART

一、前言 串口作为STM32的重要外设&#xff0c;对程序调试具有不可替代的作用。通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。其主要具备以下特性&am…

CSP-J模拟赛四补题报告

前言 T1: 100 p t s \color{green}100pts 100pts T2: 100 p t s \color{green}100pts 100pts T3: 20 p t s → 5 p t s \color{red}20pts\rightarrow5pts 20pts→5pts T4: 20 p t s \color{red}20pts 20pts T1,2秒了&#xff0c;T3&#xff0c;4死了 T1 三个(three) 题面…

数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall

数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall 数据集-目标检测系列- 货船 检测数据集 freighter>> DataBall 数据量&#xff1a;3k 想要进一步了解&#xff0c;请联系。 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种…

SQL优化 - 排序

文章目录 排序和索引降序索引 FilesortORDER BY 顺序问题ORDER BY LIMIT 排序和索引 如果ORDER BY操作使用了索引&#xff0c;那么就可以避免排序操作&#xff0c;因为索引本身就是按索引 key 排好序的。那什么情况下&#xff0c;ORDER BY会走索引呢&#xff1f; 例如&#…

阿里云域名注册购买和备案

文章目录 1、阿里云首页搜索 域名注册2、点击 控制台3、域名控制台 1、阿里云首页搜索 域名注册 2、点击 控制台 3、域名控制台

【08】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-Scroll容器与Tabs组件

序言&#xff1a; 本文详细讲解了关于我们在页面上经常看到的可滚动页面和导航栏在鸿蒙开发中如何用Scroll和Tabs组件实现&#xff0c;介绍了Scroll和Tabs的基本用法与属性。 笔者也是跟着B站黑马的课程一步步学习&#xff0c;学习的过程中添加部分自己的想法整理为笔记分享出…

【漏洞复现】泛微OA E-Office do_excel.php 任意文件写入漏洞

》》》产品描述《《《 泛微0-0fice是一款标准化的协同 OA办公软件&#xff0c;泛微协同办公产品系列成员之一,实行通用化产品设计&#xff0c;充分贴合企业管理需求&#xff0c;本着简洁易用、高效智能的原则&#xff0c;为企业快速打造移动化、无纸化、数字化的办公平台。 》》…

深度学习:基于MindSpore实现CycleGAN壁画修复

关于CycleGAN的基础知识可参考&#xff1a; 深度学习&#xff1a;CycleGAN图像风格迁移转换-CSDN博客 以及MindSpore官方的教学视频&#xff1a; CycleGAN图像风格迁移转换_哔哩哔哩_bilibili 本案例将基于CycleGAN实现破损草图到线稿图的转换 数据集 本案例使用的数据集里…

【含文档】基于Springboot+Vue的护肤品推荐系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…