关于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(),只是使用前和使用后须要绑定和解除缓冲区的绑定。