/* * Copyright (C) 2018 Baidu, Inc. All Rights Reserved. */ package com.example.datalibrary.view; import android.opengl.GLES20; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; /** * GL图形绘制渲染器 */ public class ColorViewImpl { private int program1; private int textureI; private int tIindex; private float[] vertices; private int positionHandle1 = -1; private int coordHandle1 = -1; private int yhandle = -1; private int ytid = -1; private ByteBuffer verticebuffer; private ByteBuffer coordbuffer; private int videowidth = -1; private int videoheight = -1; private boolean isProgBuilt = false; public ColorViewImpl() { setup(); } private void setup() { vertices = squareVertices; textureI = GLES20.GL_TEXTURE0; tIindex = 0; createBuffers(vertices); } private void createBuffers(float[] vert) { verticebuffer = ByteBuffer.allocateDirect(vert.length * 4); verticebuffer.order(ByteOrder.nativeOrder()); verticebuffer.asFloatBuffer().put(vert); verticebuffer.position(0); if (coordbuffer == null) { coordbuffer = ByteBuffer.allocateDirect(coordVertices.length * 4); coordbuffer.order(ByteOrder.nativeOrder()); coordbuffer.asFloatBuffer().put(coordVertices); coordbuffer.position(0); } } public void drawSelf() { // 将program加入OpenGL ES环境中 GLES20.glUseProgram(program1); // ShaderUtil.checkGlError("glUseProgram"); GLES20.glVertexAttribPointer(positionHandle1, 2, GLES20.GL_FLOAT, false, 8, verticebuffer); // ShaderUtil.checkGlError("glVertexAttribPointer mPositionHandle"); GLES20.glEnableVertexAttribArray(positionHandle1); GLES20.glVertexAttribPointer(coordHandle1, 2, GLES20.GL_FLOAT, false, 8, coordbuffer); // ShaderUtil.checkGlError("glVertexAttribPointer maTextureHandle"); GLES20.glEnableVertexAttribArray(coordHandle1); // bind textures GLES20.glActiveTexture(textureI); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, ytid); GLES20.glUniform1i(yhandle, tIindex); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glDisableVertexAttribArray(positionHandle1); GLES20.glDisableVertexAttribArray(coordHandle1); GLES20.glFinish(); } private static float[] squareVertices = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f}; private static float[] coordVertices = {0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f}; /** * 用于渲染形状的顶点的OpenGLES图形代码 */ private static final String VERTEX_SHADER = "attribute vec4 vPosition;\n" + "attribute vec2 a_texCoord;\n" + "varying vec2 tc;\n" + "void main() {\n" + "gl_Position = vPosition;\n" + "tc = a_texCoord;\n" + "}\n"; /** * 用于渲染形状的外观(颜色或纹理)的OpenGLES代码 */ private static final String FRAGMENT_SHADER = "precision mediump float;\n" + "uniform sampler2D tex_y;\n" + "varying vec2 tc;\n" + "void main() {\n" + "gl_FragColor = texture2D(tex_y,tc);\n" + "}\n"; public boolean isProgramBuilt() { return isProgBuilt; } public void buildProgram() { if (program1 <= 0) { program1 = ImiShaderUtil.createProgram(VERTEX_SHADER, FRAGMENT_SHADER); } // 获取指向vertex shader的成员vPosition的 handle positionHandle1 = GLES20.glGetAttribLocation(program1, "vPosition"); ImiShaderUtil.checkGlError("glGetAttribLocation vPosition"); if (positionHandle1 == -1) { throw new RuntimeException( "Could not get attribute location for vPosition"); } coordHandle1 = GLES20.glGetAttribLocation(program1, "a_texCoord"); ImiShaderUtil.checkGlError("glGetAttribLocation a_texCoord"); if (coordHandle1 == -1) { throw new RuntimeException( "Could not get attribute location for a_texCoord"); } yhandle = GLES20.glGetUniformLocation(program1, "tex_y"); ImiShaderUtil.checkGlError("glGetUniformLocation tex_y"); if (yhandle == -1) { throw new RuntimeException( "Could not get uniform location for tex_y"); } isProgBuilt = true; } public void buildTextures(Buffer rgbBuffer, int width, int height) { boolean videoSizeChanged = (width != videowidth || height != videoheight); if (videoSizeChanged) { videowidth = width; videoheight = height; } if (ytid < 0 || videoSizeChanged) { if (ytid >= 0) { GLES20.glDeleteTextures(1, new int[]{ytid}, 0); ImiShaderUtil.checkGlError("glDeleteTextures"); } int[] textures = new int[1]; GLES20.glGenTextures(1, textures, 0); ImiShaderUtil.checkGlError("glGenTextures"); ytid = textures[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, ytid); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); } GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, ytid); ImiShaderUtil.checkGlError("glBindTexture"); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, videowidth, videoheight, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, rgbBuffer); ImiShaderUtil.checkGlError("glTexImage2D"); } }