Simplify GPU image filter implementation

Signed-off-by: Leo Ma <begeekmyfriend@gmail.com>
camera2
Leo Ma 9 years ago
parent 44d9e47484
commit 81696ed5ad

@ -11,14 +11,14 @@ import com.seu.magicfilter.utils.OpenGlUtils;
import android.opengl.GLES20; import android.opengl.GLES20;
public class MagicBaseGroupFilter extends GPUImageFilter{ public class MagicBaseGroupFilter extends GPUImageFilter {
protected static int[] frameBuffers = null; private static int[] frameBuffers = null;
protected static int[] frameBufferTextures = null; private static int[] frameBufferTextures = null;
private int frameWidth = -1; private int frameWidth = -1;
private int frameHeight = -1; private int frameHeight = -1;
protected List<GPUImageFilter> filters; protected List<GPUImageFilter> filters;
public MagicBaseGroupFilter(List<GPUImageFilter> filters){ public MagicBaseGroupFilter(List<GPUImageFilter> filters) {
this.filters = filters; this.filters = filters;
} }
@ -44,16 +44,16 @@ public class MagicBaseGroupFilter extends GPUImageFilter{
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
filters.get(i).onInputSizeChanged(width, height); filters.get(i).onInputSizeChanged(width, height);
} }
if(frameBuffers != null && (frameWidth != width || frameHeight != height || frameBuffers.length != size-1)){ if (frameBuffers != null && (frameWidth != width || frameHeight != height || frameBuffers.length != size - 1)) {
destroyFramebuffers(); destroyFramebuffers();
frameWidth = width; frameWidth = width;
frameHeight = height; frameHeight = height;
} }
if (frameBuffers == null) { if (frameBuffers == null) {
frameBuffers = new int[size-1]; frameBuffers = new int[size - 1];
frameBufferTextures = new int[size-1]; frameBufferTextures = new int[size - 1];
for (int i = 0; i < size-1; i++) { for (int i = 0; i < size - 1; i++) {
GLES20.glGenFramebuffers(1, frameBuffers, i); GLES20.glGenFramebuffers(1, frameBuffers, i);
GLES20.glGenTextures(1, frameBufferTextures, i); GLES20.glGenTextures(1, frameBufferTextures, i);
@ -97,7 +97,7 @@ public class MagicBaseGroupFilter extends GPUImageFilter{
filter.onDrawFrame(previousTexture, mGLCubeBuffer, mGLTextureBuffer); filter.onDrawFrame(previousTexture, mGLCubeBuffer, mGLTextureBuffer);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
previousTexture = frameBufferTextures[i]; previousTexture = frameBufferTextures[i];
}else{ } else {
GLES20.glViewport(0, 0, mOutputWidth, mOutputHeight); GLES20.glViewport(0, 0, mOutputWidth, mOutputHeight);
filter.onDrawFrame(previousTexture, cubeBuffer, textureBuffer); filter.onDrawFrame(previousTexture, cubeBuffer, textureBuffer);
} }
@ -106,7 +106,7 @@ public class MagicBaseGroupFilter extends GPUImageFilter{
} }
@Override @Override
public int onDrawFrame(final int textureId) { public int onDrawFrame(int textureId, boolean needFbo) {
if (frameBuffers == null || frameBufferTextures == null) { if (frameBuffers == null || frameBufferTextures == null) {
return OpenGlUtils.NOT_INIT; return OpenGlUtils.NOT_INIT;
} }
@ -121,7 +121,7 @@ public class MagicBaseGroupFilter extends GPUImageFilter{
filter.onDrawFrame(previousTexture, mGLCubeBuffer, mGLTextureBuffer); filter.onDrawFrame(previousTexture, mGLCubeBuffer, mGLTextureBuffer);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
previousTexture = frameBufferTextures[i]; previousTexture = frameBufferTextures[i];
}else{ } else {
filter.onDrawFrame(previousTexture, mGLCubeBuffer, mGLTextureBuffer); filter.onDrawFrame(previousTexture, mGLCubeBuffer, mGLTextureBuffer);
} }
} }
@ -139,7 +139,7 @@ public class MagicBaseGroupFilter extends GPUImageFilter{
} }
} }
public int getSize(){ public int getSize() {
return filters.size(); return filters.size();
} }
} }

