从0到1学习Qt -- Qt3D入门

下面这篇文章会详细介绍Qt3D相关的知识

1.示例演示

我们现在Qt的欢迎搜索qt3D,选择第一排的第四个演示示例,我们会根据这个示例来学习Qt3D相关的知识。

2. 代码分析

2.1. .pro文件

我们看到第九行内容为 QT += 3dcore 3drender 3dinput 3dextras这是Qt3D项目中4哥关键的模块。

2.1.1. Qt3DCore

是Qt3D中的基础架构和核心系统

一. 核心架构 - 实体组件系统(ECS)

1.QEntity - 实体

实体是3D场景的基本构建块,本身不包含功能,通过附加组件来获得行为.

在代码示例中有关实体的代码:

  1. QCompoent - 组件

组件为实体提供具体的功能,实体本身是不可见的你要为实体加上相关的组件,才可在界面上显示你想要的相关内容,一个组件可以提供几何形状、材质、变换、灯光、相机。

同时要注意的是QCompoent是一个抽象基类,本身不可以实例化出QCompoent对象,相关具体的几何类型是通过继承QCompoent得到的。

QCompoent的职责:

a.功能化模块:通过将不同的功能封装成组件,实体可以灵活地组合这些组件来实现复杂的行为。

b.数据共享:多个实体可以共享同一个组件实例

c.生命周期管理:组件的创建和销毁与实体绑定,当实体被删除时,其上的组件也会被清理。

cpp 复制代码
// QComponent是所有组件的抽象基类
class Q_COMPONENTS_EXPORT QComponent : public Qt3DCore::QNode {
    Q_OBJECT
public:
    explicit QComponent(Qt3DCore::QNode *parent = nullptr);
    virtual ~QComponent();
    
    // 核心功能:管理组件与实体的关联
    Qt3DCore::QEntity *entity() const;
    void setEntity(Qt3DCore::QEntity *entity);
    
    // 组件类型标识
    enum ComponentType {
        TransformComponent,      // 变换组件
        GeometryRendererComponent, // 几何体渲染组件
        MaterialComponent,       // 材质组件
        CameraComponent,         // 相机组件
        LightComponent,          // 光源组件
        UserComponent = 1000     // 自定义组件起始值
    };
    virtual ComponentType componentType() const;
};

3.QNode - 节点基类

所有Qt3D对象的基类,提供父子关系和属性系统。

二. 变换系统

1.QTransform - 变换组件

QTransform用来管理实体的位置、旋转和缩放,继承自QCompoent,在示例代码中:

  1. 变换层次结构

举个例子:为父实体的组件设置相关属性之后为继承子父实体的子实体设置不同的变化属性

cpp 复制代码
Qt3DCore::QEntity *parent = new Qt3DCore::QEntity();
Qt3DCore::QTransform *parentTransform = new Qt3DCore::QTransform();
parentTransform->setTranslation(QVector3D(5, 0, 0));
parent->addComponent(parentTransform);

// 子实体的变换相对于父实体
Qt3DCore::QEntity *child = new Qt3DCore::QEntity(parent);
Qt3DCore::QTransform *childTransform = new Qt3DCore::QTransform();
childTransform->setTranslation(QVector3D(0, 3, 0)); // 实际世界位置:(5, 3, 0)
child->addComponent(childTransform);

三. 动画系统

  1. 属性动画

属性动画是通过插值计算,随时间改变Qt对象属性的机制。它允许你平滑地修改任Q_PROPERTY的值。

示例:

cpp 复制代码
// 简单示例:让立方体从A点移动到B点
Qt3DCore::QTransform *transform = new Qt3DCore::QTransform();
transform->setTranslation(QVector3D(0, 0, 0));  // 起点

// 创建属性动画 -- 这里将transform传递进来只是设置父节点
Qt3DCore::QPropertyAnimation *animation = new Qt3DCore::QPropertyAnimation(transform);
animation->setTargetObject(transform);         // 目标对象
animation->setPropertyName("translation");     // 要动画化的属性
animation->setDuration(2000);                  // 持续时间2秒

// 设置动画值
animation->setStartValue(QVariant::fromValue(QVector3D(0, 0, 0)));
animation->setEndValue(QVariant::fromValue(QVector3D(10, 0, 0)));

animation->start();  // 开始动画
// 立方体会在2秒内从(0,0,0)平滑移动到(10,0,0)

2.1.2. Qt3DRender

Qt3DRender模块是Qt3D中负责渲染的核心模块,它提供了底层的渲染API抽象,渲染管线,材质系统,着色器管理,几何体处理,纹理和帧缓冲功能。

