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_VERTEXATTRIB_VERTEXATTRIB_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;