Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save guodong1111/6270b1e6d9ef62747f65b2fefbf1ccd2 to your computer and use it in GitHub Desktop.
Save guodong1111/6270b1e6d9ef62747f65b2fefbf1ccd2 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 = "u_TexelWidth";
private static final String UNIFORM_TEXELHEIGHT = "u_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"
+"uniform samplerExternalOES "+UNIFORM_OES+";\n"
+"uniform float "+UNIFORM_TEXELWIDTH+";\n"
+"uniform float "+UNIFORM_TEXELHEIGHT+";\n"
+ "\n"
+"void main(){\n"
+ " gl_FragColor = texture2D(" + UNIFORM_OES + ", " + VARYING_TEXCOORD + ");\n"
+"}\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);
GLES20.glUniform1f(shader.glShader.getUniformLocation(UNIFORM_TEXELWIDTH), frameWidth);
GLES20.glUniform1f(shader.glShader.getUniformLocation(UNIFORM_TEXELHEIGHT), frameHeight);
}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