一.核心架构:渲染管线与帧图

1.帧图(Frame Graph)概念

帧图是Qt3DRender的核心,定义了渲染过程的流程和状态。它是一个有向无环图,节点控制渲染的各个方面。通俗一点说:你使用Qt3D来渲染某个特定的场景的时候,帧图就是对这个渲染过程的描述,描述在该帧的时候场景的各种属性。

代码示例:

cpp 复制代码
// 创建基本帧图
Qt3DRender::QRenderSettings *renderSettings = new Qt3DRender::QRenderSettings();

// 帧图根节点
Qt3DRender::QRenderSurfaceSelector *surfaceSelector = new Qt3DRender::QRenderSurfaceSelector();
surfaceSelector->setSurface(window);  // 渲染到哪个窗口

Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport(surfaceSelector);
viewport->setNormalizedRect(QRectF(0, 0, 1, 1));  // 整个视口

Qt3DRender::QCameraSelector *cameraSelector = new Qt3DRender::QCameraSelector(viewport);
cameraSelector->setCamera(m_camera);  // 指定使用哪个相机

// 清空缓冲区
Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers(cameraSelector);
clearBuffers->setBuffers(Qt3DRender::QClearBuffers::ColorDepthBuffer);
clearBuffers->setClearColor(QColor(QRgb(0x4d4d4f)));

// 设置活动帧图
renderSettings->setActiveFrameGraph(surfaceSelector);
rootEntity->addComponent(renderSettings);

二.材质系统

1.材质的理解

在Qt3D中,材质决定了3D对象的外观,包括颜色,纹理,光照反应等。材质系统是Qt3DRender模块的一部分,它基于着色器程序和渲染状态来定义物体的视觉属性。

简单理解:材质 = 物体的 "皮肤" 或 "外表"

cpp 复制代码
// 没有材质:物体不可见(只有形状)
Qt3DCore::QEntity *entity = new Qt3DCore::QEntity();
entity->addComponent(mesh);  // 只有网格 → 看不见!

// 加上材质:物体可见(有颜色、纹理)
Qt3DRender::QMaterial *material = new Qt3DExtras::QPhongMaterial();
material->setDiffuse(QColor(255, 0, 0));  // 红色
entity->addComponent(material);  // 现在可见了!
  1. 材质层次结构

三. 着色器系统

着色器的简单理解

着色器 = 运行在GPU上的小程序,它告诉显卡如何绘制每个像素

cpp 复制代码
// 类比:绘画过程
画家(CPU)说:"画一个红色的球"
助理(GPU)问:"怎么画?"
着色器说:"按这个规则画:1.确定形状 2.涂红色 3.加高光"

着色器这个方面难度有点大在后面再详细介绍

2.1.3. Qt3DInput

Qt3DInput模块是用于处理3D场景的输入事件,比如鼠标,键盘和游戏手柄。它允许用户与3D对象进行交互。

  1. Qt3DInput的简单理解

Qt3DInput = 让3D场景能和用户的鼠标和键盘交互起来的模块

cpp 复制代码
// 没有Qt3D Input:3D场景是静态的,不能交互
// 有Qt3D Input:可以点击物体、旋转视角、键盘控制移动

Qt3DCore和Qt3DRender和Qt3DInput的类比

cpp 复制代码
Qt3D Core:搭建舞台和演员
Qt3D Render:给演员化妆、打灯光
Qt3D Input:让观众能和演员互动

2.Qt3DInput的三种主要的输入设备

cpp 复制代码
#include <Qt3DInput/QInputAspect>

// 1. 鼠标设备(处理鼠标事件)
Qt3DInput::QMouseDevice *mouse = new Qt3DInput::QMouseDevice();

// 2. 键盘设备(处理键盘事件)
Qt3DInput::QKeyboardDevice *keyboard = new Qt3DInput::QKeyboardDevice();

// 3. 游戏手柄设备(可选)
// Qt3DInput::QGamepadDevice *gamepad = new Qt3DInput::QGamepadDevice();

2.1.4. Qt3DExtras

Qt3DExtras提供了许多预定义的组件和实体,包括:

基本几何体(立方体,球体,圆柱体等)

材质(如QPhongMaterial,QDiffuseMapMaterial等)

相机控制器(如QOrbitCameraConreoller,QFirstPersonCameraController等)

其他辅助类(如QSkyboxEntity,QForwardRender等)

可以帮助我们快速的搭建3D场景。

相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner12 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00614 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术14 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript