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;