就是我们常说的VBO。我们使用glGenBuffer申请BUFFER的标识(有GL管理),使用glBindBuffer指定当前操作哪一个VBO,使用glBufferData向显存传输数据。关于这些函数的用法,我们可以在http://www.khronos.org/opengles/sdk/docs/man/ 查到。
显卡有了数据,但还不知到该如何解释这些数据,所以我们要告诉他。这样Vertex Array Object就派上了用场。我们使用GLprogram对象的getAttribLocation方法,获取顶点数组在shader中的位置,使用glEnableVertexAttribute来激活这个位置,使用glAttributePointer来制定对数据的解析。
glAttributePointer的几个参数比较有讲究,我单独拿出来讲讲。第一个参数index是指用getAttribLocation获取的那个位置,第二个参数size,是一个顶点由几维,只能写1,2,3,4,如我们程序传的都是二维顶点,写2就好了。第三个参数type是数据类型,我们通常用GLFloat。第四个参数normalize指是否归一化,我们通常写false。第5个参数stride,指的是一个顶点数据的字节数,如果我们定点数据只有一种,如位置,这里写0就可以。第6个参数,offest,指的是第一个该数据在传入VBO中的偏移量。我们的这个程序里只传入了顶点位置,写0就好了。
这些工作做完后,我们不要忘了把VBO和VAO绑定回0,以免影响其他图元的绘制。
最后,在ondraw函数中,绑定前面的VAO,调用drawArray命令,完成三角形的绘制。
在这个程序里,我们的shader写的很简单,就是把传过来的顶点负值,把
颜色设为蓝色。
2.4 彩色的三角形
有的小伙伴看到这里,不禁要吐槽了。”擦,老子裤子都脱了,你就给我看这个”。别急,下面我们让三角形带上点颜色。我们对之前的代码做如下修改,如图2.9,2.10,2.11所示,运行效果如2.12所示。
图2.9 彩色三角形代码修改-1
图2.10 彩色三角形代码修改-2
图2.11 彩色三角形代码修改-3
图2.12 彩色三角形运行效果
Vertex Shader:
attribute vec2 position; attribute vec4 color;
varying vec4 v_color; uniform mat4 vmatrix;
void main() { }
gl_Position = vmatrix * vec4(position,0.0,1.0); v_color = color;
Fragment Shader:
varying vec4 v_color; uniform mat4 cmatrix;
void main() { }
gl_FragColor = cmatrix * v_color;
在这个程序中,我们对每个顶点添加了颜色,为顶点的变幻和颜色的变幻添加了一个控制矩阵。在shader中,我们让矩阵乘以这些值。
2.5 shader语法简介
Shader的整体语法与C++类似,但也有些许不同,现在我们来逐一分析。
2.5.1 变量的声明
Shader中的变量与C语言类似,有float,double, int, uint, bool。这些类型的详细解释如图2.13所示。但要注意的是,不能用unsigned做修饰,bool型变量目前不能用作unifrom,因为引擎没有提供传值得基础。
图2.13 shader中的基本类型
除了上面的基础类型,在shader中还有一些和向量矩阵有关的拓展类型,如图2.14所示。
图2.14 shader中的拓展类型
脑筋灵活的同学,又该发出疑问,在shader中数组和指针该如何定义呢。额,告诉大家一个不幸的好消息,shader是脚本语言,指针这种杀伤脑细胞的东西是木有滴,对于数组的声明,我们可以像既可以c语言那样在变量后面加中括号(float a[3];),也可以像C#那样在类型名后加中括号(float[] a;)
2.5.2 变量的转换
在shader的语法中,对类型的隐式转换比C更加严格,比如float a= false这样的代码是会报错的。只有一下类型的隐式转换是被允许的,如图2.15所示。
图2.15 shader中的隐式类型转换
大多数情况下,我们使用显示类型转换,类型名()的形式,如