commit 77fcb24dc8e29890570da00f1204412ae459df17
Author: Leszek Koltunski <leszek@distorted.org>
Date:   Thu Aug 11 23:41:29 2016 +0100

    Fix for Bug #17: Regions of Fragment Effects migrate.
    
    Fix is: don't send vertex position and the Fragment Effect region to the fragment shader already multiplied by the ModelView matrix (that introduces the imprecise interpolation because of the projection effect) but simply send both of them in local coords.

diff --git a/src/main/java/org/distorted/library/DistortedObject.java b/src/main/java/org/distorted/library/DistortedObject.java
index c5cb30a..e111e20 100644
--- a/src/main/java/org/distorted/library/DistortedObject.java
+++ b/src/main/java/org/distorted/library/DistortedObject.java
@@ -168,7 +168,6 @@ public abstract class DistortedObject
     mV.send();
         
     mF.compute(currTime);
-    mF.postprocess(mViewMatrix);
     mF.send();
        
     mGrid.draw();
diff --git a/src/main/java/org/distorted/library/EffectQueueFragment.java b/src/main/java/org/distorted/library/EffectQueueFragment.java
index 70d613f..85e90dd 100644
--- a/src/main/java/org/distorted/library/EffectQueueFragment.java
+++ b/src/main/java/org/distorted/library/EffectQueueFragment.java
@@ -38,7 +38,6 @@ class EffectQueueFragment extends EffectQueue
   {
   private static final int NUM_UNIFORMS = 8;
   private static final int INDEX = EffectTypes.FRAGMENT.ordinal();
-  private float[] mBuf;
   private static int mNumEffectsH;
   private static int mTypeH;
   private static int mUniformsH;
@@ -48,11 +47,6 @@ class EffectQueueFragment extends EffectQueue
   public EffectQueueFragment(DistortedObject obj)
     { 
     super(obj,NUM_UNIFORMS,INDEX);
-   
-    if( mMax[INDEX]>0 )
-      {
-      mBuf= new float[4*mMax[INDEX]];
-      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -93,7 +87,13 @@ class EffectQueueFragment extends EffectQueue
         else mInter[0][i] = null;
         }
 
-      if( mInter[1][i]!=null ) mInter[1][i].interpolateMain(     mBuf,            4*i  , mCurrentDuration[i]);
+      if( mInter[1][i]!=null )
+        {
+        mInter[1][i].interpolateMain( mUniforms, NUM_UNIFORMS*i+4, mCurrentDuration[i]);
+
+        mUniforms[NUM_UNIFORMS*i+4] = mUniforms[NUM_UNIFORMS*i+4]-mObjHalfX;
+        mUniforms[NUM_UNIFORMS*i+5] =-mUniforms[NUM_UNIFORMS*i+5]+mObjHalfY;
+        }
 
       if( mInter[2][i]!=null ) mInter[2][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+1, mCurrentDuration[i]);
 
@@ -107,15 +107,18 @@ class EffectQueueFragment extends EffectQueue
 
   protected void moveEffect(int index)
     {
-    mBuf[4*index  ] = mBuf[4*index+4];
-    mBuf[4*index+1] = mBuf[4*index+5];
-    mBuf[4*index+2] = mBuf[4*index+6];
-    mBuf[4*index+3] = mBuf[4*index+7];
-              
     mUniforms[NUM_UNIFORMS*index  ] = mUniforms[NUM_UNIFORMS*(index+1)  ];
     mUniforms[NUM_UNIFORMS*index+1] = mUniforms[NUM_UNIFORMS*(index+1)+1];
-    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];  
-    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];  
+    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];
+    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];
+
+    if( mInter[1][index]==null )
+      {
+      mUniforms[NUM_UNIFORMS*index+4] = mUniforms[NUM_UNIFORMS*(index+1)+4];
+      mUniforms[NUM_UNIFORMS*index+5] = mUniforms[NUM_UNIFORMS*(index+1)+5];
+      mUniforms[NUM_UNIFORMS*index+6] = mUniforms[NUM_UNIFORMS*(index+1)+6];
+      mUniforms[NUM_UNIFORMS*index+7] = mUniforms[NUM_UNIFORMS*(index+1)+7];
+      }
     }
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -126,7 +129,7 @@ class EffectQueueFragment extends EffectQueue
       
     if( mNumEffects>0 )
       {     
-      GLES20.glUniform1iv( mTypeH    ,  mNumEffects, mName,0);
+      GLES20.glUniform1iv( mTypeH    ,  mNumEffects, mName    ,0);
       GLES20.glUniform4fv( mUniformsH,2*mNumEffects, mUniforms,0);
       }  
     }
@@ -137,32 +140,7 @@ class EffectQueueFragment extends EffectQueue
     {
     GLES20.glUniform1i( mNumEffectsH, 0);
     }
-    
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Do various post-processing on already computed effects.
-// 1) move all Points and scale all Region radii by a ModelView matrix
 
