Use GlFramebuffer

egloo2
Mattia Iavarone 5 years ago
parent 4e6dbd9604
commit bbf12c7e0d
  1. 60
      cameraview/src/main/java/com/otaliastudios/cameraview/filter/MultiFilter.java

@ -10,6 +10,8 @@ import com.otaliastudios.cameraview.size.Size;
import com.otaliastudios.opengl.core.Egloo; import com.otaliastudios.opengl.core.Egloo;
import com.otaliastudios.opengl.program.GlProgram; import com.otaliastudios.opengl.program.GlProgram;
import com.otaliastudios.opengl.program.GlTextureProgram; import com.otaliastudios.opengl.program.GlTextureProgram;
import com.otaliastudios.opengl.texture.GlFramebuffer;
import com.otaliastudios.opengl.texture.GlTexture;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -48,8 +50,8 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
@VisibleForTesting boolean isFramebufferCreated = false; @VisibleForTesting boolean isFramebufferCreated = false;
@VisibleForTesting Size size = null; @VisibleForTesting Size size = null;
private int programHandle = -1; private int programHandle = -1;
private int outputFramebufferId = -1; private GlFramebuffer outputFramebuffer = null;
private int outputTextureId = -1; private GlTexture outputTexture = null;
} }
@VisibleForTesting final List<Filter> filters = new ArrayList<>(); @VisibleForTesting final List<Filter> filters = new ArrayList<>();
@ -136,40 +138,12 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
//noinspection ConstantConditions //noinspection ConstantConditions
if (state.isFramebufferCreated || isLast) return; if (state.isFramebufferCreated || isLast) return;
state.isFramebufferCreated = true; state.isFramebufferCreated = true;
state.outputTexture = new GlTexture(GLES20.GL_TEXTURE0,
int[] framebufferArray = new int[1];
int[] textureArray = new int[1];
GLES20.glGenFramebuffers(1, framebufferArray, 0);
GLES20.glGenTextures(1, textureArray, 0);
state.outputFramebufferId = framebufferArray[0];
state.outputTextureId = textureArray[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, state.outputTextureId);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,
state.size.getWidth(), state.size.getHeight(), 0, GLES20.GL_RGBA,
GLES20.GL_UNSIGNED_BYTE, null);
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);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, state.outputFramebufferId);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_2D,
state.outputTextureId, state.size.getWidth(),
0); state.size.getHeight());
state.outputFramebuffer = new GlFramebuffer();
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); state.outputFramebuffer.attach(state.outputTexture);
if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) {
throw new RuntimeException("Invalid framebuffer generation. Error:" + status);
}
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
} }
private void maybeDestroyFramebuffer(@NonNull Filter filter) { private void maybeDestroyFramebuffer(@NonNull Filter filter) {
@ -177,10 +151,10 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
//noinspection ConstantConditions //noinspection ConstantConditions
if (!state.isFramebufferCreated) return; if (!state.isFramebufferCreated) return;
state.isFramebufferCreated = false; state.isFramebufferCreated = false;
GLES20.glDeleteFramebuffers(1, new int[]{state.outputFramebufferId}, 0); state.outputFramebuffer.release();
state.outputFramebufferId = -1; state.outputFramebuffer = null;
GLES20.glDeleteTextures(1, new int[]{state.outputTextureId}, 0); state.outputTexture.release();
state.outputTextureId = -1; state.outputTexture = null;
} }
private void maybeSetSize(@NonNull Filter filter) { private void maybeSetSize(@NonNull Filter filter) {
@ -240,6 +214,7 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
boolean isLast = i == filters.size() - 1; boolean isLast = i == filters.size() - 1;
Filter filter = filters.get(i); Filter filter = filters.get(i);
State state = states.get(filter); State state = states.get(filter);
maybeSetSize(filter); maybeSetSize(filter);
maybeCreateProgram(filter, isFirst, isLast); maybeCreateProgram(filter, isFirst, isLast);
maybeCreateFramebuffer(filter, isFirst, isLast); maybeCreateFramebuffer(filter, isFirst, isLast);
@ -251,7 +226,7 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
// Each filter outputs into its own framebuffer object, except the // Each filter outputs into its own framebuffer object, except the
// last filter, which outputs into the default framebuffer. // last filter, which outputs into the default framebuffer.
if (!isLast) { if (!isLast) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, state.outputFramebufferId); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, state.outputFramebuffer.getId());
GLES20.glClearColor(0, 0, 0, 0); GLES20.glClearColor(0, 0, 0, 0);
} else { } else {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
@ -270,7 +245,7 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
// It is the framebuffer texture from this cycle. If this is the last // It is the framebuffer texture from this cycle. If this is the last
// filter, reset this value just to cleanup. // filter, reset this value just to cleanup.
if (!isLast) { if (!isLast) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, state.outputTextureId); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, state.outputTexture.getId());
} else { } else {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
} }
@ -285,6 +260,9 @@ public class MultiFilter implements Filter, OneParameterFilter, TwoParameterFilt
public Filter copy() { public Filter copy() {
synchronized (lock) { synchronized (lock) {
MultiFilter copy = new MultiFilter(); MultiFilter copy = new MultiFilter();
if (size != null) {
copy.setSize(size.getWidth(), size.getHeight());
}
for (Filter filter : filters) { for (Filter filter : filters) {
copy.addFilter(filter.copy()); copy.addFilter(filter.copy());
} }

Loading…
Cancel
Save