Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save guodong1111/4e10fad8e7f87b22472b8e73d24f54ea to your computer and use it in GitHub Desktop.
Save guodong1111/4e10fad8e7f87b22472b8e73d24f54ea to your computer and use it in GitHub Desktop.
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