案例06:大球自转+小球公转+移动

简介: 大球自转+小球公转+移动

这个案例是OpenGL中的一个比较经典的综合案例,结合了OpenGL中大部分知识点,下面就来了解下这个案例


先来看看最终的效果

微信图片_20220513235607.png

整体的流程的如下

微信图片_20220513235747.png


其中,比较重要的逻辑都在以下三个函数中


  • SetupRC函数
  • RenderScene函数
  • SpecialKeys函数


下面来详细说说整体的效果的实现,可以大致分为4部分


  • 地板
  • 大球(自转)
  • 小球(包含50个静态小球+1个围绕大球公转的动态小球)
  • 移动(特殊键位上下左右触发)


准备工作


流程图中的ChangeSize、main函数,这里就不作过多说明,相信大家对这两个函数已经印象非常深刻,如果还有不明白的,可以结合案例 03:金字塔、六边形、圆环的绘制先了解下这两个函数中到底做了哪些工作


地板


  • SetupRC函数:准备地板的顶点数据
  • RenderScene函数:利用平面着色器绘制地板


两个函数此时的流程图大致如下

微信图片_20220513235952.png

大球


在地板绘制完成的基础上,绘制大球,并实现其自转功能,主要步骤如下


  • SetupRC函数:利用系统模型类创建大球
  • RenderScene函数:分为三部分
  • 设置定时器:基于时间的变化,记录当前时间的角度
  • 设置大球变换(仅平移一次,并随定时器旋转)及绘制大球
  • 开启定时器:通过提交重新渲染请求,实现定时器触发的效果


两个函数的流程图如下,图中红框部分流程均与大球相关

微信图片_20220514000138.png

大球变换


大球变换的代码如下

    //5.使得大球位置平移(3.0)向屏幕里面
    modelViewMatrix.Translate(0.0f, 0.0f, -3.0f);
    //6.压栈(复制栈顶)
    modelViewMatrix.PushMatrix();
    //7.大球自转
    modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);


  • Translate:目的是为了更好的观察的大球,因为大球创建时默认是在(0,0,0)原点位置,当前的观察者也处于原点位置,不便于观察
  • PushMatrix:拷贝矩阵堆栈栈顶并压栈,此时只需要将大球平移一次,然后在平移后坐标基础上围绕y轴旋转,实现自转
  • Rotate:大球围绕y轴旋转,实现自转


自转的原理


仅为个人理解:可以将时间看作一个圆,大球映射到xoy平面上其实也是一个圆,然后基于时间的变化所得到的的角度,在大球的映射圆中也是同样的角度,然后大球基于上次的角度,再继续旋转α的角度,每360度是一个循环,以此来实现大球自转

微信图片_20220514000349.png


小球


在绘制完大球的基础上,继续绘制小球


  • SetupRC函数:初始化小球数据
  • RenderScene函数:绘制静态+动态小球
  • 绘制50个静态小球:每绘制一个小球都需要push和pop
  • 矩阵堆栈记录平移+旋转的变换
  • 绘制动态小球


此时两个函数的流程图如下:

微信图片_20220514000528.png


小球公转


其实小球的公转可以理解为: 自转+平移,如果只有rotate变换,那么小球就是在原地围绕y轴自转,但是此时大球跟小球是处于同一个位置的,为了更好的观察,需要将小球平移,与大球之间有一定的间隔,且每次旋转,小球旋转的角度是大球的两倍,意味着小球比大球转的快,公转原理如图所示

微信图片_20220514000730.png

  • 注:这里的rotate+tranalate的顺序是不能互换的,因为矩阵相乘是叉乘,不满足交换律,详细的可参考八、了解OpenGL中的向量、矩阵其中的模型变换部分有提到,如果互换了得到的是另一种结果,经过测试,如果顺序是tranalate+rotate,此时的小球是县移动后旋转,意味着小球位置变换后,是在原地实现的自转。具体的可以自己修改代码试试。


移动


到这步,主要的功能都基本实现了,只需要在增加特殊键位的移动即可,此时的移动是作用于所有图形的,所以需要在绘制图形前增加一个观察者,用于记录所有图形的变换


此时,项目中setupRc、RenderScene、SpecialKeys总的流程图如下

微信图片_20220514000911.png


到此,这个综合项目就完成啦。

相关文章
|
2天前
|
前端开发 小程序 API
技术心得记录:小程序—九宫格心形拼图
技术心得记录:小程序—九宫格心形拼图
|
1月前
|
存储
面试题 05.08:绘制直线
面试题 05.08:绘制直线
25 0
|
9月前
|
移动开发 前端开发 JavaScript
74行代码实现浪漫的红心下落的动画效果
74行代码实现浪漫的红心下落的动画效果
74行代码实现浪漫的红心下落的动画效果
求小球下落弹起的高度与路程
求小球下落弹起的高度与路程
80 0
|
小程序
做个经典宝石方块游戏
在做了一个月的进阶课程之后,终于又可以回来做游戏了。不得不说,对于我来讲做课程要比做游戏的难的多。做出来是一回事儿,讲出来又是另一回事儿了。尤其是还希望能讲的明白,讲的浅显易懂,感觉还是很难的。不过还好,做课程这件事情也是可以练习的,比如说我现在面对镜头讲一个东西的时候,就比一年前要好很多了。
114 0
|
前端开发 JavaScript
使用html+css+JavaScript制作抛物线小球
使用html+css+JavaScript制作抛物线小球
101 0
140.递归法绘制三角形图案
140.递归法绘制三角形图案
64 0
|
机器学习/深度学习 算法
第四周:循环
所谓循环,就是多次重复执行某些类似的操作,这个操作一般不是完全一样的操作,而是类似的操作。都有哪些操作呢?通过阅读这篇文章来体会一下吧
68 0
|
C++
201803-2 碰撞的小球
201803-2 碰撞的小球
69 0
201803-2 碰撞的小球
|
前端开发 JavaScript
使用konvajs三步实现一个小球游戏
使用konvajs三步实现一个小球游戏
260 0
使用konvajs三步实现一个小球游戏