commit 6bb59aad4f6f04f04ca6e6ff22be8ad86b31b252
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Thu Jun 8 16:54:30 2017 +0100

    Progress with support for Effect classes.

diff --git a/src/main/java/org/distorted/library/effect/Effect.java b/src/main/java/org/distorted/library/effect/Effect.java
index 4a90d18..1a68c8d 100644
--- a/src/main/java/org/distorted/library/effect/Effect.java
+++ b/src/main/java/org/distorted/library/effect/Effect.java
@@ -29,6 +29,7 @@ public abstract class Effect
   private final int mDimension;
   private final boolean mSupportsR;
   private final boolean mSupportsC;
+  private final String mStr;
 
   private static long mNextID = 0;
 
@@ -39,6 +40,7 @@ public abstract class Effect
 
   public static final int LENGTH = 4;           // The number of effect types above.
   public static final int MASK= (1<<LENGTH)-1;  // Needed when we do bitwise operations on Effect Types.
+  static final int MAX_EFFECTS = 1000;          // The can be no more than MAX_EFFECTS effects of a given type.
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -61,6 +63,13 @@ public abstract class Effect
     maxtable[3] = PostprocessEffect.MAX;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static int getType(int name)
+    {
+    return name/MAX_EFFECTS;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public int getType()
@@ -82,6 +91,13 @@ public abstract class Effect
     return mID;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public String getString()
+    {
+    return mStr;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public boolean supportsCenter()
@@ -105,7 +121,7 @@ public abstract class Effect
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  Effect(int type, int name, int dimension, boolean center, boolean region)
+  Effect(int type, int name, int dimension, boolean center, boolean region, final String str)
     {
     mID        = mNextID++;
 
@@ -114,5 +130,6 @@ public abstract class Effect
     mDimension = dimension;
     mSupportsC = center;
     mSupportsR = region;
+    mStr       = str;
     }
   }
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffect.java b/src/main/java/org/distorted/library/effect/FragmentEffect.java
index 9f63d06..c0057c9 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffect.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffect.java
@@ -19,9 +19,10 @@
 
 package org.distorted.library.effect;
 
-import org.distorted.library.type.Data4D;
 import org.distorted.library.type.Dynamic;
+import org.distorted.library.type.Dynamic4D;
 import org.distorted.library.type.Static;
+import org.distorted.library.type.Static4D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // FRAGMENT EFFECTS
@@ -31,33 +32,34 @@ public abstract class FragmentEffect extends Effect
   {
   public static final int NUM_UNIFORMS = 8;
 
-  public static final int CHROMA            = 0;
-  public static final int SMOOTH_CHROMA     = 1;
-  public static final int ALPHA             = 2;
-  public static final int SMOOTH_ALPHA      = 3;
-  public static final int BRIGHTNESS        = 4;
-  public static final int SMOOTH_BRIGHTNESS = 5;
-  public static final int CONTRAST          = 6;
-  public static final int SMOOTH_CONTRAST   = 7;
-  public static final int SATURATION        = 8;
-  public static final int SMOOTH_SATURATION = 9;
-  public static final int NUM_EFFECTS       =10;
+  public static final int CHROMA            = MAX_EFFECTS*FRAGMENT    ;
+  public static final int SMOOTH_CHROMA     = MAX_EFFECTS*FRAGMENT + 1;
+  public static final int ALPHA             = MAX_EFFECTS*FRAGMENT + 2;
+  public static final int SMOOTH_ALPHA      = MAX_EFFECTS*FRAGMENT + 3;
+  public static final int BRIGHTNESS        = MAX_EFFECTS*FRAGMENT + 4;
+  public static final int SMOOTH_BRIGHTNESS = MAX_EFFECTS*FRAGMENT + 5;
+  public static final int CONTRAST          = MAX_EFFECTS*FRAGMENT + 6;
+  public static final int SMOOTH_CONTRAST   = MAX_EFFECTS*FRAGMENT + 7;
+  public static final int SATURATION        = MAX_EFFECTS*FRAGMENT + 8;
+  public static final int SMOOTH_SATURATION = MAX_EFFECTS*FRAGMENT + 9;
+  public static final int NUM_EFFECTS       = 10;
 
   static final int MAX = 5;
   private static final int MAX_UNITY_DIM = 1;
 
   Dynamic mDynamic0, mDynamic1;
   Static mStatic0, mStatic1;
-  Data4D mRegion;
+  Dynamic4D mDynamicRegion;
+  Static4D mStaticRegion;
 
   private final static float[] mUnity    = new float[MAX_UNITY_DIM*NUM_EFFECTS];
   private final static int[]   mUnityDim = new int[NUM_EFFECTS];
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public FragmentEffect(int name,float[] unity, int dimension, boolean center, boolean region)
+  public FragmentEffect(int name,float[] unity, int dimension, boolean center, boolean region, final String str)
     {
-    super(FRAGMENT,name,dimension,center,region);
+    super(FRAGMENT,name,dimension,center,region,str);
 
     for(int i=0; i<unity.length; i++)
       {
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectAlpha.java b/src/main/java/org/distorted/library/effect/FragmentEffectAlpha.java
index dd5dc4e..b425c9e 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectAlpha.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectAlpha.java
@@ -22,22 +22,33 @@ package org.distorted.library.effect;
 import org.distorted.library.type.Data1D;
 import org.distorted.library.type.Data4D;
 import org.distorted.library.type.Dynamic1D;
+import org.distorted.library.type.Dynamic4D;
 import org.distorted.library.type.Static1D;
+import org.distorted.library.type.Static4D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class FragmentEffectAlpha extends FragmentEffect
   {
+  private static final String NAME = "ALPHA";
   private static final float[] UNITIES = new float[] {1.0f};
   private static final int DIMENSION = 1;
   private static final boolean SUPPORTS_CENTER = false;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes a certain sub-region of the Object smoothly change its transparency level.
+ *
+ * @param alpha  1-dimensional Data that returns the level of transparency we want to have at any given
+ *               moment: pixel.a *= alpha.
+ *               Valid range: <0,1>
+ * @param region Region this Effect is limited to.
+ * @param smooth If true, the level of 'alpha' will smoothly fade out towards the edges of the region.
+ */
   public FragmentEffectAlpha(Data1D alpha, Data4D region, boolean smooth)
     {
-    super(smooth?SMOOTH_ALPHA:ALPHA ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(smooth?SMOOTH_ALPHA:ALPHA ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( alpha instanceof Dynamic1D )
       {
@@ -48,14 +59,27 @@ public class FragmentEffectAlpha extends FragmentEffect
       mStatic0 = (Static1D)alpha;
       }
 
-    mRegion = region;
+    if( region instanceof Static4D)
+      {
+      mStaticRegion = (Static4D)region;
+      }
+    else if( region instanceof Dynamic4D)
+      {
+      mDynamicRegion = (Dynamic4D)region;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes the whole Object smoothly change its transparency level.
+ *
+ * @param alpha  1-dimensional Data that returns the level of transparency we want to have at any
+ *               given moment: pixel.a *= alpha.
+ *               Valid range: <0,1>
+ */
   public FragmentEffectAlpha(Data1D alpha)
     {
-    super(ALPHA,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(ALPHA,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( alpha instanceof Dynamic1D )
       {
@@ -65,12 +89,26 @@ public class FragmentEffectAlpha extends FragmentEffect
       {
       mStatic0 = (Static1D)alpha;
       }
+
+    mStaticRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public boolean compute(float[] uniforms, int index, long currentDuration, long step )
     {
+    if( mDynamicRegion!=null )
+      {
+      mDynamicRegion.interpolateMain(uniforms,index+4,currentDuration,step);
+      }
+    else
+      {
+      uniforms[index+4] = mStaticRegion.getX();
+      uniforms[index+5] = mStaticRegion.getY();
+      uniforms[index+6] = mStaticRegion.getZ();
+      uniforms[index+7] = mStaticRegion.getW();
+      }
+
     if( mDynamic0!=null )
       {
       return mDynamic0.interpolateMain(uniforms,index,currentDuration,step);
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectBrightness.java b/src/main/java/org/distorted/library/effect/FragmentEffectBrightness.java
index 0968057..c59c6ed 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectBrightness.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectBrightness.java
@@ -22,22 +22,32 @@ package org.distorted.library.effect;
 import org.distorted.library.type.Data1D;
 import org.distorted.library.type.Data4D;
 import org.distorted.library.type.Dynamic1D;
+import org.distorted.library.type.Dynamic4D;
 import org.distorted.library.type.Static1D;
+import org.distorted.library.type.Static4D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class FragmentEffectBrightness extends FragmentEffect
   {
+  private static final String NAME = "BRIGHTNESS";
   private static final float[] UNITIES = new float[] {1.0f};
   private static final int DIMENSION = 1;
   private static final boolean SUPPORTS_CENTER = false;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes a certain sub-region of the Object smoothly change its brightness level.
+ *
+ * @param brightness 1-dimensional Data that returns the level of brightness we want to have
+ *                   at any given moment. Valid range: <0,infinity)
+ * @param region     Region this Effect is limited to.
+ * @param smooth     If true, the level of 'brightness' will smoothly fade out towards the edges of the region.
+ */
   public FragmentEffectBrightness(Data1D brightness, Data4D region, boolean smooth)
     {
-    super(smooth?SMOOTH_BRIGHTNESS:BRIGHTNESS ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(smooth?SMOOTH_BRIGHTNESS:BRIGHTNESS ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( brightness instanceof Dynamic1D )
       {
@@ -48,14 +58,26 @@ public class FragmentEffectBrightness extends FragmentEffect
       mStatic0 = (Static1D)brightness;
       }
 
-    mRegion = region;
+    if( region instanceof Static4D)
+      {
+      mStaticRegion = (Static4D)region;
+      }
+    else if( region instanceof Dynamic4D)
+      {
+      mDynamicRegion = (Dynamic4D)region;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes the whole Object smoothly change its brightness level.
+ *
+ * @param brightness 1-dimensional Data that returns the level of brightness we want to have
+ *                   at any given moment. Valid range: <0,infinity)
+ */
   public FragmentEffectBrightness(Data1D brightness)
     {
-    super(BRIGHTNESS,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(BRIGHTNESS,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( brightness instanceof Dynamic1D )
       {
@@ -65,12 +87,26 @@ public class FragmentEffectBrightness extends FragmentEffect
       {
       mStatic0 = (Static1D)brightness;
       }
+
+    mStaticRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public boolean compute(float[] uniforms, int index, long currentDuration, long step )
     {
+    if( mDynamicRegion!=null )
+      {
+      mDynamicRegion.interpolateMain(uniforms,index+4,currentDuration,step);
+      }
+    else
+      {
+      uniforms[index+4] = mStaticRegion.getX();
+      uniforms[index+5] = mStaticRegion.getY();
+      uniforms[index+6] = mStaticRegion.getZ();
+      uniforms[index+7] = mStaticRegion.getW();
+      }
+
     if( mDynamic0!=null )
       {
       return mDynamic0.interpolateMain(uniforms,index,currentDuration,step);
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectChroma.java b/src/main/java/org/distorted/library/effect/FragmentEffectChroma.java
index 33c6bf8..5c1350c 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectChroma.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectChroma.java
@@ -24,23 +24,35 @@ import org.distorted.library.type.Data3D;
 import org.distorted.library.type.Data4D;
 import org.distorted.library.type.Dynamic1D;
 import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Dynamic4D;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static4D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class FragmentEffectChroma extends FragmentEffect
   {
+  private static final String NAME = "CHROMA";
   private static final float[] UNITIES = new float[] {0.0f};
   private static final int DIMENSION = 4;
   private static final boolean SUPPORTS_CENTER = false;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
+ *
+ * @param blend  1-dimensional Data that returns the level of blend a given pixel will be
+ *               mixed with the next parameter 'color': pixel = (1-level)*pixel + level*color.
+ *               Valid range: <0,1>
+ * @param color  Color to mix. (1,0,0) is RED.
+ * @param region Region this Effect is limited to.
+ * @param smooth If true, the level of 'blend' will smoothly fade out towards the edges of the region.
+ */
   public FragmentEffectChroma(Data1D blend, Data3D color, Data4D region, boolean smooth)
     {
-    super(smooth?SMOOTH_CHROMA:CHROMA ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(smooth?SMOOTH_CHROMA:CHROMA ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( blend instanceof Dynamic1D )
       {
@@ -60,14 +72,28 @@ public class FragmentEffectChroma extends FragmentEffect
       mStatic1 = (Static3D)color;
       }
 
-    mRegion = region;
+    if( region instanceof Static4D)
+      {
+      mStaticRegion = (Static4D)region;
+      }
+    else if( region instanceof Dynamic4D)
+      {
+      mDynamicRegion = (Dynamic4D)region;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes the whole Object smoothly change all three of its RGB components.
+ *
+ * @param blend  1-dimensional Data that returns the level of blend a given pixel will be
+ *               mixed with the next parameter 'color': pixel = (1-level)*pixel + level*color.
+ *               Valid range: <0,1>
+ * @param color  Color to mix. (1,0,0) is RED.
+ */
   public FragmentEffectChroma(Data1D blend, Data3D color)
     {
-    super(CHROMA,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(CHROMA,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( blend instanceof Dynamic1D )
       {
@@ -86,12 +112,26 @@ public class FragmentEffectChroma extends FragmentEffect
       {
       mStatic1 = (Static3D)color;
       }
+
+    mStaticRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public boolean compute(float[] uniforms, int index, long currentDuration, long step )
     {
+    if( mDynamicRegion!=null )
+      {
+      mDynamicRegion.interpolateMain(uniforms,index+4,currentDuration,step);
+      }
+    else
+      {
+      uniforms[index+4] = mStaticRegion.getX();
+      uniforms[index+5] = mStaticRegion.getY();
+      uniforms[index+6] = mStaticRegion.getZ();
+      uniforms[index+7] = mStaticRegion.getW();
+      }
+
     if( mDynamic1!=null )
       {
       mDynamic1.interpolateMain(uniforms,index+1,currentDuration,step);
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectContrast.java b/src/main/java/org/distorted/library/effect/FragmentEffectContrast.java
index ea88713..e314f7d 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectContrast.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectContrast.java
@@ -22,22 +22,32 @@ package org.distorted.library.effect;
 import org.distorted.library.type.Data1D;
 import org.distorted.library.type.Data4D;
 import org.distorted.library.type.Dynamic1D;
+import org.distorted.library.type.Dynamic4D;
 import org.distorted.library.type.Static1D;
+import org.distorted.library.type.Static4D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class FragmentEffectContrast extends FragmentEffect
   {
+  private static final String NAME = "CONTRAST";
   private static final float[] UNITIES = new float[] {1.0f};
   private static final int DIMENSION = 1;
   private static final boolean SUPPORTS_CENTER = false;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes a certain sub-region of the Object smoothly change its contrast level.
+ *
+ * @param contrast 1-dimensional Data that returns the level of contrast we want to have
+ *                 at any given moment. Valid range: <0,infinity)
+ * @param region   Region this Effect is limited to.
+ * @param smooth   If true, the level of 'contrast' will smoothly fade out towards the edges of the region.
+ */
   public FragmentEffectContrast(Data1D contrast, Data4D region, boolean smooth)
     {
-    super(smooth?SMOOTH_CONTRAST:CONTRAST ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(smooth?SMOOTH_CONTRAST:CONTRAST ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( contrast instanceof Dynamic1D )
       {
@@ -48,14 +58,26 @@ public class FragmentEffectContrast extends FragmentEffect
       mStatic0 = (Static1D)contrast;
       }
 
-    mRegion = region;
+    if( region instanceof Static4D)
+      {
+      mStaticRegion = (Static4D)region;
+      }
+    else if( region instanceof Dynamic4D)
+      {
+      mDynamicRegion = (Dynamic4D)region;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes the whole Object smoothly change its contrast level.
+ *
+ * @param contrast 1-dimensional Data that returns the level of contrast we want to have
+ *                 at any given moment. Valid range: <0,infinity)
+ */
   public FragmentEffectContrast(Data1D contrast)
     {
-    super(CONTRAST,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(CONTRAST,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( contrast instanceof Dynamic1D )
       {
@@ -65,12 +87,26 @@ public class FragmentEffectContrast extends FragmentEffect
       {
       mStatic0 = (Static1D)contrast;
       }
+
+    mStaticRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public boolean compute(float[] uniforms, int index, long currentDuration, long step )
     {
+    if( mDynamicRegion!=null )
+      {
+      mDynamicRegion.interpolateMain(uniforms,index+4,currentDuration,step);
+      }
+    else
+      {
+      uniforms[index+4] = mStaticRegion.getX();
+      uniforms[index+5] = mStaticRegion.getY();
+      uniforms[index+6] = mStaticRegion.getZ();
+      uniforms[index+7] = mStaticRegion.getW();
+      }
+
     if( mDynamic0!=null )
       {
       return mDynamic0.interpolateMain(uniforms,index,currentDuration,step);
diff --git a/src/main/java/org/distorted/library/effect/FragmentEffectSaturation.java b/src/main/java/org/distorted/library/effect/FragmentEffectSaturation.java
index 2af5c70..f5e7cad 100644
--- a/src/main/java/org/distorted/library/effect/FragmentEffectSaturation.java
+++ b/src/main/java/org/distorted/library/effect/FragmentEffectSaturation.java
@@ -22,22 +22,32 @@ package org.distorted.library.effect;
 import org.distorted.library.type.Data1D;
 import org.distorted.library.type.Data4D;
 import org.distorted.library.type.Dynamic1D;
+import org.distorted.library.type.Dynamic4D;
 import org.distorted.library.type.Static1D;
+import org.distorted.library.type.Static4D;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class FragmentEffectSaturation extends FragmentEffect
   {
+  private static final String NAME = "SATURATION";
   private static final float[] UNITIES = new float[] {1.0f};
   private static final int DIMENSION = 1;
   private static final boolean SUPPORTS_CENTER = false;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes a certain sub-region of the Object smoothly change its saturation level.
+ *
+ * @param saturation 1-dimensional Data that returns the level of saturation we want to have
+ *                   at any given moment. Valid range: <0,infinity)
+ * @param region     Region this Effect is limited to.
+ * @param smooth     If true, the level of 'saturation' will smoothly fade out towards the edges of the region.
+ */
   public FragmentEffectSaturation(Data1D saturation, Data4D region, boolean smooth)
     {
-    super(smooth?SMOOTH_SATURATION:SATURATION ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(smooth?SMOOTH_SATURATION:SATURATION ,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( saturation instanceof Dynamic1D )
       {
@@ -48,14 +58,26 @@ public class FragmentEffectSaturation extends FragmentEffect
       mStatic0 = (Static1D)saturation;
       }
 
-    mRegion = region;
+    if( region instanceof Static4D)
+      {
+      mStaticRegion = (Static4D)region;
+      }
+    else if( region instanceof Dynamic4D)
+      {
+      mDynamicRegion = (Dynamic4D)region;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Makes the whole Object smoothly change its saturation level.
+ *
+ * @param saturation 1-dimensional Data that returns the level of saturation we want to have
+ *                   at any given moment. Valid range: <0,infinity)
+ */
   public FragmentEffectSaturation(Data1D saturation)
     {
-    super(SATURATION,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(SATURATION,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( saturation instanceof Dynamic1D )
       {
@@ -65,12 +87,26 @@ public class FragmentEffectSaturation extends FragmentEffect
       {
       mStatic0 = (Static1D)saturation;
       }
+
+    mStaticRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public boolean compute(float[] uniforms, int index, long currentDuration, long step )
     {
+    if( mDynamicRegion!=null )
+      {
+      mDynamicRegion.interpolateMain(uniforms,index+4,currentDuration,step);
+      }
+    else
+      {
+      uniforms[index+4] = mStaticRegion.getX();
+      uniforms[index+5] = mStaticRegion.getY();
+      uniforms[index+6] = mStaticRegion.getZ();
+      uniforms[index+7] = mStaticRegion.getW();
+      }
+
     if( mDynamic0!=null )
       {
       return mDynamic0.interpolateMain(uniforms,index,currentDuration,step);
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffect.java b/src/main/java/org/distorted/library/effect/MatrixEffect.java
index 9fa6f30..9a8367e 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffect.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffect.java
@@ -29,11 +29,11 @@ public abstract class MatrixEffect extends Effect
   {
   public static final int NUM_UNIFORMS = 7;
 
-  public static final int MOVE       = 0;
-  public static final int SCALE      = 1;
-  public static final int ROTATE     = 2;
-  public static final int QUATERNION = 3;
-  public static final int SHEAR      = 4;
+  public static final int MOVE       = MAX_EFFECTS*MATRIX    ;
+  public static final int SCALE      = MAX_EFFECTS*MATRIX + 1;
+  public static final int ROTATE     = MAX_EFFECTS*MATRIX + 2;
+  public static final int QUATERNION = MAX_EFFECTS*MATRIX + 3;
+  public static final int SHEAR      = MAX_EFFECTS*MATRIX + 4;
   public static final int NUM_EFFECTS= 5;
 
   static final int MAX = 5;
@@ -49,9 +49,9 @@ public abstract class MatrixEffect extends Effect
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public MatrixEffect(int name, float[] unity, int dimension, boolean center, boolean region)
+  public MatrixEffect(int name, float[] unity, int dimension, boolean center, boolean region, final String str)
     {
-    super(MATRIX,name,dimension,center,region);
+    super(MATRIX,name,dimension,center,region,str);
 
     for(int i=0; i<unity.length; i++)
       {
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectMove.java b/src/main/java/org/distorted/library/effect/MatrixEffectMove.java
index 79bbe37..4b4c9cb 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectMove.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectMove.java
@@ -27,16 +27,22 @@ import org.distorted.library.type.Static3D;
 
 public class MatrixEffectMove extends MatrixEffect
   {
+  private static final String NAME = "MOVE";
   private static final float[] UNITIES = new float[]{0.0f, 0.0f, 0.0f};
   private static final int DIMENSION = 3;
   private static final boolean SUPPORTS_CENTER = false;
   private static final boolean SUPPORTS_REGION = false;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Moves the Object by a (possibly changing in time) vector.
+ *
+ * @param vector 3-dimensional Data which at any given time will return a Static3D
+ *               representing the current coordinates of the vector we want to move the Object with.
+ */
   public MatrixEffectMove(Data3D vector)
     {
-    super(MOVE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(MOVE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( vector instanceof Static3D)
       {
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java b/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java
index ae2f863..f445123 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectQuaternion.java
@@ -30,16 +30,22 @@ import org.distorted.library.type.Static4D;
 
 public class MatrixEffectQuaternion extends MatrixEffect
   {
+  private static final String NAME = "QUATERNION";
   private static final float[] UNITIES = new float[]{0.0f, 0.0f, 0.0f};
   private static final int DIMENSION = 4;
   private static final boolean SUPPORTS_CENTER = true;
   private static final boolean SUPPORTS_REGION = false;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Rotates the Object by quaternion.
+ *
+ * @param quaternion The quaternion describing the rotation.
+ * @param center     Coordinates of the Point we are rotating around.
+ */
   public MatrixEffectQuaternion(Data4D quaternion, Data3D center )
     {
-    super(QUATERNION,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(QUATERNION,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( quaternion instanceof Static4D)
       {
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java b/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
index cf55c18..8ccc8a0 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectRotate.java
@@ -33,16 +33,24 @@ import org.distorted.library.type.Static4D;
 
 public class MatrixEffectRotate extends MatrixEffect
   {
+  private static final String NAME = "ROTATE";
   private static final float[] UNITIES = new float[]{0.0f};
   private static final int DIMENSION = 4;
   private static final boolean SUPPORTS_CENTER = true;
   private static final boolean SUPPORTS_REGION = false;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Rotates the Object by 'angle' degrees around the center.
+ * Static axis of rotation is given by the last parameter.
+ *
+ * @param angle  Angle that we want to rotate the Object to. Unit: degrees
+ * @param axis   Axis of rotation
+ * @param center Coordinates of the Point we are rotating around.
+ */
   public MatrixEffectRotate(Data1D angle, Static3D axis, Data3D center)
     {
-    super(ROTATE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(ROTATE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( angle instanceof Static1D )
       {
@@ -66,10 +74,16 @@ public class MatrixEffectRotate extends MatrixEffect
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Rotates the Object by 'angle' degrees around the center.
+ * Here both angle and axis can dynamically change.
+ *
+ * @param angleaxis Combined 4-tuple representing the (angle,axisX,axisY,axisZ).
+ * @param center    Coordinates of the Point we are rotating around.
+ */
   public MatrixEffectRotate(Data4D angleaxis, Data3D center)
     {
-    super(ROTATE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(ROTATE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( angleaxis instanceof Static4D)
       {
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectScale.java b/src/main/java/org/distorted/library/effect/MatrixEffectScale.java
index 20e57f0..25db43c 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectScale.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectScale.java
@@ -27,16 +27,22 @@ import org.distorted.library.type.Static3D;
 
 public class MatrixEffectScale extends MatrixEffect
   {
+  private static final String NAME = "SCALE";
   private static final float[] UNITIES = new float[] {1.0f,1.0f,1.0f};
   private static final int DIMENSION = 3;
   private static final boolean SUPPORTS_CENTER = false;
   private static final boolean SUPPORTS_REGION = false;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Scales the Object by (possibly changing in time) 3D scale factors.
+ *
+ * @param scale 3-dimensional Data which at any given time returns a Static3D
+ *              representing the current x- , y- and z- scale factors.
+ */
   public MatrixEffectScale(Data3D scale)
     {
-    super(SCALE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(SCALE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( scale instanceof Static3D)
       {
@@ -49,10 +55,14 @@ public class MatrixEffectScale extends MatrixEffect
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Scales the Object by (possibly changing in time) 3D scale factors.
+ *
+ * @param scale Common x,y, and z scale factor.
+ */
   public MatrixEffectScale(float scale)
     {
-    super(SCALE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(SCALE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     mStatic0 = new Static3D(scale,scale,scale);
     }
diff --git a/src/main/java/org/distorted/library/effect/MatrixEffectShear.java b/src/main/java/org/distorted/library/effect/MatrixEffectShear.java
index cbdec55..db5e62d 100644
--- a/src/main/java/org/distorted/library/effect/MatrixEffectShear.java
+++ b/src/main/java/org/distorted/library/effect/MatrixEffectShear.java
@@ -27,16 +27,25 @@ import org.distorted.library.type.Static3D;
 
 public class MatrixEffectShear extends MatrixEffect
   {
+  private static final String NAME = "SHEAR";
   private static final float[] UNITIES = new float[] {0.0f,0.0f,0.0f};
   private static final int DIMENSION = 3;
   private static final boolean SUPPORTS_CENTER = true;
   private static final boolean SUPPORTS_REGION = false;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Shears the Object.
+ *
+ * @param shear   The 3-tuple of shear factors. The first controls level
+ *                of shearing in the X-axis, second - Y-axis and the third -
+ *                Z-axis. Each is the tangens of the shear angle, i.e 0 -
+ *                no shear, 1 - shear by 45 degrees (tan(45deg)=1) etc.
+ * @param center  Center of shearing, i.e. the point which stays unmoved.
+ */
   public MatrixEffectShear(Data3D shear, Data3D center)
     {
-    super(SHEAR,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(SHEAR,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( shear instanceof Static3D)
       {
diff --git a/src/main/java/org/distorted/library/effect/PostprocessEffect.java b/src/main/java/org/distorted/library/effect/PostprocessEffect.java
index a3c736e..133cc2d 100644
--- a/src/main/java/org/distorted/library/effect/PostprocessEffect.java
+++ b/src/main/java/org/distorted/library/effect/PostprocessEffect.java
@@ -30,9 +30,9 @@ public abstract class PostprocessEffect extends Effect
   {
   public static final int NUM_UNIFORMS = 5;
 
-  public static final int BLUR       =0;
-  public static final int GLOW       =1;
-  public static final int NUM_EFFECTS=2;
+  public static final int BLUR       = MAX_EFFECTS*POSTPROCESS    ;
+  public static final int GLOW       = MAX_EFFECTS*POSTPROCESS + 1;
+  public static final int NUM_EFFECTS= 2;
 
   static final int MAX = 5;
   private static final int MAX_UNITY_DIM = 1;
@@ -45,9 +45,9 @@ public abstract class PostprocessEffect extends Effect
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public PostprocessEffect(int name, float[] unity, int dimension, boolean center, boolean region)
+  public PostprocessEffect(int name, float[] unity, int dimension, boolean center, boolean region, final String str)
     {
-    super(POSTPROCESS,name,dimension,center,region);
+    super(POSTPROCESS,name,dimension,center,region,str);
 
     for(int i=0; i<unity.length; i++)
       {
diff --git a/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java b/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
index d4f968b..bf81f70 100644
--- a/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
+++ b/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
@@ -27,6 +27,7 @@ import org.distorted.library.type.Static1D;
 
 public class PostprocessEffectBlur extends PostprocessEffect
   {
+  private static final String NAME = "BLUR";
   private static final float[] UNITIES = new float[] {0.0f};
   private static final int DIMENSION = 1;
   private static final boolean SUPPORTS_CENTER = false;
@@ -36,7 +37,7 @@ public class PostprocessEffectBlur extends PostprocessEffect
 
   public PostprocessEffectBlur(Data1D radius)
     {
-    super(BLUR,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(BLUR,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( radius instanceof Dynamic1D)
       {
diff --git a/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java b/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
index ae0c06e..ea47b2e 100644
--- a/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
+++ b/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
@@ -30,6 +30,7 @@ import org.distorted.library.type.Static4D;
 
 public class PostprocessEffectGlow extends PostprocessEffect
   {
+  private static final String NAME = "GLOW";
   private static final float[] UNITIES = new float[] {0.0f};
   private static final int DIMENSION = 5;
   private static final boolean SUPPORTS_CENTER = false;
@@ -39,7 +40,7 @@ public class PostprocessEffectGlow extends PostprocessEffect
 
   public PostprocessEffectGlow(Data1D radius, Data4D color)
     {
-    super(GLOW,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(GLOW,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( radius instanceof Dynamic1D)
       {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffect.java b/src/main/java/org/distorted/library/effect/VertexEffect.java
index 641317c..7946a6a 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffect.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffect.java
@@ -34,13 +34,13 @@ public abstract class VertexEffect extends Effect
   {
   public static final int NUM_UNIFORMS = 12;
 
-  public static final int DISTORT    =0;
-  public static final int DEFORM     =1;
-  public static final int SINK       =2;
-  public static final int PINCH      =3;
-  public static final int SWIRL      =4;
-  public static final int WAVE       =5;
-  public static final int NUM_EFFECTS=6;
+  public static final int DISTORT    = MAX_EFFECTS*VERTEX    ;
+  public static final int DEFORM     = MAX_EFFECTS*VERTEX + 1;
+  public static final int SINK       = MAX_EFFECTS*VERTEX + 2;
+  public static final int PINCH      = MAX_EFFECTS*VERTEX + 3;
+  public static final int SWIRL      = MAX_EFFECTS*VERTEX + 4;
+  public static final int WAVE       = MAX_EFFECTS*VERTEX + 5;
+  public static final int NUM_EFFECTS= 6;
 
   static final int MAX = 5;
   private static final int MAX_UNITY_DIM = 3;
@@ -57,9 +57,9 @@ public abstract class VertexEffect extends Effect
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public VertexEffect(int name, float[] unity, int dimension, boolean center, boolean region)
+  public VertexEffect(int name, float[] unity, int dimension, boolean center, boolean region, final String str)
     {
-    super(VERTEX,name,dimension,center,region);
+    super(VERTEX,name,dimension,center,region,str);
 
     for(int i=0; i<unity.length; i++)
       {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectDeform.java b/src/main/java/org/distorted/library/effect/VertexEffectDeform.java
index 5cbaae6..d4fb791 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectDeform.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectDeform.java
@@ -30,16 +30,24 @@ import org.distorted.library.type.Static4D;
 
 public class VertexEffectDeform extends VertexEffect
   {
+  private static final String NAME = "DEFORM";
   private static final float[] UNITIES = new float[] {0.0f,0.0f,0.0f};
   private static final int DIMENSION = 3;
   private static final boolean SUPPORTS_CENTER = true;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Deform the shape of the whole Object with a (possibly changing in time) vector of force applied to
+ * a (possibly changing in time) point on the Object.
+ *
+ * @param vector Vector of force that deforms the shape of the whole Object.
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ * @param region Region that masks the Effect.
+ */
   public VertexEffectDeform(Data3D vector, Data3D center, Data4D region)
     {
-    super(DEFORM,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(DEFORM,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( vector instanceof Dynamic3D )
       {
@@ -70,10 +78,16 @@ public class VertexEffectDeform extends VertexEffect
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Deform the shape of the whole Object with a (possibly changing in time) vector of force applied to
+ * a (possibly changing in time) point on the Object.
+ *
+ * @param vector Vector of force that deforms the shape of the whole Object.
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ */
   public VertexEffectDeform(Data3D vector, Data3D center)
     {
-    super(DEFORM,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(DEFORM,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( vector instanceof Dynamic3D )
       {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectDistort.java b/src/main/java/org/distorted/library/effect/VertexEffectDistort.java
index fb1a43d..755c90f 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectDistort.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectDistort.java
@@ -30,16 +30,24 @@ import org.distorted.library.type.Static4D;
 
 public class VertexEffectDistort extends VertexEffect
   {
+  private static final String NAME = "DISORT";
   private static final float[] UNITIES = new float[] {0.0f,0.0f,0.0f};
   private static final int DIMENSION = 3;
   private static final boolean SUPPORTS_CENTER = true;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Distort a (possibly changing in time) part of the Object by a (possibly changing in time) vector of force.
+ *
+ * @param vector 3-dimensional Vector which represents the force the Center of the Effect is
+ *               currently being dragged with.
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ * @param region Region that masks the Effect.
+ */
   public VertexEffectDistort(Data3D vector, Data3D center, Data4D region)
     {
-    super(DISTORT,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(DISTORT,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( vector instanceof Dynamic3D )
       {
@@ -70,10 +78,16 @@ public class VertexEffectDistort extends VertexEffect
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Distort the whole Object by a (possibly changing in time) vector of force.
+ *
+ * @param vector 3-dimensional Vector which represents the force the Center of the Effect is
+ *               currently being dragged with.
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ */
   public VertexEffectDistort(Data3D vector, Data3D center)
     {
-    super(DISTORT,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(DISTORT,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( vector instanceof Dynamic3D )
       {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectPinch.java b/src/main/java/org/distorted/library/effect/VertexEffectPinch.java
index 4015581..6182e1a 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectPinch.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectPinch.java
@@ -33,16 +33,24 @@ import org.distorted.library.type.Static4D;
 
 public class VertexEffectPinch extends VertexEffect
   {
+  private static final String NAME = "PINCH";
   private static final float[] UNITIES = new float[] {1.0f};
   private static final int DIMENSION = 2;
   private static final boolean SUPPORTS_CENTER = true;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Pull all points around the center of the Effect towards a line passing through the center
+ * (that's if degree>=1) or push them away from the line (degree<=1)
+ *
+ * @param pinch  The current degree of the Effect + angle the line forms with X-axis
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ * @param region Region that masks the Effect.
+ */
   public VertexEffectPinch(Data2D pinch, Data3D center, Data4D region)
     {
-    super(PINCH,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(PINCH,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( pinch instanceof Dynamic2D)
       {
@@ -73,10 +81,16 @@ public class VertexEffectPinch extends VertexEffect
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Pull all points around the center of the Effect towards a line passing through the center
+ * (that's if degree>=1) or push them away from the line (degree<=1)
+ *
+ * @param pinch  The current degree of the Effect + angle the line forms with X-axis
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ */
   public VertexEffectPinch(Data2D pinch, Data3D center)
     {
-    super(PINCH,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(PINCH,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( pinch instanceof Dynamic2D)
       {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectSink.java b/src/main/java/org/distorted/library/effect/VertexEffectSink.java
index fb82ae7..f5f3b50 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectSink.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectSink.java
@@ -33,16 +33,24 @@ import org.distorted.library.type.Static4D;
 
 public class VertexEffectSink extends VertexEffect
   {
+  private static final String NAME = "SINK";
   private static final float[] UNITIES = new float[] {1.0f};
   private static final int DIMENSION = 1;
   private static final boolean SUPPORTS_CENTER = true;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Pull all points around the center of the Effect towards the center (if degree>=1) or push them
+ * away from the center (degree<=1)
+ *
+ * @param sink   The current degree of the Effect.
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ * @param region Region that masks the Effect.
+ */
   public VertexEffectSink(Data1D sink, Data3D center, Data4D region)
     {
-    super(SINK,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(SINK,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( sink instanceof Dynamic1D)
       {
@@ -73,10 +81,16 @@ public class VertexEffectSink extends VertexEffect
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Pull all points around the center of the Effect towards the center (if degree>=1) or push them
+ * away from the center (degree<=1)
+ *
+ * @param sink   The current degree of the Effect.
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ */
   public VertexEffectSink(Data1D sink, Data3D center)
     {
-    super(SINK,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(SINK,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( sink instanceof Dynamic1D)
       {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectSwirl.java b/src/main/java/org/distorted/library/effect/VertexEffectSwirl.java
index 7d8eddb..139e834 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectSwirl.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectSwirl.java
@@ -33,16 +33,23 @@ import org.distorted.library.type.Static4D;
 
 public class VertexEffectSwirl extends VertexEffect
   {
+  private static final String NAME = "SWIRL";
   private static final float[] UNITIES = new float[] {0.0f};
   private static final int DIMENSION = 1;
   private static final boolean SUPPORTS_CENTER = true;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Rotate part of the Object around the Center of the Effect by a certain angle.
+ *
+ * @param swirl  The angle of Swirl (in degrees). Positive values swirl clockwise.
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ * @param region Region that masks the Effect.
+ */
   public VertexEffectSwirl(Data1D swirl, Data3D center, Data4D region)
     {
-    super(SWIRL,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(SWIRL,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( swirl instanceof Dynamic1D)
       {
@@ -73,10 +80,15 @@ public class VertexEffectSwirl extends VertexEffect
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
+/**
+ * Rotate the whole Object around the Center of the Effect by a certain angle.
+ *
+ * @param swirl  The angle of Swirl (in degrees). Positive values swirl clockwise.
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ */
   public VertexEffectSwirl(Data1D swirl, Data3D center)
     {
-    super(SWIRL,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(SWIRL,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( swirl instanceof Dynamic1D)
       {
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectWave.java b/src/main/java/org/distorted/library/effect/VertexEffectWave.java
index 17d68c6..e9b9925 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectWave.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectWave.java
@@ -33,16 +33,43 @@ import org.distorted.library.type.Static5D;
 
 public class VertexEffectWave extends VertexEffect
   {
+  private static final String NAME = "WAVE";
   private static final float[] UNITIES = new float[] {0.0f};
   private static final int DIMENSION = 5;
   private static final boolean SUPPORTS_CENTER = true;
   private static final boolean SUPPORTS_REGION = true;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public VertexEffectWave(Data5D wave, Data3D center, Data4D region)
+/**
+ * Directional, sinusoidal wave effect.
+ *
+ * @param wave   A 5-dimensional data structure describing the wave: first member is the amplitude,
+ *               second is the wave length, third is the phase (i.e. when phase = PI/2, the sine
+ *               wave at the center does not start from sin(0), but from sin(PI/2) ) and the next two
+ *               describe the 'direction' of the wave.
+ *               <p>
+ *               Wave direction is defined to be a 3D vector of length 1. To define such vectors, we
+ *               need 2 floats: thus the third member is the angle Alpha (in degrees) which the vector
+ *               forms with the XY-plane, and the fourth is the angle Beta (again in degrees) which
+ *               the projection of the vector to the XY-plane forms with the Y-axis (counterclockwise).
+ *               <p>
+ *               <p>
+ *               Example1: if Alpha = 90, Beta = 90, (then V=(0,0,1) ) and the wave acts 'vertically'
+ *               in the X-direction, i.e. cross-sections of the resulting surface with the XZ-plane
+ *               will be sine shapes.
+ *               <p>
+ *               Example2: if Alpha = 90, Beta = 0, the again V=(0,0,1) and the wave is 'vertical',
+ *               but this time it waves in the Y-direction, i.e. cross sections of the surface and the
+ *               YZ-plane with be sine shapes.
+ *               <p>
+ *               Example3: if Alpha = 0 and Beta = 45, then V=(sqrt(2)/2, -sqrt(2)/2, 0) and the wave
+ *               is entirely 'horizontal' and moves point (x,y,0) in direction V by whatever is the
+ *               value if sin at this point.
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ */
+  public VertexEffectWave(Data5D wave, Data3D center)
     {
-    super(WAVE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(WAVE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( wave instanceof Dynamic5D)
       {
@@ -57,26 +84,25 @@ public class VertexEffectWave extends VertexEffect
       {
       mStaticCenter = (Static3D)center;
       }
-    else if( center instanceof Dynamic3D)
+    else if( center instanceof Dynamic3D )
       {
       mDynamicCenter = (Dynamic3D)center;
       }
 
-    if( region instanceof Static4D)
-      {
-      mStaticRegion = (Static4D)region;
-      }
-    else if( region instanceof Dynamic4D)
-      {
-      mDynamicRegion = (Dynamic4D)region;
-      }
+    mStaticRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public VertexEffectWave(Data5D wave, Data3D center)
+/**
+ * Directional, sinusoidal wave effect.
+ *
+ * @param wave   see {@link VertexEffectWave(Data5D,Data3D)}
+ * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
+ * @param region Region that masks the Effect.
+ */
+  public VertexEffectWave(Data5D wave, Data3D center, Data4D region)
     {
-    super(WAVE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION);
+    super(WAVE,UNITIES,DIMENSION,SUPPORTS_CENTER,SUPPORTS_REGION,NAME);
 
     if( wave instanceof Dynamic5D)
       {
@@ -91,12 +117,19 @@ public class VertexEffectWave extends VertexEffect
       {
       mStaticCenter = (Static3D)center;
       }
-    else if( center instanceof Dynamic3D )
+    else if( center instanceof Dynamic3D)
       {
       mDynamicCenter = (Dynamic3D)center;
       }
 
-    mStaticRegion = new Static4D(0,0,Float.MAX_VALUE, Float.MAX_VALUE);
+    if( region instanceof Static4D)
+      {
+      mStaticRegion = (Static4D)region;
+      }
+    else if( region instanceof Dynamic4D)
+      {
+      mDynamicRegion = (Dynamic4D)region;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/main/DistortedEffects.java b/src/main/java/org/distorted/library/main/DistortedEffects.java
index e3901c7..11b968f 100644
--- a/src/main/java/org/distorted/library/main/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/main/DistortedEffects.java
@@ -31,17 +31,12 @@ import org.distorted.library.program.FragmentUniformsException;
 import org.distorted.library.program.LinkingException;
 import org.distorted.library.program.VertexCompilationException;
 import org.distorted.library.program.VertexUniformsException;
-import org.distorted.library.type.Data1D;
-import org.distorted.library.type.Data2D;
-import org.distorted.library.type.Data3D;
-import org.distorted.library.type.Data4D;
-import org.distorted.library.type.Data5D;
-import org.distorted.library.type.Static3D;
 
 import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.FloatBuffer;
+import java.util.ArrayList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
@@ -55,17 +50,7 @@ public class DistortedEffects
   /// MAIN PROGRAM ///
   private static DistortedProgram mMainProgram;
   private static int mMainTextureH;
-  private static boolean[] mEffectEnabled = new boolean[EffectNames.size()];
-
-  static
-    {
-    int len = EffectNames.size();
-
-    for(int i=0; i<len; i++)
-      {
-      mEffectEnabled[i] = false;
-      }
-    }
+  private static ArrayList<Effect> mEnabledEffects = new ArrayList<>();
 
   /// BLIT PROGRAM ///
   private static DistortedProgram mBlitProgram;
@@ -112,28 +97,25 @@ public class DistortedEffects
     String mainVertHeader= Distorted.GLSL_VERSION;
     String mainFragHeader= Distorted.GLSL_VERSION;
 
-    EffectNames name;
-    EffectTypes type;
     boolean foundF = false;
     boolean foundV = false;
+    int type, effects = mEnabledEffects.size();
+    Effect effect;
 
-    for(int i=0; i<mEffectEnabled.length; i++)
+    for(int i=0; i<effects; i++)
       {
-      if( mEffectEnabled[i] )
+      effect = mEnabledEffects.remove(0);
+      type   = effect.getType();
+
+      if( type == Effect.VERTEX )
+        {
+        mainVertHeader += ("#define "+effect.getString()+" "+effect.getName()+"\n");
+        foundV = true;
+        }
+      else if( type == Effect.FRAGMENT )
         {
-        name = EffectNames.getName(i);
-        type = EffectNames.getType(i);
-
-        if( type == EffectTypes.VERTEX )
-          {
-          mainVertHeader += ("#define "+name.name()+" "+name.ordinal()+"\n");
-          foundV = true;
-          }
-        else if( type == EffectTypes.FRAGMENT )
-          {
-          mainFragHeader += ("#define "+name.name()+" "+name.ordinal()+"\n");
-          foundF = true;
-          }
+        mainFragHeader += ("#define "+effect.getString()+" "+effect.getName()+"\n");
+        foundF = true;
         }
       }
 
@@ -357,13 +339,6 @@ public class DistortedEffects
   static void onDestroy()
     {
     mNextID = 0;
-
-    int len = EffectNames.size();
-
-    for(int i=0; i<len; i++)
-      {
-      mEffectEnabled[i] = false;
-      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -458,17 +433,18 @@ public class DistortedEffects
 /**
  * Aborts all Effects of a given type, for example all MATRIX Effects.
  * 
- * @param type one of the constants defined in {@link EffectTypes}
+ * @param type one of the constants defined in {@link Effect}
  * @return Number of effects aborted.
  */
-  public int abortEffects(EffectTypes type)
+  public int abortByType(int type)
     {
     switch(type)
       {
-      case MATRIX     : return mM.abortAll(true);
-      case VERTEX     : return mV.abortAll(true);
-      case FRAGMENT   : return mF.abortAll(true);
-      default         : return 0;
+      case Effect.MATRIX     : return mM.abortAll(true);
+      case Effect.VERTEX     : return mV.abortAll(true);
+      case Effect.FRAGMENT   : return mF.abortAll(true);
+  //  case Effect.POSTPROCESS: return mP.abortAll(true);
+      default                : return 0;
       }
     }
     
@@ -476,56 +452,43 @@ public class DistortedEffects
 /**
  * Aborts a single Effect.
  * 
- * @param id ID of the Effect we want to abort.
+ * @param effect the Effect we want to abort.
  * @return number of Effects aborted. Always either 0 or 1.
  */
-  public int abortEffect(long id)
+  public int abortEffect(Effect effect)
     {
-    int type = (int)(id&Effect.MASK);
-
-    if( type==Effect.MATRIX   ) return mM.removeByID(id>>Effect.LENGTH);
-    if( type==Effect.VERTEX   ) return mV.removeByID(id>>Effect.LENGTH);
-    if( type==Effect.FRAGMENT ) return mF.removeByID(id>>Effect.LENGTH);
-
-    return 0;
+    switch(effect.getType())
+      {
+      case Effect.MATRIX     : return mM.removeEffect(effect);
+      case Effect.VERTEX     : return mV.removeEffect(effect);
+      case Effect.FRAGMENT   : return mF.removeEffect(effect);
+  //  case Effect.POSTPROCESS: return mP.removeEffect(effect);
+      default                : return 0;
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * Abort all Effects of a given name, for example all rotations.
  * 
- * @param name one of the constants defined in {@link EffectNames}
+ * @param name one of the constants defined in
+ *             {@link org.distorted.library.effect.MatrixEffect},
+ *             {@link org.distorted.library.effect.VertexEffect},
+ *             {@link org.distorted.library.effect.FragmentEffect} or
+ *             {@link org.distorted.library.effect.PostprocessEffect}
  * @return number of Effects aborted.
  */
-  public int abortEffects(EffectNames name)
+  public int abortByName(int name)
     {
-    switch(name.getType())
+    switch(Effect.getType(name))
       {
-      case MATRIX     : return mM.removeByType(name);
-      case VERTEX     : return mV.removeByType(name);
-      case FRAGMENT   : return mF.removeByType(name);
-      default         : return 0;
+      case Effect.MATRIX     : return mM.removeByName(name);
+      case Effect.VERTEX     : return mV.removeByName(name);
+      case Effect.FRAGMENT   : return mF.removeByName(name);
+  //  case Effect.POSTPROCESS: return mP.removeByName(name);
+      default                : return 0;
       }
     }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Print some info about a given Effect to Android's standard out. Used for debugging only.
- * 
- * @param id Effect ID we want to print info about
- * @return <code>true</code> if a single Effect of type effectType has been found.
- */
-  @SuppressWarnings("unused")
-  public boolean printEffect(long id)
-    {
-    int type = (int)(id&EffectTypes.MASK);
-
-    if( type==EffectTypes.MATRIX.type  )  return mM.printByID(id>>EffectTypes.LENGTH);
-    if( type==EffectTypes.VERTEX.type  )  return mV.printByID(id>>EffectTypes.LENGTH);
-    if( type==EffectTypes.FRAGMENT.type)  return mF.printByID(id>>EffectTypes.LENGTH);
-
-    return false;
-    }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
@@ -535,11 +498,15 @@ public class DistortedEffects
  * This needs to be called BEFORE shaders get compiled, i.e. before the call to Distorted.onCreate().
  * The point: by enabling only the effects we need, we can optimize the shaders.
  *
- * @param name Name of the Effect to enable.
+ * @param name one of the constants defined in
+ *             {@link org.distorted.library.effect.MatrixEffect},
+ *             {@link org.distorted.library.effect.VertexEffect},
+ *             {@link org.distorted.library.effect.FragmentEffect} or
+ *             {@link org.distorted.library.effect.PostprocessEffect}
  */
-  public static void enableEffect(EffectNames name)
+  public static void enableEffect(int name)
     {
-    mEffectEnabled[name.ordinal()] = true;
+    mEffectEnabled[name] = true;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -551,7 +518,7 @@ public class DistortedEffects
   @SuppressWarnings("unused")
   public static int getMaxMatrix()
     {
-    return EffectQueue.getMax(EffectTypes.MATRIX.ordinal());
+    return EffectQueue.getMax(Effect.MATRIX);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -563,7 +530,7 @@ public class DistortedEffects
   @SuppressWarnings("unused")
   public static int getMaxVertex()
     {
-    return EffectQueue.getMax(EffectTypes.VERTEX.ordinal());
+    return EffectQueue.getMax(Effect.VERTEX);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -575,7 +542,7 @@ public class DistortedEffects
   @SuppressWarnings("unused")
   public static int getMaxFragment()
     {
-    return EffectQueue.getMax(EffectTypes.FRAGMENT.ordinal());
+    return EffectQueue.getMax(Effect.FRAGMENT);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -597,7 +564,7 @@ public class DistortedEffects
   @SuppressWarnings("unused")
   public static boolean setMaxMatrix(int max)
     {
-    return EffectQueue.setMax(EffectTypes.MATRIX.ordinal(),max);
+    return EffectQueue.setMax(Effect.MATRIX,max);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -619,7 +586,7 @@ public class DistortedEffects
   @SuppressWarnings("unused")
   public static boolean setMaxVertex(int max)
     {
-    return EffectQueue.setMax(EffectTypes.VERTEX.ordinal(),max);
+    return EffectQueue.setMax(Effect.VERTEX,max);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -641,448 +608,23 @@ public class DistortedEffects
   @SuppressWarnings("unused")
   public static boolean setMaxFragment(int max)
     {
-    return EffectQueue.setMax(EffectTypes.FRAGMENT.ordinal(),max);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////   
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Individual effect functions.
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Matrix-based effects
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Moves the Object by a (possibly changing in time) vector.
- * 
- * @param vector 3-dimensional Data which at any given time will return a Static3D
- *               representing the current coordinates of the vector we want to move the Object with.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long move(Data3D vector)
-    {   
-    return mM.add(EffectNames.MOVE,vector);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Scales the Object by (possibly changing in time) 3D scale factors.
- * 
- * @param scale 3-dimensional Data which at any given time returns a Static3D
- *              representing the current x- , y- and z- scale factors.
- * @return      ID of the effect added, or -1 if we failed to add one.
- */
-  public long scale(Data3D scale)
-    {   
-    return mM.add(EffectNames.SCALE,scale);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Scales the Object by one uniform, constant factor in all 3 dimensions. Convenience function.
- *
- * @param scale The factor to scale all 3 dimensions with.
- * @return      ID of the effect added, or -1 if we failed to add one.
- */
-  public long scale(float scale)
-    {
-    return mM.add(EffectNames.SCALE, new Static3D(scale,scale,scale));
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Rotates the Object by 'angle' degrees around the center.
- * Static axis of rotation is given by the last parameter.
- *
- * @param angle  Angle that we want to rotate the Object to. Unit: degrees
- * @param axis   Axis of rotation
- * @param center Coordinates of the Point we are rotating around.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long rotate(Data1D angle, Static3D axis, Data3D center )
-    {   
-    return mM.add(EffectNames.ROTATE, angle, axis, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Rotates the Object by 'angle' degrees around the center.
- * Here both angle and axis can dynamically change.
- *
- * @param angleaxis Combined 4-tuple representing the (angle,axisX,axisY,axisZ).
- * @param center    Coordinates of the Point we are rotating around.
- * @return          ID of the effect added, or -1 if we failed to add one.
- */
-  public long rotate(Data4D angleaxis, Data3D center)
-    {
-    return mM.add(EffectNames.ROTATE, angleaxis, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Rotates the Object by quaternion.
- *
- * @param quaternion The quaternion describing the rotation.
- * @param center     Coordinates of the Point we are rotating around.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long quaternion(Data4D quaternion, Data3D center )
-    {
-    return mM.add(EffectNames.QUATERNION,quaternion,center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Shears the Object.
- *
- * @param shear   The 3-tuple of shear factors. The first controls level
- *                of shearing in the X-axis, second - Y-axis and the third -
- *                Z-axis. Each is the tangens of the shear angle, i.e 0 -
- *                no shear, 1 - shear by 45 degrees (tan(45deg)=1) etc.
- * @param center  Center of shearing, i.e. the point which stays unmoved.
- * @return        ID of the effect added, or -1 if we failed to add one.
- */
-  public long shear(Data3D shear, Data3D center)
-    {
-    return mM.add(EffectNames.SHEAR, shear, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Fragment-based effects  
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change all three of its RGB components.
- *        
- * @param blend  1-dimensional Data that returns the level of blend a given pixel will be
- *               mixed with the next parameter 'color': pixel = (1-level)*pixel + level*color.
- *               Valid range: <0,1>
- * @param color  Color to mix. (1,0,0) is RED.
- * @param region Region this Effect is limited to.
- * @param smooth If true, the level of 'blend' will smoothly fade out towards the edges of the region.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long chroma(Data1D blend, Data3D color, Data4D region, boolean smooth)
-    {
-    return mF.add( smooth? EffectNames.SMOOTH_CHROMA:EffectNames.CHROMA, blend, color, region);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes the whole Object smoothly change all three of its RGB components.
- *
- * @param blend  1-dimensional Data that returns the level of blend a given pixel will be
- *               mixed with the next parameter 'color': pixel = (1-level)*pixel + level*color.
- *               Valid range: <0,1>
- * @param color  Color to mix. (1,0,0) is RED.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long chroma(Data1D blend, Data3D color)
-    {
-    return mF.add(EffectNames.CHROMA, blend, color);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its transparency level.
- *        
- * @param alpha  1-dimensional Data that returns the level of transparency we want to have at any given
- *               moment: pixel.a *= alpha.
- *               Valid range: <0,1>
- * @param region Region this Effect is limited to. 
- * @param smooth If true, the level of 'alpha' will smoothly fade out towards the edges of the region.
- * @return       ID of the effect added, or -1 if we failed to add one. 
- */
-  public long alpha(Data1D alpha, Data4D region, boolean smooth)
-    {
-    return mF.add( smooth? EffectNames.SMOOTH_ALPHA:EffectNames.ALPHA, alpha, region);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes the whole Object smoothly change its transparency level.
- *
- * @param alpha  1-dimensional Data that returns the level of transparency we want to have at any
- *               given moment: pixel.a *= alpha.
- *               Valid range: <0,1>
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long alpha(Data1D alpha)
-    {
-    return mF.add(EffectNames.ALPHA, alpha);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its brightness level.
- *        
- * @param brightness 1-dimensional Data that returns the level of brightness we want to have
- *                   at any given moment. Valid range: <0,infinity)
- * @param region     Region this Effect is limited to.
- * @param smooth     If true, the level of 'brightness' will smoothly fade out towards the edges of the region.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long brightness(Data1D brightness, Data4D region, boolean smooth)
-    {
-    return mF.add( smooth ? EffectNames.SMOOTH_BRIGHTNESS: EffectNames.BRIGHTNESS, brightness, region);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes the whole Object smoothly change its brightness level.
- *
- * @param brightness 1-dimensional Data that returns the level of brightness we want to have
- *                   at any given moment. Valid range: <0,infinity)
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long brightness(Data1D brightness)
-    {
-    return mF.add(EffectNames.BRIGHTNESS, brightness);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its contrast level.
- *        
- * @param contrast 1-dimensional Data that returns the level of contrast we want to have
- *                 at any given moment. Valid range: <0,infinity)
- * @param region   Region this Effect is limited to.
- * @param smooth   If true, the level of 'contrast' will smoothly fade out towards the edges of the region.
- * @return         ID of the effect added, or -1 if we failed to add one.
- */
-  public long contrast(Data1D contrast, Data4D region, boolean smooth)
-    {
-    return mF.add( smooth ? EffectNames.SMOOTH_CONTRAST:EffectNames.CONTRAST, contrast, region);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes the whole Object smoothly change its contrast level.
- *
- * @param contrast 1-dimensional Data that returns the level of contrast we want to have
- *                 at any given moment. Valid range: <0,infinity)
- * @return         ID of the effect added, or -1 if we failed to add one.
- */
-  public long contrast(Data1D contrast)
-    {
-    return mF.add(EffectNames.CONTRAST, contrast);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes a certain sub-region of the Object smoothly change its saturation level.
- *        
- * @param saturation 1-dimensional Data that returns the level of saturation we want to have
- *                   at any given moment. Valid range: <0,infinity)
- * @param region     Region this Effect is limited to.
- * @param smooth     If true, the level of 'saturation' will smoothly fade out towards the edges of the region.
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long saturation(Data1D saturation, Data4D region, boolean smooth)
-    {
-    return mF.add( smooth ? EffectNames.SMOOTH_SATURATION:EffectNames.SATURATION, saturation, region);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Makes the whole Object smoothly change its saturation level.
- *
- * @param saturation 1-dimensional Data that returns the level of saturation we want to have
- *                   at any given moment. Valid range: <0,infinity)
- * @return           ID of the effect added, or -1 if we failed to add one.
- */
-  public long saturation(Data1D saturation)
-    {
-    return mF.add(EffectNames.SATURATION, saturation);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Vertex-based effects  
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Distort a (possibly changing in time) part of the Object by a (possibly changing in time) vector of force.
- *
- * @param vector 3-dimensional Vector which represents the force the Center of the Effect is
- *               currently being dragged with.
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @param region Region that masks the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long distort(Data3D vector, Data3D center, Data4D region)
-    {  
-    return mV.add(EffectNames.DISTORT, vector, center, region);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Distort the whole Object by a (possibly changing in time) vector of force.
- *
- * @param vector 3-dimensional Vector which represents the force the Center of the Effect is
- *               currently being dragged with.
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long distort(Data3D vector, Data3D center)
-    {
-    return mV.add(EffectNames.DISTORT, vector, center, null);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Deform the shape of the whole Object with a (possibly changing in time) vector of force applied to
- * a (possibly changing in time) point on the Object.
- *
- * @param vector Vector of force that deforms the shape of the whole Object.
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @param region Region that masks the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long deform(Data3D vector, Data3D center, Data4D region)
-    {
-    return mV.add(EffectNames.DEFORM, vector, center, region);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Deform the shape of the whole Object with a (possibly changing in time) vector of force applied to
- * a (possibly changing in time) point on the Object.
- *     
- * @param vector Vector of force that deforms the shape of the whole Object.
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long deform(Data3D vector, Data3D center)
-    {  
-    return mV.add(EffectNames.DEFORM, vector, center, null);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Pull all points around the center of the Effect towards the center (if degree>=1) or push them
- * away from the center (degree<=1)
- *
- * @param sink   The current degree of the Effect.
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @param region Region that masks the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long sink(Data1D sink, Data3D center, Data4D region)
-    {
-    return mV.add(EffectNames.SINK, sink, center, region);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Pull all points around the center of the Effect towards the center (if degree>=1) or push them
- * away from the center (degree<=1)
- *
- * @param sink   The current degree of the Effect.
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long sink(Data1D sink, Data3D center)
-    {
-    return mV.add(EffectNames.SINK, sink, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Pull all points around the center of the Effect towards a line passing through the center
- * (that's if degree>=1) or push them away from the line (degree<=1)
- *
- * @param pinch  The current degree of the Effect + angle the line forms with X-axis
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @param region Region that masks the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long pinch(Data2D pinch, Data3D center, Data4D region)
-    {
-    return mV.add(EffectNames.PINCH, pinch, center, region);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Pull all points around the center of the Effect towards a line passing through the center
- * (that's if degree>=1) or push them away from the line (degree<=1)
- *
- * @param pinch  The current degree of the Effect + angle the line forms with X-axis
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long pinch(Data2D pinch, Data3D center)
-    {
-    return mV.add(EffectNames.PINCH, pinch, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////  
-/**
- * Rotate part of the Object around the Center of the Effect by a certain angle.
- *
- * @param swirl  The angle of Swirl (in degrees). Positive values swirl clockwise.
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @param region Region that masks the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long swirl(Data1D swirl, Data3D center, Data4D region)
-    {    
-    return mV.add(EffectNames.SWIRL, swirl, center, region);
+    return EffectQueue.setMax(Effect.FRAGMENT,max);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Rotate the whole Object around the Center of the Effect by a certain angle.
+ * Add a new Effect to our queue.
  *
- * @param swirl  The angle of Swirl (in degrees). Positive values swirl clockwise.
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
+ * @param effect The Effect to add.
  */
-  public long swirl(Data1D swirl, Data3D center)
+  public void apply(Effect effect)
     {
-    return mV.add(EffectNames.SWIRL, swirl, center);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Directional, sinusoidal wave effect.
- *
- * @param wave   A 5-dimensional data structure describing the wave: first member is the amplitude,
- *               second is the wave length, third is the phase (i.e. when phase = PI/2, the sine
- *               wave at the center does not start from sin(0), but from sin(PI/2) ) and the next two
- *               describe the 'direction' of the wave.
- *               <p>
- *               Wave direction is defined to be a 3D vector of length 1. To define such vectors, we
- *               need 2 floats: thus the third member is the angle Alpha (in degrees) which the vector
- *               forms with the XY-plane, and the fourth is the angle Beta (again in degrees) which
- *               the projection of the vector to the XY-plane forms with the Y-axis (counterclockwise).
- *               <p>
- *               <p>
- *               Example1: if Alpha = 90, Beta = 90, (then V=(0,0,1) ) and the wave acts 'vertically'
- *               in the X-direction, i.e. cross-sections of the resulting surface with the XZ-plane
- *               will be sine shapes.
- *               <p>
- *               Example2: if Alpha = 90, Beta = 0, the again V=(0,0,1) and the wave is 'vertical',
- *               but this time it waves in the Y-direction, i.e. cross sections of the surface and the
- *               YZ-plane with be sine shapes.
- *               <p>
- *               Example3: if Alpha = 0 and Beta = 45, then V=(sqrt(2)/2, -sqrt(2)/2, 0) and the wave
- *               is entirely 'horizontal' and moves point (x,y,0) in direction V by whatever is the
- *               value if sin at this point.
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long wave(Data5D wave, Data3D center)
-    {
-    return mV.add(EffectNames.WAVE, wave, center, null);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Directional, sinusoidal wave effect.
- *
- * @param wave   see {@link DistortedEffects#wave(Data5D,Data3D)}
- * @param center 3-dimensional Data that, at any given time, returns the Center of the Effect.
- * @param region Region that masks the Effect.
- * @return       ID of the effect added, or -1 if we failed to add one.
- */
-  public long wave(Data5D wave, Data3D center, Data4D region)
-    {
-    return mV.add(EffectNames.WAVE, wave, center, region);
+    switch(effect.getType())
+      {
+      case Effect.VERTEX      : mV.add(effect); break;
+      case Effect.FRAGMENT    : mF.add(effect); break;
+      case Effect.MATRIX      : mM.add(effect); break;
+   // case Effect.POSTPROCESS : mP.add(effect); break;
+      }
     }
   }
diff --git a/src/main/java/org/distorted/library/main/EffectQueue.java b/src/main/java/org/distorted/library/main/EffectQueue.java
index 9faf9ff..dfc576b 100644
--- a/src/main/java/org/distorted/library/main/EffectQueue.java
+++ b/src/main/java/org/distorted/library/main/EffectQueue.java
@@ -138,7 +138,26 @@ abstract class EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  synchronized int removeByType(Effect effect)
+  synchronized int removeByName(int name)
+    {
+    int ret = 0;
+
+    for(int i=0; i<mNumEffects; i++)
+      {
+      if( mEffects[i].getName() == name )
+        {
+        remove(i);
+        i--;
+        ret++;
+        }
+      }
+
+    return ret;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  synchronized int removeEffect(Effect effect)
     {
     int ret = 0;
 
