图形渲染+事件处理最终版

基于之前做的项目图形移动处理-CSDN博客添加了相机,透视投影,鼠标控制图形旋转。虽然个人感觉这个项目用的是一个二维的三角形,给他加透视投影和相机意义不大,因为透视投影是近大远小,我这个程序设置了放大缩小的限制,说实话,理论上加没加看不出去别来,只是为了实践一下,并且是通过鼠标让三角形旋转,也不需要再设置相机绕着三角形看不同角度,视觉上是一样的。后面改用三维度图形才会有区别。这里就讲讲相对于之前的项目新添加到功能吧。

三角形旋转事件

我设计的这个是根据鼠标横向/纵向移动,使得三角形绕y轴/x轴旋转。

添加的成员变量
复制代码
//旋转参数
    QVector3D m_rotationangles;//三维向量,存放x,y,z轴旋转角度
    bool m_isrotating;
    QPoint m_lastmousepos;

|------------------|----------------------------|
| m_rotationangles | 是一个三维向量,里面存放着绕x,y,z轴旋转的角度。 |
| m_isrotating | 旋转状态 |
| m_lastmousepos | 记录上一次鼠标停留的坐标 |

在构造函数中初始化m_rotationangles为一个{0,0,0}的向量矩阵,m_isrotating为false

复制代码
myWediget::myWediget(QWidget *parent) : QOpenGLWidget(parent) {
    setFocusPolicy(Qt::StrongFocus);
    m_rotationangles=QVector3D(0,0,0);//初始化为000
    m_isrotating=false;//初始化旋转状态
}
鼠标事件加入

我们设计他的逻辑是鼠标左键按下以后,m_lastmousepos会记录鼠标的当前位置,然后鼠标拖动,用现在鼠标的位置-上次鼠标的位置得到的是一个移动路径的向量,注意这里操作角度用的数据都是向量,然后更新旋转矩阵{x,y,z},绕x轴正向旋转就是m_rotationangles.x()+delta.y()*0.5f,为什么加的是delta的y,可以试着想一下,想让三角形绕x轴旋转不就是用鼠标向上向下移动。

复制代码
//鼠标按下事件
void myWediget::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton){
        m_isrotating=true;//开始旋转
        m_lastmousepos=event->pos();//获取鼠标位置
        event->accept();
    }
}

//鼠标松开事件
void myWediget::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton){
        m_isrotating=false;
        event->accept();
    }
}

//鼠标移动事件
void myWediget::mouseMoveEvent(QMouseEvent *event)
{
    if(m_isrotating){
        QPoint delta=event->pos()-m_lastmousepos;
        m_rotationangles.setX(m_rotationangles.x()+delta.y()*0.5f);//绕x轴旋转
        m_rotationangles.setY(m_rotationangles.y()+delta.x()*0.5f);//绕y轴旋转
        m_lastmousepos=event->pos();
        update();
        event->accept();
    }
}

把旋转矩阵传入绘制函数逐帧绘制,在原有基础上加几句就行了

复制代码
transform.rotate(m_rotationangles.x(),1,0,0);
transform.rotate(m_rotationangles.y(),0,1,0);
transform.rotate(m_rotationangles.z(),0,0,1);

前面第一个参数是旋转矩阵的对应轴的参数,后面是要绕哪个轴旋转就把他设置为1,到这里功能就完成了,为啥没设置shader,我之前的项目中transform就是专门用来处理三角形运动的uniform,之前是只有移动和缩放,缩放建议最后处理,不然有些问题。

透视投影和相机

另外两个带一嘴吧,透视投影是近大远小的效果,绘画让三位图形比较立体

复制代码
//设置透视投影
     QMatrix4x4 projection;
     projection.perspective(45.0f,(float)w/h,0.1,100.0f);
     sdprogram.bind();
     sdprogram.setUniformValue("projection",projection);
     sdprogram.release();

projection.perspective(45.0f,(float)w/h,0.1,100.0f);第一个参数是视角,可以理解为你眼睛张多大,第二个参数就是宽高比,推荐和屏幕或者视口一致,第三个最近离你多近,超过了就看不见了,第四个就是最远离你有多远,超出了就看不见了,就是模拟你眼睛。

再就是相机,相机 是有一个自己的坐标系的,镜头指向的方向是自己坐标系z轴的正方向

复制代码
// 视图矩阵(相机后移3单位)
    QMatrix4x4 view;
    view.translate(0, 0, -3.0f);

我这里就把他后移了三个单位,十分简陋,因为设置了和没设置没区别,就懒得设置他了,我这是不是有些敷衍哈哈。

就这样,程序大功告成,展示最终效果

相关推荐
Hxyle7 分钟前
c++设计模式
开发语言·c++·设计模式
www_pp_32 分钟前
# 创建一个功能完备的计算器应用:使用PyQt5和Python
开发语言·python·qt
神仙别闹1 小时前
基于QT(C++)实现(图形界面)校园导览系统
数据库·c++·qt
明月看潮生1 小时前
青少年编程与数学 02-018 C++数据结构与算法 25课题、图像处理算法
c++·图像处理·算法·青少年编程·编程与数学
我是一只鱼02231 小时前
LeetCode算法题 (反转链表)Day17!!!C/C++
数据结构·c++·算法·leetcode·链表
菜鸟破茧计划2 小时前
C++ 算法学习之旅:从入门到精通的秘籍
c++·学习·算法
喜欢吃燃面2 小时前
C++:扫雷游戏
c语言·c++·学习
海木漄2 小时前
关于点胶机的精度
c++·点胶机
yunbao00_3 小时前
C++ 复习(一)
开发语言·c++
vvilkim3 小时前
C++并发编程完全指南:从基础到实践
c++