先上效果图
首先AndroidManifest.xml里声明版本:
然后在Acitivity里声明版本:
GLSurfaceView glSurfaceView = new GLSurfaceView(this);
glSurfaceView.setEGLContextClientVersion(3);
setContentView(glSurfaceView);
glSurfaceView.setRenderer(new TriangleRenderer(this));
然后在Renderer的onSurfaceCreated回调里初始化顶点和颜色数据:
float[] triangleCoords = new float[] {
0.0f, 1, 0.0f,
-1.0f, -1, 0.0f,
1.0f, -1, 0.0f
};
mVertexBuffer = Utils.floatArray2FloatBuffer(triangleCoords);
float[] color = new float[] {
1, 0, 0, 0,
0, 0, 1, 0,
0, 1, 0, 0
};
mColorBuffer = Utils.floatArray2FloatBuffer(color);
public static FloatBuffer floatArray2FloatBuffer(float[] array) {
FloatBuffer floatBuffer = ByteBuffer.allocateDirect(array.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
floatBuffer.put(array).position(0);
return floatBuffer;
}
并且创建program:
mProgram = Utils.createProgram(mContext, R.raw.triangle_v, R.raw.triangle_f);
muMVPMatrixHandler = GLES30.glGetUniformLocation(mProgram, "uMVPMatrix");
mPosHandler = GLES30.glGetAttribLocation(mProgram, "aPosition");
mColorHandler = GLES30.glGetAttribLocation(mProgram, "aColor");
public static int createProgram(Context context, int vertextRawId, int fragmentRawId) {
int vertexShader = loadShader(context, GL_VERTEX_SHADER, vertextRawId);
if (vertexShader == 0) return 0;
int fragmentShader = loadShader(context, GL_FRAGMENT_SHADER, fragmentRawId);
if (fragmentShader == 0) return 0;
int program = glCreateProgram();
if (program != 0) {
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
int[] linkStatus = new int[1];
glGetProgramiv(program, GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GL_TRUE) {
Log.e(TAG, "createProgram : Cannot link program");
Log.e(TAG, "createProgram glError : " + glGetProgramInfoLog(program));
glDeleteProgram(program);
program = 0;
}
}
return program;
}
public static int loadShader(Context context, int type, int rawId) {
String shaderCode = readStringFromInputStream(context.getResources().openRawResource(rawId));
return loadShader(type, shaderCode);
}
public static String readStringFromInputStream(InputStream inputStream) {
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader);
StringBuilder builder = new StringBuilder("");
String str;
try {
while ((str = bufferedReader.readLine()) != null) {
builder.append(str);
builder.append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return builder.toString();
}
public static int loadShader(int type, String shaderCode) {
int shader = glCreateShader(type);
glShaderSource(shader, shaderCode);
glCompileShader(shader);
int[] compiled = new int[1];
glGetShaderiv(shader, GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e(TAG, glGetShaderInfoLog(shader));
glDeleteShader(shader);
return 0;
}
return shader;
}
triangle_v.glsl代码如下:
#version 300 es
uniform mat4 uMVPMatrix;
layout (location = 0) in vec4 aPosition;
layout (location = 1) in vec4 aColor;
out vec4 vColor;
void main() {
gl_Position = uMVPMatrix * aPosition;
vColor = aColor;
}
triangle_f.glsl代码如下:
#version 300 es
precision mediump float;
in vec4 vColor;
out vec4 fragColor;
void main() {
fragColor = vColor;
}
然后在onSurfaceChanged里执行如下代码:
float ratio = (float) height / width;
Matrix.frustumM(frustumM, 0, -1, 1, -ratio, ratio, 3, 7);
Matrix.setLookAtM(lookAtM, 0, 0, 0, 5, 0, 0, 0, 0, 1, 0);
Matrix.multiplyMM(mMVPMatrix, 0, frustumM, 0, lookAtM, 0);
最后在onDrawFrame里执行:
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
GLES30.glUseProgram(mProgram);
GLES30.glUniformMatrix4fv(muMVPMatrixHandler, 1, false, mMVPMatrix, 0);
GLES30.glVertexAttribPointer(mPosHandler, 3, GLES30.GL_FLOAT, false, 3 * 4, mVertexBuffer);
GLES30.glEnableVertexAttribArray(mPosHandler);
GLES30.glVertexAttribPointer(mColorHandler, 4, GLES30.GL_FLOAT, false, 4 * 4, mColorBuffer);
GLES30.glEnableVertexAttribArray(mColorHandler);
GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 3);
至此就可以绘制出上面截图中的三角形了。