Qt3D绘制旋转立方体

news2024/12/28 3:21:32

近期用了款叫DesktopSpace,也想实现一下这款软件实现的效果
具体实现步骤:

  1. 使用Qt3D绘制个旋转的立方体(一)
  2. 使用快捷键控制立方体显示面(二)
  3. 创建6个人虚拟桌面,截取不同虚拟桌面,显示在不同的面上 (三)
  4. 在立方体上播放视频

首先用Qt3D绘制一下桌面截图旋转的效果

Qt3D简单介绍

Qt 3D 是一个用于创建交互式 3D 图形应用程序的框架。它提供了一组类和函数,用于创建、渲染和操作 3D 场景。Qt 3D 在 Qt c++ 和 Qt Quick 应用程序中支持 2D 和 3D 渲染,为近实时仿真系统提供了功能。

以下是 Qt 3D 中一些常用的类说明和代码流程:

Qt3DCore:这是 Qt 3D 框架的核心模块,包含了一些基本类和接口,用于构建 3D 场景和实体。其中一些重要的类包括:

QEntity:表示 3D 场景中的实体,可以添加组件和子实体。
QTransform:表示实体的变换信息,用于控制实体的位置、旋转和缩放等属性。
Qt3DRender:这个模块主要用于渲染图形对象,包括定义材质、纹理和着色器等。其中一些重要的类包括:

QMaterial:表示实体的材质,包含了表面属性、纹理和渲染状态等。
QEffect:定义了渲染效果的着色器程序。
QTexture:表示纹理,可以加载图像并应用于材质。
Qt3DInput:这个模块用于处理用户输入(例如鼠标和键盘事件),以及与用户交互的功能。其中一些重要的类包括:

QMouseDevice:用于监听和处理鼠标事件。
QKeyboardDevice:用于监听和处理键盘事件。

下面是一个简单的 Qt 3 D 代码流程示例,展示了如何创建一个带有实体、材质和变换的场景:

#include <Qt3DCore/QEntity>   
#include <Qt3DRender/QMaterial>   
#include <Qt3DRender/QEffect>   
#include <Qt3DRender/QTexture>   
#include <Qt3DCore/QTransform>   
  
int main(int argc, char** argv) {  
    QApplication app(argc, argv);  
    // 创建场景根实体  
    Qt3DCore::QEntity sceneRoot;  
    // 创建一个实体  
    Qt3DCore::QEntity* entity = new Qt3DCore::QEntity(&sceneRoot);  
    // 创建材质  
    Qt3DRender::QMaterial* material = new Qt3DRender::QMaterial(entity);  
    // 创建纹理  
    Qt3DRender::QTexture2D* texture = new Qt3DRender::QTexture2D(material);  
    // 设置纹理属性  
    // 创建效果  
    Qt3DRender::QEffect* effect = new Qt3DRender::QEffect();  
    // ...  
}

这个示例只是 Qt 3 D 的一个简单应用,如果需要更深入了解和使用 Qt 3 D ,建议阅读官方文档和相关教程。

绘制旋转立方体

主函数

#include "cubewidget.h"
#include <Qt3DExtras/QTextureMaterial>
#include <QImage>
#include <QApplication>
#include <QWidget>
#include <QHBoxLayout>
#include <QLabel>
#include <QCheckBox>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DExtras/QForwardRenderer>
#include <QTimer>
#include <Qt3DRender/QCamera>
#include <Qt3DCore/QComponent>
#include <Qt3DRender/QTextureImage>
#include <Qt3DRender/QTexture>
#include <QMatrix3x3>
#include <QRenderSurfaceSelector>
#include <QImage>
#include "rotatorutil.h"
#include "rotator.h"
#include "hotkeymanager.h"
#include "mymaterialimage.h"
#include "lazyutil.h"

#include "animationutil.h"

