Android OpenGL ES 2.0 手把手教学(5)- 绘制模式

3,447 阅读3分钟

大家好,下面和大学一起学习绘制模式,在我的github上有一个项目OpenGLES2.0SamplesForAndroid,我会不断地编写学习样例,文章和代码同步更新,欢迎关注,链接:github.com/kenneycode/…

在我们之前的例子中,我们都是以三个独立顶点为一个三角形的方式来进行渲染,如果大家有注意观察的话,会发现我们在调用glDrawArrays()方法的时候,第一个参数都是用GL_TRIANGLES,这第一个参数就是用来设置绘制模式的,下面给大家介绍三个比较常用的绘制模式GL_TRIANGLESGL_TRIANGLE_STRIPGL_TRIANGLE_FAN,我们先来看一张图:

这张图展示了这三种绘制模式的区别

GL_TRIANGLES就是我们之前的例子中一直在用的,它是将每三个独立顶点构成一个三角形,不同三角形之间不会共用顶点

GL_TRIANGLE_STRIP的效果就像它名字一样,是带状的,它构成三角形的规则和顶点编号的奇偶有关,如果当前顶点编号是奇数,则三角形顶点顺序是k-1, k-2, k, 如果顶点数量是偶数,则三角形顶点顺序为k-2, k-1, k,这是什么意思呢?我们对照上图来看,对于2号点,那么就是(v0, v1, v2)对于3号点,那么就是(v2, v1, v3),可以看到它三角形顶点是会共用的,并且我们能看到,每个三角形都是同一个方向的旋转。

这里稍微解释一下这个顶点顺序有什么用,比如对于v0, v1, v2三个点构成的三角形,我们可以用v0, v1, v2这个顺序去渲染,也可以用v0, v2, v1这个顺序去渲染,有什么区别呢?在2D渲染中,没什么太大区别,但在3D渲染中,很有用,我们想象一下在玩3D游戏时,前面有一个房子,我们围着这个房子转,能从不同的角度看这个房子,但无论在什么角度,这个房子总有一些墙面被比更靠近我们的墙面遮挡,从而看不见,但在一般情况下,被遮挡的墙面也是会被渲染的,只不过由于OpenGL的深度测试机制,更靠近我们的墙面,它的深度更浅,于是会把color buffer中较远墙面的color覆盖,从而实现遮挡。

那么既然会被遮挡,能不能干脆就不渲染它?是有办法的,这就涉及到面剔除(glCullFace),就是告诉OpenGL不要渲染正/反面,其中正/反面通过glFrontFace去定义,可以定义顺时针或者逆时针的顶点环绕绕为正面,然后glCullFace告诉OpenGL剔除正面还是反面,注意这里的顺时针或者逆时针是从观察方向来定义的,

回到刚才的例子,一面靠近我们的墙如果是正面,那么当我们走到房子另一面再看过来时,它就变成了反面,因为三角 顶点环绕顺序刚好反过来了,于是就可以进行剔除。

GL_TRIANGLE_FAN的效果也像它名字一样,一扇形的,以第0个点为扇形的中心,其它点就连接0号点与上一个点构成三角形。

这三种绘制模式各有特点,可根据实际需要来采用,在能满足需求的情况下,尽量采用传递顶点少的方式,可以提高性能,例如我们之前的例子中,是否能用GL_TRIANGLE_STRIP或者GL_TRIANGLE_FAN来替代,减少传递的顶点呢?大家可以思考一下。

我们来看看例子中的效果,从左到右依次是GL_TRIANGLESGL_TRIANGLE_STRIPGL_TRIANGLE_FAN,可以通过按钮切换:

代码在我github的OpenGLES2.0SamplesForAndroid项目中,本文对应的是SampleDrawMode,项目链接:github.com/kenneycode/…

感谢阅读!