后面补充,先上代码:
MainActvity:
public class MainActivity extends AppCompatActivity {
private GLSurfaceView glSurfaceView;
private ActivityManager am;
private boolean rendererSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
glSurfaceView = new GLSurfaceView(this);
am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
boolean supportES2 = am.getDeviceConfigurationInfo().reqGlEsVersion >= 2000;
if (!supportES2) {
Toast.makeText(this, "This device does not support ES 2.0"
, Toast.LENGTH_SHORT).show();
return;
}
glSurfaceView.setEGLContextClientVersion(2);
rendererSet = true;
setContentView(glSurfaceView);
glSurfaceView.setRenderer(new MyGLRenderer(this));
}
@Override
protected void onPause() {
super.onPause();
if (rendererSet) {
glSurfaceView.onPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (rendererSet) {
glSurfaceView.onResume();
}
}
}
MatrixHelper:
public class MatrixHelper {
public static void perspectiveM(float[] m, float yFovInDegrees, float aspect, float n, float f) {
float angleInRadians = (float) (yFovInDegrees * Math.PI / 180.0);
float a = (float) (1.0 / Math.tan(angleInRadians / 2.0));
//OpenGL是按照列的方式写的,不是行的形式
m[0] = a / aspect;
m[1] = 0f;
m[2] = 0f;
m[3] = 0f;
m[4] = 0f;
m[5] = a;
m[6] = 0f;
m[7] = 0f;
m[8] = 0f;
m[9] = 0f;
m[10] = -((f + n) / (f - n));
m[11] = -1f;
m[12] = 0f;
m[13] = 0f;
m[14] = -((2f * f * n) / (f - n));
m[15] = 0f;
}
}
MyGLRenderer:
public class MyGLRenderer implements GLSurfaceView.Renderer {
/* private float[] tableVerticesWidthTriangles = {
//三角形1
0f, 0f,
9f, 14f,
0f, 14f,
//三角形2
0f, 0f,
9f, 0f,
9f, 14f,
//直线
0f, 7f,
9f, 7f,
//mallets
4.5f, 2f,
4.5f, 12f
};*/
private float[] tableVerticesWidthTriangles = {
//三角形1
// -0.5f, -0.5f,
// 0.5f, 0.5f,
// -0.5f, 0.5f,
//
// //三角形2
// -0.5f, -0.5f,
// 0.5f, -0.5f,
// 0.5f, 0.5f,
// 三角形扇,带有z和w
// 0f, 0f, 0f, 1.5f, 1f, 1f, 1f,
// -0.5f, -0.8f, 0f, 1f, 0.7f, 0.7f, 0.7f,
// 0.5f, -0.8f, 0f, 1f, 0.7f, 0.7f, 0.7f,
// 0.5f, 0.8f, 0f, 2f, 0.7f, 0.7f, 0.7f,
// -0.5f, 0.8f, 0f, 2f, 0.7f, 0.7f, 0.7f,
// -0.5f, -0.8f, 0f, 1f, 0.7f, 0.7f, 0.7f,
//
// //直线
// -0.5f, 0f, 0f, 1.5f, 1f, 0f, 0f,
// 0.5f, 0f, 0f, 1.5f, 1f, 0f, 0f,
//
// //mallets
// 0f, -0.4f, 0f, 1.25f, 0f, 0f, 1f,
// 0f, 0.4f, 0f, 1.75f, 1f, 0f, 0f
//三角形扇
0f, 0f, 1f, 1f, 1f,
-0.5f, -0.8f, 0.7f, 0.7f, 0.7f,
0.5f, -0.8f, 0.7f, 0.7f, 0.7f,
0.5f, 0.8f, 0.7f, 0.7f, 0.7f,
-0.5f, 0.8f, 0.7f, 0.7f, 0.7f,
-0.5f, -0.8f, 0.7f, 0.7f, 0.7f,
//直线
-0.5f, 0f, 1f, 0f, 0f,
0.5f, 0f, 1f, 0f, 0f,
//mallets
0f, -0.4f, 0f, 0f, 1f,
0f, 0.4f, 1f, 0f, 0f
};
private static final int BYTES_PER_FLOAT = 4;
private FloatBuffer vertexData;
private final Context mContext;
private int program;
// private static final String U_COLOR = "u_Color";
// private int uColorLocation;
private static final String A_POSITION = "a_Position";
private int aPositionLocation;
private static final int POSITION_COMPONENT_COUNT = 2;
// private static final int POSITION_COMPONENT_COUNT = 4;
private static final String A_COLOR = "a_Color";
private static final int COLOR_COMPONENT_COUNT = 3;
private static final int STRIDE = (POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT;
private int aColorLocation;
private static final String U_MATRIX = "u_Matrix";
private final float[] projectionMatrix = new float[16];
private int uMatrixLocation;
private final float[] modelMatrix = new float[16];
public MyGLRenderer(Context context) {
mContext = context;
vertexData = ByteBuffer
.allocateDirect(tableVerticesWidthTriangles.length * BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
vertexData.put(tableVerticesWidthTriangles);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
String vertexShaderSource = TextResourceReader.readTextFileFromResource(mContext, R.raw.simple_vertex_shader);
String fragmentShaderSource = TextResourceReader.readTextFileFromResource(mContext, R.raw.simple_fragment_shader);
int vertexShader = ShaderHelper.compileVertexShader(vertexShaderSource);
int fragmentShader = ShaderHelper.compileFragmentShader(fragmentShaderSource);
program = ShaderHelper.linkProgram(vertexShader, fragmentShader);
ShaderHelper.validateProgram(program);//验证program
glUseProgram(program);
// uColorLocation = glGetUniformLocation(program, U_COLOR);//获取uniform位置
aColorLocation = glGetAttribLocation(program, A_COLOR);//获取新属性位置
aPositionLocation = glGetAttribLocation(program, A_POSITION);
uMatrixLocation = glGetUniformLocation(program, U_MATRIX);
//关联属性与顶点数据的数组
vertexData.position(0);//从数据开头读取位置
// glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, vertexData);//
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, STRIDE, vertexData);//
glEnableVertexAttribArray(aPositionLocation);// 使顶点数组可用
vertexData.position(POSITION_COMPONENT_COUNT);//从第三位开始读取颜色
glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT, false, STRIDE, vertexData);//
glEnableVertexAttribArray(aColorLocation);// 使顶点数组可用
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
glViewport(0, 0, width, height);//设置视图尺寸
// final float aspectRatio = width > height ?
// (float) width / (float) height :
// (float) height / (float) width;
// if (width > height) {
// Matrix.orthoM(projectionMatrix, 0, -aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);
// } else {
// Matrix.orthoM(projectionMatrix, 0, -1f, 1f, -aspectRatio, aspectRatio, -1f, 1f);
// }
// Matrix.perspectiveM(projectionMatrix, 0, 45, (float) width / (float) height, 1f, 10f);
MatrixHelper.perspectiveM(projectionMatrix, 45f, (float) width / (float) height, 1f, 10f);
// 利用模型矩阵平移物体
Matrix.setIdentityM(modelMatrix, 0);
Matrix.translateM(modelMatrix, 0, 0f, 0f, -2f);
//绕X轴旋转桌子
Matrix.translateM(modelMatrix, 0, 0f, 0f, -2.5f);
Matrix.rotateM(modelMatrix, 0, -60f, 1f, 0f, 0f);
final float[] temp = new float[16];//用来存矩阵相乘临时结果
Matrix.multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0);
System.arraycopy(temp, 0, projectionMatrix, 0, temp.length);//将计算结果拷贝回projectionMatrix
}
@Override
public void onDrawFrame(GL10 gl) {
glClear(GL_COLOR_BUFFER_BIT);
glUniformMatrix4fv(uMatrixLocation, 1, false, projectionMatrix, 0);
// //绘制桌子
// glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);
// glDrawArrays(GL_TRIANGLES, 0, 6);
//三角形扇的形式绘制桌子
// glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);
glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
//绘制直线
// glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
glDrawArrays(GL_LINES, 6, 2);
//绘制木槌1
// glUniform4f(uColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
glDrawArrays(GL_POINTS, 8, 1);
//绘制木槌2
// glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
glDrawArrays(GL_POINTS, 9, 1);
}
}
ShaderHelper:
public class ShaderHelper {
private static String TAG = "ShaderHelper";
public static int compileVertexShader(String shaderCode) {
return compileShader(GL_VERTEX_SHADER, shaderCode);
}
public static int compileFragmentShader(String shaderCode) {
return compileShader(GL_FRAGMENT_SHADER, shaderCode);
}
public static int compileShader(int type, String shaderCode) {
int shaderObjectId = glCreateShader(type);
if (shaderObjectId == 0) {
Log.w(TAG, "could not create new shader! ");
return 0;
}
glShaderSource(shaderObjectId, shaderCode);
glCompileShader(shaderObjectId);
final int[] compileStatus = new int[1];
glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0);
Log.w(TAG, "Results of compile source: \n" + shaderCode + "\n"
+ glGetShaderInfoLog(shaderObjectId));
if (compileStatus[0] == 0) {
Log.w(TAG, "compilation of shader failed!");
//if it failed, delete the shader object.
glDeleteShader(shaderObjectId);
return 0;
}
return shaderObjectId;
}
public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
int programObjectId = glCreateProgram();
if (programObjectId == 0) {
Log.w(TAG, "Could not create a new program!");
return 0;
}
glAttachShader(programObjectId, vertexShaderId);
glAttachShader(programObjectId, fragmentShaderId);
glLinkProgram(programObjectId);
final int[] linkStatus = new int[1];
glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0);
Log.w(TAG, "Results of link program: \n"
+ glGetProgramInfoLog(programObjectId));
if (linkStatus[0] == 0) {
Log.w(TAG, "linking of program failed!");
//if it failed, delete the program object.
glDeleteProgram(programObjectId);
return 0;
}
return programObjectId;
}
public static boolean validateProgram(int programObjectId) {
glValidateProgram(programObjectId);
final int[] validateStatus = new int[1];
glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateStatus, 0);
Log.w(TAG, "Results of validating program: " + validateStatus[0]
+ "\nLog: " + glGetProgramInfoLog(programObjectId));
return validateStatus[0] != 0;
}
}
TextResourceReader:
public class TextResourceReader {
public static String readTextFileFromResource(Context context, int resId) {
StringBuffer body = new StringBuffer();
try {
InputStream inputStream = context.getResources().openRawResource(resId);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine()) != null) {
body.append(line);
body.append("\n");
}
} catch (IOException e) {
throw new RuntimeException("could not open resource: " + resId, e);
} catch (Resources.NotFoundException e) {
throw new RuntimeException("resource not found: " + resId, e);
}
return body.toString();
}
}
simple_fragment_shader.glsl:
precision mediump float;
uniform vec4 u_Color;
varying vec4 v_Color;
void main()
{
// gl_FragColor = u_Color;
gl_FragColor = v_Color;
}
simple_vertex_shader.glsl:
uniform mat4 u_Matrix;
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main()
{
v_Color = a_Color;
// gl_Position = a_Position;
gl_Position = u_Matrix * a_Position;
gl_PointSize = 10.0;//指定点的大小
}