關於opengl es的着色器語言,我推薦一個地址:http://imgtec.eetrend.com/blog/1948,這篇文章寫的至關不錯,你們要是有興趣能夠去看一下。數組
我在這裏簡單總結一下,uniform在着色器中是隻讀的,不能被修改,它的值只能被opengl es的API注入。Attribute至關於opengl es的API向頂點着色器注入數據的入口,它與uniform的不一樣之處在於:uniform是全局常量,該全局性對頂點着色器與片元着色器都可見;Attributes是針對每個頂點的輸入數據,並且只能在頂點着色器中使用。varying用於從頂點着色器向片斷着色器傳遞數據,在光柵化階段,varying變量會被作線性插值處理。spa
咱們接着講對着色器的編譯。orm
在Android裏面,着色器文件一遍都放在raw文件夾下面,所以咱們要先把內容讀取到內存中,接下來的步驟以下:對象
1.建立新的着色器對象。blog
int shaderID = GLES20.glCreateShader(type);索引
這裏的type能夠表明頂點着色器的 GLES20.GL_VERTEX_SHADER,和片斷着色器的GLES20.GL_FRAGMENT_SHADER。接口
2.上傳和編譯着色器的源代碼內存
GLES20.GLES20.glShaderSource(shaderID, shaderCode);
GLES20.glCompileShader(shaderID);ci
這裏的shaderCode表示從raw文件夾下讀取的頂點着色器或片斷着色器的字符串內容。字符串
3.對頂點着色器和片斷着色器執行第一步和第二步的操做。
4.新建一個opengl程序,注意,這裏的程序指的是opengl中的組件。
int programID = GLES20.glCreateProgram();
5.將咱們以前建立的頂點着色器和片斷着色器的ID附加到這個opengl的程序上。
GLES20.glAttachShader(programID, vertexShaderID);
GLES20.glAttachShader(programID, fragmentShaderID);
6.連接程序,把頂點着色器和片斷着色器連接起來。
GLES20.glLinkProgram(programID);
7.使用咱們建立的opengl程序
GLES20.glUseProgram(programID);
而後咱們講講如何將數據經過opengl es接口注入到着色器當中去。咱們如下邊的着色器爲例:
頂點着色器
attribute vec4 a_Position;
void main()
{
gl_Position = a_Position;
}
片斷着色器:
precision mediump float;
uniform vec4 u_Color;
void main()
{
gl_FragColor = u_Color;
}
給uniform屬性注入數據:
1. GLES20.得到uniform的位置
String U_COLOR = "u_Color";
int colorPosition = GLES20.glGetUniformLocation(program, U_COLOR);
2.把數據傳遞給uniform
GLES20.glUniform4f(colorPosition, 1, 1, 1, 1);
給Attribute屬性注入數據:
1.得到屬性的位置
String A_POSITION = "a_Position";
positionLocation = GLES20.glGetAttribLocation(program, A_POSITION);
2.關聯屬性與頂點數據的數組
GLES20.glVertexAttribPointer(positionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, 0, vertexArray);
3.啓動該頂點數組
GLES20.glEnableVertexAttribArray(positionLocation);
此外還有關於繪製部分,繪製能夠分爲三種繪製方式:數組繪製,頂點索引繪製,緩衝區繪製
1.數組繪製,GLES20.glDrawArrays(type, startPosition, count);
2.頂點 索引繪製,GLES20.glDrawElements(type, indexCount, dataType, indexArray);
3.緩衝區繪製分爲緩衝區對象的建立和緩衝區的繪製。緩衝區分爲頂點緩衝區和索引緩衝區。
好比頂點緩衝區對象的建立:
int buffers[] = new int[1];
GLES20.glGenBuffers(length,)//生成緩衝區
bufferID = buffers[0];
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);//綁定緩衝區
FloatBuffer vertexArray = ................//生成floatBuffer,而且注入數據
vertexArray.position(0);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexArray.capacity()*BYTES_PER_FLOAT, vertexArray, GLES20.GL_STATIC_DRAW); //將native中的數據傳入到GPU
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);//解除綁定
建立索引緩衝區對象和建立頂點緩衝區對象其實差很少,只須要對上面的代碼作以下改動:
1.使用short[]和ShortBuffer做爲類型
2.使用GLES20.GL_ELEMENT_ARRAY_BUFFER,而不是GLES20.GL_ARRAY_BUFFER
經過緩衝區繪製,可使用GLES20.glDrawElements(),只是使用前和使用後須要綁定和解除緩衝區的綁定。