当前位置: 首页 > news >正文

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

基于之前做的项目图形移动处理-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);//初始化为000m_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);

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

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

相关文章:

  • KRaft (Kafka 4.0) 集群配置指南(超简单,脱离 ZooKeeper 集群)还包含了简化测试指令的脚本!!!
  • 线性回归算法介绍和代码例程
  • uniapp 微信小程序使用图表
  • uniapp中score-view中的文字无法换行问题。
  • MySQL的索引和事务
  • 【开源版】likeshop上门家政系统PHP版全开源+uniapp前端
  • Linux开发工具【中】
  • 《构建社交应用用户激励引擎:React Native与Flutter实战解析》
  • WiFi出现感叹号上不了网怎么办 轻松恢复网络
  • C++模板【上篇】 —详解模板基础语法
  • 构建高可用性的LVS-DR群集:实现无缝的负载均衡与故障转移
  • 58.[前端开发-前端工程化]Day05-webpack-Git安装-配置-Git命令
  • http协议理解
  • 量子密码的轻量级通信协议笔记
  • Office宏病毒钓鱼-打点突破
  • 【嵌入式开发-LCD】
  • mac连接lniux服务器教学笔记
  • 代码随想录算法训练营第60期第三十天打卡
  • QT中的网络请求
  • 【软件设计师:软件工程】11.项目管理
  • 东洋学人|滨田青陵:近代日本考古学第一人
  • 昆明阳宗海风景名胜区19口井违规抽取地热水,整改后用自来水代替温泉
  • 少年中国之少年的形塑
  • 国务院安委会办公室印发通知:坚决防范遏制重特大事故发生
  • 中国电信财务部总经理周响华调任华润集团总会计师
  • 一网红被指涉脱衣殴打霸凌事件,沈阳警方:刑拘1人,处罚5人