-  void postprocess(float[] MVmatrix)
-    {
-    if( mNumEffects>0 )
-      {
-      float tx,ty;   
-      float w = (float)Math.sqrt(MVmatrix[0]*MVmatrix[0] + MVmatrix[4]*MVmatrix[4]);  // The scale factors are the lengths of the first 3 vectors of the upper-left 3x3 submatrix; here
-      float h = (float)Math.sqrt(MVmatrix[1]*MVmatrix[1] + MVmatrix[5]*MVmatrix[5]);  // m[2]=m[6]=m[8]=m[9]=0 so it is really only the upper-left 2x2 matrix.
-   
-      for(int i=0; i<mNumEffects; i++)
-        {   
-        tx = mBuf[4*i  ]-mObjHalfX; // we have to invert y and move everything by (half of bmp width, half of bmp height)
-        ty =-mBuf[4*i+1]+mObjHalfY; //
-
-        mUniforms[NUM_UNIFORMS*i+4] = MVmatrix[0]*tx + MVmatrix[4]*ty + MVmatrix[12]; // multiply the ModelView matrix times the (x,y,0,1) point, i.e. the (x,y) point on the surface of the bitmap.
-        mUniforms[NUM_UNIFORMS*i+5] = MVmatrix[1]*tx + MVmatrix[5]*ty + MVmatrix[13]; //
-        mUniforms[NUM_UNIFORMS*i+6] = w*mBuf[4*i+2];                                  // in fragment shader rx and ry radii are the last two values of the second vec4
-        mUniforms[NUM_UNIFORMS*i+7] = h*mBuf[4*i+3];                                  //
-        }
-      }
-    }
-  
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // alpha, brightness, contrast, saturation
 
@@ -182,8 +160,8 @@ class EffectQueueFragment extends EffectQueue
       else return -1;
 
       mInter[1][mNumEffects] = null;
-      mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
-      mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
+      mUniforms[NUM_UNIFORMS*mNumEffects+6] = 1000*mObjHalfX;
+      mUniforms[NUM_UNIFORMS*mNumEffects+7] = 1000*mObjHalfY;
 
       mInter[2][mNumEffects] = null;
 
@@ -216,10 +194,10 @@ class EffectQueueFragment extends EffectQueue
       else if( region instanceof Static4D )
         {
         mInter[1][mNumEffects]  = null;
-        mBuf[4*mNumEffects  ] = ((Static4D)region).getX();
-        mBuf[4*mNumEffects+1] = ((Static4D)region).getY();
-        mBuf[4*mNumEffects+2] = ((Static4D)region).getZ();
-        mBuf[4*mNumEffects+3] = ((Static4D)region).getW();
+        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static4D)region).getX()-mObjHalfX;
+        mUniforms[NUM_UNIFORMS*mNumEffects+5] =-((Static4D)region).getY()+mObjHalfY;
+        mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static4D)region).getZ();
+        mUniforms[NUM_UNIFORMS*mNumEffects+7] = ((Static4D)region).getW();
         }
       else return -1;
 
@@ -267,10 +245,10 @@ class EffectQueueFragment extends EffectQueue
       else if( region instanceof Static4D )
         {
         mInter[1][mNumEffects]  = null;
-        mBuf[4*mNumEffects  ] = ((Static4D)region).getX();
-        mBuf[4*mNumEffects+1] = ((Static4D)region).getY();
-        mBuf[4*mNumEffects+2] = ((Static4D)region).getZ();
-        mBuf[4*mNumEffects+3] = ((Static4D)region).getW();
+        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static4D)region).getX()-mObjHalfX;
+        mUniforms[NUM_UNIFORMS*mNumEffects+5] =-((Static4D)region).getY()+mObjHalfY;
+        mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static4D)region).getZ();
+        mUniforms[NUM_UNIFORMS*mNumEffects+7] = ((Static4D)region).getW();
         }
       else return -1;
 
@@ -311,9 +289,9 @@ class EffectQueueFragment extends EffectQueue
         }
       else return -1;
 
-      mInter[1][mNumEffects]  = null;          //
-      mBuf[4*mNumEffects+2] = 1000*mObjHalfX;  // i.e. null region
-      mBuf[4*mNumEffects+3] = 1000*mObjHalfY;  //
+      mInter[1][mNumEffects]  = null;
+      mUniforms[NUM_UNIFORMS*mNumEffects+6] = 1000*mObjHalfX;
+      mUniforms[NUM_UNIFORMS*mNumEffects+7] = 1000*mObjHalfY;
 
       return addBase(eln);
       }
diff --git a/src/main/res/raw/main_vertex_shader.glsl b/src/main/res/raw/main_vertex_shader.glsl
index 334dd93..1b2e16a 100644
--- a/src/main/res/raw/main_vertex_shader.glsl
+++ b/src/main/res/raw/main_vertex_shader.glsl
@@ -356,7 +356,7 @@ void main()
   restrict(v.z);  
 #endif
    
-  v_Position      = vec3(u_MVMatrix*v);           
+  v_Position      = v.xyz;
   v_TexCoordinate = a_TexCoordinate;
   v_Normal        = normalize(vec3(u_MVMatrix*n));
   gl_Position     = u_MVPMatrix*v;      
