diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/filters/DuotoneFilter.java b/cameraview/src/main/java/com/otaliastudios/cameraview/filters/DuotoneFilter.java index 7617cd6d..a508c9d7 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/filters/DuotoneFilter.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/filters/DuotoneFilter.java @@ -123,6 +123,7 @@ public class DuotoneFilter extends BaseFilter { Color.blue(mSecondColor) / 255f }; GLES20.glUniform3fv(mFirstColorLocation, 1, first, 0); + GlUtils.checkError("glUniform3fv"); GLES20.glUniform3fv(mSecondColorLocation, 1, second, 0); GlUtils.checkError("glUniform3fv"); } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/filters/FillLightFilter.java b/cameraview/src/main/java/com/otaliastudios/cameraview/filters/FillLightFilter.java index 5c2c4e30..346435d9 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/filters/FillLightFilter.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/filters/FillLightFilter.java @@ -1,15 +1,38 @@ package com.otaliastudios.cameraview.filters; +import android.opengl.GLES20; + import androidx.annotation.NonNull; import com.otaliastudios.cameraview.filter.BaseFilter; +import com.otaliastudios.cameraview.internal.GlUtils; /** * Applies back-light filling to the frames. */ public class FillLightFilter extends BaseFilter { + private final static String FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n" + + "precision mediump float;\n" + + "uniform samplerExternalOES sTexture;\n" + + "uniform float mult;\n" + + "uniform float igamma;\n" + + "varying vec2 vTextureCoord;\n" + + "void main() {\n" + + " const vec3 color_weights = vec3(0.25, 0.5, 0.25);\n" + + " vec4 color = texture2D(sTexture, vTextureCoord);\n" + + " float lightmask = dot(color.rgb, color_weights);\n" + + " float backmask = (1.0 - lightmask);\n" + + " vec3 ones = vec3(1.0, 1.0, 1.0);\n" + + " vec3 diff = pow(mult * color.rgb, igamma * ones) - color.rgb;\n" + + " diff = min(diff, 1.0);\n" + + " vec3 new_color = min(color.rgb + diff * backmask, 1.0);\n" + + " gl_FragColor = vec4(new_color, color.a);\n" + + "}\n"; + private float strength = 0.5f; + private int multiplierLocation = -1; + private int gammaLocation = -1; @SuppressWarnings("WeakerAccess") public FillLightFilter() { } @@ -39,45 +62,49 @@ public class FillLightFilter extends BaseFilter { return strength; } - @Override - protected BaseFilter onCopy() { - FillLightFilter filter = new FillLightFilter(); - filter.setStrength(getStrength()); - return filter; - } @NonNull @Override public String getFragmentShader() { - float fade_gamma = 0.3f; - float amt = 1.0f - strength; - float mult = 1.0f / (amt * 0.7f + 0.3f); - float faded = fade_gamma + (1.0f - fade_gamma) * mult; - float igamma = 1.0f / faded; - - String multString = "mult = " + mult + ";\n"; - String igammaString = "igamma = " + igamma + ";\n"; - - return "#extension GL_OES_EGL_image_external : require\n" - + "precision mediump float;\n" - + "uniform samplerExternalOES sTexture;\n" - + " float mult;\n" - + " float igamma;\n" - + "varying vec2 vTextureCoord;\n" - + "void main() {\n" - // Parameters that were created above - + multString - + igammaString - + " const vec3 color_weights = vec3(0.25, 0.5, 0.25);\n" - + " vec4 color = texture2D(sTexture, vTextureCoord);\n" - + " float lightmask = dot(color.rgb, color_weights);\n" - + " float backmask = (1.0 - lightmask);\n" - + " vec3 ones = vec3(1.0, 1.0, 1.0);\n" - + " vec3 diff = pow(mult * color.rgb, igamma * ones) - color.rgb;\n" - + " diff = min(diff, 1.0);\n" - + " vec3 new_color = min(color.rgb + diff * backmask, 1.0);\n" - + " gl_FragColor = vec4(new_color, color.a);\n" - + "}\n"; + return FRAGMENT_SHADER; + } + + @Override + public void onCreate(int programHandle) { + super.onCreate(programHandle); + multiplierLocation = GLES20.glGetUniformLocation(programHandle, "mult"); + GlUtils.checkLocation(multiplierLocation, "mult"); + gammaLocation = GLES20.glGetUniformLocation(programHandle, "igamma"); + GlUtils.checkLocation(gammaLocation, "igamma"); } + @Override + public void onDestroy() { + super.onDestroy(); + multiplierLocation = -1; + gammaLocation = -1; + } + + @Override + protected void onPreDraw(float[] transformMatrix) { + super.onPreDraw(transformMatrix); + float amount = 1.0f - strength; + float multiplier = 1.0f / (amount * 0.7f + 0.3f); + GLES20.glUniform1f(multiplierLocation, multiplier); + GlUtils.checkError("glUniform1f"); + + float fadeGamma = 0.3f; + float faded = fadeGamma + (1.0f - fadeGamma) * multiplier; + float gamma = 1.0f / faded; + GLES20.glUniform1f(gammaLocation, gamma); + GlUtils.checkError("glUniform1f"); + } + + + @Override + protected BaseFilter onCopy() { + FillLightFilter filter = new FillLightFilter(); + filter.setStrength(getStrength()); + return filter; + } }