package com.example.datalibrary.lim; import android.annotation.SuppressLint; import android.opengl.GLES20; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; public class GLGraphics { 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 }; 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"; 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"; private FloatBuffer mVertexBuffer; private FloatBuffer mColorBuffer; private ByteBuffer coordbuffer; private ByteBuffer verticebuffer; private int mVertexCount = -1; private int mProgram = 0; private int mTexture = 0; private int mIndex = 0; private int mPositionHandle = -1; private int mCoordHandle = -1; private int yhandle = -1; private int ytid = -1; private int mGraphWidth = -1; private int mGraphHeight = -1; private boolean isProgBuilt = false; public GLGraphics() { mTexture = GLES20.GL_TEXTURE0; createBuffers(); } private void createBuffers() { verticebuffer = ByteBuffer.allocateDirect(squareVertices.length * 4); verticebuffer.order(ByteOrder.nativeOrder()); verticebuffer.asFloatBuffer().put(squareVertices); verticebuffer.position(0); coordbuffer = ByteBuffer.allocateDirect(coordVertices.length * 4); coordbuffer.order(ByteOrder.nativeOrder()); coordbuffer.asFloatBuffer().put(coordVertices); coordbuffer.position(0); } public void setVertexData(float[] vertices) { if (vertices != null) { mVertexCount = vertices.length / 3; ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asFloatBuffer(); mVertexBuffer.put(vertices); mVertexBuffer.position(0); float[] colors = new float[mVertexCount * 4]; for (int i = 0; i < colors.length; i++) { if (i % 4 == 3) { colors[i] = 0; } else { colors[i] = 1; } } ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); cbb.order(ByteOrder.nativeOrder()); mColorBuffer = cbb.asFloatBuffer(); mColorBuffer.put(colors); mColorBuffer.position(0); } } @SuppressLint("NewApi") public void draw() { GLES20.glUseProgram(mProgram); ShaderUtil.checkGlError("glUseProgram"); GLES20.glVertexAttribPointer(mPositionHandle, 2, GLES20.GL_FLOAT, false, 8, verticebuffer); ShaderUtil.checkGlError("glVertexAttribPointer mPositionHandle"); GLES20.glEnableVertexAttribArray(mPositionHandle); GLES20.glVertexAttribPointer(mCoordHandle, 2, GLES20.GL_FLOAT, false, 8, coordbuffer); ShaderUtil.checkGlError("glVertexAttribPointer maTextureHandle"); GLES20.glEnableVertexAttribArray(mCoordHandle); // bind textures GLES20.glActiveTexture(mTexture); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, ytid); GLES20.glUniform1i(yhandle, mIndex); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glDisableVertexAttribArray(mPositionHandle); GLES20.glDisableVertexAttribArray(mCoordHandle); } public boolean isProgramBuilt() { return isProgBuilt; } @SuppressLint("NewApi") public void buildProgram() { if (mProgram <= 0) { mProgram = ShaderUtil.createProgram(VERTEX_SHADER, FRAGMENT_SHADER); } mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); ShaderUtil.checkGlError("glGetAttribLocation vPosition"); if (mPositionHandle == -1) { throw new RuntimeException( "Could not get attribute location for vPosition"); } mCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_texCoord"); ShaderUtil.checkGlError("glGetAttribLocation a_texCoord"); if (mCoordHandle == -1) { throw new RuntimeException( "Could not get attribute location for a_texCoord"); } yhandle = GLES20.glGetUniformLocation(mProgram, "tex_y"); ShaderUtil.checkGlError("glGetUniformLocation tex_y"); if (yhandle == -1) { throw new RuntimeException( "Could not get uniform location for tex_y"); } isProgBuilt = true; } @SuppressLint("NewApi") public void buildTextures(Buffer rgbBuffer, int width, int height) { boolean videoSizeChanged = (width != mGraphWidth || height != mGraphHeight); if (videoSizeChanged) { mGraphWidth = width; mGraphHeight = height; } if (ytid < 0 || videoSizeChanged) { if (ytid >= 0) { GLES20.glDeleteTextures(1, new int[] { ytid }, 0); ShaderUtil.checkGlError("glDeleteTextures"); } int[] textures = new int[1]; GLES20.glGenTextures(1, textures, 0); ShaderUtil.checkGlError("glGenTextures"); ytid = textures[0]; } GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, ytid); ShaderUtil.checkGlError("glBindTexture"); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, mGraphWidth, mGraphHeight, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, rgbBuffer); ShaderUtil.checkGlError("glTexImage2D"); 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); } }