Back to project page FxCameraApp.
The source code is released under:
MIT License
If you think the Android project FxCameraApp listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.af.experiments.FxCameraApp.renderer; /*ww w . ja va 2s . c o m*/ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.SurfaceTexture; import android.hardware.Camera; import android.opengl.GLES11Ext; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.util.Log; import com.af.experiments.FxCameraApp.R; import com.af.experiments.FxCameraApp.Utils.OpenGlUtils; import com.af.experiments.FxCameraApp.View.GlPreview; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.util.List; public class MainRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener { private final String vss = "attribute vec2 vPosition;\n" + "attribute vec2 vTexCoord;\n" + "varying vec2 texCoord;\n" + "void main() {\n" + " texCoord = vTexCoord;\n" + " gl_Position = vec4 ( vPosition.x, vPosition.y, 0.0, 1.0 );\n" + "}"; private final String fss = "#extension GL_OES_EGL_image_external : require\n" + "varying mediump vec2 texCoord;\n" + "precision mediump float;\n" + "uniform samplerExternalOES sTexture;\n" + "uniform sampler2D iChannel1;\n" + "\n" + "int off0 = 0;\n" + "int off1 = 1;\n" + "int off2 = 16; \n" + "int off3 = 17;\n" + "int off4 = 256;\n" + "int off5 = 257;\n" + "int off6 = 272;\n" + "int off7 = 273;\n" + "\n" + "\n" + "float interpr(int p, float dr,float dg, float db) { \n" + " float fr00 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off0),float(256.0)))), int(abs(float(p+off0)/256.0)))).r*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off1),float(256.0)))), int(abs(float(p+off1)/256.0)))).r*1.0*dr;\n" + " float fr01 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off2),float(256.0)))), int(abs(float(p+off2)/256.0)))).r*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off3),float(256.0)))), int(abs(float(p+off3)/256.0)))).r*1.0*dr;\n" + " float fr10 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off4),float(256.0)))), int(abs(float(p+off4)/256.0)))).r*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off5),float(256.0)))), int(abs(float(p+off5)/256.0)))).r*1.0*dr;\n" + " float fr11 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off6),float(256.0)))), int(abs(float(p+off6)/256.0)))).r*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off7),float(256.0)))), int(abs(float(p+off7)/256.0)))).r*1.0*dr;\n" + " \n" + " float frb0 = fr00 * (1.0-db)+fr01*db;\n" + " float frb1 = fr10 * (1.0-db)+fr11*db;\n" + " float frbg = frb0 * (1.0-dg)+frb1*dg;\n" + "\n" + " return frbg;\n" + "}\n" + "\n" + "float interpg(int p, float dr,float dg, float db) { \n" + " float fr00 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off0),float(256.0)))), int(abs(float(p+off0)/256.0)))).g*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off1),float(256.0)))), int(abs(float(p+off1)/256.0)))).g*1.0*dr;\n" + " float fr01 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off2),float(256.0)))), int(abs(float(p+off2)/256.0)))).g*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off3),float(256.0)))), int(abs(float(p+off3)/256.0)))).g*1.0*dr;\n" + " float fr10 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off4),float(256.0)))), int(abs(float(p+off4)/256.0)))).g*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off5),float(256.0)))), int(abs(float(p+off5)/256.0)))).g*1.0*dr;\n" + " float fr11 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off6),float(256.0)))), int(abs(float(p+off6)/256.0)))).g*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off7),float(256.0)))), int(abs(float(p+off7)/256.0)))).g*1.0*dr;\n" + "\n" + "\n" + " \n" + " float frb0 = fr00 * (1.0-db)+fr01*db;\n" + " float frb1 = fr10 * (1.0-db)+fr11*db;\n" + " float frbg = frb0 * (1.0-dg)+frb1*dg;\n" + "\n" + " return frbg;\n" + "}\n" + "\n" + "float interpb(int p, float dr,float dg, float db) { \n" + " float fr00 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off0),float(256.0)))), int(abs(float(p+off0)/256.0)))).b*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off1),float(256.0)))), int(abs(float(p+off1)/256.0)))).b*1.0*dr;\n" + " float fr01 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off2),float(256.0)))), int(abs(float(p+off2)/256.0)))).b*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off3),float(256.0)))), int(abs(float(p+off3)/256.0)))).b*1.0*dr;\n" + " float fr10 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off4),float(256.0)))), int(abs(float(p+off4)/256.0)))).b*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off5),float(256.0)))), int(abs(float(p+off5)/256.0)))).b*1.0*dr;\n" + " float fr11 = \n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off6),float(256.0)))), int(abs(float(p+off6)/256.0)))).b*1.0*(1.0 - dr) +\n" + " texture2D(iChannel1, vec2(int(abs(mod(float(p+off7),float(256.0)))), int(abs(float(p+off7)/256.0)))).b*1.0*dr;\n" + " \n" + " float frb0 = fr00 * (1.0-db)+fr01*db;\n" + " float frb1 = fr10 * (1.0-db)+fr11*db;\n" + " float frbg = frb0 * (1.0-dg)+frb1*dg;\n" + "\n" + " return frbg;\n" + "}\n" + "\n" + "\n" + "mediump vec4 Sepia( mediump vec4 color ) {\n" + "\treturn vec4(\n" + " clamp(color.r * 0.393 + color.g * 0.769 + color.b * 0.189, 0.0, 1.0),\n" + " clamp(color.r * 0.349 + color.g * 0.686 + color.b * 0.168, 0.0, 1.0),\n" + " clamp(color.r * 0.272 + color.g * 0.534 + color.b * 0.131, 0.0, 1.0), \n" + " color.a );\n" + "} \n" + "\n" + "float scale_R = (16.0-1.0)/256.0;\n" + "float scale_G = (16.0-1.0)/256.0;\n" + "float scale_B = (16.0-1.0)/256.0;\n" + "\n" + "void main(void)\n" + "{\n" + "\t\n" + " vec4 color = texture2D(sTexture, texCoord );\n" + " float r = color.r;\n" + " float b = color.b;\n" + " float g = color.g;\n" + " \n" + " float fb = b*scale_B;\n" + "\tfloat fg = g*scale_G;\n" + "\tfloat fr = r*scale_R;\n" + "\tfloat lut_b = fb;\n" + "\tfloat lut_g = fg;\n" + "\tfloat lut_r = fr;\n" + "\tint p = int(lut_r+lut_b*16.0+lut_g*16.0*16.0);\n" + " \n" + "\tfloat dr = fr-lut_r;\n" + "\tfloat dg = fg-lut_g;\n" + "\tfloat db = fb-lut_b;\n" + " \n" + " color.r = dr; //interpr(p, dr,dg,db);\n" + " color.g = dg; //interpg(p, dr,dg,db);\n" + " color.b = db; //interpb(p, dr,dg,db);\n" + "\t\n" + " gl_FragColor = color;\n" + "}"; private final String fss_sepia = "#extension GL_OES_EGL_image_external : require\n" + "varying mediump vec2 texCoord;\n" + "precision mediump float;\n" + "uniform samplerExternalOES sTexture;\n" + "void main() {\n" + " vec4 FragColor = texture2D(sTexture, texCoord);\n" + " gl_FragColor.r = dot(FragColor.rgb, vec3(.393, .769, .189));\n" + " gl_FragColor.g = dot(FragColor.rgb, vec3(.349, .686, .168));\n" + " gl_FragColor.b = dot(FragColor.rgb, vec3(.272, .534, .131));\n" + "}"; private int[] hTex; private FloatBuffer pVertex; private FloatBuffer pTexCoord; private int hProgram; private int sepiaProgram; private int cyanoProgram; private Camera mCamera; private SurfaceTexture mSTexture; private boolean mUpdateST = false; private GlPreview mView; public MainRenderer ( GlPreview view ) { mView = view; float[] vtmp = { 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f }; float[] ttmp = { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; pVertex = ByteBuffer.allocateDirect(8 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); pVertex.put ( vtmp ); pVertex.position(0); pTexCoord = ByteBuffer.allocateDirect(8*4).order(ByteOrder.nativeOrder()).asFloatBuffer(); pTexCoord.put ( ttmp ); pTexCoord.position(0); } public void close() { mUpdateST = false; mSTexture.release(); mCamera.stopPreview(); mCamera = null; deleteTex(); } public void onSurfaceCreated ( GL10 unused, EGLConfig config ) { //String extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS); //Log.i("mr", "Gl extensions: " + extensions); //Assert.assertTrue(extensions.contains("OES_EGL_image_external")); initTex(); mSTexture = new SurfaceTexture ( hTex[0] ); mSTexture.setOnFrameAvailableListener(this); mCamera = Camera.open(); try { mCamera.setPreviewTexture(mSTexture); } catch ( IOException ioe ) { } GLES20.glClearColor(1.0f, 1.0f, 0.0f, 1.0f); hProgram = loadShader ( vss, fss ); sepiaProgram = loadShader(vss, fss_sepia); hProgram = sepiaProgram; } public void onDrawFrame ( GL10 unused ) { GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT ); synchronized(this) { if ( mUpdateST ) { mSTexture.updateTexImage(); mUpdateST = false; } } GLES20.glUseProgram(hProgram); int ph = GLES20.glGetAttribLocation(hProgram, "vPosition"); int tch = GLES20.glGetAttribLocation ( hProgram, "vTexCoord" ); int th = GLES20.glGetUniformLocation ( hProgram, "sTexture" ); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex[0]); GLES20.glUniform1i(th, 0); int offsetDepthMapTextureUniform = GLES20.glGetUniformLocation(hProgram, "iChannel1"); GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, hTex[1]); GLES20.glUniform1i(offsetDepthMapTextureUniform, 3); GLES20.glVertexAttribPointer(ph, 2, GLES20.GL_FLOAT, false, 4*2, pVertex); GLES20.glVertexAttribPointer(tch, 2, GLES20.GL_FLOAT, false, 4*2, pTexCoord ); GLES20.glEnableVertexAttribArray(ph); GLES20.glEnableVertexAttribArray(tch); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glFlush(); } public void onSurfaceChanged ( GL10 unused, int width, int height ) { GLES20.glViewport( 0, 0, width, height ); Camera.Parameters param = mCamera.getParameters(); List<Camera.Size> psize = param.getSupportedPreviewSizes(); if ( psize.size() > 0 ) { int i; for ( i = 0; i < psize.size(); i++ ) { if ( psize.get(i).width < width || psize.get(i).height < height ) break; } if ( i > 0 ) i--; param.setPreviewSize(psize.get(i).width, psize.get(i).height); //Log.i("mr","ssize: "+psize.get(i).width+", "+psize.get(i).height); } param.set("orientation", "landscape"); //param.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); mCamera.setParameters ( param ); mCamera.startPreview(); } private void initTex() { BitmapFactory.Options o = new BitmapFactory.Options(); o.inScaled = false; int mFxBitmapId = R.drawable.ic_launcher; Bitmap mFxBitmap = BitmapFactory.decodeResource(mView.getResources(), mFxBitmapId, o); hTex = new int[2]; GLES20.glGenTextures ( 2, hTex, 0 ); hTex[1] = -1; GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex[0]); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); hTex[1] = OpenGlUtils.loadTexture(mFxBitmap, hTex[1], true); } private void deleteTex() { GLES20.glDeleteTextures ( 1, hTex, 0 ); } public synchronized void onFrameAvailable ( SurfaceTexture st ) { mUpdateST = true; mView.requestRender(); } private static int loadShader ( String vss, String fss ) { int vshader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER); GLES20.glShaderSource(vshader, vss); GLES20.glCompileShader(vshader); int[] compiled = new int[1]; GLES20.glGetShaderiv(vshader, GLES20.GL_COMPILE_STATUS, compiled, 0); if (compiled[0] == 0) { Log.e("Shader", "Could not compile vshader"); Log.v("Shader", "Could not compile vshader:"+GLES20.glGetShaderInfoLog(vshader)); GLES20.glDeleteShader(vshader); vshader = 0; } int fshader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER); GLES20.glShaderSource(fshader, fss); GLES20.glCompileShader(fshader); GLES20.glGetShaderiv(fshader, GLES20.GL_COMPILE_STATUS, compiled, 0); if (compiled[0] == 0) { Log.e("Shader", "Could not compile fshader"); Log.v("Shader", "Could not compile fshader:"+GLES20.glGetShaderInfoLog(fshader)); GLES20.glDeleteShader(fshader); fshader = 0; } int program = GLES20.glCreateProgram(); GLES20.glAttachShader(program, vshader); GLES20.glAttachShader(program, fshader); GLES20.glLinkProgram(program); return program; } }