CubeWidget::CubeWidget(QWidget *parent)
    : QWidget{parent}
{
    // 创建3D窗口
    Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();
    view->defaultFrameGraph()->setClearColor(QColor(210, 210, 220, 0));
    view->setTitle("Qt3D C++ example: rotate cube");

    // 创建一个容器小部件和窗口布局
    QWidget *container = QWidget::createWindowContainer(view);
    container->setAttribute(Qt::WA_TranslucentBackground, true);

    QHBoxLayout *layout = new QHBoxLayout();
    layout->addWidget(container, 1);

    // 创建一个用于窗口的小部件并设置其布局
    setLayout(layout);

    // 创建场景的根实体
    Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();

    // 创建相机实体并设置其位置和视图中心
    Qt3DRender::QCamera *cameraEntity = view->camera();
    cameraEntity->setPosition(QVector3D(10.0f, 0, 0.0f));
    cameraEntity->setViewCenter(QVector3D(0, 0, 0));

    // 创建立方体实体并添加立方体网格组件和冯氏材质组件
    Qt3DCore::QEntity *cubeEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DExtras::QCuboidMesh *cubeMesh = new Qt3DExtras::QCuboidMesh();
    cubeMesh->setXExtent(5.1f);
    cubeMesh->setYExtent(3.23f);
    cubeMesh->setZExtent(5.1f);

//    cubeMesh->setXYMeshResolution(QSize(300, 100));
//    cubeMesh->setXZMeshResolution(QSize(300, 100));
//    cubeMesh->setYZMeshResolution(QSize(100, 100));

    auto *image = new MyQPaintedTextureImage;
    image->setImage(LazyUtil::Instance()->grabScreenImage());
    auto *cubeMaterial = new Qt3DExtras::QTextureMaterial;
    cubeMaterial->texture()->addTextureImage(image);
#ifdef USE_OCV
    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, image, &MyQPaintedTextureImage::updateImage);
    timer->start(50); // 1000毫秒刷新一次
#endif
    // 将立方体网格组件和冯氏材质组件添加到立方体实体
    cubeEntity->addComponent(cubeMesh);
    cubeEntity->addComponent(cubeMaterial);

    // 创建一个变换组件并将其添加到立方体实体
    Qt3DCore::QTransform *transform = new Qt3DCore::QTransform();
    cubeEntity->addComponent(transform);

#if 1
    // 定时旋转
    Rotator *rotator = new Rotator();
    QObject::connect(rotator, &Rotator::rotationChanged, transform, &Qt3DCore::QTransform::setRotation);
#else
    // 快捷键旋转
    RotatorUtil *rotator = new RotatorUtil();
    QObject::connect(rotator, &RotatorUtil::rotationChanged, transform, &Qt3DCore::QTransform::setRotation);

    QObject::connect(HotkeyManager::Instance(), &HotkeyManager::angleHorizontalChanged, rotator, &RotatorUtil::updateAngleHorizontal);
    HotkeyManager::Instance()->registerLeftRotateHotkey(rotator);
    HotkeyManager::Instance()->registerRightRotateHotkey(rotator);

    QObject::connect(HotkeyManager::Instance(), &HotkeyManager::angleVerticalChanged, rotator, &RotatorUtil::updateAngleVertical);
    HotkeyManager::Instance()->registerTopRotateHotkey(rotator);
    HotkeyManager::Instance()->registerBottomRotateHotkey(rotator);

    QObject::connect(HotkeyManager::Instance()->getWorker(), &RotateWorker::angleHorizontalChanged, rotator, &RotatorUtil::updateAngleHorizontal);
    QObject::connect(HotkeyManager::Instance()->getWorker(), &RotateWorker::angleVerticalChanged, rotator, &RotatorUtil::updateAngleVertical);
#endif

    // 设置窗口的根实体
    view->setRootEntity(rootEntity);

    setAttribute(Qt::WA_TranslucentBackground, true);

    AnimationUtil::AnimationSmaller(this);
}

动画控制类

#ifndef ROTATOR_H
#define ROTATOR_H

#include <Qt3DCore/QComponent>
#include <QTimer>
#include <QVector3D>
#include <QQuaternion>

