iOS 的shader实际上是iOS平台shang 基于GLSL的opengl开发框架,该框架采用填空式编程的思想,application需要实现的是两个着色器-顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)。着色器面对单点或单面编程,opengl库在运行时应该会采用单指令多数据流的方式工作。
对于顶点着色器,输入有三类:
1.uniform参数,此类参数在一次绘制中,所有顶点着色器的实例都相同,且为application传入引擎数据。
2.attribute参数,此类参数不同顶点着色器的实例不同,单同一顶点着色器在不同绘制中都相同,且为application传入引擎数据。
3.build-in参数,此类参数为opengl内建参数,可以看成是opengl的绘制上下文信息。
顶点着色器的输出有两类:
1.build-in参数,顶点着色器通过这些内建参数与控制后续计算框架的计算。
2.varying参数,顶点着色器通过这些参数把数据传递给片段着色器。
对于片段着色器,输入有两类:
1.build-in参数,此类参数为opengl内建参数,可以看成是opengl的绘制上下文信息。
2.varying参数,顶点着色器通过这些参数把数据传递给片段着色器。
输出只有一类:
1.build-in参数,片段着色器通过这些内建参数与控制后续计算框架的计算。
attribute参数的传递:
1.在shader中定义参数如
attribute vec4 position;
attribute vec3 normal;
attribute vec3 color;
2.在程序中定义数据如
GLfloat gCubeVertexData[27] =
{
// Data layout for each line below is:
// positionX, positionY, positionZ, normalX, normalY, normalZ,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
}
3.通过以下方法把数据传入系统
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, 36, BUFFER_OFFSET(0));
glEnableVertexAttribArray(ATTRIB_NORMAL);
glVertexAttribPointer(ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, 36, BUFFER_OFFSET(12));
glVertexAttribPointer(ATTRIB_COLOR, 3, GL_FLOAT, GL_FALSE, 36, BUFFER_OFFSET(24));
glEnableVertexAttribArray(ATTRIB_COLOR);
glBindVertexArrayOES(0);
4.用下面方法告诉系统数据与脚本中定义的参数的对应关系
glBindAttribLocation(_program, ATTRIB_VERTEX, "position");
glBindAttribLocation(_program, ATTRIB_NORMAL, "normal");
glBindAttribLocation(_program, ATTRIB_COLOR, "color");
注意,例子中的ATTRIB_VERTEX、ATTRIB_VERTEX、ATTRIB_COLOR是关键,系统正是通过这几个枚举值把变量跟数据内容建立关联的。这些枚举值的定义如下
// Attribute index.
enum
{
ATTRIB_VERTEX,
ATTRIB_NORMAL,
ATTRIB_COLOR,
NUM_ATTRIBUTES
};
uniform参数的传递:
uniform参数的传递方式与attribute参数类似,也是通过索引进行关联,只是uniform的索引值是系统对着色器链接后生产的,索引值通过下面的方法获得
glGetUniformLocation(_program, "modelViewProjectionMatrix");
在需要传入uniform参数的地方,通过glUniformXXX函数族传入对应参数值,比如上例中的参数值传入方法如下
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
其中_modelViewProjectionMatrix的定义如下
GLKMatrix4 _modelViewProjectionMatrix;
此uniform变量在着色器中的定义如下
uniform mat4 modelViewProjectionMatrix;