|
3D图形编程首先OpenGL。OpenGL的英文全称是OpenGL Graphics Library,中午名称是开发式图形库。OpenGL为程序开发人员定义了一个跨平台的图形硬件编程接口,可用于三维图像(二维亦可),功能非常强大,适用于从普通PC到大型图型工作站等计算机。它采用LGPL或者GPL许可证。在行业领域中被广泛接纳,自其诞生之日起已经催生了许多优秀的应用程序。OpenGL独立于操作系统,广泛应用在CAD、能源、娱乐、游戏开发、制造业、制药业、虚拟现实等行业。OpenGL定义的软件接口与硬件无关,具有很好的移植性,应用非常广泛。
OpenGLES是OpenGL的子集,针对手机、PAD、游戏机等嵌入式系统设计。OpenGL ES是OpenGL的裁剪版,去除了四边形、多边形等复杂图元,这些图元不是绝对必要的特性。既然决定使用OpenGL ES,就需要决定使用的OpenGL ES版本,目前主要存在的OpenGL ES有OpenGL ES 1.0/1.1、OpenGL ES 2.0,这两个版本的差异非常大。其中对重要的是OpenGL ES2.0 使用了可编程管线技术,允许开发者通过编程的方式控制顶点着色器和片元着色器,实现比OpenGL ES1.x更酷的界面效果。
1.1 3D图形学理论基础
现在,我们队OpenGL有个初步的认识了。作为图形开发人员需要了解一些3D图形学的理论,虽然这不是OpenGL初学者的必需条件。正如你知道的OpenGL已经替我们完成了几乎所有的图形处理和计算,不过,了解3D图形学相关的知识对我们理解和使用OpenGL进行开发将会大有帮助。
1.1.1 点、线段、距离
图形学中点是最基本的几何对象。为了便于描述,会把点放到坐标系中进行描述,一般利用直角坐标系来确定点的位置。例如,原点的坐标为(0,0),位于两个坐标轴相交的地方。通常,我们确定x轴为水平方向,并且x轴的正方向向右,y轴为水平方向,并且y轴的正方向向上。
直角坐标系
只是用X/Y轴表示的为2D空间,两个点P1和P2确定一条线段。假设P1和P2的坐标分别为(和 )和(和),那么它们之间的距离为:
如果在2D坐标系的基础上增加一个Z轴,即可建立3D空间。3D空间中的点需要使用三个坐标表示,根据Z轴方向,可以分为左手系和右手系。如上图所示坐标系,通过沿X轴正方向到Y轴正方向握拳,大拇指所致的方向即为Z轴方向,Z轴朝向屏幕外面,这就是右手坐标系,同理,我们可以使用左手确定Z轴的方向朝向屏幕里边。
3D空间中的距离计算公式为:
通常情况下,大多数程序开发人员都是用右手坐标系,而且OpenGL也采用这种坐标系,所以后续我们使用的都是右手坐标系。
1.1.2 向量和矩阵
介绍向量之前,有必要先介绍下标量。标量表示数量的大小,仅仅是一个数值而已。例如绳子的长度,物体的重量等。
向量表示为同时具有数值和方向的量,相当于具有方向的标量。例如,物体运动的速度,它不仅具有表示大小的数值(速率),而且还有一个方向用于表示行进的方向。通常情况下,在2D空间向量具有x、y两个分量,在3D空间中向量具有x、y、z三个分量。比如球体表面的法线就是向量,它不仅有大小而且具有方向性。
很多时候,我们只关心向量的方向而不在乎他的大小,在这样的情况下,使用单位向量变得非常方便。所谓的单位向量就是大小为1的向量,通常,单位向量也称为标准化向量。一个非零向量的归一化表示如下:
其中 是向量的模(也称为大小,是向量坐标和原点的距离)
具有相同维数的向量可以进行加减法运算。就是说,参加加、减运算的两个向量都是2维、3维或者4维等,具体运算规则,需要把对应的分量相加。例如向量和向量相加结果为,同理我们可以计算出向量。
此外,向量还支持点乘和叉乘运算。
点乘描述了两个向量的相关性,运算结果是一个标量,表示两个向量的“相似”程度。
如果向量A和B的长度都是1,公式简化为:
然后通过反余弦计算,可以知道向量A和向量B之间的夹角。
叉乘仅可应用于3D场景,与点乘不一样的是,向量叉乘得到的是一个向量。向量A和向量B叉乘结果的大小为,方向垂直于向量A和向量B,具体指向,可以使用右手定则进行判断。例如,在A、B交叉点伸出右手,食指指向A,弯曲其他手指直到指向B,此时,拇指的指向就是的指向。向量的这一性质可以帮助我们找出平面的法向量。
矩阵是3D图形学的重要理论基础。在OpenGL 3D图形开发中,物体位移、缩放、旋转等变换和坐标系的转换都使用矩阵表示,对于学习过线性代数的读者肯定不会陌生,我们通过行数列数的方式定义矩阵尺寸。对于矩阵M可以表示为:
方阵、对角矩阵、单位矩阵是特殊的矩阵。
其中,方阵表示函数和列数相同的矩阵,如上所示矩阵M。如果方阵的对角线元素(方阵中行号和列好相同的元素、、)外,所有非对角元素都是0,那么我们称之为对角矩阵。
而单位矩阵是更加特殊的方阵,它是的矩阵,而且对角线元素都是1,其余元素都是0。它具有特殊的性质。
任何矩阵和一个单位矩阵相乘,结果还是原来的矩阵。
矩阵可以和标量相乘,相当于矩阵中的么个元素乘以该标量。
向量是只有一行或者一列的矩阵,它可以和矩阵相乘,并且存在两种组合。行向量左乘矩阵得到行向量;列向量右乘矩阵得到列向量。其中行向量的列数和矩阵的行数相等,列向量的行数和矩阵的列数相等。例如:
图形处理过程中,经常会遇到平移、缩放、旋转等几何变换操作,在OpenGL开发中都是通过矩阵变换来实现的。可以说几何变换是图形处理的核心内容。举个简单的例子,通过如下矩阵运算可以发现结果,,。
所以,矩阵M代表了一个在X轴移动距离a,在Y轴移动b,在Z轴移动c的平移操作。
细心的读者可以能已经发现了,我们在三维坐标空间的矩阵运算使用的是矩阵,没错。这种表示方法叫做齐次坐标表示,基本思想是在n+1维空间解决n为空间的几何问题,它使用了n+1个分量表示n个分量的向量。一般齐次坐标表示不具备唯一性,通常情况下,计算机图形学中会采用规范化齐次坐标,即使用(x,y,1)的形式表示点(x,y)。
同理,我们也可以利用矩阵运算实现缩放和旋转的效果。
说明:旋转矩阵表示了点P绕轴向量旋转度,运算比较复杂,由于本章只是介绍3D图形相关的基础知识,所以就不进行验证计算了,有兴趣的读者可以参考其他资料进一步研究学习。
是一个缩放矩阵,、、分别描述了缩放转换过程中沿X、Y、Z轴方向的缩放率。3D空间中点的齐次坐标乘以此矩阵后,相当于沿坐标轴X、Y、Z方向缩放、、