// A custom component that controls the rotation of an entity
class Rotator : public Qt3DCore::QComponent
{
    Q_OBJECT
public:
    Rotator(Qt3DCore::QNode *parent = nullptr)
        : Qt3DCore::QComponent(parent)
        , m_angle(0.0f)
    {
        // Create a timer to update the angle every 10 ms
        QTimer* timer=new QTimer(this);
        connect(timer, &QTimer::timeout, this, &Rotator::updateAngle);
        timer->start(10);
    }

    // A function to get the current rotation as a quaternion
    QQuaternion rotation() const
    {
        // Calculate the rotation axis as the cross product of the up vector and the forward vector
        QVector3D axis = QVector3D(0.0f, 1.0f, 0.0f)
                             .crossProduct(QVector3D(0.0f, -1.0f, 0.0f),
                                           QVector3D(-1.0f, 0.0f, 1.0f));

        // Normalize the axis
        axis.normalize();

        // Return the rotation as a quaternion
        return QQuaternion::fromAxisAndAngle(axis, m_angle);
    }

private slots:
    // A slot to update the angle by 1 degree
    void updateAngle()
    {
        // Increment the angle by 1 degree
        m_angle += 0.2f;

        // Wrap the angle to [0, 360) range
        if (m_angle >= 360.0f) {
            m_angle -= 360.0f;
        }

        // Emit a signal to notify the change of rotation
        emit rotationChanged(rotation());
    }

signals:
    void rotationChanged(const QQuaternion &rotation);

private:
    float m_angle; // The angle of rotation in degrees
};

#endif // ROTATOR_H

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

15、SpringCloud -- 延迟消息、异步下单失败处理方案

目录 延迟消息需求理解:思路:代码:发送延迟消息消费延迟消息:1、订单支付状态:2、回补真实库存:3、回补预库存:4、修改本地标识:测试:清除MQ数据:期望结果:实际结果:问题:异步下单失败需求1:代码:发送消息:消费消息:测试:需求2:延迟消息 需求理解: 用户成…

从制造到创造:揭示中国制造的基础瓶颈及其突破

中国制造的产品遍布全球&#xff0c;但很多人认为中国制造的产品缺乏基础&#xff0c;这是为什么呢&#xff1f;本文将从制造的基础入手&#xff0c;探讨中国制造缺乏基础的原因。 一、制造的基础 制造的基础是工艺&#xff0c;工艺的基础包括三个方面&#xff1a;基础材料的研…

如何将word格式的文档转换成markdown格式的文档

如何将word格式的文档转换成markdown格式的文档 前言 A. 介绍Markdown和Word格式文档 什么是Markdown&#xff1f; Markdown是一种轻量级标记语言&#xff0c;旨在简化文本格式化和排版的过程。它以纯文本形式编写&#xff0c;通过使用简单的标记语法&#xff0c;使文档更具…

HarmonyOS开发:基于http开源一个网络请求库

前言 网络封装的目的&#xff0c;在于简洁&#xff0c;使用起来更加的方便&#xff0c;也易于我们进行相关动作的设置&#xff0c;如果&#xff0c;我们不封装&#xff0c;那么每次请求&#xff0c;就会重复大量的代码逻辑&#xff0c;如下代码&#xff0c;是官方给出的案例&am…

0003net程序设计-net旅游景点推荐系统

文章目录 摘 要目录系统设计开发环境 摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#…

【IDEA】设置sql提示

第一步&#xff1a;注入SQL语言 1.首先选择任意一条sql语句&#xff0c;右击&#xff0c;选择 ‘显示上下文操作’ 2.选择 ‘注入语言或引用’ 3. 往下翻&#xff0c;找到MySQL 第二步&#xff1a;配置MySQL数据库连接 1.首先点击侧边的数据库&#xff0c;再点击上面的加号 2…

antv/g6使用教程及图配置

介绍 G6 是一款由蚂蚁金服 AntV 团队开发的 JavaScript 图形引擎&#xff0c;用于构建各种交互式可视化图形&#xff0c;包括但不限于图表、网络拓扑图、关系图、流程图等。无论是数据分析、决策支持&#xff0c;还是信息可视化&#xff0c;G6 都是一个强大的工具。 以下是 G…

