本节书摘来自华章出版社《OpenGL ES应用开发实践指南:Android卷》一 书中的第2章,第2.3节,作者:(美)Kevin Brothaler ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
2.3 定义空气曲棍球桌子的结构
在桌子被绘制到屏幕之前,我们需要告诉OpenGL要画什么。开发过程中的第一步是以OpenGL能理解的形式定义一个桌子结构。在OpenGL里,所有东西的结构都是从一个顶点开始。
2.3.1 介绍顶点
简单来说,一个顶点就是一个代表几何对象的拐角的点,这个点有很多附加属性;最重要的属性就是位置,它代表了这个顶点在空间中的定位。
2.3.2 用顶点构建游戏中的桌子
我们曾说过要暂时保持事物简单,那什么是能表达空气曲棍球桌子结构的最基本的图形呢?我们可以使用长方形。既然一个长方形有4个拐角,我们就需要4个顶点。长方形是一个二维物体,因此每个顶点都需要一个位置,这个位置在每个维度上都要有一个坐标。
如果我们要把它画到一张图纸上,我们会得到与图2-2类似的图形。

2.3.3 在代码中定义顶点
让我们继续,并写一些代码存储这些顶点;这些顶点会表示为一个浮点数列表;因为它们定义在二维坐标系里,所以每个顶点要用两个浮点数进行标记:一个标记x轴的位置,另外一个标记y轴的位置。
因为一个顶点有两个分量,所以首先创建一个常量用来记住这一事实;打开AirHockeyRenderer类,并在它的顶端加入如下常量:
我们采用了浮点数的顺序列表定义顶点数据,因此,我们可以用有小数点的十进制数存储这些位置;这个数组通常称为顶点属性(attribute)数组。到目前为止,只有位置属性储存了,但是,我们稍后也会把颜色及其他属性用同样的概念储存起来。
2.3.4 点、直线及三角形
还记得前面曾说过表示曲棍球桌子的最容易的方式是长方形吗?然而,令人感到混乱的一点是:在OpenGL里,只能绘制点、直线以及三角形。
三角形是最基本的几何图形;因为它的结构如此稳定,它随处可见,比如桥梁的结构化构件;它有三条边用来连接它的三个顶点,如果我们拿掉其中一个顶点,剩下的就是一条直线,如果我们再拿掉一个点,就只剩下一个点了。
点和直线可以用于某些效果,但是,只有三角形才能用来构建拥有复杂的对象和纹理的场景。在OpenGL里,我们把单独的点放在一个组里构建出三角形,再告诉OpenGL如何连接这些点。我们想要构建的所有东西都要用点、直线和三角形定义;如果想构建更复杂的图形,例如拱形,那我们就需要用足够的点拟合这样的曲线。
如果不能使用长方形,我们怎么定义空气曲棍球的桌子呢?事实上,我们可以认为桌子是由两个三角形连接在一起的,如图2-3所示。

让我们改变代码以反映这一事实,我们现在使用两个三角形而不是一个长方形:
三角形的卷曲顺序
你可能注意到了,当我们定义三角形的时候,我们总是以逆时针的顺序排列顶点;这称为卷曲顺序(winding order)。因为在任何地方都使用这种一致的卷曲顺序,可以优化性能:使用卷曲顺序可以指出一个三角形属于任何给定物体的前面或者后面,OpenGL可以忽略那些无论如何都无法被看到的后面的三角形。
在12.5节中我们会学到更多内容。
这个数组表示用六个顶点表示两个三角形;第一个三角形由(0, 0)、(9, 14)及(0, 14)连接组成,第二个三角形共用了其中的两个点,它由(0, 0)、(9,0)及(9, 14)构成。
无论何时,如果我们想表示一个OpenGL中的物体,都要考虑如何用点、直线及三角形把它组合出来。
2.3.5 添加中间线和两个木槌
我们几乎要完成所有顶点的定义了;我们只需要为中间线和两个木槌添加一些顶点。最后,会得到与图2-4相似的图形。

我们将用一条直线定义中间线,并用一个点表示每个木槌。在数组的最后添加一个分号,然后加入下面这些新的
顶点:
如你所见,由于这个数组由浮点值组合而成,我们可以使用带小数的十进制坐标。为了让Java编译器工作,需要在每个数的后面加上小写f,它告诉Java编译器把这个数字解释为浮点数(float),而不是双精度浮点数(double);双精度浮点数有大约两倍的精度(这是其名字的由来),如果我们不加f,Java编译器会把它当作精度丢失的转换,会要求增加显式的类型转换(cast)。