diff options
author | Jorge Ruesga <jorge@ruesga.com> | 2013-08-14 18:48:42 +0200 |
---|---|---|
committer | Jorge Ruesga <jorge@ruesga.com> | 2013-08-14 18:48:42 +0200 |
commit | 136bf6e119cfc5308c73b1fe7ea8c1a78b95405f (patch) | |
tree | f35a37167a3994f9697a7413966916dc701e1375 /src/org/cyanogenmod | |
parent | 8c07c923cf89fb633c042e0851a1cd82827133ca (diff) | |
download | android_packages_wallpapers_PhotoPhase-136bf6e119cfc5308c73b1fe7ea8c1a78b95405f.tar.gz android_packages_wallpapers_PhotoPhase-136bf6e119cfc5308c73b1fe7ea8c1a78b95405f.tar.bz2 android_packages_wallpapers_PhotoPhase-136bf6e119cfc5308c73b1fe7ea8c1a78b95405f.zip |
Make effects factory more heritable + Scanlines effect
Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
Diffstat (limited to 'src/org/cyanogenmod')
5 files changed, 216 insertions, 114 deletions
diff --git a/src/org/cyanogenmod/wallpapers/photophase/effects/Effects.java b/src/org/cyanogenmod/wallpapers/photophase/effects/Effects.java index cf9ff79..bfee378 100644 --- a/src/org/cyanogenmod/wallpapers/photophase/effects/Effects.java +++ b/src/org/cyanogenmod/wallpapers/photophase/effects/Effects.java @@ -52,10 +52,6 @@ public class Effects { */ DOCUMENTARY, /** - * @see PhotoPhaseEffectFactory#EFFECT_HALFTONE - */ - HALFTONE, - /** * @see EffectFactory#EFFECT_DUOTONE */ DUOTONE, @@ -72,6 +68,10 @@ public class Effects { */ GRAYSCALE, /** + * @see PhotoPhaseEffectFactory#EFFECT_HALFTONE + */ + HALFTONE, + /** * @see EffectFactory#EFFECT_LOMOISH */ LOMOISH, @@ -88,6 +88,10 @@ public class Effects { */ SATURATE, /** + * @see PhotoPhaseEffectFactory#EFFECT_SCANLINES + */ + SCANLINES, + /** * @see EffectFactory#EFFECT_SEPIA */ SEPIA, @@ -160,11 +164,6 @@ public class Effects { if (EffectFactory.isEffectSupported(EffectFactory.EFFECT_DOCUMENTARY)) { effect = effectFactory.createEffect(EffectFactory.EFFECT_DOCUMENTARY); } - } else if (nextEffect.compareTo(EFFECTS.HALFTONE) == 0) { - if (EffectFactory.isEffectSupported(PhotoPhaseEffectFactory.EFFECT_HALFTONE)) { - effect = effectFactory.createEffect(PhotoPhaseEffectFactory.EFFECT_HALFTONE); - effect.setParameter("strength", 30.0f); - } } else if (nextEffect.compareTo(EFFECTS.DUOTONE) == 0) { if (EffectFactory.isEffectSupported(EffectFactory.EFFECT_DUOTONE)) { effect = effectFactory.createEffect(EffectFactory.EFFECT_DUOTONE); @@ -185,6 +184,11 @@ public class Effects { if (EffectFactory.isEffectSupported(EffectFactory.EFFECT_GRAYSCALE)) { effect = effectFactory.createEffect(EffectFactory.EFFECT_GRAYSCALE); } + } else if (nextEffect.compareTo(EFFECTS.HALFTONE) == 0) { + if (EffectFactory.isEffectSupported(PhotoPhaseEffectFactory.EFFECT_HALFTONE)) { + effect = effectFactory.createEffect(PhotoPhaseEffectFactory.EFFECT_HALFTONE); + effect.setParameter("strength", 30.0f); + } } else if (nextEffect.compareTo(EFFECTS.LOMOISH) == 0) { if (EffectFactory.isEffectSupported(EffectFactory.EFFECT_LOMOISH)) { effect = effectFactory.createEffect(EffectFactory.EFFECT_LOMOISH); @@ -202,6 +206,10 @@ public class Effects { effect = effectFactory.createEffect(EffectFactory.EFFECT_SATURATE); effect.setParameter("scale", .5f); } + } else if (nextEffect.compareTo(EFFECTS.SCANLINES) == 0) { + if (EffectFactory.isEffectSupported(PhotoPhaseEffectFactory.EFFECT_SCANLINES)) { + effect = effectFactory.createEffect(PhotoPhaseEffectFactory.EFFECT_SCANLINES); + } } else if (nextEffect.compareTo(EFFECTS.SEPIA) == 0) { if (EffectFactory.isEffectSupported(EffectFactory.EFFECT_SEPIA)) { effect = effectFactory.createEffect(EffectFactory.EFFECT_SEPIA); diff --git a/src/org/cyanogenmod/wallpapers/photophase/effects/HalftoneEffect.java b/src/org/cyanogenmod/wallpapers/photophase/effects/HalftoneEffect.java index b09696f..7e03396 100644 --- a/src/org/cyanogenmod/wallpapers/photophase/effects/HalftoneEffect.java +++ b/src/org/cyanogenmod/wallpapers/photophase/effects/HalftoneEffect.java @@ -28,10 +28,6 @@ import android.util.Log; import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - /** * A halftone effect<br/> * <table> @@ -47,22 +43,8 @@ public class HalftoneEffect extends PhotoPhaseEffect { private static final String TAG = "HalftoneEffect"; - /** - * The halftone steps multiplier parameter key - */ - public static final String STRENGTH_PARAMETER = "strength"; - - private static final int FLOAT_SIZE_BYTES = 4; + private static final String STRENGTH_PARAMETER = "strength"; - private static final String VERTEX_SHADER = - "attribute vec4 a_position;\n" + - "attribute vec2 a_texcoord;\n" + - "varying vec2 v_texcoord;\n" + - "void main() {\n" + - " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n" + - " gl_Position = sign(gl_Position);\n" + - " v_texcoord = a_texcoord;\n" + - "}\n"; private static final String FRAGMENT_SHADER = "precision mediump float;\n" + "uniform sampler2D tex_sampler;\n" + @@ -81,20 +63,9 @@ public class HalftoneEffect extends PhotoPhaseEffect { " };\n" + "}\n"; - private static final float[] TEX_VERTICES = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; - private static final float[] POS_VERTICES = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f}; - private float mStrength = 32.0f; - - private int mProgram; - private int mTexSamplerHandle; - private int mTexCoordHandle; - private int mPosCoordHandle; private int mStepsHandle; - private FloatBuffer mTexVertices; - private FloatBuffer mPosVertices; - /** * An abstract contructor of <code>Effect</code> to follow the rules * defined by {@see EffectFactory}. @@ -104,83 +75,29 @@ public class HalftoneEffect extends PhotoPhaseEffect { */ public HalftoneEffect(EffectContext ctx, String name) { super(ctx, HalftoneEffect.class.getName()); - init(); + init(VERTEX_SHADER, FRAGMENT_SHADER); } /** - * Method that initializes the effect + * {@inheritDoc} */ - private void init() { - // Create program - mProgram = GLESUtil.createProgram(VERTEX_SHADER, FRAGMENT_SHADER); + @Override + void init(String vertexShader, String fragmentShader) { + super.init(vertexShader, fragmentShader); - // Bind attributes and uniforms - mTexSamplerHandle = GLES20.glGetUniformLocation(mProgram, "tex_sampler"); - GLESUtil.glesCheckError("glGetUniformLocation"); - mTexCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_texcoord"); - GLESUtil.glesCheckError("glGetAttribLocation"); - mPosCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_position"); - GLESUtil.glesCheckError("glGetAttribLocation"); + // Parameters mStepsHandle = GLES20.glGetUniformLocation(mProgram, "steps"); GLESUtil.glesCheckError("glGetUniformLocation"); - - // Setup coordinate buffers - mTexVertices = ByteBuffer.allocateDirect( - TEX_VERTICES.length * FLOAT_SIZE_BYTES) - .order(ByteOrder.nativeOrder()).asFloatBuffer(); - mTexVertices.put(TEX_VERTICES).position(0); - mPosVertices = ByteBuffer.allocateDirect( - POS_VERTICES.length * FLOAT_SIZE_BYTES) - .order(ByteOrder.nativeOrder()).asFloatBuffer(); - mPosVertices.put(POS_VERTICES).position(0); } /** * {@inheritDoc} */ @Override - void apply(int inputTexId) { - // Use our shader program - GLES20.glUseProgram(mProgram); - GLESUtil.glesCheckError("glUseProgram"); - - // Disable blending - GLES20.glDisable(GLES20.GL_BLEND); - GLESUtil.glesCheckError("glDisable"); - - // Set the vertex attributes - GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mTexVertices); - GLESUtil.glesCheckError("glVertexAttribPointer"); - GLES20.glEnableVertexAttribArray(mTexCoordHandle); - GLESUtil.glesCheckError("glEnableVertexAttribArray"); - GLES20.glVertexAttribPointer(mPosCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mPosVertices); - GLESUtil.glesCheckError("glVertexAttribPointer"); - GLES20.glEnableVertexAttribArray(mPosCoordHandle); - GLESUtil.glesCheckError("glEnableVertexAttribArray"); - + void applyParameters() { // Set parameters GLES20.glUniform1f(mStepsHandle, mStrength); GLESUtil.glesCheckError("glUniform1f"); - - // Set the input texture - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTexId); - GLESUtil.glesCheckError("glBindTexture"); - GLES20.glUniform1i(mTexSamplerHandle, 0); - GLESUtil.glesCheckError("glUniform1i"); - - // Draw - GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - GLESUtil.glesCheckError("glClearColor"); - GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); - GLESUtil.glesCheckError("glClear"); - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - GLESUtil.glesCheckError("glDrawArrays"); - - // Disable attributes - GLES20.glDisableVertexAttribArray(mTexCoordHandle); - GLESUtil.glesCheckError("glDisableVertexAttribArray"); - GLES20.glDisableVertexAttribArray(mPosCoordHandle); - GLESUtil.glesCheckError("glDisableVertexAttribArray"); } /** @@ -202,17 +119,4 @@ public class HalftoneEffect extends PhotoPhaseEffect { } } - /** - * {@inheritDoc} - */ - @Override - public void release() { - if (GLES20.glIsProgram(mProgram)) { - GLES20.glDeleteProgram(mProgram); - GLESUtil.glesCheckError("glDeleteProgram"); - } - mTexVertices = null; - mPosVertices = null; - } - } diff --git a/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java b/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java index 83f461d..b5a6dbf 100644 --- a/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java +++ b/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java @@ -23,6 +23,9 @@ import android.opengl.GLUtils; import org.cyanogenmod.wallpapers.photophase.utils.GLESUtil; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; import java.nio.IntBuffer; /** @@ -30,9 +33,32 @@ import java.nio.IntBuffer; */ public abstract class PhotoPhaseEffect extends Effect { + private static final int FLOAT_SIZE_BYTES = 4; + + static final String VERTEX_SHADER = + "attribute vec4 a_position;\n" + + "attribute vec2 a_texcoord;\n" + + "varying vec2 v_texcoord;\n" + + "void main() {\n" + + " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n" + + " gl_Position = sign(gl_Position);\n" + + " v_texcoord = a_texcoord;\n" + + "}\n"; + + private static final float[] TEX_VERTICES = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; + private static final float[] POS_VERTICES = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f}; + private final EffectContext mEffectContext; private final String mName; + int mProgram; + int mTexSamplerHandle; + int mTexCoordHandle; + int mPosCoordHandle; + + FloatBuffer mTexVertices; + FloatBuffer mPosVertices; + /** * An abstract contructor of <code>Effect</code> to follow the rules * defined by {@see EffectFactory}. @@ -47,6 +73,32 @@ public abstract class PhotoPhaseEffect extends Effect { } /** + * Method that initializes the effect + */ + void init(String vertexShader, String fragmentShader) { + // Create program + mProgram = GLESUtil.createProgram(vertexShader, fragmentShader); + + // Bind attributes and uniforms + mTexSamplerHandle = GLES20.glGetUniformLocation(mProgram, "tex_sampler"); + GLESUtil.glesCheckError("glGetUniformLocation"); + mTexCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_texcoord"); + GLESUtil.glesCheckError("glGetAttribLocation"); + mPosCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_position"); + GLESUtil.glesCheckError("glGetAttribLocation"); + + // Setup coordinate buffers + mTexVertices = ByteBuffer.allocateDirect( + TEX_VERTICES.length * FLOAT_SIZE_BYTES) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mTexVertices.put(TEX_VERTICES).position(0); + mPosVertices = ByteBuffer.allocateDirect( + POS_VERTICES.length * FLOAT_SIZE_BYTES) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mPosVertices.put(POS_VERTICES).position(0); + } + + /** * {@inheritDoc} */ @Override @@ -115,9 +167,77 @@ public abstract class PhotoPhaseEffect extends Effect { } /** + * {@inheritDoc} + */ + @Override + public void setParameter(String parameterKey, Object value) { + } + + /** + * {@inheritDoc} + */ + @Override + public void release() { + if (GLES20.glIsProgram(mProgram)) { + GLES20.glDeleteProgram(mProgram); + GLESUtil.glesCheckError("glDeleteProgram"); + } + mTexVertices = null; + mPosVertices = null; + } + + /** * Method that applies the effect. * * @param inputTexId The input texture */ - abstract void apply(int inputTexId); + void apply(int inputTexId) { + // Use our shader program + GLES20.glUseProgram(mProgram); + GLESUtil.glesCheckError("glUseProgram"); + + // Disable blending + GLES20.glDisable(GLES20.GL_BLEND); + GLESUtil.glesCheckError("glDisable"); + + // Set the vertex attributes + GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mTexVertices); + GLESUtil.glesCheckError("glVertexAttribPointer"); + GLES20.glEnableVertexAttribArray(mTexCoordHandle); + GLESUtil.glesCheckError("glEnableVertexAttribArray"); + GLES20.glVertexAttribPointer(mPosCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mPosVertices); + GLESUtil.glesCheckError("glVertexAttribPointer"); + GLES20.glEnableVertexAttribArray(mPosCoordHandle); + GLESUtil.glesCheckError("glEnableVertexAttribArray"); + + // Set parameters + applyParameters(); + + // Set the input texture + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, inputTexId); + GLESUtil.glesCheckError("glBindTexture"); + GLES20.glUniform1i(mTexSamplerHandle, 0); + GLESUtil.glesCheckError("glUniform1i"); + + // Draw + GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + GLESUtil.glesCheckError("glClearColor"); + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); + GLESUtil.glesCheckError("glClear"); + GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); + GLESUtil.glesCheckError("glDrawArrays"); + + // Disable attributes + GLES20.glDisableVertexAttribArray(mTexCoordHandle); + GLESUtil.glesCheckError("glDisableVertexAttribArray"); + GLES20.glDisableVertexAttribArray(mPosCoordHandle); + GLESUtil.glesCheckError("glDisableVertexAttribArray"); + } + + /** + * Method that applies the parameters of the effect. + */ + void applyParameters() { + // Do nothing + } } diff --git a/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffectFactory.java b/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffectFactory.java index eaa5f32..2e89236 100644 --- a/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffectFactory.java +++ b/src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffectFactory.java @@ -35,4 +35,13 @@ public class PhotoPhaseEffectFactory { * </table> */ public static final String EFFECT_HALFTONE = "org.cyanogenmod.wallpapers.photophase.effects.HalftoneEffect"; + + /** + * <p>Applies a TV scanlines effect to the image.</p> + * <p>Available parameters:</p> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * </table> + */ + public static final String EFFECT_SCANLINES = "org.cyanogenmod.wallpapers.photophase.effects.ScanlinesEffect"; } diff --git a/src/org/cyanogenmod/wallpapers/photophase/effects/ScanlinesEffect.java b/src/org/cyanogenmod/wallpapers/photophase/effects/ScanlinesEffect.java new file mode 100644 index 0000000..a8bfeae --- /dev/null +++ b/src/org/cyanogenmod/wallpapers/photophase/effects/ScanlinesEffect.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 Max Maischein + * Copyright (C) 2013 The CyanogenMod Project + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// +// Based in the shaders of Max Maischein of App-VideoMixer: +// http://cpansearch.perl.org/src/CORION/App-VideoMixer-0.02/filters/scanlines.glsl +// + +package org.cyanogenmod.wallpapers.photophase.effects; + +import android.media.effect.EffectContext; + +/** + * A TV scanline effect<br/> + * <table> + * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr> + * </table> + */ +public class ScanlinesEffect extends PhotoPhaseEffect { + + private static final String FRAGMENT_SHADER = + "precision mediump float;\n" + + "uniform sampler2D tex_sampler;\n" + + "uniform float offset;\n" + + "float frequency = 83.0;\n" + + "varying vec2 v_texcoord;\n" + + "void main(void)\n" + + "{\n" + + " float global_pos = (v_texcoord.y + offset) * frequency;\n" + + " float wave_pos = cos((fract( global_pos ) - 0.5)*3.14);\n" + + " vec4 pel = texture2D( tex_sampler, v_texcoord );\n" + + " gl_FragColor = mix(vec4(0,0,0,0), pel, wave_pos);\n" + + "}"; + + /** + * An abstract contructor of <code>Effect</code> to follow the rules + * defined by {@see EffectFactory}. + * + * @param ctx The effect context + * @param name The effect name + */ + public ScanlinesEffect(EffectContext ctx, String name) { + super(ctx, ScanlinesEffect.class.getName()); + init(VERTEX_SHADER, FRAGMENT_SHADER); + } + +} |