aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/cyanogenmod/wallpapers/photophase/transitions
diff options
context:
space:
mode:
authorjruesga <jorge@ruesga.com>2013-07-01 02:42:54 +0200
committerjruesga <jorge@ruesga.com>2013-07-01 02:42:54 +0200
commitf29d68d929061ccbb982019c5020be721bbef862 (patch)
tree24ce41fb0dd7f942ca9dbe956fe93fe836da66c2 /src/org/cyanogenmod/wallpapers/photophase/transitions
downloadandroid_packages_wallpapers_PhotoPhase-f29d68d929061ccbb982019c5020be721bbef862.tar.gz
android_packages_wallpapers_PhotoPhase-f29d68d929061ccbb982019c5020be721bbef862.tar.bz2
android_packages_wallpapers_PhotoPhase-f29d68d929061ccbb982019c5020be721bbef862.zip
Initial commit
Signed-off-by: jruesga <jorge@ruesga.com>
Diffstat (limited to 'src/org/cyanogenmod/wallpapers/photophase/transitions')
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/transitions/FadeTransition.java137
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/transitions/NullTransition.java182
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/transitions/SwapTransition.java113
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/transitions/Transition.java202
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/transitions/Transitions.java104
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/transitions/TranslateTransition.java354
6 files changed, 1092 insertions, 0 deletions
diff --git a/src/org/cyanogenmod/wallpapers/photophase/transitions/FadeTransition.java b/src/org/cyanogenmod/wallpapers/photophase/transitions/FadeTransition.java
new file mode 100644
index 0000000..d88aafc
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/transitions/FadeTransition.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+package org.cyanogenmod.wallpapers.photophase.transitions;
+
+import android.content.Context;
+import android.opengl.GLException;
+import android.os.SystemClock;
+
+import org.cyanogenmod.wallpapers.photophase.Colors;
+import org.cyanogenmod.wallpapers.photophase.PhotoFrame;
+import org.cyanogenmod.wallpapers.photophase.TextureManager;
+import org.cyanogenmod.wallpapers.photophase.shapes.ColorShape;
+import org.cyanogenmod.wallpapers.photophase.transitions.Transitions.TRANSITIONS;
+
+/**
+ * A transition that applies a fade transition to the picture.
+ */
+public class FadeTransition extends NullTransition {
+
+ private static final float TRANSITION_TIME = 800.0f;
+
+ private boolean mRunning;
+ private long mTime;
+
+ ColorShape mOverlay;
+
+ /**
+ * Constructor of <code>FadeTransition</code>
+ *
+ * @param ctx The current context
+ * @param tm The texture manager
+ */
+ public FadeTransition(Context ctx, TextureManager tm) {
+ super(ctx, tm);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public TRANSITIONS getType() {
+ return TRANSITIONS.FADE;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasTransitionTarget() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isRunning() {
+ return mRunning;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ mTime = -1;
+ mRunning = true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void select(PhotoFrame target) {
+ super.select(target);
+ mOverlay = new ColorShape(mContext, target.getPictureVertex(), Colors.getBackground());
+ mOverlay.setAlpha(0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void apply(float[] matrix) throws GLException {
+ // Check internal vars
+ if (mTarget == null ||
+ mTarget.getPictureVertexBuffer() == null ||
+ mTarget.getTextureBuffer() == null ||
+ mTarget.getVertexOrderBuffer() == null) {
+ return;
+ }
+ if (mTransitionTarget == null ||
+ mTransitionTarget.getPictureVertexBuffer() == null ||
+ mTransitionTarget.getTextureBuffer() == null ||
+ mTransitionTarget.getVertexOrderBuffer() == null) {
+ return;
+ }
+
+ // Set the time the first time
+ if (mTime == -1) {
+ mTime = SystemClock.uptimeMillis();
+ }
+
+ final float delta = Math.min(SystemClock.uptimeMillis() - mTime, TRANSITION_TIME) / TRANSITION_TIME;
+ if (delta <= 0.5) {
+ // Draw the src target
+ draw(mTarget, matrix);
+ mOverlay.setAlpha(delta * 2.0f);
+ } else {
+ // Draw the dst target
+ draw(mTransitionTarget, matrix);
+ mOverlay.setAlpha((1 - delta) * 2.0f);
+ }
+ mOverlay.draw(matrix);
+
+ // Transition ended
+ if (delta == 1) {
+ mRunning = false;
+ }
+ }
+
+}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/transitions/NullTransition.java b/src/org/cyanogenmod/wallpapers/photophase/transitions/NullTransition.java
new file mode 100644
index 0000000..66f89d1
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/transitions/NullTransition.java
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ */
+
+package org.cyanogenmod.wallpapers.photophase.transitions;
+
+import android.content.Context;
+import android.opengl.GLES20;
+import android.opengl.GLException;
+
+import org.cyanogenmod.wallpapers.photophase.GLESUtil;
+import org.cyanogenmod.wallpapers.photophase.PhotoFrame;
+import org.cyanogenmod.wallpapers.photophase.R;
+import org.cyanogenmod.wallpapers.photophase.TextureManager;
+import org.cyanogenmod.wallpapers.photophase.transitions.Transitions.TRANSITIONS;
+
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+/**
+ * A special transition that does nothing other than draw the {@link PhotoFrame}
+ * on the screen continually. No transition is done.
+ */
+public class NullTransition extends Transition {
+
+ private static final int[] VERTEX_SHADER = {R.raw.default_vertex_shader};
+ private static final int[] FRAGMENT_SHADER = {R.raw.default_fragment_shader};
+
+ /**
+ * Constructor of <code>NullTransition</code>
+ *
+ * @param ctx The current context
+ * @param tm The texture manager
+ */
+ public NullTransition(Context ctx, TextureManager tm) {
+ super(ctx, tm, VERTEX_SHADER, FRAGMENT_SHADER);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void select(PhotoFrame target) {
+ super.select(target);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public TRANSITIONS getType() {
+ return TRANSITIONS.NO_TRANSITION;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasTransitionTarget() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isRunning() {
+ return mTarget == null || !mTarget.isLoaded();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isSelectable(PhotoFrame frame) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void reset() {
+ // Nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void apply(float[] matrix) throws GLException {
+ // Check internal vars
+ if (mTarget == null ||
+ mTarget.getPictureVertexBuffer() == null ||
+ mTarget.getTextureBuffer() == null ||
+ mTarget.getVertexOrderBuffer() == null) {
+ return;
+ }
+
+ // Draw the current target
+ draw(mTarget, matrix);
+ }
+
+ /**
+ * Method that draws the picture texture
+ *
+ * @param target
+ * @param matrix The model-view-projection matrix
+ */
+ protected void draw(PhotoFrame target, float[] matrix) {
+ // Set the program
+ useProgram(0);
+
+ // Bind the texture
+ int textureHandle = target.getTextureHandle();
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+ GLESUtil.glesCheckError("glActiveTexture");
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle);
+ GLESUtil.glesCheckError("glBindTexture");
+
+ // Position
+ FloatBuffer vertexBuffer = target.getPictureVertexBuffer();
+ vertexBuffer.position(0);
+ GLES20.glVertexAttribPointer(
+ mPositionHandlers[0],
+ PhotoFrame.COORDS_PER_VERTER,
+ GLES20.GL_FLOAT,
+ false,
+ PhotoFrame.COORDS_PER_VERTER * 4,
+ vertexBuffer);
+ GLESUtil.glesCheckError("glVertexAttribPointer");
+ GLES20.glEnableVertexAttribArray(mPositionHandlers[0]);
+ GLESUtil.glesCheckError("glEnableVertexAttribArray");
+
+ // Texture
+ FloatBuffer textureBuffer = target.getTextureBuffer();
+ textureBuffer.position(0);
+ GLES20.glVertexAttribPointer(
+ mTextureCoordHandlers[0],
+ 2,
+ GLES20.GL_FLOAT,
+ false,
+ 2 * 4,
+ textureBuffer);
+ GLESUtil.glesCheckError("glVertexAttribPointer");
+ GLES20.glEnableVertexAttribArray(mTextureCoordHandlers[0]);
+ GLESUtil.glesCheckError("glEnableVertexAttribArray");
+
+ // Apply the projection and view transformation
+ GLES20.glUniformMatrix4fv(mMVPMatrixHandlers[0], 1, false, matrix, 0);
+ GLESUtil.glesCheckError("glUniformMatrix4fv");
+
+ // Draw the photo frame
+ ShortBuffer vertexOrderBuffer = target.getVertexOrderBuffer();
+ vertexOrderBuffer.position(0);
+ GLES20.glDrawElements(
+ GLES20.GL_TRIANGLE_FAN,
+ 6,
+ GLES20.GL_UNSIGNED_SHORT,
+ vertexOrderBuffer);
+ GLESUtil.glesCheckError("glDrawElements");
+
+ // Disable attributes
+ GLES20.glDisableVertexAttribArray(mPositionHandlers[0]);
+ GLESUtil.glesCheckError("glDisableVertexAttribArray");
+ GLES20.glDisableVertexAttribArray(mTextureCoordHandlers[0]);
+ GLESUtil.glesCheckError("glDisableVertexAttribArray");
+ }
+
+}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/transitions/SwapTransition.java b/src/org/cyanogenmod/wallpapers/photophase/transitions/SwapTransition.java
new file mode 100644
index 0000000..d100110
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/transitions/SwapTransition.java
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+package org.cyanogenmod.wallpapers.photophase.transitions;
+
+import android.content.Context;
+import android.opengl.GLException;
+import android.os.SystemClock;
+
+import org.cyanogenmod.wallpapers.photophase.TextureManager;
+import org.cyanogenmod.wallpapers.photophase.transitions.Transitions.TRANSITIONS;
+
+/**
+ * A simple transition that swap an image after the transition time is ended.
+ */
+public class SwapTransition extends NullTransition {
+
+ private static final float TRANSITION_TIME = 250.0f;
+
+ private boolean mRunning;
+ private long mTime;
+
+ /**
+ * Constructor of <code>SwapTransition</code>
+ *
+ * @param ctx The current context
+ * @param tm The texture manager
+ */
+ public SwapTransition(Context ctx, TextureManager tm) {
+ super(ctx, tm);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public TRANSITIONS getType() {
+ return TRANSITIONS.SWAP;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasTransitionTarget() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isRunning() {
+ return mRunning;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ mTime = -1;
+ mRunning = true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void apply(float[] matrix) throws GLException {
+ // Check internal vars
+ if (mTarget == null ||
+ mTarget.getPictureVertexBuffer() == null ||
+ mTarget.getTextureBuffer() == null ||
+ mTarget.getVertexOrderBuffer() == null) {
+ return;
+ }
+ if (mTransitionTarget == null ||
+ mTransitionTarget.getPictureVertexBuffer() == null ||
+ mTransitionTarget.getTextureBuffer() == null ||
+ mTransitionTarget.getVertexOrderBuffer() == null) {
+ return;
+ }
+
+ // Set the time the first time
+ if (mTime == -1) {
+ mTime = SystemClock.uptimeMillis();
+ }
+
+ // Calculate the delta time
+ final float delta = Math.min(SystemClock.uptimeMillis() - mTime, TRANSITION_TIME) / TRANSITION_TIME;
+
+ // Apply the transition
+ boolean ended = delta == 1;
+ draw(ended ? mTransitionTarget : mTarget, matrix);
+ mRunning = !ended;
+ }
+
+}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/transitions/Transition.java b/src/org/cyanogenmod/wallpapers/photophase/transitions/Transition.java
new file mode 100644
index 0000000..315a9f8
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/transitions/Transition.java
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+package org.cyanogenmod.wallpapers.photophase.transitions;
+
+import android.content.Context;
+import android.opengl.GLES20;
+
+import org.cyanogenmod.wallpapers.photophase.GLESUtil;
+import org.cyanogenmod.wallpapers.photophase.PhotoFrame;
+import org.cyanogenmod.wallpapers.photophase.TextureManager;
+import org.cyanogenmod.wallpapers.photophase.transitions.Transitions.TRANSITIONS;
+
+/**
+ * The base class of all transitions that can be applied to the {@link PhotoFrame} classes.
+ */
+public abstract class Transition {
+
+ public static final long MAX_TRANSTION_TIME = 1500L;
+
+ protected final Context mContext;
+ private final TextureManager mTextureManager;
+
+ protected int[] mProgramHandlers;
+ protected int[] mPositionHandlers;
+ protected int[] mTextureCoordHandlers;
+ protected int[] mMVPMatrixHandlers;
+
+ protected PhotoFrame mTarget;
+ protected PhotoFrame mTransitionTarget;
+
+ private final int[] mVertexShader;
+ private final int[] mFragmentShader;
+
+ /**
+ * Constructor of <code>Transition</code>
+ *
+ * @param ctx The current context
+ * @param tm The current texture manager
+ * @param vertexShader The vertex shaders of the programs
+ * @param fragmentShader The fragment shaders of the programs
+ */
+ public Transition(Context ctx, TextureManager tm, int[] vertexShader, int[] fragmentShader) {
+ super();
+ mContext = ctx;
+ mTextureManager = tm;
+ mVertexShader = vertexShader;
+ mFragmentShader = fragmentShader;
+
+ // Compile every program
+ assert mVertexShader.length != mFragmentShader.length;
+ int cc = mVertexShader.length;
+ mProgramHandlers = new int[cc];
+ mPositionHandlers = new int[cc];
+ mTextureCoordHandlers = new int[cc];
+ mMVPMatrixHandlers = new int[cc];
+ for (int i = 0; i < cc; i++) {
+ createProgram(i);
+ }
+ }
+
+ /**
+ * Method that requests to apply this transition.
+ *
+ * @param target The target photo frame
+ */
+ public void select(PhotoFrame target) {
+ mTarget = target;
+ if (hasTransitionTarget()) {
+ // Load the transition frame and request a picture for it
+ mTransitionTarget =
+ new PhotoFrame(
+ mContext,
+ mTextureManager,
+ mTarget.getFrameVertex(),
+ mTarget.getPictureVertex(),
+ mTarget.getBackgroundColor());
+ }
+ }
+
+ /**
+ * Method that returns the target of the transition.
+ *
+ * @return PhotoFrame The target of the transition
+ */
+ public PhotoFrame getTarget() {
+ return mTarget;
+ }
+
+ /**
+ * Method that returns the transition target of the transition.
+ *
+ * @return PhotoFrame The transition target of the transition
+ */
+ public PhotoFrame getTransitionTarget() {
+ return mTransitionTarget;
+ }
+
+ /**
+ * Method that returns if the transition is selectable for the passed frame.
+ *
+ * @param frame The frame which the transition should be applied to
+ * @return boolean If the transition is selectable for the passed frame
+ */
+ public abstract boolean isSelectable(PhotoFrame frame);
+
+ /**
+ * Method that resets the current status of the transition.
+ */
+ public abstract void reset();
+
+ /**
+ * Method that returns the type of transition.
+ *
+ * @return TRANSITIONS The type of transition
+ */
+ public abstract TRANSITIONS getType();
+
+ /**
+ * Method that requests to apply this transition.
+ *
+ * @param matrix The model-view-projection matrix
+ */
+ public abstract void apply(float[] matrix);
+
+ /**
+ * Method that returns if the transition is being transition.
+ *
+ * @return boolean If the transition is being transition.
+ */
+ public abstract boolean isRunning();
+
+ /**
+ * Method that return if the transition has a secondary target
+ *
+ * @return boolean If the transition has a secondary target
+ */
+ public abstract boolean hasTransitionTarget();
+
+ /**
+ * Method that creates the program
+ */
+ protected void createProgram(int index) {
+ mProgramHandlers[index] =
+ GLESUtil.createProgram(
+ mContext.getResources(), mVertexShader[index], mFragmentShader[index]);
+ mPositionHandlers[index] =
+ GLES20.glGetAttribLocation(mProgramHandlers[index], "aPosition");
+ GLESUtil.glesCheckError("glGetAttribLocation");
+ mTextureCoordHandlers[index] =
+ GLES20.glGetAttribLocation(mProgramHandlers[index], "aTextureCoord");
+ GLESUtil.glesCheckError("glGetAttribLocation");
+ mMVPMatrixHandlers[index] =
+ GLES20.glGetUniformLocation(mProgramHandlers[index], "uMVPMatrix");
+ GLESUtil.glesCheckError("glGetUniformLocation");
+ }
+
+ /**
+ * Method that set the program to use
+ *
+ * @param index The index of the program to use
+ */
+ protected void useProgram(int index) {
+ if (!GLES20.glIsProgram(mProgramHandlers[index])) {
+ createProgram(index);
+ }
+ GLES20.glUseProgram(mProgramHandlers[index]);
+ GLESUtil.glesCheckError("glUseProgram(" + index + ")");
+ }
+
+ /**
+ * Method that requests to the transition to remove its internal references and resources.
+ */
+ public void recycle() {
+ int cc = mProgramHandlers.length;
+ for (int i = 0; i < cc; i++) {
+ if (GLES20.glIsProgram(mProgramHandlers[i])) {
+ GLES20.glDeleteProgram(mProgramHandlers[i]);
+ GLESUtil.glesCheckError("glDeleteProgram");
+ }
+ mProgramHandlers[i] = 0;
+ mPositionHandlers[i] = 0;
+ mTextureCoordHandlers[i] = 0;
+ mMVPMatrixHandlers[i] = 0;
+ }
+ mTransitionTarget = null;
+ mTarget = null;
+ }
+}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/transitions/Transitions.java b/src/org/cyanogenmod/wallpapers/photophase/transitions/Transitions.java
new file mode 100644
index 0000000..e29bfce
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/transitions/Transitions.java
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+package org.cyanogenmod.wallpapers.photophase.transitions;
+
+import android.content.Context;
+
+import org.cyanogenmod.wallpapers.photophase.PhotoFrame;
+import org.cyanogenmod.wallpapers.photophase.TextureManager;
+import org.cyanogenmod.wallpapers.photophase.preferences.PreferencesProvider.Preferences;
+
+
+/**
+ * A class that manages all the supported transitions
+ */
+public class Transitions {
+
+ /**
+ * Enumeration of the supported transitions
+ */
+ public enum TRANSITIONS {
+ /**
+ * A random combination of all supported transitions
+ */
+ RANDOM,
+ /**
+ * @see NullTransition
+ */
+ NO_TRANSITION,
+ /**
+ * @see SwapTransition
+ */
+ SWAP,
+ /**
+ * @see FadeTransition
+ */
+ FADE,
+ /**
+ * @see TranslateTransition
+ */
+ TRANSLATION;
+ }
+
+ /**
+ * Method that return the next type of transition to apply the picture.
+ *
+ * @param frame The frame which the effect will be applied to
+ * @return TRANSITIONS The next type of transition to apply
+ */
+ public static TRANSITIONS getNextTypeOfTransition(PhotoFrame frame) {
+ int transition = Preferences.General.Transitions.getTransitionTypes();
+ if (transition == TRANSITIONS.RANDOM.ordinal()) {
+ int low = TRANSITIONS.SWAP.ordinal();
+ int hight = TRANSITIONS.values().length - 1;
+ transition = low + (int)(Math.random() * ((hight - low) + 1));
+ }
+ if (transition == TRANSITIONS.SWAP.ordinal()) {
+ return TRANSITIONS.SWAP;
+ }
+ if (transition == TRANSITIONS.FADE.ordinal()) {
+ return TRANSITIONS.FADE;
+ }
+ if (transition == TRANSITIONS.TRANSLATION.ordinal()) {
+ return TRANSITIONS.TRANSLATION;
+ }
+ return TRANSITIONS.NO_TRANSITION;
+ }
+
+ /**
+ * Method that creates a new transition.
+ *
+ * @param ctx The current context
+ * @param tm The texture manager
+ * @param type The type of transition
+ * @param frame The frame which the effect will be applied to
+ * @return Transition The next transition to apply
+ */
+ public static Transition createTransition(
+ Context ctx, TextureManager tm, TRANSITIONS type, PhotoFrame frame) {
+ if (type.compareTo(TRANSITIONS.SWAP) == 0) {
+ return new SwapTransition(ctx, tm);
+ }
+ if (type.compareTo(TRANSITIONS.FADE) == 0) {
+ return new FadeTransition(ctx, tm);
+ }
+ if (type.compareTo(TRANSITIONS.TRANSLATION) == 0) {
+ return new TranslateTransition(ctx, tm);
+ }
+ return new NullTransition(ctx, tm);
+ }
+}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/transitions/TranslateTransition.java b/src/org/cyanogenmod/wallpapers/photophase/transitions/TranslateTransition.java
new file mode 100644
index 0000000..4e32a4a
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/transitions/TranslateTransition.java
@@ -0,0 +1,354 @@
+/*
+ * 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.
+ */
+
+package org.cyanogenmod.wallpapers.photophase.transitions;
+
+import android.content.Context;
+import android.opengl.GLES20;
+import android.opengl.GLException;
+import android.opengl.Matrix;
+import android.os.SystemClock;
+
+import org.cyanogenmod.wallpapers.photophase.GLESUtil;
+import org.cyanogenmod.wallpapers.photophase.PhotoFrame;
+import org.cyanogenmod.wallpapers.photophase.R;
+import org.cyanogenmod.wallpapers.photophase.TextureManager;
+import org.cyanogenmod.wallpapers.photophase.transitions.Transitions.TRANSITIONS;
+
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A transition that applies a translation transition to the picture.
+ */
+public class TranslateTransition extends Transition {
+
+ /**
+ * The enumeration of all possibles translations movements
+ */
+ public enum TRANSLATE_MODES {
+ /**
+ * Translate the picture from left to right
+ */
+ LEFT_TO_RIGHT,
+ /**
+ * Translate the picture from right to left
+ */
+ RIGHT_TO_LEFT,
+ /**
+ * Translate the picture from up to down
+ */
+ UP_TO_DOWN,
+ /**
+ * Translate the picture from down to up
+ */
+ DOWN_TO_UP
+ }
+
+ private static final int[] VERTEX_SHADER = {R.raw.translate_vertex_shader, R.raw.default_vertex_shader};
+ private static final int[] FRAGMENT_SHADER = {R.raw.translate_fragment_shader, R.raw.default_fragment_shader};
+
+ private static final float TRANSITION_TIME = 800.0f;
+
+ private TRANSLATE_MODES mMode;
+
+ private boolean mRunning;
+ private long mTime;
+
+ /**
+ * Constructor of <code>TranslateTransition</code>
+ *
+ * @param ctx The current context
+ * @param tm The texture manager
+ */
+ public TranslateTransition(Context ctx, TextureManager tm) {
+ super(ctx, tm, VERTEX_SHADER, FRAGMENT_SHADER);
+
+ // Initialized
+ reset();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public TRANSITIONS getType() {
+ return TRANSITIONS.TRANSLATION;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasTransitionTarget() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isRunning() {
+ return mRunning;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void select(PhotoFrame target) {
+ super.select(target);
+
+ // Discard all non-supported modes
+ List<TRANSLATE_MODES> modes =
+ new ArrayList<TranslateTransition.TRANSLATE_MODES>(
+ Arrays.asList(TRANSLATE_MODES.values()));
+ float[] vertex = target.getFrameVertex();
+ if (vertex[0] != -1.0f) {
+ modes.remove(TRANSLATE_MODES.RIGHT_TO_LEFT);
+ }
+ if (vertex[9] != 1.0f) {
+ modes.remove(TRANSLATE_MODES.LEFT_TO_RIGHT);
+ }
+ if (vertex[1] != 1.0f) {
+ modes.remove(TRANSLATE_MODES.DOWN_TO_UP);
+ }
+ if (vertex[4] != -1.0f) {
+ modes.remove(TRANSLATE_MODES.UP_TO_DOWN);
+ }
+
+ // Random mode
+ int low = 0;
+ int hight = modes.size() - 1;
+ mMode = modes.get(low + (int)(Math.random() * ((hight - low) + 1)));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isSelectable(PhotoFrame frame) {
+ float[] vertex = frame.getFrameVertex();
+ if (vertex[0] == -1.0f || vertex[9] == 1.0f ||
+ vertex[1] == 1.0f || vertex[4] == -1.0f) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void reset() {
+ mTime = -1;
+ mRunning = true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void apply(float[] matrix) throws GLException {
+ // Check internal vars
+ if (mTarget == null ||
+ mTarget.getPictureVertexBuffer() == null ||
+ mTarget.getTextureBuffer() == null ||
+ mTarget.getVertexOrderBuffer() == null) {
+ return;
+ }
+ if (mTransitionTarget == null ||
+ mTransitionTarget.getPictureVertexBuffer() == null ||
+ mTransitionTarget.getTextureBuffer() == null ||
+ mTransitionTarget.getVertexOrderBuffer() == null) {
+ return;
+ }
+
+ // Set the time the first time
+ if (mTime == -1) {
+ mTime = SystemClock.uptimeMillis();
+ }
+
+ // Calculate the delta time
+ final float delta = Math.min(SystemClock.uptimeMillis() - mTime, TRANSITION_TIME) / TRANSITION_TIME;
+
+ // Apply the transition
+ applyTransitionToTransitionTarget(delta, matrix);
+ if (delta < 1) {
+ applyTransitionToTarget(delta, matrix);
+ }
+
+ // Transition ending
+ if (delta == 1) {
+ mRunning = false;
+ }
+ }
+
+ /**
+ * Apply the transition to the passed frame
+ *
+ * @param delta The delta time
+ * @param matrix The model-view-projection matrix
+ */
+ private void applyTransitionToTarget(float delta, float[] matrix) {
+ // Set the program
+ useProgram(0);
+
+ // Bind the texture
+ int textureHandle = mTarget.getTextureHandle();
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+ GLESUtil.glesCheckError("glActiveTexture");
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle);
+ GLESUtil.glesCheckError("glBindTexture");
+
+ // Position
+ FloatBuffer vertexBuffer = mTarget.getPictureVertexBuffer();
+ vertexBuffer.position(0);
+ GLES20.glVertexAttribPointer(
+ mPositionHandlers[0],
+ PhotoFrame.COORDS_PER_VERTER,
+ GLES20.GL_FLOAT,
+ false,
+ PhotoFrame.COORDS_PER_VERTER * 4,
+ vertexBuffer);
+ GLESUtil.glesCheckError("glVertexAttribPointer");
+ GLES20.glEnableVertexAttribArray(mPositionHandlers[0]);
+ GLESUtil.glesCheckError("glEnableVertexAttribArray");
+
+ // Texture
+ FloatBuffer textureBuffer = mTarget.getTextureBuffer();
+ textureBuffer.position(0);
+ GLES20.glVertexAttribPointer(
+ mTextureCoordHandlers[0],
+ 2,
+ GLES20.GL_FLOAT,
+ false,
+ 2 * 4,
+ textureBuffer);
+ GLESUtil.glesCheckError("glVertexAttribPointer");
+ GLES20.glEnableVertexAttribArray(mTextureCoordHandlers[0]);
+ GLESUtil.glesCheckError("glEnableVertexAttribArray");
+
+ // Calculate the delta distance
+ float distance =
+ (mMode.compareTo(TRANSLATE_MODES.LEFT_TO_RIGHT) == 0 || mMode.compareTo(TRANSLATE_MODES.RIGHT_TO_LEFT) == 0)
+ ? mTarget.getPictureWidth()
+ : mTarget.getPictureHeight();
+ if (mMode.compareTo(TRANSLATE_MODES.RIGHT_TO_LEFT) == 0 || mMode.compareTo(TRANSLATE_MODES.DOWN_TO_UP) == 0) {
+ distance *= -1;
+ }
+ distance *= delta;
+ boolean vertical = (mMode.compareTo(TRANSLATE_MODES.UP_TO_DOWN) == 0 || mMode.compareTo(TRANSLATE_MODES.DOWN_TO_UP) == 0);
+
+ // Apply the projection and view transformation
+ float[] translationMatrix = new float[16];
+ if (vertical) {
+ Matrix.translateM(translationMatrix, 0, matrix, 0, 0.0f, distance, 0.0f);
+ } else {
+ Matrix.translateM(translationMatrix, 0, matrix, 0, distance, 0.0f, 0.0f);
+ }
+ GLES20.glUniformMatrix4fv(mMVPMatrixHandlers[0], 1, false, translationMatrix, 0);
+ GLESUtil.glesCheckError("glUniformMatrix4fv");
+
+ // Draw the photo frame
+ ShortBuffer vertexOrderBuffer = mTarget.getVertexOrderBuffer();
+ vertexOrderBuffer.position(0);
+ GLES20.glDrawElements(
+ GLES20.GL_TRIANGLE_FAN,
+ 6,
+ GLES20.GL_UNSIGNED_SHORT,
+ vertexOrderBuffer);
+ GLESUtil.glesCheckError("glDrawElements");
+
+ // Disable attributes
+ GLES20.glDisableVertexAttribArray(mPositionHandlers[0]);
+ GLESUtil.glesCheckError("glDisableVertexAttribArray");
+ GLES20.glDisableVertexAttribArray(mTextureCoordHandlers[0]);
+ GLESUtil.glesCheckError("glDisableVertexAttribArray");
+ }
+
+ /**
+ * Apply the transition to the passed frame
+ *
+ * @param delta The delta time
+ * @param matrix The model-view-projection matrix
+ */
+ private void applyTransitionToTransitionTarget(float delta, float[] matrix) {
+ // Set the program
+ useProgram(1);
+
+ // Bind the texture
+ int textureHandle = mTransitionTarget.getTextureHandle();
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+ GLESUtil.glesCheckError("glActiveTexture");
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle);
+ GLESUtil.glesCheckError("glBindTexture");
+
+ // Position
+ FloatBuffer vertexBuffer = mTransitionTarget.getPictureVertexBuffer();
+ vertexBuffer.position(0);
+ GLES20.glVertexAttribPointer(
+ mPositionHandlers[1],
+ PhotoFrame.COORDS_PER_VERTER,
+ GLES20.GL_FLOAT,
+ false,
+ PhotoFrame.COORDS_PER_VERTER * 4,
+ vertexBuffer);
+ GLESUtil.glesCheckError("glVertexAttribPointer");
+ GLES20.glEnableVertexAttribArray(mPositionHandlers[1]);
+ GLESUtil.glesCheckError("glEnableVertexAttribArray");
+
+ // Texture
+ FloatBuffer textureBuffer = mTransitionTarget.getTextureBuffer();
+ textureBuffer.position(0);
+ GLES20.glVertexAttribPointer(
+ mTextureCoordHandlers[1],
+ 2,
+ GLES20.GL_FLOAT,
+ false,
+ 2 * 4,
+ textureBuffer);
+ GLESUtil.glesCheckError("glVertexAttribPointer");
+ GLES20.glEnableVertexAttribArray(mTextureCoordHandlers[1]);
+ GLESUtil.glesCheckError("glEnableVertexAttribArray");
+
+ // Apply the projection and view transformation
+ float[] translationMatrix = new float[16];
+ Matrix.translateM(translationMatrix, 0, matrix, 0, 0.0f, 0.0f, 0.0f);
+ GLES20.glUniformMatrix4fv(mMVPMatrixHandlers[1], 1, false, translationMatrix, 0);
+ GLESUtil.glesCheckError("glUniformMatrix4fv");
+
+ // Draw the photo frame
+ ShortBuffer vertexOrderBuffer = mTransitionTarget.getVertexOrderBuffer();
+ vertexOrderBuffer.position(0);
+ GLES20.glDrawElements(
+ GLES20.GL_TRIANGLE_FAN,
+ 6,
+ GLES20.GL_UNSIGNED_SHORT,
+ vertexOrderBuffer);
+ GLESUtil.glesCheckError("glDrawElements");
+
+ // Disable attributes
+ GLES20.glDisableVertexAttribArray(mPositionHandlers[1]);
+ GLESUtil.glesCheckError("glDisableVertexAttribArray");
+ GLES20.glDisableVertexAttribArray(mTextureCoordHandlers[1]);
+ GLESUtil.glesCheckError("glDisableVertexAttribArray");
+ }
+
+}