@ -9,7 +9,7 @@ import com.seu.magicfilter.utils.OpenGlUtils;
public class MagicLookupFilter extends GPUImageFilter { public class MagicLookupFilter extends GPUImageFilter {
public static final String LOOKUP_FRAGMENT_SHADER = ""+ public static final String LOOKUP_FRAGMENT_SHADER = "" +
"varying highp vec2 textureCoordinate;\n" + "varying highp vec2 textureCoordinate;\n" +
" \n" + " \n" +
" uniform sampler2D inputImageTexture;\n" + " uniform sampler2D inputImageTexture;\n" +
@ -51,40 +51,40 @@ public class MagicLookupFilter extends GPUImageFilter {
this.table = table; this.table = table;
} }
public int mLookupTextureUniform; private int mLookupTextureUniform;
public int mLookupSourceTexture = OpenGlUtils.NO_TEXTURE; private int mLookupSourceTexture = OpenGlUtils.NO_TEXTURE;
protected void onInit(){ protected void onInit() {
super.onInit(); super.onInit();
mLookupTextureUniform = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture2"); mLookupTextureUniform = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture2");
} }
protected void onInitialized(){ protected void onInitialized() {
super.onInitialized(); super.onInitialized();
runOnDraw(new Runnable(){ runOnDraw(new Runnable() {
public void run(){ public void run() {
mLookupSourceTexture = OpenGlUtils.loadTexture(MagicFilterFactory.getCurrentContext(), table); mLookupSourceTexture = OpenGlUtils.loadTexture(MagicFilterFactory.getCurrentContext(), table);
} }
}); });
} }
protected void onDestroy(){ protected void onDestroy() {
super.onDestroy(); super.onDestroy();
int[] texture = new int[]{mLookupSourceTexture}; int[] texture = new int[]{mLookupSourceTexture};
GLES20.glDeleteTextures(1, texture, 0); GLES20.glDeleteTextures(1, texture, 0);
mLookupSourceTexture = -1; mLookupSourceTexture = -1;
} }
protected void onDrawArraysAfter(){ protected void onDrawArraysAfter() {
if (mLookupSourceTexture != -1){ if (mLookupSourceTexture != -1) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glActiveTexture(GLES20.GL_TEXTURE3);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
} }
} }
protected void onDrawArraysPre(){ protected void onDrawArraysPre() {
if (mLookupSourceTexture != -1){ if (mLookupSourceTexture != -1) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glActiveTexture(GLES20.GL_TEXTURE3);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mLookupSourceTexture); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mLookupSourceTexture);
GLES20.glUniform1i(mLookupTextureUniform, 3); GLES20.glUniform1i(mLookupTextureUniform, 3);

@ -222,87 +222,12 @@ public class GPUImageFilter {
return OpenGlUtils.ON_DRAWN; return OpenGlUtils.ON_DRAWN;
} }
public int onDrawFrame(int textureId) { public int onDrawFrame(int textureId, boolean needFbo) {
if (!mIsInitialized) { if (!mIsInitialized) {
return OpenGlUtils.NOT_INIT; return OpenGlUtils.NOT_INIT;
} }
GLES20.glUseProgram(mGLProgId); if (needFbo && mGLFboId == null) {
runPendingOnDrawTasks();
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGLCubeId[0]);
GLES20.glEnableVertexAttribArray(mGLPositionIndex);
GLES20.glVertexAttribPointer(mGLPositionIndex, 2, GLES20.GL_FLOAT, false, 4 * 2, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGLTextureId[0]);
GLES20.glEnableVertexAttribArray(mGLTextureCoordinateIndex);
GLES20.glVertexAttribPointer(mGLTextureCoordinateIndex, 2, GLES20.GL_FLOAT, false, 4 * 2, 0);
GLES20.glUniformMatrix4fv(mGLTextureTransformIndex, 1, false, mGLTextureTransformMatrix, 0);
if (textureId != OpenGlUtils.NO_TEXTURE) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glUniform1i(mGLInputImageTextureIndex, 0);
}
onDrawArraysPre();
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
onDrawArraysAfter();
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glDisableVertexAttribArray(mGLPositionIndex);
GLES20.glDisableVertexAttribArray(mGLTextureCoordinateIndex);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
return OpenGlUtils.ON_DRAWN;
}
public int onDrawFrameOES(int textureId) {
if (!mIsInitialized) {
return OpenGlUtils.NOT_INIT;
}
GLES20.glUseProgram(mGLProgId);
runPendingOnDrawTasks();
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGLCubeId[0]);
GLES20.glEnableVertexAttribArray(mGLPositionIndex);
GLES20.glVertexAttribPointer(mGLPositionIndex, 2, GLES20.GL_FLOAT, false, 4 * 2, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGLTextureId[0]);
GLES20.glEnableVertexAttribArray(mGLTextureCoordinateIndex);
GLES20.glVertexAttribPointer(mGLTextureCoordinateIndex, 2, GLES20.GL_FLOAT, false, 4 * 2, 0);
GLES20.glUniformMatrix4fv(mGLTextureTransformIndex, 1, false, mGLTextureTransformMatrix, 0);
if (textureId != OpenGlUtils.NO_TEXTURE) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
GLES20.glUniform1i(mGLInputImageTextureIndex, 0);
}
onDrawArraysPre();
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
onDrawArraysAfter();
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
GLES20.glDisableVertexAttribArray(mGLPositionIndex);
GLES20.glDisableVertexAttribArray(mGLTextureCoordinateIndex);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
return OpenGlUtils.ON_DRAWN;
}
public int onDrawToTexture(int textureId) {
if (!mIsInitialized) {
return OpenGlUtils.NOT_INIT;
}
if (mGLFboId == null) {
return OpenGlUtils.NO_TEXTURE; return OpenGlUtils.NO_TEXTURE;
} }
@ -326,13 +251,16 @@ public class GPUImageFilter {
} }
onDrawArraysPre(); onDrawArraysPre();
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
if (needFbo) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mGLFboId[0]); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mGLFboId[0]);
GLES20.glViewport(0, 0, mInputWidth, mInputHeight); GLES20.glViewport(0, 0, mInputWidth, mInputHeight);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glViewport(0, 0, mOutputWidth, mOutputHeight); GLES20.glViewport(0, 0, mOutputWidth, mOutputHeight);
GLES20.glReadPixels(0, 0, mInputWidth, mInputHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mGLFboBuffer); GLES20.glReadPixels(0, 0, mInputWidth, mInputHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mGLFboBuffer);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
}
onDrawArraysAfter(); onDrawArraysAfter();
@ -343,14 +271,15 @@ public class GPUImageFilter {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
return mGLFboTextureId[0]; return needFbo ? mGLFboTextureId[0] : OpenGlUtils.ON_DRAWN;
} }
public int onDrawToTextureOES(int textureId) { public int onDrawFrameOES(int textureId, boolean needFbo) {
if (!mIsInitialized) { if (!mIsInitialized) {
return OpenGlUtils.NOT_INIT; return OpenGlUtils.NOT_INIT;
} }
if (mGLFboId == null) {
if (needFbo && mGLFboId == null) {
return OpenGlUtils.NO_TEXTURE; return OpenGlUtils.NO_TEXTURE;
} }
@ -374,13 +303,16 @@ public class GPUImageFilter {
} }
onDrawArraysPre(); onDrawArraysPre();
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
if (needFbo) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mGLFboId[0]); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mGLFboId[0]);
GLES20.glViewport(0, 0, mInputWidth, mInputHeight); GLES20.glViewport(0, 0, mInputWidth, mInputHeight);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glViewport(0, 0, mOutputWidth, mOutputHeight); GLES20.glViewport(0, 0, mOutputWidth, mOutputHeight);
GLES20.glReadPixels(0, 0, mInputWidth, mInputHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mGLFboBuffer); GLES20.glReadPixels(0, 0, mInputWidth, mInputHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mGLFboBuffer);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
}
onDrawArraysAfter(); onDrawArraysAfter();
@ -391,10 +323,11 @@ public class GPUImageFilter {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
return mGLFboTextureId[0]; return needFbo ? mGLFboTextureId[0] : OpenGlUtils.ON_DRAWN;
} }
protected void onDrawArraysPre() {} protected void onDrawArraysPre() {}
protected void onDrawArraysAfter() {} protected void onDrawArraysAfter() {}
protected void runPendingOnDrawTasks() { protected void runPendingOnDrawTasks() {

@ -109,8 +109,7 @@ public class SrsCameraView extends GLSurfaceView implements GLSurfaceView.Render
surfaceTexture.getTransformMatrix(mtx); surfaceTexture.getTransformMatrix(mtx);
magicFilter.setTextureTransformMatrix(mtx); magicFilter.setTextureTransformMatrix(mtx);
magicFilter.onDrawFrameOES(mTextureId); magicFilter.onDrawFrameOES(mTextureId, true);
magicFilter.onDrawToTextureOES(mTextureId);
mGLIntBufferCache.add(magicFilter.getGlFboBuffer()); mGLIntBufferCache.add(magicFilter.getGlFboBuffer());
synchronized (writeLock) { synchronized (writeLock) {
writeLock.notifyAll(); writeLock.notifyAll();

Loading…
Cancel
Save