由于android 采集出来的是OES的所以绘制的时候要设置成OES,这个类实现了直接绘制OES或把OES转成标准纹理ID然后绘制 OpenGlUtils类是android gpuImage里面的 //------------------------------------------------------- protected DrawTexture dOES; //用法 @SuppressLint("WrongCall") @Override public void onDrawFrame(GL10 gl) { synchronized(mRunOnDraw) { while(!mRunOnDraw.isEmpty()) { mRunOnDraw.poll().run(); } } synchronized(this) { if (mUpdateSurfaceTex) { mSurfaceTexture.updateTexImage(); mSurfaceTexture.getTransformMatrix(mTextureTransformMatrix); mUpdateSurfaceTex = false; } } dOES.setTextureTransformMatrix(mTextureTransformMatrix); dOES.onDrawTextOES(mOutputTextureId, mOutputWidth, mOutputHeight); //int textId = dOES.onDrawTexOESToTex2D(mOutputTextureId); //dOES.onDrawText2D(textId, mOutputWidth, mOutputHeight); } @Override public void onSurfaceCreated(GL10 arg0, javax.microedition.khronos.egl.EGLConfig arg1) { dOES = new DrawTexture(mPreviewWidth, mPreviewHeight); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { mOutputWidth = width; mOutputHeight = height; } //------------------------------------------------------- public class DrawTexture { private static final String CAMERA_INPUT_VERTEX_SHADER = ""+ "attribute vec4 position;\n" + "attribute vec4 inputTextureCoordinate;\n" + "\n" + "uniform mat4 textureTransform;\n" + "varying vec2 textureCoordinate;\n" + "\n" + "void main()\n" + "{\n" + " textureCoordinate = (textureTransform * inputTextureCoordinate).xy;\n" + " gl_Position = position;\n" + "}"; private static final String CAMERA_INPUT_FRAGMENT_SHADER = ""+ "#extension GL_OES_EGL_image_external : require\n" + "//varying highp vec2 textureCoordinate;\n" + "\n" + "precision mediump float;\n" + "varying vec2 textureCoordinate;\n" + "uniform samplerExternalOES inputImageTexture;\n" + "\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(inputImageTexture, textureCoordinate);\n" + "}"; private float[] mTextureTransformMatrix; private int mTextureTransformMatrixLocation; private final String mVertexShader; private final String mFragmentShader; protected int mGLProgId; protected int mGLAttribPosition; protected int mGLUniformTexture; protected int mGLAttribTextureCoordinate; protected FloatBuffer mGLCubeBuffer; protected FloatBuffer mGLTextureBuffer; protected int[] mFrameBuffers = null; protected int[] mFrameBufferTextures = null; private int mFrameWidth = -1; private int mFrameHeight = -1; private DrawText2D drawText2D; private final float vertexPoint[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; private final float texturePoint[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, }; public DrawTexture(int width, int height){ mVertexShader = CAMERA_INPUT_VERTEX_SHADER; mFragmentShader = CAMERA_INPUT_FRAGMENT_SHADER; mGLCubeBuffer = ByteBuffer.allocateDirect(vertexPoint.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); mGLCubeBuffer.put(vertexPoint).position(0); mGLTextureBuffer = ByteBuffer.allocateDirect(texturePoint.length * 4) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); mGLTextureBuffer.put(texturePoint).position(0); mFrameWidth = width; mFrameHeight = height; drawText2D = new DrawText2D(); onInit(); initCameraFrameBuffer(); } protected void onInit() { mGLProgId = OpenGlUtils.loadProgram(mVertexShader, mFragmentShader); mGLAttribPosition = GLES20.glGetAttribLocation(mGLProgId, "position"); mGLUniformTexture = GLES20.glGetUniformLocation(mGLProgId, "inputImageTexture"); mGLAttribTextureCoordinate = GLES20.glGetAttribLocation(mGLProgId, "inputTextureCoordinate"); mTextureTransformMatrixLocation = GLES20.glGetUniformLocation(mGLProgId, "textureTransform"); } public void setTextureTransformMatrix(float[] mtx){ mTextureTransformMatrix = mtx; } public final void destroy() { drawText2D.destroy(); destroyFramebuffers(); GLES20.glDeleteProgram(mGLProgId); } public int onDrawText2D(int textureId, int displayWidth, int displayHeight) { drawText2D.onDrawText2D(textureId, displayWidth, displayHeight); return 0; } public int onDrawTextOES(int textureId, int displayWidth, int displayHeight) { GLES20.glViewport(0, 0, displayWidth, displayHeight); GLES20.glUseProgram(mGLProgId); mGLCubeBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribPosition, 2, GLES20.GL_FLOAT, false, 0, mGLCubeBuffer); GLES20.glEnableVertexAttribArray(mGLAttribPosition); mGLTextureBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, mGLTextureBuffer); GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glUniformMatrix4fv(mTextureTransformMatrixLocation, 1, false, mTextureTransformMatrix, 0); if(textureId != 0){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); GLES20.glUniform1i(mGLUniformTexture, 0); } GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(mGLAttribPosition); GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); return 0; } public int onDrawTexOESToTex2D(int textureId) { if(mFrameBuffers == null) return -2; GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffers[0]); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0]); GLES20.glViewport(0, 0, mFrameWidth, mFrameHeight); GLES20.glUseProgram(mGLProgId); mGLCubeBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribPosition, 2, GLES20.GL_FLOAT, false, 0, mGLCubeBuffer); GLES20.glEnableVertexAttribArray(mGLAttribPosition); mGLTextureBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, mGLTextureBuffer); GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glUniformMatrix4fv(mTextureTransformMatrixLocation, 1, false, mTextureTransformMatrix, 0); if(textureId != -1){ GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); GLES20.glUniform1i(mGLUniformTexture, 0); } GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(mGLAttribPosition); GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); return mFrameBufferTextures[0]; } public void initCameraFrameBuffer() { if (mFrameBuffers == null) { mFrameBuffers = new int[1]; mFrameBufferTextures = new int[1]; GLES20.glGenFramebuffers(1, mFrameBuffers, 0); GLES20.glGenTextures(1, mFrameBufferTextures, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0]); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, mFrameWidth, mFrameHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); 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); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffers[0]); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0], 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); } } public void destroyFramebuffers() { if (mFrameBufferTextures != null) { GLES20.glDeleteTextures(1, mFrameBufferTextures, 0); mFrameBufferTextures = null; } if (mFrameBuffers != null) { GLES20.glDeleteFramebuffers(1, mFrameBuffers, 0); mFrameBuffers = null; } mFrameWidth = -1; mFrameHeight = -1; } class DrawText2D { public static final String NO_FILTER_VERTEX_SHADER = "" + "attribute vec4 position;\n" + "attribute vec4 inputTextureCoordinate;\n" + " \n" + "varying vec2 textureCoordinate;\n" + " \n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " textureCoordinate = inputTextureCoordinate.xy;\n" + "}"; public static final String NO_FILTER_FRAGMENT_SHADER = "" + "varying highp vec2 textureCoordinate;\n" + " \n" + "uniform sampler2D inputImageTexture;\n" + " \n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(inputImageTexture, textureCoordinate);\n" + "}"; final float CUBE[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; final float TEXTURE_NO_ROTATION[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; protected FloatBuffer mGLCubeBuffer; protected FloatBuffer mGLTextureBuffer; private final String mVertexShader; private final String mFragmentShader; protected int mGLProgId; protected int mGLAttribPosition; protected int mGLUniformTexture; protected int mGLAttribTextureCoordinate; public DrawText2D() { this(NO_FILTER_VERTEX_SHADER, NO_FILTER_FRAGMENT_SHADER); } public DrawText2D(final String vertexShader, final String fragmentShader) { mVertexShader = vertexShader; mFragmentShader = fragmentShader; onInit(); } public void onInit() { 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(); mGLTextureBuffer.put(TEXTURE_NO_ROTATION).position(0); mGLProgId = OpenGlUtils.loadProgram(mVertexShader, mFragmentShader); mGLAttribPosition = GLES20.glGetAttribLocation(mGLProgId, "position"); mGLUniformTexture = GLES20.glGetUniformLocation(mGLProgId, "inputImageTexture"); mGLAttribTextureCoordinate = GLES20.glGetAttribLocation(mGLProgId, "inputTextureCoordinate"); } public final void destroy() { GLES20.glDeleteProgram(mGLProgId); } public void onDrawText2D(final int textureId, int displayWidth, int displayHeight) { GLES20.glViewport(0, 0, displayWidth, displayHeight); GLES20.glUseProgram(mGLProgId); mGLCubeBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribPosition, 2, GLES20.GL_FLOAT, false, 0, mGLCubeBuffer); GLES20.glEnableVertexAttribArray(mGLAttribPosition); mGLTextureBuffer.position(0); GLES20.glVertexAttribPointer(mGLAttribTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, mGLTextureBuffer); GLES20.glEnableVertexAttribArray(mGLAttribTextureCoordinate); if (textureId != OpenGlUtils.NO_TEXTURE) { GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId); GLES20.glUniform1i(mGLUniformTexture, 0); } GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(mGLAttribPosition); GLES20.glDisableVertexAttribArray(mGLAttribTextureCoordinate); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); } } }