一. 着色器
顶点着色器的输出在OpenGL ES 2.0中称作varying
,但是在OpenGL ES 3.0改名为顶点着色器输出变量。
下图是图形渲染管线的每个阶段抽象展示。蓝色代表的是我们可以注入自定义的着色器的部分。
- 获取
Vertex Data[]
:以数组的形式传递3个3D坐标作为图形渲染管线的输入,表示一个三角形,这个数组叫顶点数据(Vertex Data)。顶点数据是一系列顶点的集合,一个顶点(Vertex)是一个3D坐标数据的集合。而顶点数据是用顶点属性表示的(Vertex Atrribute)。 - 顶点着色器(Vertex Shader):图形渲染管线的第一个部分是顶点着色器(Vertex Shader),它把一个单独的顶点作为输入。顶点着色器允许我们对顶点属性进行一些基本处理
- ->
图元(形状)装配
->几何着色器
->光栅化
->片段着色器
二:glVertexAttribPointer
API:glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
这是在使用GLES时候很常用的一个api,在网上找了很多资料大多都是抄过来,很难看懂。
根据API的名称Vertex Atrrib 可以猜到大概的意思是改变顶点的属性。顶点属性我们是在shader里面声明的,所以这个API是GLES 赋值 shader内的属性,举个例子:
static GLfloat plane1[] = {
-0.5, 0.5f, 0, 1, 0, 0, // x, y, z, r, g, b,每一行存储一个点的信息,位置和颜色
-0.5f, -0.5f, 0, 0, 1, 0,
0.5f, -0.5f, 0, 0, 0, 1,
0.5, -0.5f, 0, 0, 0, 1,
0.5f, 0.5f, 0, 0, 1, 0,
-0.5f, 0.5f, 0, 1, 0, 0,
};
// 启用Shader中的两个属性
// attribute vec4 position;
// attribute vec4 color;
GLuint positionAttribLocation = glGetAttribLocation(program, "position");
glEnableVertexAttribArray(positionAttribLocation);
GLuint colorAttribLocation = glGetAttribLocation(program, "normal");
glEnableVertexAttribArray(colorAttribLocation);
/**
告诉OpenGL ES 丁点数据在哪里,以及怎么结束为每顶点保存的数据。
@param positionAttribLocation 指示当前绑定的缓存包含每个顶点位置信息
@param 3 指示每个位置有3个部分
@param GL_FLOAT 告诉OpenGL ES每个部分都保存为一直浮点类型的值
@param GL_FALSE 告诉OpenGL ES小数点固定数据是否可以被改变
@param sceneVertex “步幅” 它指定了每个顶点的保存需要多少字节(步幅指定了GPU从一个顶点的内存开始位置到下一个顶点的内存开始位置需要跳过多少字节)
sizeof(sceneVertex)指示在d缓存中没有额外的字节,
@return return value description
*/
glVertexAttribPointer(positionAttribLocation, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (char *)triangleData);
glVertexAttribPointer(colorAttribLocation, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (char *)triangleData + 3 * sizeof(GLfloat));
- 第一个参数指定我们要配置的顶点属性,可以由
glGetAttribLocation
函数去shader内获取。 - 第二个参数指定顶点属性的大小,顶点属性是一个
vec3
由3个值组成,所以大小是3。在上面的代码块中plane1中对应第一行的(-0.5,0.5,0)3个数据,将这3个数据复制给shader中的position
。 - 第三个参数指定数据的类型
GL_FLOAT
- 第四个参数一般都设置为
GL_FALSE
。下个参数定义我们是否希望数据被标准化(Normalize)。如果我们设置为GL_TRUE,所有数据都会被映射到0(对于有符号型signed数据是-1)到1之间。所以一般我们把它设置为GL_FALSE。 - 第五个参数叫做
步长
或者步幅
(Stride)。意思是一组数据有多长,这里6 * sizeof(GLfloat)
说明一组数据有6*4个byte