python采集电商jd app商品详情数据(2023-10-30)

一、技术要点&#xff1a; 1、cookie可以从手机app端用charles抓包获取&#xff1b; 2、无需安装nodejs&#xff0c;纯python源码&#xff1b; 3、商品详情接口为&#xff1a;functionId "wareBusiness"&#xff1b; 4、clientVersion "10.1.4"同…

自学C语言的最恐怖的地方是什么?

自学C语言的最恐怖的地方是什么&#xff1f; 当年在网吧学C&#xff0c;人家在玩游戏&#xff0c;我在敲代码&#xff0c;基本上从9点敲到1点&#xff0c;然后再开始玩游戏。。。当时不是装逼&#xff0c;就是觉得有意思&#xff0c;而且当时计算机的确是一门很高大上的职业。…

redis加入window服务及删除

1、命令redis-server.exe --service-install redis.windows.conf&#xff0c;在服务中可配置自动启动 删除redis服务&#xff0c;先停止redis服务运行&#xff0c;管理员cmd模式&#xff0c;sc delete "redis" ,

mysql 间隙锁

mysql 默认是可重复读的隔离级别&#xff0c;这种默认会有幻读&#xff0c;幻读指的什么现象呢&#xff0c;就是在同一个事物中前后两次查到的结果不一致&#xff0c;那么mysql是怎么解决幻读的呢&#xff0c;这就是mvcc mvcc 什么是mvcc呢&#xff0c;就是多版本并发控制&am…

数据结构之树(图解)

文章目录 前言一、树是什么&#xff1f;二、树的特点三、树的相关概念四、树的表示方法&#xff08;孩子兄弟表示法&#xff09;总结 前言 在学习完线性结构&#xff0c;例如顺序表、链表、栈、队列后&#xff0c;我们要开始学习一个新的数据结构----树 一、树是什么&#xf…

超全整理,Jmeter性能测试-脚本error报错排查/分布式压测(详全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能脚本error报错…

iOS 使用dsym符号化线上crash日志(ips文件)

1.获取崩溃日志 可以iphone连接mac复制当时的崩溃日志。 Xcode->Window->Devices View Device Logs 如果是testflight的崩溃是可以分享的&#xff0c;分享出来可能是ips文件。 把文件名称改成my.crash 使用脚本把新版本崩溃日志转成老版本格式 这一步不是必须的&…

c++小惊喜——stringstream

当需要读取一行字符串时&#xff0c;我们通常会有将这个字符串分开的想法 #include<iostream> #include<sstream> using namespace std;int main() {string str;getline(cin, str);stringstream ssin(str);string s[10];int cnt 0;while (ssin >> s[cnt]) …

vue实现记事本(含样式)

实现增加、删除、全删、合计功能。 html代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport&q…

中文复制到ubuntu内变为乱码

如果你将中文文本复制到 Ubuntu操作系统内后出现乱码&#xff0c;这可能是字符编码设置不正确所致。 检查终端编码设置&#xff1a; 在终端中&#xff0c;确保你的终端编码设置正确。你可以使用locale 命令来检查系统的默认编码 设置。一般来说&#xff0c;UTF-8是一种广泛支持…

【K8s】白话容器基础(二):隔离与限制

白话容器基础&#xff08;二&#xff09;&#xff1a;隔离与限制 容器与虚拟机 在上一篇文章中&#xff0c;我详细介绍了 Linux 容器中用来实现“隔离”的技术手段&#xff1a;Namespace。而通过这些讲解&#xff0c;你应该能够明白&#xff0c;Namespace 技术实际上修改了应…

如何本地部署Jellyfin影音服务器并实现在公网访问

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…

如何做好企业的设备维护和保养?报修工单管理系统软件有哪些?

随着信息化技术的飞速发展&#xff0c;企业运营的各个方面都在逐步实现信息化。设备维护作为企业运营中的重要环节&#xff0c;其可靠性对于企业的正常运营至关重要。报修工单管理系统软件作为解决这一问题的有效方案&#xff0c;已经受到业界的广泛关注。本文将从测评专家的角…