package com.yinuo.library.vlc; import android.content.Context; import android.opengl.GLES20; import android.opengl.Matrix; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import static android.opengl.GLES20.glGetAttribLocation; import static android.opengl.GLES20.glGetUniformLocation; import static android.opengl.GLES20.glUniformMatrix4fv; import static android.opengl.Matrix.scaleM; import static android.opengl.Matrix.setIdentityM; /** * Created by liwentian on 17/6/22. */ public class RGBProgram extends ShaderProgram { protected final int mUniformSTextureLocation; protected final int mUniformMatrixLocation; static final float CUBE[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; public static final float TEXTURE_NO_ROTATION[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; // Attribute locations private final int aPositionLocation; private final int aTextureCoordinatesLocation; private final FloatBuffer mGLCubeBuffer; private final FloatBuffer mGLTextureBuffer; private int mTextureId; private ByteBuffer mBuffer; private float[] mMatrix = new float[16]; public RGBProgram(Context context, int width, int height) { super(context, R.raw.rgb_vertex, R.raw.rgb_fragment, width, height); mUniformSTextureLocation = glGetUniformLocation(program, "s_texture"); mUniformMatrixLocation = glGetUniformLocation(program, "u_Matrix"); aPositionLocation = glGetAttribLocation(program, "a_Position"); aTextureCoordinatesLocation = glGetAttribLocation(program, "a_TextureCoordinates"); mGLCubeBuffer = ByteBuffer.allocateDirect(CUBE.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); mGLCubeBuffer.put(CUBE).position(0); mGLTextureBuffer = ByteBuffer.allocateDirect(TEXTURE_NO_ROTATION.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); mBuffer = ByteBuffer.allocateDirect(width * height * 4) .order(ByteOrder.nativeOrder()); int[] textures = new int[1]; GLES20.glGenTextures(1, textures, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); mTextureId = textures[0]; mGLCubeBuffer.clear(); mGLCubeBuffer.put(CUBE).position(0); mGLTextureBuffer.clear(); mGLTextureBuffer.put(TEXTURE_NO_ROTATION).position(0); } public void setUniforms(byte[] data) { setUniforms(data, 0); } public void setUniforms(byte[] data, int rotateDegrees) { setUniforms(data, 1f, 1f, rotateDegrees); } public void setUniforms(byte[] data, float scaleX, float scaleY, int rotateDegrees) { mBuffer.position(0); mBuffer.put(data, 0, width * height * 4); mBuffer.position(0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureId); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mBuffer); GLES20.glUniform1i(mUniformSTextureLocation, 0); mGLCubeBuffer.position(0); GLES20.glVertexAttribPointer(aPositionLocation, 2, GLES20.GL_FLOAT, false, 0, mGLCubeBuffer); GLES20.glEnableVertexAttribArray(aPositionLocation); mGLTextureBuffer.position(0); GLES20.glVertexAttribPointer(aTextureCoordinatesLocation, 2, GLES20.GL_FLOAT, false, 0, mGLTextureBuffer); GLES20.glEnableVertexAttribArray(aTextureCoordinatesLocation); setIdentityM(mMatrix, 0); scaleM(mMatrix, 0, scaleX, scaleY, 1); Matrix.rotateM(mMatrix, 0, rotateDegrees, 0.0f, 0.0f, 1.0f); glUniformMatrix4fv(mUniformMatrixLocation, 1, false, mMatrix, 0); } public void draw() { GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(aPositionLocation); GLES20.glDisableVertexAttribArray(aTextureCoordinatesLocation); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glUseProgram(0); } }