Created
June 29, 2017 04:05
-
-
Save guodong1111/4e10fad8e7f87b22472b8e73d24f54ea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.gogomaper.meat.feature.live_chat.apprtc; | |
import android.opengl.GLES20; | |
import org.webrtc.GlShader; | |
import org.webrtc.GlUtil; | |
import org.webrtc.RendererCommon; | |
import java.nio.FloatBuffer; | |
import java.util.IdentityHashMap; | |
import java.util.Iterator; | |
import java.util.Map; | |
/** | |
* Created by tony on 2017/6/28. | |
*/ | |
class GaussianBlurGlDrawer implements RendererCommon.GlDrawer { | |
private static final String VARYING_TEXCOORD = "interp_tc"; | |
private static final String ATTRIBUTE_POSITION = "a_Position"; | |
private static final String ATTRIBUTE_TEXCOORD = "a_TexCoord"; | |
private static final String UNIFORM_TEXMATRIX = "texMatrix"; | |
private static final String UNIFORM_YTEX = "y_tex"; | |
private static final String UNIFORM_UTEX = "u_tex"; | |
private static final String UNIFORM_VTEX = "v_tex"; | |
private static final String UNIFORM_RGB = "rgb_tex"; | |
private static final String UNIFORM_OES = "oes_tex"; | |
private static final String UNIFORM_TEXELWIDTH = "texelWidth"; | |
private static final String UNIFORM_TEXELHEIGHT = "texelHeight"; | |
private static final String VERTEX_SHADER_STRING = | |
"varying vec2 " + VARYING_TEXCOORD + ";\n" | |
+ "attribute vec4 " + ATTRIBUTE_POSITION + ";\n" | |
+ "attribute vec4 " + ATTRIBUTE_TEXCOORD + ";\n" | |
+ "\n" | |
+ "uniform mat4 " + UNIFORM_TEXMATRIX + ";\n" | |
+ "\n" | |
+ "void main() {\n" | |
+ " gl_Position = " + ATTRIBUTE_POSITION + ";\n" | |
+ " " + VARYING_TEXCOORD + " = (" + UNIFORM_TEXMATRIX + " * " + ATTRIBUTE_TEXCOORD + ").xy;\n" | |
+ "}\n"; | |
private static final String YUV_FRAGMENT_SHADER_STRING = | |
"precision mediump float;\n" | |
+ "varying vec2 " + VARYING_TEXCOORD + ";\n" | |
+ "\n" | |
+ "uniform sampler2D " + UNIFORM_YTEX + ";\n" | |
+ "uniform sampler2D " + UNIFORM_UTEX + ";\n" | |
+ "uniform sampler2D " + UNIFORM_VTEX + ";\n" | |
+ "\n" | |
+ "void main() {\n" | |
+ " float y = texture2D(" + UNIFORM_YTEX + ", " + VARYING_TEXCOORD + ").r;\n" | |
+ " float u = texture2D(" + UNIFORM_UTEX + ", " + VARYING_TEXCOORD + ").r - 0.5;\n" | |
+ " float v = texture2D(" + UNIFORM_VTEX + ", " + VARYING_TEXCOORD + ").r - 0.5;\n" | |
+ " gl_FragColor = vec4(y + 1.403 * v, " | |
+ " y - 0.344 * u - 0.714 * v, " | |
+ " y + 1.77 * u, 1);\n" | |
+ "}\n"; | |
private static final String RGB_FRAGMENT_SHADER_STRING = | |
"precision mediump float;\n" | |
+ "varying vec2 " + VARYING_TEXCOORD + ";\n" | |
+ "uniform sampler2D " + UNIFORM_RGB + ";\n" | |
+ "\n" | |
+ "void main() {\n" | |
+ " gl_FragColor = texture2D(" + UNIFORM_RGB + ", " + VARYING_TEXCOORD + ");\n" | |
+ "}\n"; | |
// private static final String OES_FRAGMENT_SHADER_STRING = | |
// "#extension GL_OES_EGL_image_external : require\n" + | |
// "precision mediump float;\n" + | |
// "varying vec2 " + VARYING_TEXCOORD + ";\n" + | |
// "\n" + | |
// "uniform samplerExternalOES " + UNIFORM_OES + ";\n" + | |
// "float resolution = float(1);\n" + | |
// "float radius = float(1000);\n" + | |
// "vec2 dir = vec2(0,0);\n" + | |
// "\n" + | |
// "void main() {\n" + | |
// " vec4 sum = vec4(0.0);\n" + | |
// "\n" + | |
// " vec2 tc = " + VARYING_TEXCOORD + ";\n" + | |
// "\n" + | |
// " float blur = radius/resolution; \n" + | |
// "\n" + | |
// " float hstep = dir.x;\n" + | |
// " float vstep = dir.y;\n" + | |
// "\n" + | |
// " vec4 color = texture2D("+UNIFORM_OES+", "+VARYING_TEXCOORD+");\n" + | |
// " sum += texture2D(" + UNIFORM_OES + ", vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;\n" + | |
// " sum += texture2D(" + UNIFORM_OES + ", vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;\n" + | |
// " sum += texture2D(" + UNIFORM_OES + ", vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;\n" + | |
// " sum += texture2D(" + UNIFORM_OES + ", vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;\n" + | |
// "\n" + | |
// " sum += texture2D(" + UNIFORM_OES + ", vec2(tc.x, tc.y)) * 0.2270270270;\n" + | |
// "\n" + | |
// " sum += texture2D(" + UNIFORM_OES + ", vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;\n" + | |
// " sum += texture2D(" + UNIFORM_OES + ", vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;\n" + | |
// " sum += texture2D(" + UNIFORM_OES + ", vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;\n" + | |
// " sum += texture2D(" + UNIFORM_OES + ", vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;\n" + | |
// "\n" + | |
// " gl_FragColor = color * vec4(sum.rgb, 1.0);\n" + | |
// "}"; | |
private static final String OES_FRAGMENT_SHADER_STRING = | |
"#extension GL_OES_EGL_image_external : require\n" + | |
"precision mediump float;\n" + | |
"uniform samplerExternalOES " + UNIFORM_OES + ";\n" + | |
"varying vec2 " + VARYING_TEXCOORD + ";\n" + | |
"\n" + | |
"float bias = float(20);\n" + | |
" \n" + | |
"void main() {\n" + | |
" vec4 texColor = texture2D(" + UNIFORM_OES + ", " + VARYING_TEXCOORD + ", bias);\n" + | |
" vec4 vColor = texture2D("+UNIFORM_OES+", "+VARYING_TEXCOORD+");\n" + | |
" gl_FragColor = texColor;\n" + | |
"}"; | |
private static final FloatBuffer FULL_RECTANGLE_BUF = GlUtil.createFloatBuffer(new float[]{-1.0F, -1.0F, 1.0F, -1.0F, -1.0F, 1.0F, 1.0F, 1.0F}); | |
private static final FloatBuffer FULL_RECTANGLE_TEX_BUF = GlUtil.createFloatBuffer(new float[]{0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F}); | |
private final Map<String, GaussianBlurGlDrawer.Shader> shaders = new IdentityHashMap(); | |
public GaussianBlurGlDrawer() { | |
} | |
public void drawOes(int oesTextureId, float[] texMatrix, int frameWidth, int frameHeight, int viewportX, int viewportY, int viewportWidth, int viewportHeight) { | |
this.prepareShader(OES_FRAGMENT_SHADER_STRING, texMatrix, frameWidth, frameHeight); | |
GLES20.glActiveTexture('蓀'); | |
GLES20.glBindTexture('赥', oesTextureId); | |
this.drawRectangle(viewportX, viewportY, viewportWidth, viewportHeight); | |
GLES20.glBindTexture('赥', 0); | |
} | |
public void drawRgb(int textureId, float[] texMatrix, int frameWidth, int frameHeight, int viewportX, int viewportY, int viewportWidth, int viewportHeight) { | |
this.prepareShader(RGB_FRAGMENT_SHADER_STRING, texMatrix, frameWidth, frameHeight); | |
GLES20.glActiveTexture('蓀'); | |
GLES20.glBindTexture(3553, textureId); | |
this.drawRectangle(viewportX, viewportY, viewportWidth, viewportHeight); | |
GLES20.glBindTexture(3553, 0); | |
} | |
public void drawYuv(int[] yuvTextures, float[] texMatrix, int frameWidth, int frameHeight, int viewportX, int viewportY, int viewportWidth, int viewportHeight) { | |
this.prepareShader(YUV_FRAGMENT_SHADER_STRING, texMatrix, frameWidth, frameHeight); | |
int i; | |
for(i = 0; i < 3; ++i) { | |
GLES20.glActiveTexture('蓀' + i); | |
GLES20.glBindTexture(3553, yuvTextures[i]); | |
} | |
this.drawRectangle(viewportX, viewportY, viewportWidth, viewportHeight); | |
for(i = 0; i < 3; ++i) { | |
GLES20.glActiveTexture('蓀' + i); | |
GLES20.glBindTexture(3553, 0); | |
} | |
} | |
private void drawRectangle(int x, int y, int width, int height) { | |
GLES20.glViewport(x, y, width, height); | |
GLES20.glDrawArrays(5, 0, 4); | |
} | |
private void prepareShader(String fragmentShader, float[] texMatrix, int frameWidth, int frameHeight) { | |
GaussianBlurGlDrawer.Shader shader; | |
if(this.shaders.containsKey(fragmentShader)) { | |
shader = (GaussianBlurGlDrawer.Shader)this.shaders.get(fragmentShader); | |
} else { | |
shader = new GaussianBlurGlDrawer.Shader(fragmentShader); | |
this.shaders.put(fragmentShader, shader); | |
shader.glShader.useProgram(); | |
if(YUV_FRAGMENT_SHADER_STRING.equals(fragmentShader)) { | |
GLES20.glUniform1i(shader.glShader.getUniformLocation(UNIFORM_YTEX), 0); | |
GLES20.glUniform1i(shader.glShader.getUniformLocation(UNIFORM_UTEX), 1); | |
GLES20.glUniform1i(shader.glShader.getUniformLocation(UNIFORM_VTEX), 2); | |
} else if(RGB_FRAGMENT_SHADER_STRING.equals(fragmentShader)) { | |
GLES20.glUniform1i(shader.glShader.getUniformLocation(UNIFORM_RGB), 0); | |
} else if(OES_FRAGMENT_SHADER_STRING.equals(fragmentShader)) { | |
GLES20.glUniform1i(shader.glShader.getUniformLocation(UNIFORM_OES), 0); | |
}else { | |
throw new IllegalStateException("Unknown fragment shader: " + fragmentShader); | |
} | |
GlUtil.checkNoGLES2Error("Initialize fragment shader uniform values."); | |
shader.glShader.setVertexAttribArray(ATTRIBUTE_POSITION, 2, FULL_RECTANGLE_BUF); | |
shader.glShader.setVertexAttribArray(ATTRIBUTE_TEXCOORD, 2, FULL_RECTANGLE_TEX_BUF); | |
} | |
shader.glShader.useProgram(); | |
GLES20.glUniformMatrix4fv(shader.texMatrixLocation, 1, false, texMatrix, 0); | |
} | |
public void release() { | |
Iterator i$ = this.shaders.values().iterator(); | |
while(i$.hasNext()) { | |
GaussianBlurGlDrawer.Shader shader = (GaussianBlurGlDrawer.Shader)i$.next(); | |
shader.glShader.release(); | |
} | |
this.shaders.clear(); | |
} | |
private static class Shader { | |
public final GlShader glShader; | |
public final int texMatrixLocation; | |
public Shader(String fragmentShader) { | |
this.glShader = new GlShader(VERTEX_SHADER_STRING, fragmentShader); | |
this.texMatrixLocation = this.glShader.getUniformLocation(UNIFORM_TEXMATRIX); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment