forked from Doikki/DKVideoPlayer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Doikki#790 from Doikki/dev
视频滤镜功能
- Loading branch information
Showing
56 changed files
with
3,917 additions
and
6 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
133 changes: 133 additions & 0 deletions
133
dkplayer-sample/src/main/java/xyz/doikki/dkplayer/widget/render/gl2/EglUtil.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package xyz.doikki.dkplayer.widget.render.gl2; | ||
|
||
import static android.opengl.GLES20.GL_ARRAY_BUFFER; | ||
import static android.opengl.GLES20.GL_CLAMP_TO_EDGE; | ||
import static android.opengl.GLES20.GL_LINK_STATUS; | ||
import static android.opengl.GLES20.GL_STATIC_DRAW; | ||
import static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER; | ||
import static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER; | ||
import static android.opengl.GLES20.GL_TEXTURE_WRAP_S; | ||
import static android.opengl.GLES20.GL_TEXTURE_WRAP_T; | ||
import static android.opengl.GLES20.GL_TRUE; | ||
import static android.opengl.GLES20.glCreateProgram; | ||
|
||
import android.graphics.Bitmap; | ||
import android.opengl.GLES20; | ||
import android.opengl.GLException; | ||
import android.opengl.GLUtils; | ||
import android.util.Log; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.ByteOrder; | ||
import java.nio.FloatBuffer; | ||
|
||
import xyz.doikki.dkplayer.BuildConfig; | ||
|
||
|
||
public class EglUtil { | ||
|
||
public static final int NO_TEXTURE = -1; | ||
|
||
private static final int FLOAT_SIZE_BYTES = 4; | ||
|
||
public static int loadShader(final String strSource, final int iType) { | ||
int[] compiled = new int[1]; | ||
int iShader = GLES20.glCreateShader(iType); | ||
GLES20.glShaderSource(iShader, strSource); | ||
GLES20.glCompileShader(iShader); | ||
GLES20.glGetShaderiv(iShader, GLES20.GL_COMPILE_STATUS, compiled, 0); | ||
if (compiled[0] == 0) { | ||
Log.d("Load Shader Failed", "Compilation\n" + GLES20.glGetShaderInfoLog(iShader)); | ||
return 0; | ||
} | ||
return iShader; | ||
} | ||
|
||
public static int createProgram(final int vertexShader, final int pixelShader) throws GLException { | ||
final int program = glCreateProgram(); | ||
if (program == 0) { | ||
throw new RuntimeException("Could not create program"); | ||
} | ||
|
||
GLES20.glAttachShader(program, vertexShader); | ||
GLES20.glAttachShader(program, pixelShader); | ||
|
||
GLES20.glLinkProgram(program); | ||
final int[] linkStatus = new int[1]; | ||
GLES20.glGetProgramiv(program, GL_LINK_STATUS, linkStatus, 0); | ||
if (linkStatus[0] != GL_TRUE) { | ||
GLES20.glDeleteProgram(program); | ||
throw new RuntimeException("Could not link program"); | ||
} | ||
return program; | ||
} | ||
|
||
public static void checkEglError(String operation) { | ||
if (!BuildConfig.DEBUG) return; | ||
int error; | ||
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { | ||
throw new RuntimeException(operation + ": glError " + error); | ||
} | ||
} | ||
|
||
public static void setupSampler(final int target, final int mag, final int min) { | ||
GLES20.glTexParameterf(target, GL_TEXTURE_MAG_FILTER, mag); | ||
GLES20.glTexParameterf(target, GL_TEXTURE_MIN_FILTER, min); | ||
GLES20.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
GLES20.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
} | ||
|
||
|
||
public static int createBuffer(final float[] data) { | ||
return createBuffer(toFloatBuffer(data)); | ||
} | ||
|
||
public static int createBuffer(final FloatBuffer data) { | ||
final int[] buffers = new int[1]; | ||
GLES20.glGenBuffers(buffers.length, buffers, 0); | ||
updateBufferData(buffers[0], data); | ||
return buffers[0]; | ||
} | ||
|
||
public static FloatBuffer toFloatBuffer(final float[] data) { | ||
final FloatBuffer buffer = ByteBuffer | ||
.allocateDirect(data.length * FLOAT_SIZE_BYTES) | ||
.order(ByteOrder.nativeOrder()) | ||
.asFloatBuffer(); | ||
buffer.put(data).position(0); | ||
return buffer; | ||
} | ||
|
||
|
||
public static void updateBufferData(final int bufferName, final FloatBuffer data) { | ||
GLES20.glBindBuffer(GL_ARRAY_BUFFER, bufferName); | ||
GLES20.glBufferData(GL_ARRAY_BUFFER, data.capacity() * FLOAT_SIZE_BYTES, data, GL_STATIC_DRAW); | ||
GLES20.glBindBuffer(GL_ARRAY_BUFFER, 0); | ||
} | ||
|
||
public static int loadTexture(final Bitmap img, final int usedTexId, final boolean recycle) { | ||
int[] textures = new int[1]; | ||
if (usedTexId == NO_TEXTURE) { | ||
GLES20.glGenTextures(1, textures, 0); | ||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); | ||
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); | ||
|
||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img, 0); | ||
} else { | ||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, usedTexId); | ||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, img); | ||
textures[0] = usedTexId; | ||
} | ||
if (recycle) { | ||
img.recycle(); | ||
} | ||
return textures[0]; | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
...mple/src/main/java/xyz/doikki/dkplayer/widget/render/gl2/GLFrameBufferObjectRenderer.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package xyz.doikki.dkplayer.widget.render.gl2; | ||
|
||
import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT; | ||
import static android.opengl.GLES20.GL_DEPTH_BUFFER_BIT; | ||
import static android.opengl.GLES20.GL_FRAMEBUFFER; | ||
|
||
import android.opengl.GLES20; | ||
import android.opengl.GLSurfaceView; | ||
|
||
import java.util.LinkedList; | ||
import java.util.Queue; | ||
|
||
import javax.microedition.khronos.egl.EGLConfig; | ||
import javax.microedition.khronos.opengles.GL10; | ||
|
||
import xyz.doikki.dkplayer.widget.render.gl2.filter.GlFilter; | ||
|
||
|
||
abstract class GLFrameBufferObjectRenderer implements GLSurfaceView.Renderer { | ||
|
||
private GLFramebufferObject framebufferObject; | ||
private GlFilter normalShader; | ||
|
||
private final Queue<Runnable> runOnDraw; | ||
|
||
|
||
GLFrameBufferObjectRenderer() { | ||
runOnDraw = new LinkedList<Runnable>(); | ||
} | ||
|
||
|
||
@Override | ||
public final void onSurfaceCreated(final GL10 gl, final EGLConfig config) { | ||
framebufferObject = new GLFramebufferObject(); | ||
normalShader = new GlFilter(); | ||
normalShader.setup(); | ||
onSurfaceCreated(config); | ||
} | ||
|
||
@Override | ||
public final void onSurfaceChanged(final GL10 gl, final int width, final int height) { | ||
framebufferObject.setup(width, height); | ||
normalShader.setFrameSize(width, height); | ||
onSurfaceChanged(width, height); | ||
} | ||
|
||
@Override | ||
public final void onDrawFrame(final GL10 gl) { | ||
synchronized (runOnDraw) { | ||
while (!runOnDraw.isEmpty()) { | ||
runOnDraw.poll().run(); | ||
} | ||
} | ||
framebufferObject.enable(); | ||
GLES20.glViewport(0, 0, framebufferObject.getWidth(), framebufferObject.getHeight()); | ||
|
||
onDrawFrame(framebufferObject); | ||
|
||
GLES20.glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
GLES20.glViewport(0, 0, framebufferObject.getWidth(), framebufferObject.getHeight()); | ||
|
||
GLES20.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
normalShader.draw(framebufferObject.getTexName(), null); | ||
|
||
} | ||
|
||
@Override | ||
protected void finalize() throws Throwable { | ||
|
||
} | ||
|
||
public abstract void onSurfaceCreated(EGLConfig config); | ||
|
||
public abstract void onSurfaceChanged(int width, int height); | ||
|
||
public abstract void onDrawFrame(GLFramebufferObject fbo); | ||
} |
Oops, something went wrong.