在复习一次绘制流程。
- 创建顶点和片段着色器
- 加载编译
- 创建程序
- 附着,连接
- 使用
- 得到位置信息 (不太规范的叫法,就是属性等参数的位置)
- 传值
- 绘制
创建着色器
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
这个很简单的,将传递进来的顶点属性直接给内置变量。片段着色器直接将传递的值给内置变量gl_FragColor,这个值会通过后续步骤之后显示在屏幕上的。
加载和编译
- 创建着色器
//根据type创建顶点着色器或者片元着色器
int shader = GLES20.glCreateShader(type);
- 加载程序
//将资源加入到着色器中,并编译
GLES20.glShaderSource(shader, shaderCode);
- 编译程序
GLES20.glCompileShader(shader);
- 检查异常
int []arr = new int[1] GLES20.glGetShaderiv(shader,GLES20.GL_COMPILE_STATUS,arr,0);
int i = arr[0];
if (i == 0){
//失败了
int [] length = new int[1];
GLES20.glGetShaderiv(shader,GLES20.GL_INFO_LOG_LENGTH,length,0);
if (length[0]>0){
String s = GLES20.glGetShaderInfoLog(shader);
System.out.println(s);
}
}
return shader;
}
创建程序
- 创建程序
mProgram = GLES20.glCreateProgram();
- 附着着色器
GLES20.glAttachShader(mProgram,vertexShader);
GLES20.glAttachShader(mProgram,fragmentShader);
- 连接
GLES20.glLinkProgram(mProgram);
- 检查
int lin[] = new int[1];
GLES20.glGetProgramiv(mProgram,GLES20.GL_LINK_STATUS,lin,0);
if (lin[0] == 0){
String s = GLES20.glGetProgramInfoLog(mProgram);
System.out.println(s);
}
使用
GLES20.glUseProgram(mProgram);
得到位置
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
传值
color使用的是uniform,可以直接的传值,传入数组就可以了。
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
但是对于属性值就比较麻烦一点,需要使用到FloatBuffer.它 是一个特殊的区域,就是jvm和操作系统共享的区域。
float triangleCoords[] = {
0.5f, 0.5f, 0.0f, // top
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f // bottom right
};
ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(triangleCoords);
vertexBuffer.position(0);
GLES20.glVertexAttribPointer(
mPositionHandle,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
vertexStride,
vertexBuffer);
完整代码
/**
* 三角形
*/
public class Triangle extends BaseGameScreen {
static final int COORDS_PER_VERTEX = 3;
private FloatBuffer vertexBuffer;
static float triangleCoords[] = {
0.5f, 0.5f, 0.0f, // top
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f // bottom right
};
//顶点个数
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
//顶点之间的偏移量
private final int vertexStride = COORDS_PER_VERTEX * 4; // 每个顶点四个字节
//设置颜色,依次为红绿蓝和透明通道
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
private int mPositionHandle;
private int mColorHandle;
float d = 0.01F;
public Triangle(){
}
public void create(){
ByteBuffer bb = ByteBuffer.allocateDirect(
triangleCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(triangleCoords);
vertexBuffer.position(0);
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode);
mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram,vertexShader);
GLES20.glAttachShader(mProgram,fragmentShader);
GLES20.glLinkProgram(mProgram);
//程序加入到环境里面
GLES20.glUseProgram(mProgram);
// 检查是否有效
GLES20.glValidateProgram(mProgram);
//得到活跃的unifor
int arr[] = new int[1];
int arr1[] = new int[1];
int arr2[] = new int[1];
int arr3[] = new int[1];
byte arr4[] = new byte[10];
GLES20.glGetProgramiv(mProgram,GLES20.GL_ACTIVE_UNIFORMS,arr,0);
GLES20.glGetActiveUniform(
mProgram,
1,
1,
arr1,
1,
arr2,
1,
arr3,
1,
arr4,
0
);
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
}
@Override
public void surfaceChange(int width, int height) {
GLES20.glViewport(0,0,width,height);
}
@Override
public void dispose() {
}
@Override
public void render() {
//获取位置句柄 属性句柄
GLES20.glEnableVertexAttribArray(mPositionHandle);
//准备三角形的坐标数据
GLES20.glVertexAttribPointer(
mPositionHandle,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
vertexStride,
vertexBuffer);
//获取片元着色器的vColor成员的句柄
color[1] = color[1]-d;
if (color[1]<=0||color[1]>=1){
d=-d;
}
//设置绘制三角形的颜色
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
//绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
//禁止顶点数组的句柄
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
网友评论