学习OpenglES大概一个月的时间了,现在回头复习下,顺便写点东西整理下知识。刚开始学的时候一头雾水,磕磕绊绊将就学下来,学OpenglES最重要的就是对概念和流程的理解了,要是直接拿代码去学,根本啥都看不懂。对于第二遍的学习,记录下自己的理解,方便大家交流和自己理解。
简介
简介这不多写了,百度好多,简单的来说Opengl是一种跨平台的编程语言。可以对图形硬件设备访问的软件库,显卡基本都支持Opengl,可能有些版本的不同。OpenglES是针对移动设备,手机游戏机等。OpenglES可以用于绘制3D图形,提高渲染效率,图像的处理。
CPU和GPU
OpenglES主要通过GPU绘制图形,下面是CPU和GPU的架构图,绿色的为运算单元,黄色为控制单元,红色是缓存。
CPU和GPU它们分别针对了两种不同的应用场景。CPU需要很强的通用性来处理各种不同的数据类型,同时又要逻辑判断又会引入大量的分支跳转和中断的处理。这些都使得CPU的内部结构异常复杂。而GPU面对的则是类型高度统一的、相互无依赖的大规模数据和不需要被打断的纯净的计算环境。
GPU采用了数量众多的计算单元和超长的流水线,但只有非常简单的控制逻辑并省去了Cache。而CPU不仅被Cache占据了大量空间,而且还有有复杂的控制逻辑和诸多优化电路,相比之下计算能力只是CPU很小的一部分
opengl的渲染流程
这里不具体写OpenglES如何编写,先介绍大体的流程和用处,OpenglES目前分为三个版本,OpenglES1.0(固定管线),2.0(可编程管线),3.0(在2.0的基础上扩展),这里我用的是2.0。
图形渲染的基本单位就是点,两个点之间用点渲染成线,三个点之间渲染成面,一个面就是由一个或多个三角形组成,3D物体就是由许许多多的三角形拼接而成。渲染完图形的框架后,可以在每个点上添加颜色,或者加上图片对应点的颜色,看起来就是一个完整的物体了。在绘制时,简单的图形我们可以自己定义,复杂的需要用工具导出数据,这些数据包括顶点信息、纹理信息、法线信息,这里的法线是用来做光照效果的,就算漫反射也是由无数个镜面反射组成的,法线就是用来计算反射角,这样的计算是由系统来做的。
关于3D,我们的手机是一个平面,所看的3D效果是由数据经过一系列的矩阵变换,投影到平面上展示的。移动、平移、缩放,矩阵的变换是不可缺少的。
图像顶点数据到显示结果有几个大体的过程
顶点数据:buffer是放置数据的地方,老外起的名字
顶点着色器:顶点数据传递给着色器,着色器通过glsl对顶点进行编辑
顶点变换:顶点数据有时需要矩阵变换
图元装配:顶点信息根据画图的需要,将一些点连接起来
光栅化:连接顶点的线段上用点拼接起来,三角形填充也用点
片元着色器:将所有的点通过片元着色器填充颜色或纹理图片
运用到的一些知识
学了一个月感觉大体的流程还是比较清楚地,像大多数的程序语言一样,语法不是重点,想要绘制好看的东西,还是要靠自己的思考和勤加练习。
glsl(Opengl shading language )着色器语言,在工程里单独建立的一个文件,通过程序加载到opengl的执行程序里,分顶点着色器和片元着色器,可以操作片元的位置和颜色,大多数情况下都要依靠这两个文件,通过变量传递给着色器,在里面编写位置的变化,矩阵相称,纹理取值等。
坐标系,物体坐标系:起初的坐标系和世界坐标系是重叠的,物体移动后坐标系原点也会跟着移动。
惯性坐标系:物体坐标系原点起,坐标轴平行于世界坐标系。
世界坐标系:在空间中建立起的坐标系,默认原点在屏幕的正中央,x轴向右,y向上,z向屏幕外。
观察者坐标系:原点起,x轴和y轴和世界坐标系一致,z轴相反(向屏幕里面)。FOV是视角的大小,NEAR PLANE是近平面,FAR PLANE是远平面,物体只有在两个平面之间的椎体内,才能被看见。
向量和矩阵,在opengl中向量都是列向量(向量的书写都是从上往下),所以我们会看到在着色器中会用矩阵乘以向量,如果反过来向量乘以矩阵,是没有意义的。在文章中我们看到的向量横着写,是为了方便书写。矩阵也是特殊的向量,如果我们把一个矩阵的每一行看成一个向量
1,0,0 x轴
0,1,0 y轴
0,0,1 z轴
那么这个矩阵三个向量组成的也就是(1,1,1),矩阵和向量的相乘其实也可以看成在每个轴缩放的倍数(这只是矩阵为对角线的),如果需要旋转,会用到cos和sin,具体的计算我不写了,脑补下围绕某个轴旋转后,每个向量的取值和角度的关系,不太难。
再说一个四维向量,我们绘制的是3D物体,只有三个轴,opengl中的四维向量很多,我们上面讲到,三阶矩阵和向量相乘,只能旋转缩放,如果移动嗯,这是时候就需要再加一个w(x,y,z,w),向量的w默认为1,这样矩阵就可以把移动的距离放在第四个w中,来举个例子,x轴移动1,y轴移动2,z轴移动3,那么矩阵就是
1,0,0,1
0,1,0,2
0,0,1,3
0,0,0,1
向量的叉乘,同时垂直两个向量的向量,即c垂直于a,同时c垂直于b(a与c的夹角为90°,b与c的夹角为90°)
c = a×b = (a.y*b.z-b.y*a.z , b.x*a.z-a.x*b.z , a.x*b.y-b.x*a.y)
向量点乘,是一个向量和它在另一个向量上的投影的长度的乘积;是标量。
a * b = |a| * |b| * cosθ |a|为向量长度