在復(fù)習(xí)一次繪制流程荐糜。
- 創(chuàng)建頂點和片段著色器
- 加載編譯
- 創(chuàng)建程序
- 附著,連接
- 使用
- 得到位置信息 (不太規(guī)范的叫法葛超,就是屬性等參數(shù)的位置)
- 傳值
- 繪制
創(chuàng)建著色器
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;" +
"}";
這個很簡單的暴氏,將傳遞進(jìn)來的頂點屬性直接給內(nèi)置變量。片段著色器直接將傳遞的值給內(nèi)置變量gl_FragColor绣张,這個值會通過后續(xù)步驟之后顯示在屏幕上的答渔。
加載和編譯
- 創(chuàng)建著色器
//根據(jù)type創(chuàng)建頂點著色器或者片元著色器
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;
}
創(chuàng)建程序
- 創(chuàng)建程序
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侥涵,可以直接的傳值,傳入數(shù)組就可以了沼撕。
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
但是對于屬性值就比較麻煩一點宋雏,需要使用到FloatBuffer.它 是一個特殊的區(qū)域,就是jvm和操作系統(tǒng)共享的區(qū)域务豺。
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
};
//頂點個數(shù)
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
//頂點之間的偏移量
private final int vertexStride = COORDS_PER_VERTEX * 4; // 每個頂點四個字節(jié)
//設(shè)置顏色磨总,依次為紅綠藍(lán)和透明通道
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);
//程序加入到環(huán)境里面
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);
//準(zhǔn)備三角形的坐標(biāo)數(shù)據(jù)
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;
}
//設(shè)置繪制三角形的顏色
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
//繪制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
//禁止頂點數(shù)組的句柄
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}