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

基于之前做的项目图形移动处理-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);

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

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

相关推荐
希望_睿智6 分钟前
实战设计模式之建造者模式
c++·设计模式·架构
@曲终39 分钟前
C++:栈帧、命名空间、引用
java·开发语言·c++·经验分享·笔记
強云43 分钟前
原子操作(C++)
c++
敲代码的瓦龙1 小时前
C++?多态!!!
c语言·开发语言·c++·windows·后端
我不是程序猿儿1 小时前
【C++】C++面向对象设计的核心思想之一: 接口抽象、解耦和可扩展性
java·开发语言·c++
~山有木兮2 小时前
new和delete的理解
c++·算法
whoarethenext2 小时前
使用 C/C++ 和 OpenCV 调用摄像头
c语言·c++·opencv
Dovis(誓平步青云)3 小时前
探索C++标准模板库(STL):从容器到底层奥秘-全面解析String类高效技巧(上篇)
开发语言·c++·stl·string
wheeldown3 小时前
【C++】STL详解(四)---Stack和Queue
开发语言·c++
✿ ༺ ོIT技术༻3 小时前
笔试强训:Day6
数据结构·c++·算法