刚开始学,记录一下调用顺序,套路都是一样的
文章参考:http://blog.csdn.net/column/details/openges.html
1、创建一个ShaderUtil来编译glsl
public class ShaderUtil { public static int compileVertexShader(String vertexShaderCode) throws RuntimeException { return compileShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); } public static int compileFragmentShader(String fragmentShaderCode) throws RuntimeException { return compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); } private static int compileShader(int type, String shaderCode) throws RuntimeException { // 1、创建shader int shaderID = GLES20.glCreateShader(type); if (shaderID == 0) { throw new RuntimeException("着色器创建失败,type:" + type); } // 2、传入着色器代码 GLES20.glShaderSource(shaderID, shaderCode); // 3、编译着色器 GLES20.glCompileShader(shaderID); // 4、获取编译的状态 int[] compileStatus = new int[1]; GLES20.glGetShaderiv(shaderID, GLES20.GL_COMPILE_STATUS, compileStatus, 0); // 5、确认编译状态,如果编译失败需要删除该对象 if (compileStatus[0] == 0) { GLES20.glDeleteShader(shaderID); throw new RuntimeException("着色器编译失败:" + GLES20.glGetShaderInfoLog(shaderID)); } return shaderID; } public static int buildProgram(String vertexShaderCode, String fragmentShaderCode) throws RuntimeException { // 1、编译着色器 int vertexShader = compileVertexShader(vertexShaderCode); int fragmentShader = compileFragmentShader(fragmentShaderCode); // 2、链接program int program = linkProgram(vertexShader, fragmentShader); // 3、验证program validateProgram(program); return program; } private static void validateProgram(int program) throws RuntimeException { } private static int linkProgram(int vertexShader, int fragmentShader) throws RuntimeException { // 1、新建一个program对象 int program = GLES20.glCreateProgram(); if (program == 0) { throw new RuntimeException("创建program失败"); } // 2、attach顶点着色器 GLES20.glAttachShader(program, vertexShader); //3、attach片段着色器 GLES20.glAttachShader(program, fragmentShader); // 4、将两个着色器连成一个program GLES20.glLinkProgram(program); // 5、获取连接状态 int[] linkStatus = new int[1]; GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); // 验证状态 if (linkStatus[0] == 0) { GLES20.glDeleteProgram(program); throw new RuntimeException("连接着色器失败"); } return program; } }
2、创建一个Trangle1类来表示一个三角形
public class Triangle1 { private float[] vertexs = { 0, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f }; private int vertexLocationCount = 2;// 每个顶点坐标的坐标数 private FloatBuffer vertexBuffer; private Context context; private int program; private int vertexPosition; private int colorPosition; public Triangle1(Context context) { this.context = context; // 第一步:创建顶点坐标 vertexBuffer = ByteBuffer.allocateDirect(vertexs.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); vertexBuffer.put(vertexs); vertexBuffer.position(0); // 第二步:创建着色器 initShader(); // 第三步:获取着色器语言中的位置和颜色id vertexPosition = GLES20.glGetAttribLocation(program, "a_Position"); colorPosition = GLES20.glGetUniformLocation(program, "u_Color"); // 第四步:传入数据 GLES20.glVertexAttribPointer(vertexPosition, vertexLocationCount, GLES20.GL_FLOAT, false, 0, vertexBuffer); GLES20.glEnableVertexAttribArray(vertexPosition); } private void initShader() { String vertexCode = TextResourceReader.readTextFileFromResource(context, R.raw.simple_vertex_shader); String fragmentCode = TextResourceReader.readTextFileFromResource(context, R.raw.simple_fragment_shader); program = ShaderUtil.buildProgram(vertexCode, fragmentCode); GLES20.glUseProgram(program); } public void draw() { GLES20.glUniform4f(colorPosition, 0, 0, 1, 1); GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); } }3、创建一个GLSurefaceView
@SuppressLint("WrongViewCast") public class GLSureViewActivity extends Activity { private GLSurfaceView surfaceView; private Triangle1 triangle; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_opengl_es); surfaceView = findViewById(R.id.gl); surfaceView.setEGLContextClientVersion(2); surfaceView.setRenderer(renderer); surfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); } private GLSurfaceView.Renderer renderer = new GLSurfaceView.Renderer() { @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // 设置清空屏幕用的颜色,前三个参数对应红绿蓝,最后一个对应alpha glClearColor(1, 0, 0, 0); triangle = new Triangle1(GLSureViewActivity.this); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { //设置视口尺寸,即告诉opengl可以用来渲染的surface大小 glViewport(0, 0, width, height); } @Override public void onDrawFrame(GL10 gl) { //Third:清空屏幕,擦除屏幕上所有的颜色,并用之前glClearColor定义的颜色填充整个屏幕 glClear(GL_COLOR_BUFFER_BIT); //绘制三角形 triangle.draw(); } }; }