Qt3D绘制旋转立方体

近期用了款叫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
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

telllong

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值