aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/cyanogenmod
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2013-08-14 18:48:42 +0200
committerJorge Ruesga <jorge@ruesga.com>2013-08-14 18:48:42 +0200
commit136bf6e119cfc5308c73b1fe7ea8c1a78b95405f (patch)
treef35a37167a3994f9697a7413966916dc701e1375 /src/org/cyanogenmod
parent8c07c923cf89fb633c042e0851a1cd82827133ca (diff)
downloadandroid_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')
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/effects/Effects.java26
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/effects/HalftoneEffect.java112
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffect.java122
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/effects/PhotoPhaseEffectFactory.java9
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/effects/ScanlinesEffect.java61
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);
+ }
+
+}