commit 16b22aabfc97f522e59f5e3daf37b86835f85856
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Mar 20 12:40:51 2019 +0000

    Fix several more apps for the 'center-of-matrix-effects-in-screen-center' change.

diff --git a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java
index 64bd8d0..7752a98 100644
--- a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java
+++ b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java
@@ -27,7 +27,6 @@ import org.distorted.examples.R;
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.FragmentEffectChroma;
 import org.distorted.library.effect.FragmentEffectContrast;
-import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.effect.VertexEffectDistort;
 import org.distorted.library.effect.VertexEffectPinch;
@@ -56,20 +55,17 @@ class AroundTheWorldRenderer implements GLSurfaceView.Renderer
    private DistortedScreen mScreen;
    private MeshFlat mMesh;
    private AroundTheWorldEffectsManager mManager;
-   private int mObjWidth, mObjHeight;
-   private Static3D mMove, mScale;
+   private Static3D mScale;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    AroundTheWorldRenderer(GLSurfaceView view)
       {
-      mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
 
       mView = view;
       mManager = new AroundTheWorldEffectsManager();
       mEffects = new DistortedEffects();
-      mEffects.apply(new MatrixEffectMove(mMove));
       mEffects.apply(new MatrixEffectScale(mScale));
 
       mManager.apply(mEffects);
@@ -95,21 +91,11 @@ class AroundTheWorldRenderer implements GLSurfaceView.Renderer
     
    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
       {
-      if( (float)mObjHeight/mObjWidth > (float)height/width )
-        {
-        int w = (height*mObjWidth)/mObjHeight;
-        float factor = (float)height/mObjHeight;
-        mMove.set((width-w)/2,0,0);
-        mScale.set(factor,factor,factor);
-        }
-      else
-        {
-        int h = (width*mObjHeight)/mObjWidth;
-        float factor = (float)width/mObjWidth;
-        mMove.set(0,(height-h)/2,0);
-        mScale.set(factor,factor,factor);
-        }
+      float horiRatio = (float)width / mTexture.getWidth();
+      float vertRatio = (float)height/ mTexture.getHeight();
+      float factor    = horiRatio > vertRatio ? vertRatio : horiRatio;
 
+      mScale.set( factor,factor,factor );
       mScreen.resize(width,height);
       }
 
@@ -133,13 +119,13 @@ class AroundTheWorldRenderer implements GLSurfaceView.Renderer
         catch(IOException e) { }
         }
 
-      mObjWidth = bitmap.getWidth();
-      mObjHeight= bitmap.getHeight();
+      int objWidth = bitmap.getWidth();
+      int objHeight= bitmap.getHeight();
 
-      if( mTexture==null ) mTexture = new DistortedTexture(mObjWidth,mObjHeight);
+      if( mTexture==null ) mTexture = new DistortedTexture(objWidth,objHeight);
       mTexture.setTexture(bitmap);
 
-      if( mMesh==null ) mMesh = new MeshFlat(30,30*mObjHeight/mObjWidth);
+      if( mMesh==null ) mMesh = new MeshFlat(30,30*objHeight/objWidth);
 
       mScreen.detachAll();
       mScreen.attach(mTexture, mEffects, mMesh);
diff --git a/src/main/java/org/distorted/examples/blur/BlurRenderer.java b/src/main/java/org/distorted/examples/blur/BlurRenderer.java
index f92838c..84b2e2f 100644
--- a/src/main/java/org/distorted/examples/blur/BlurRenderer.java
+++ b/src/main/java/org/distorted/examples/blur/BlurRenderer.java
@@ -58,7 +58,7 @@ class BlurRenderer implements GLSurfaceView.Renderer
     private MeshFlat mMesh;
     private Static1D mRadiusSta;
     private int mObjHeight, mObjWidth;
-    private Static3D mMove, mScale, mBufferMove, mBufferScale;
+    private Static3D mScale, mBufferScale;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -73,18 +73,14 @@ class BlurRenderer implements GLSurfaceView.Renderer
       Dynamic1D radiusDyn = new Dynamic1D();
       radiusDyn.add(mRadiusSta);
 
-      mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
-      mBufferMove = new Static3D(0,0,0);
       mBufferScale= new Static3D(1,1,1);
 
       mBufferEffects = new DistortedEffects();
-      mBufferEffects.apply(new MatrixEffectMove(mBufferMove));
       mBufferEffects.apply(new MatrixEffectScale(mBufferScale));
 
       mEffects = new DistortedEffects();
       mEffects.apply( new PostprocessEffectBlur(radiusDyn) );
-      mEffects.apply(new MatrixEffectMove(mMove));
       mEffects.apply(new MatrixEffectScale(mScale));
       }
 
@@ -114,19 +110,13 @@ class BlurRenderer implements GLSurfaceView.Renderer
      float qw1 = (float)width /SIZE;
      float qh1 = (float)height/SIZE;
      float factor1 = 0.8f* (qw1<qh1 ? qw1:qh1);
-     int w1 = (int)(factor1*SIZE);
-     int h1 = (int)(factor1*SIZE);
 
-     mBufferMove.set((width-w1)/2 ,(height-h1)/2, 0);
      mBufferScale.set( factor1,factor1,factor1 );
 
      float qw2 = (float)SIZE/mObjWidth;
      float qh2 = (float)SIZE/mObjHeight;
      float factor2 = 0.9f* (qw2<qh2 ? qw2:qh2);
-     int w2 = (int)(factor2*mObjWidth);
-     int h2 = (int)(factor2*mObjHeight);
 
-     mMove.set((SIZE-w2)/2 ,(SIZE-h2)/2, 0);
      mScale.set( factor2,factor2,factor2 );
 
      mScreen.resize(width, height);
diff --git a/src/main/java/org/distorted/examples/check/CheckRenderer.java b/src/main/java/org/distorted/examples/check/CheckRenderer.java
index 268408f..da1dc9c 100644
--- a/src/main/java/org/distorted/examples/check/CheckRenderer.java
+++ b/src/main/java/org/distorted/examples/check/CheckRenderer.java
@@ -29,7 +29,6 @@ import org.distorted.examples.R;
 
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.FragmentEffectChroma;
-import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.effect.VertexEffectDeform;
 import org.distorted.library.effect.VertexEffectSwirl;
@@ -66,7 +65,7 @@ class CheckRenderer implements GLSurfaceView.Renderer
     private MeshFlat mMesh;
     private DistortedScreen mScreen;
     private int mObjHeight, mObjWidth;
-    private Static3D mMove, mScale, mCenter;
+    private Static3D mScale, mCenter;
     private Static3D mSwirl1, mSwirl2, mDeform1, mDeform2;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -88,12 +87,10 @@ class CheckRenderer implements GLSurfaceView.Renderer
       mSwirl2 = new Static3D(0,0,0);
       mDeform1= new Static3D(0,0,0);
       mDeform2= new Static3D(0,0,0);
-      mMove   = new Static3D(0,0,0);
       mScale  = new Static3D(1,1,1);
       mCenter = new Static3D(0,0,0);
 
       mEffects = new DistortedEffects();
-      mEffects.apply(new MatrixEffectMove(mMove));
       mEffects.apply(new MatrixEffectScale(mScale));
 
       // Try adding 2 Vertex Effects to the Bitmap.
@@ -152,7 +149,6 @@ class CheckRenderer implements GLSurfaceView.Renderer
 
       float factor = xW>xH ? SCALE*xH : SCALE*xW;
 
-      mMove.set( (width-factor*mObjWidth)/2 , (height-factor*mObjHeight)/2 , 0);
       mScale.set(factor,factor,factor);
 
       mScreen.resize(width,height);
diff --git a/src/main/java/org/distorted/examples/deform/DeformRenderer.java b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
index 0ca9e56..2946635 100644
--- a/src/main/java/org/distorted/examples/deform/DeformRenderer.java
+++ b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
@@ -63,6 +63,7 @@ class DeformRenderer implements GLSurfaceView.Renderer
 
    private Static4D mRegion;
    private int scrHeight, scrWidth;
+   private int textureWidth, textureHeight;
    private float mRadius;
 
    private EffectName mMode = EffectName.DISTORT;
@@ -173,28 +174,28 @@ class DeformRenderer implements GLSurfaceView.Renderer
      mRegion.set4(mRadius*scrWidth);
 
      Canvas stretchCanvas;
-     int w=width/2;
-     int h=height/2;
+     textureWidth = (int)(0.6f*width);
+     textureHeight= (int)(0.6f*height);
 
      if( stretchMesh!=null ) stretchMesh.markForDeletion();
 
-     stretchMesh = new MeshFlat(50,50*h/w);
-     Bitmap stretchBitmap = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
+     stretchMesh = new MeshFlat(50,50*textureHeight/textureWidth);
+     Bitmap stretchBitmap = Bitmap.createBitmap(textureWidth,textureHeight, Bitmap.Config.ARGB_8888);
      stretchCanvas = new Canvas(stretchBitmap);
 
      Paint paint = new Paint();
      paint.setColor(0xff008800);
      paint.setStyle(Style.FILL);
-     stretchCanvas.drawRect(0, 0, w, h, paint);
+     stretchCanvas.drawRect(0, 0, textureWidth, textureHeight, paint);
      paint.setColor(0xffffffff);
 
      for(int i=0; i<=NUM_LINES ; i++ )
        {
-       stretchCanvas.drawRect(w*i/NUM_LINES-1,               0, w*i/NUM_LINES+1, h              , paint);
-       stretchCanvas.drawRect(              0, h*i/NUM_LINES-1, w              , h*i/NUM_LINES+1, paint);
+       stretchCanvas.drawRect(textureWidth*i/NUM_LINES-1,                           0, textureWidth*i/NUM_LINES+1, textureHeight              , paint);
+       stretchCanvas.drawRect(                         0, textureHeight*i/NUM_LINES-1, textureWidth              , textureHeight*i/NUM_LINES+1, paint);
        }
 
-     if( stretchTexture==null ) stretchTexture = new DistortedTexture(w,h);
+     if( stretchTexture==null ) stretchTexture = new DistortedTexture(textureWidth,textureHeight);
      stretchTexture.setTexture(stretchBitmap);
 
      mScreen.detachAll();
@@ -223,29 +224,27 @@ class DeformRenderer implements GLSurfaceView.Renderer
 
    void down(int x, int y)
      {
-     int xt = x-scrWidth /4;
-     int yt = y-scrHeight/4;
-      
-     if( xt<0 ) xt=0;
-     if( xt>scrWidth /2 ) xt=scrWidth/2;
-     if( yt<0 ) yt=0;
-     if( yt>scrHeight/2 ) yt=scrHeight/2;
-      
-     mTouchPoint.set(xt, scrHeight/2-yt,0);   // OpenGL coord system and 2D coords have inverted Y axis
+     int xt = x-(scrWidth -textureWidth )/2;
+     int yt = y-(scrHeight-textureHeight)/2;
+
+     yt = textureHeight - yt;  // OpenGL coord system and 2D coords have inverted Y axis
 
      switch(mMode)
        {
        case DISTORT: vDistort[0].set(0,0,0);
                      stretchEffects.apply(mMovingDistort);
                      mLastEffect = mMovingDistort.getID();
+                     mTouchPoint.set(xt,yt,0);
                      break;
        case DEFORM : vDeform[0].set(0,0,0);
                      stretchEffects.apply(mMovingDeform);
                      mLastEffect = mMovingDeform.getID();
+                     mTouchPoint.set(xt,yt,0);
                      break;
        case SHEAR  : vShear[0].set(0,0,0);
                      stretchEffects.apply(mMovingShear);
                      mLastEffect = mMovingShear.getID();
+                     mTouchPoint.set(xt-textureWidth/2,yt-textureHeight/2,0);
                      break;
        }
      }
@@ -260,7 +259,7 @@ class DeformRenderer implements GLSurfaceView.Renderer
                      break;
        case DEFORM:  vDeform[0].set(x,-y,0);
                      break;
-       case SHEAR:   vShear[0].set( (float)x/(scrWidth/2), (float)(-y)/(scrHeight/2), 0);
+       case SHEAR:   vShear[0].set( (float)x/textureWidth, (float)(-y)/textureHeight, 0);
                      break;
        }
      }
diff --git a/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java b/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java
index 62867dd..27697d1 100644
--- a/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java
+++ b/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java
@@ -49,14 +49,14 @@ import android.opengl.GLSurfaceView;
 
 class DifferentBitmapsRenderer implements GLSurfaceView.Renderer 
 {
-   private static final int NUM = 3;
+   private static final int[] bitmap = { R.raw.dog, R.raw.face, R.raw.cat };
+   private static final int NUM = bitmap.length;
    
    private GLSurfaceView mView;
    private DistortedEffects[] mEffects;
    private DistortedTexture[] mTexture;
    private MeshFlat mMesh;
    private DistortedScreen mScreen;
-   private int bmpHeight, bmpWidth;
    private Static3D mScale;
    private Static3D[] mMove;
 
@@ -101,29 +101,6 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
       mScreen.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
       }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   private Bitmap readBitmap(int id)
-     {
-     InputStream is = mView.getContext().getResources().openRawResource(id);
-     Bitmap bitmap;
-           
-     try 
-       {
-       bitmap = BitmapFactory.decodeStream(is);
-       } 
-     finally 
-       {
-       try 
-         {
-         is.close();
-         } 
-       catch(IOException e) { }
-       }
-     
-     return bitmap;
-     }
-   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
    public void onDrawFrame(GL10 glUnused)
@@ -135,30 +112,13 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
     
    public void onSurfaceChanged(GL10 glUnused, int width, int height)
      {
-     if( (float)bmpHeight/(NUM*bmpWidth) > (float)height/width )
-       {
-       int w = (height*bmpWidth)/bmpHeight;
-       float factor = (float)height/bmpHeight;
-       mScale.set(factor,factor,factor);
+     float horiRatio = (float)width / (NUM*mTexture[0].getWidth());
+     float vertRatio = (float)height/ (    mTexture[0].getHeight());
+     float factor    = horiRatio > vertRatio ? vertRatio : horiRatio;
 
-       for(int i=NUM-1; i>=0; i--)
-         {
-         mMove[i].set((width-NUM*w)/2 +i*w ,0,0);
-         }
-       }
-     else
-       {
-       int w = width/NUM;
-       int h = (width*bmpHeight)/(bmpWidth*NUM);
-       float factor = (float)width/(bmpWidth*NUM);
-       mScale.set(factor,factor,factor);
-
-       for(int i=NUM-1; i>=0; i--)
-         {
-         mMove[i].set(i*w,(height-h)/2,0);
-         }
-       }
+     mScale.set( factor,factor,factor );
 
+     for(int i=NUM-1; i>=0; i--) mMove[i].set((i-(NUM-1)/2.0f)*(width/NUM), 0, 0);
 
      mScreen.resize(width, height);
      }
@@ -167,12 +127,15 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
     
    public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
      {
-     Bitmap bitmap0= readBitmap(R.raw.dog);
-     Bitmap bitmap1= readBitmap(R.raw.face);
-     Bitmap bitmap2= readBitmap(R.raw.cat);
-      
-     bmpHeight = bitmap0.getHeight();
-     bmpWidth  = bitmap0.getWidth();
+     Bitmap[] bmp = new Bitmap[NUM];
+
+     for(int i=0; i<NUM; i++)
+       {
+       bmp[i] = readBitmap(bitmap[i]);
+       }
+
+     int bmpHeight = bmp[0].getHeight();
+     int bmpWidth  = bmp[0].getWidth();
 
      if( mTexture==null )
        {
@@ -182,9 +145,10 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
          mTexture[i] = new DistortedTexture(bmpWidth,bmpHeight);
        }
 
-     mTexture[0].setTexture(bitmap0);
-     mTexture[1].setTexture(bitmap1);
-     mTexture[2].setTexture(bitmap2);
+     for(int i=0; i<NUM; i++)
+       {
+       mTexture[i].setTexture(bmp[i]);
+       }
 
      if( mMesh==null ) mMesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
 
@@ -203,4 +167,28 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
        android.util.Log.e("Renderer", ex.getMessage() );
        }
      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   private Bitmap readBitmap(int id)
+     {
+     InputStream is = mView.getContext().getResources().openRawResource(id);
+     Bitmap bitmap;
+
+     try
+       {
+       bitmap = BitmapFactory.decodeStream(is);
+       }
+     finally
+       {
+       try
+         {
+         is.close();
+         }
+       catch(IOException e) { }
+       }
+
+     return bitmap;
+     }
+
 }
diff --git a/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java b/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java
index 18a2076..4d882ac 100644
--- a/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java
+++ b/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java
@@ -58,7 +58,6 @@ class DifferentEffectsRenderer implements GLSurfaceView.Renderer
    private DistortedTexture mTexture;
    private MeshFlat mMesh;
    private DistortedScreen mScreen;
-   private int bmpHeight, bmpWidth;
    private Static3D mScale;
    private Static3D[] mMove;
 
@@ -131,22 +130,14 @@ class DifferentEffectsRenderer implements GLSurfaceView.Renderer
     
    public void onSurfaceChanged(GL10 glUnused, int width, int height)
      {
-     if( (float)bmpHeight/(NUM*bmpWidth) > (float)height/width )
-       {
-       int w = (height*bmpWidth)/bmpHeight;
-       float factor = (float)height/bmpHeight;
-       mScale.set(factor,factor,factor);
-       for(int i=NUM-1; i>=0; i--) mMove[i].set((width-NUM*w)/2 +i*w , 0, 0);
-       }
-     else
-       {
-       int w = width/NUM;
-       int h = (width*bmpHeight)/(bmpWidth*NUM);
-       float factor = (float)width/(bmpWidth*NUM);
-       mScale.set(factor,factor,factor);
-       for(int i=NUM-1; i>=0; i--) mMove[i].set(i*w, (height-h)/2, 0);
-       }
-       
+     float horiRatio = (float)width / (NUM*mTexture.getWidth());
+     float vertRatio = (float)height/ (    mTexture.getHeight());
+     float factor    = horiRatio > vertRatio ? vertRatio : horiRatio;
+
+     mScale.set( factor,factor,factor );
+
+     for(int i=NUM-1; i>=0; i--) mMove[i].set((i-(NUM-1)/2.0f)*(width/NUM), 0, 0);
+
      mScreen.resize(width, height);
      }
 
@@ -170,8 +161,8 @@ class DifferentEffectsRenderer implements GLSurfaceView.Renderer
        catch(IOException e) { }
        }
       
-     bmpHeight = bitmap.getHeight();
-     bmpWidth  = bitmap.getWidth();
+     int bmpHeight = bitmap.getHeight();
+     int bmpWidth  = bitmap.getWidth();
 
      if( mMesh==null ) mMesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
      if( mTexture==null ) mTexture  = new DistortedTexture(bmpWidth,bmpHeight);
diff --git a/src/main/java/org/distorted/examples/earth/EarthRenderer.java b/src/main/java/org/distorted/examples/earth/EarthRenderer.java
index 7ef64a8..3a92617 100644
--- a/src/main/java/org/distorted/examples/earth/EarthRenderer.java
+++ b/src/main/java/org/distorted/examples/earth/EarthRenderer.java
@@ -70,7 +70,7 @@ class EarthRenderer implements GLSurfaceView.Renderer
     private static final int   RADIUS_F= SIZE/15;
     private static final int   LEVEL   =      40;
     private static final float FOV     =   30.0f;
-    private static final float NEAR    =    0.1f;
+    private static final float NEAR    =   0.01f;
     private static final int   MAX_EFF =      20;
     private static final float SCALE   =   1.10f;
 
@@ -80,7 +80,7 @@ class EarthRenderer implements GLSurfaceView.Renderer
     private MeshBase mMesh;
     private DistortedScreen mScreen;
     private int mObjWidth, mObjHeight, mObjDepth;
-    private Static3D mMove, mScaleFactor, mCenter;
+    private Static3D mMove, mScaleFactor;
 
     private int mScrWidth, mScrHeight;
     private float mLevel;
@@ -109,10 +109,11 @@ class EarthRenderer implements GLSurfaceView.Renderer
       mRegionV    = new Static4D(0,0,0,RADIUS_V);
       mMove       = new Static3D(0,0,0);
       mScaleFactor= new Static3D(1,1,1);
-      mCenter     = new Static3D(0,0,0);
       mPinch      = new Static2D(0.5f,0.0f);
       mSwirl      = new Static1D(45.0f);
 
+      Static3D center = new Static3D(0,0,0);
+
       Dynamic3D scale = new Dynamic3D(0,0.5f);
       scale.add(mScaleFactor);
 
@@ -135,8 +136,8 @@ class EarthRenderer implements GLSurfaceView.Renderer
       mEffects = new DistortedEffects();
       mEffects.apply( new MatrixEffectMove(mMove) );
       mEffects.apply( new MatrixEffectScale(scale));
-      mEffects.apply( new MatrixEffectQuaternion(quatInt1, mCenter) );
-      mEffects.apply( new MatrixEffectQuaternion(quatInt2, mCenter) );
+      mEffects.apply( new MatrixEffectQuaternion(quatInt1, center) );
+      mEffects.apply( new MatrixEffectQuaternion(quatInt2, center) );
 
       mScreen = new DistortedScreen();
       mScreen.setProjection(FOV, NEAR);
@@ -159,7 +160,6 @@ class EarthRenderer implements GLSurfaceView.Renderer
 
       adjustFactor();
 
-      mCenter.set( (float)mObjWidth/2, (float)mObjHeight/2, (float)mObjDepth/2 );
       mScreen.resize(width, height);
       }
 
@@ -167,7 +167,7 @@ class EarthRenderer implements GLSurfaceView.Renderer
 
     void setLevel(int level)
       {
-      float N=3.0f;
+      final float N=2.2f;
 
       // MAP: 0--> SCALE/N   50-->SCALE   100->SCALE*N
       mLevel = SCALE* (1.0f+  (level>=50 ? N-1 : (N-1)/N) * (level-50)/50.0f);
@@ -184,7 +184,7 @@ class EarthRenderer implements GLSurfaceView.Renderer
 
       float factor = xW>xH ? mLevel*xH : mLevel*xW;
 
-      mMove.set( (mScrWidth-factor*mObjWidth)/2 , (mScrHeight-factor*mObjHeight)/2 , -factor*mObjDepth );
+      mMove.set( 0, 0, -factor*mObjDepth );
       mScaleFactor.set(factor,factor,factor);
       }
 
diff --git a/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java b/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java
index 04a8e8e..566a471 100644
--- a/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java
+++ b/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java
@@ -198,11 +198,14 @@ public class Effects3DActivity extends Activity
       {
       tr = (TableRow)mLay.getChildAt(row);
 
-      for(int col=0; col<mNumCols; col++)
+      if( tr!=null )
         {
-        butt = (Button)tr.getVirtualChildAt(col);
-        butt.setBackgroundColor(mObjectType==0 ? COLOR_ON : COLOR_INAC);
-        mShape[row*mNumCols+col] = true;
+        for(int col=0; col<mNumCols; col++)
+          {
+          butt = (Button)tr.getVirtualChildAt(col);
+          butt.setBackgroundColor(mObjectType==0 ? COLOR_ON : COLOR_INAC);
+          mShape[row*mNumCols+col] = true;
+          }
         }
       }
     }
diff --git a/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java b/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java
index c789350..e7b257c 100644
--- a/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java
+++ b/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java
@@ -57,7 +57,7 @@ class Effects3DRenderer implements GLSurfaceView.Renderer
     private DistortedTexture mObjectTexture, mBackgroundTexture, mCenterTexture, mRegionTexture;
     private DistortedScreen mScreen;
     private DistortedNode mCenterNode, mRegionNode;
-    private int mObjWidth, mObjHeight, mObjDepth;
+    private int mObjWidth, mObjHeight;
     private Static3D mCenterPoint, mRegionPoint, mRegionScalePoint;
     private Static3D mRotateCen, mMoveObject, mScaleObject, mMoveCenter, mScaleCenter, mMoveRegion, mMoveBackground, mScaleBackground;
     private boolean mShowingCenter=false;
@@ -103,7 +103,6 @@ class Effects3DRenderer implements GLSurfaceView.Renderer
 
       mObjWidth = mObjectTexture.getWidth();
       mObjHeight= mObjectTexture.getHeight();
-      mObjDepth = mObjectTexture.getDepth(mesh);
 
       mQuat1 = new Static4D(0,0,0,1);  // unity
       mQuat2 = new Static4D(0,0,0,1);  // quaternions
@@ -143,7 +142,6 @@ class Effects3DRenderer implements GLSurfaceView.Renderer
 
       resetMatrixEffects();
 
-      // quite tricky: move the background exactly to the FAR plane! (see DistortedOutputSurface.setProjection() )
       backgroundEffects.apply(new MatrixEffectMove(mMoveBackground) );
       backgroundEffects.apply(new MatrixEffectScale(mScaleBackground) );
       }
@@ -154,7 +152,7 @@ class Effects3DRenderer implements GLSurfaceView.Renderer
       {
       Effects3DActivity2 act = (Effects3DActivity2)mView.getContext();
       DistortedEffects objectEffects= act.getEffects();
-      Static3D rotateObj = new Static3D( (float)mObjWidth/2, (float)mObjHeight/2, (float)mObjDepth/2 );
+      Static3D rotateObj = new Static3D( 0,0,0 );
 
       MatrixEffectQuaternion quat1obj = new MatrixEffectQuaternion(mQuat1,  rotateObj);
       MatrixEffectQuaternion quat2obj = new MatrixEffectQuaternion(mQuat2,  rotateObj);
@@ -253,11 +251,10 @@ class Effects3DRenderer implements GLSurfaceView.Renderer
       mRegionPoint.set(mFactorObj*act.getRegionX(),-mFactorObj*act.getRegionY(),0);
       mFactorReg = 2*mFactorObj*act.getRegionR()/regionSize;
       mRegionScalePoint.set(mFactorReg,mFactorReg,mFactorReg);
-      mMoveObject.set( (width-mFactorObj*mObjWidth)/2 , (height-mFactorObj*mObjHeight)/2 , -mFactorObj*mObjDepth );
       mRotateCen.set(width/2,height/2, 0);
       mScaleObject.set(mFactorObj,mFactorObj,mFactorObj);
-      mMoveCenter.set( (width -factorCen*centerSize-mFactorObj*mObjWidth )/2 ,
-                       (height-factorCen*centerSize-mFactorObj*mObjHeight)/2 , 15 );
+      mMoveCenter.set( 0,0,15);//(width -factorCen*centerSize-mFactorObj*mObjWidth )/2 ,
+                    //   (height-factorCen*centerSize-mFactorObj*mObjHeight)/2 , 15 );
       mScaleCenter.set(factorCen,factorCen,factorCen);
       mMoveRegion.set( (width -mFactorObj*mObjWidth )/2 ,(height-mFactorObj*mObjHeight)/2 , 12 );
 
@@ -266,7 +263,7 @@ class Effects3DRenderer implements GLSurfaceView.Renderer
       float factorBackY = ((float)height)/backgroundSize;
 
       // quite tricky: move the background exactly to the FAR plane! (see DistortedOutputSurface.setProjection() )
-      mMoveBackground.set( -width/2, -height/2, -0.9f*height*(1.0f-NEAR)/(2.0f*(float)Math.tan(FOV*Math.PI/360)) );
+      mMoveBackground.set( 0, 0, -0.9f*height*(1.0f-NEAR)/(2.0f*(float)Math.tan(FOV*Math.PI/360)) );
       mScaleBackground.set( 2*factorBackX, 2*factorBackY, 1.0f );
 
       mScreen.resize(width, height);
diff --git a/src/main/java/org/distorted/examples/glow/GlowRenderer.java b/src/main/java/org/distorted/examples/glow/GlowRenderer.java
index 61851c1..693e9ca 100644
--- a/src/main/java/org/distorted/examples/glow/GlowRenderer.java
+++ b/src/main/java/org/distorted/examples/glow/GlowRenderer.java
@@ -25,7 +25,6 @@ import android.opengl.GLSurfaceView;
 
 import org.distorted.examples.R;
 import org.distorted.library.effect.EffectQuality;
-import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.effect.PostprocessEffectGlow;
 import org.distorted.library.main.Distorted;
@@ -54,7 +53,7 @@ class GlowRenderer implements GLSurfaceView.Renderer
    private DistortedScreen mScreen;
    private PostprocessEffectGlow mGlow;
    private int mRootW, mRootH;
-   private Static3D mMove, mScale;
+   private Static3D mScale;
    private Static1D mRadius;
    private Static4D mColor;
 
@@ -67,7 +66,6 @@ class GlowRenderer implements GLSurfaceView.Renderer
       mRootW = LEAF_SIZE;
       mRootH = LEAF_SIZE;
       mLeaf  = new DistortedTexture(mRootW,mRootH);
-      mMove  = new Static3D(0,0,0);
       mScale = new Static3D(1,1,1);
       mRadius= new Static1D(25);
       mColor = new Static4D(1.0f,0.0f,0.0f,0.5f); // half-transparent red
@@ -75,7 +73,6 @@ class GlowRenderer implements GLSurfaceView.Renderer
       mGlow  = new PostprocessEffectGlow(mRadius,mColor);
 
       DistortedEffects effects = new DistortedEffects();
-      effects.apply(new MatrixEffectMove(mMove));
       effects.apply(new MatrixEffectScale(mScale));
       effects.apply(mGlow);
 
@@ -124,10 +121,7 @@ class GlowRenderer implements GLSurfaceView.Renderer
      float qw = (float)width /mRootW;
      float qh = (float)height/mRootH;
      float factor = 0.8f* (qw<qh ? qw:qh);
-     int w = (int)(factor*mRootW);
-     int h = (int)(factor*mRootH);
 
-     mMove.set((width-w)/2 ,(height-h)/2, 0);
      mScale.set( factor,factor,factor );
      mScreen.resize(width, height);
      }
diff --git a/src/main/java/org/distorted/examples/inflate/InflateRenderer.java b/src/main/java/org/distorted/examples/inflate/InflateRenderer.java
index 54f7baa..add2a72 100644
--- a/src/main/java/org/distorted/examples/inflate/InflateRenderer.java
+++ b/src/main/java/org/distorted/examples/inflate/InflateRenderer.java
@@ -23,7 +23,6 @@ import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
 import org.distorted.library.effect.FragmentEffectAlpha;
-import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.main.DistortedEffects;
@@ -50,8 +49,8 @@ class InflateRenderer implements GLSurfaceView.Renderer
     private DistortedEffects mEffects;
     private MeshBase mMesh;
     private DistortedScreen mScreen;
-    private int mObjWidth, mObjHeight, mObjDepth;
-    private Static3D mMove, mScale, mCenter;
+    private int mObjWidth, mObjHeight;
+    private Static3D mScale;
     private Static1D mAlpha;
 
     Static4D mQuat1, mQuat2;
@@ -65,9 +64,9 @@ class InflateRenderer implements GLSurfaceView.Renderer
 
       mAlpha = new Static1D(1.0f);
 
-      mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
-      mCenter=new Static3D(0,0,0);
+
+      Static3D center=new Static3D(0,0,0);
 
       InflateActivity2 act = (InflateActivity2)v.getContext();
 
@@ -76,7 +75,6 @@ class InflateRenderer implements GLSurfaceView.Renderer
 
       mObjWidth = mTexture.getWidth();
       mObjHeight= mTexture.getHeight();
-      mObjDepth = mTexture.getDepth(mMesh);
 
       mQuat1 = new Static4D(0,0,0,1);  // unity
       mQuat2 = new Static4D(0,0,0,1);  // quaternions
@@ -88,10 +86,9 @@ class InflateRenderer implements GLSurfaceView.Renderer
       quatInt2.add(mQuat2);
 
       mEffects = new DistortedEffects();
-      mEffects.apply( new MatrixEffectMove(mMove) );
       mEffects.apply( new MatrixEffectScale(mScale));
-      mEffects.apply( new MatrixEffectQuaternion(quatInt1, mCenter) );
-      mEffects.apply( new MatrixEffectQuaternion(quatInt2, mCenter) );
+      mEffects.apply( new MatrixEffectQuaternion(quatInt1, center) );
+      mEffects.apply( new MatrixEffectQuaternion(quatInt2, center) );
       mEffects.apply( new FragmentEffectAlpha(mAlpha));
 
       mScreen = new DistortedScreen();
@@ -114,9 +111,7 @@ class InflateRenderer implements GLSurfaceView.Renderer
 
       mScreenMin = width<height ? width:height;
       float factor = ( width*mObjHeight > height*mObjWidth ) ? (SCALE*height)/mObjHeight :  (SCALE*width)/mObjWidth;
-      mMove.set( (width-factor*mObjWidth)/2 , (height-factor*mObjHeight)/2 , -factor*mObjDepth/2 );
       mScale.set(factor,factor,factor);
-      mCenter.set( (float)mObjWidth/2, (float)mObjHeight/2, (float)mObjDepth/2 );
       mScreen.resize(width, height);
       }
 
diff --git a/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java b/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java
index 9d76a0a..aa3cbb6 100644
--- a/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java
+++ b/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java
@@ -102,9 +102,11 @@ class MirrorRenderer implements GLSurfaceView.Renderer
       {
       mX = pos;
 
-      float headW = (HEAD_SCALE *mScreenH* mHeadW) / (mScreenW* mHeadH);
+      float headWdivScreenW = mScreenW >0 ? (float)mHeadW/mScreenW : 0.0f;
+      float left = headWdivScreenW -0.5f + MIRROR_MARGIN;
+      float right= -left;
 
-      mHeadPosition.set1(mX*(1.0f-2*MIRROR_MARGIN-headW)*mScreenW / 100.0f + MIRROR_MARGIN*mScreenW);
+      mHeadPosition.set1( ((right-left)*(mX/100.0f) + left) * mScreenW );
       }
    
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -138,15 +140,20 @@ class MirrorRenderer implements GLSurfaceView.Renderer
         if( mOffScreen1!=null ) mOffScreen1.markForDeletion();
         if( mOffScreen2!=null ) mOffScreen2.markForDeletion();
 
-        mOffScreen1 = new DistortedFramebuffer(                     mScreenW,                     mScreenH, 1, DistortedFramebuffer.NO_DEPTH_NO_STENCIL );
+        mOffScreen1 = new DistortedFramebuffer(                    mScreenW ,                    mScreenH , 1, DistortedFramebuffer.NO_DEPTH_NO_STENCIL );
         mOffScreen2 = new DistortedFramebuffer( (int)(MIRROR_SCALE*mScreenW), (int)(MIRROR_SCALE*mScreenH), 1, DistortedFramebuffer.NO_DEPTH_NO_STENCIL );
 
-        mScaleMirror.set( (float)mScreenW/mMirrorW, (float)mScreenH/mMirrorH, 1.0f);
-        mMoveOffscreen2.set( MIRROR_MOVE_H*mScreenW, MIRROR_MOVE_V*mScreenH*mMirrorW/mMirrorH, 0);
-
         float headScale = HEAD_SCALE *mScreenH/ mHeadH;
         mScaleHead.set(headScale,headScale,headScale);
-        mHeadPosition.set2( mScreenH*MIRROR_MARGIN*mMirrorW/mMirrorH );
+
+        float scaleW = (float)mScreenW/mMirrorW;
+        float scaleH = (float)mScreenH/mMirrorH;
+
+        mScaleMirror.set( scaleW, scaleH, 1.0f);
+
+        mMoveOffscreen2.set( (MIRROR_MOVE_H-0.5f+0.5f*MIRROR_SCALE)*mScreenW, (MIRROR_MOVE_V-0.5f+0.5f*MIRROR_SCALE)*mScreenH*mMirrorW/mMirrorH, 0);
+        mHeadPosition.set2( (0.5f*HEAD_SCALE - 0.5f + MIRROR_MARGIN*mMirrorW/mMirrorH)*mScreenH );
+
         setPosition(mX);
 
         mOffScreen1.attach( mTextureMirror, mEffectsMirror    , mQuad );
diff --git a/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java b/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java
index 6fc601d..63b366d 100644
--- a/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java
+++ b/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java
@@ -66,7 +66,7 @@ class MovingGlowRenderer implements GLSurfaceView.Renderer,EffectListener
    private PostprocessEffectGlow[] mGlow = new PostprocessEffectGlow[NUM_LEAVES];
    private int mRootW, mRootH;
    private int mGlowing;
-   private Static3D mMove, mScale;
+   private Static3D mScale;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -83,9 +83,9 @@ class MovingGlowRenderer implements GLSurfaceView.Renderer,EffectListener
 
       DistortedNode root = new DistortedNode(surface, new DistortedEffects(), mesh);
      
-      Static3D moveVector = new Static3D(0.55f*LEAF_SIZE, (mRootH-LEAF_SIZE)/2, 0);
+      Static3D moveVector = new Static3D(-1.45f*LEAF_SIZE, 0, 0);
       Static1D chromaLevel= new Static1D(0.5f);
-      Static3D center     = new Static3D(mRootW/2, mRootH/2, 0);
+      Static3D center     = new Static3D(0,0,0);
       Static3D axis       = new Static3D(0,0,1);
 
       MatrixEffectMove leafMove = new MatrixEffectMove(moveVector);
@@ -101,7 +101,6 @@ class MovingGlowRenderer implements GLSurfaceView.Renderer,EffectListener
         root.attach(node);
         }
 
-      mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
 
       Dynamic1D rot = new Dynamic1D(5000,0.0f);
@@ -110,7 +109,6 @@ class MovingGlowRenderer implements GLSurfaceView.Renderer,EffectListener
       rot.add(new Static1D(360));
 
       DistortedEffects effects = root.getEffects();
-      effects.apply(new MatrixEffectMove(mMove));
       effects.apply(new MatrixEffectScale(mScale));
       effects.apply( new MatrixEffectRotate(rot, axis, center) );
 
@@ -176,10 +174,7 @@ class MovingGlowRenderer implements GLSurfaceView.Renderer,EffectListener
      float qw = (float)width /mRootW;
      float qh = (float)height/mRootH;
      float factor = 0.9f* (qw<qh ? qw:qh);
-     int w = (int)(factor*mRootW);
-     int h = (int)(factor*mRootH);
 
-     mMove.set((width-w)/2 ,(height-h)/2, 0);
      mScale.set( factor,factor,factor );
      mScreen.resize(width, height);
      }
diff --git a/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java b/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java
index f78041c..1608085 100644
--- a/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java
+++ b/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java
@@ -73,7 +73,7 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
     private PostprocessEffectBlur mBlur;
     private int mDistance;
     private boolean[] mBlurStatus;
-    private Static3D mMove, mScale, mCenter;
+    private Static3D mScale;
 
     Static4D mQuat1, mQuat2;
     int mScreenMin;
@@ -121,18 +121,15 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
       mBlurStatus[0] = true;
       effects[0].apply(mBlur);
 
-      mMove   = new Static3D(0,0,0);
       mScale  = new Static3D(1,1,1);
-      mCenter = new Static3D(0,0,0);
+      Static3D center = new Static3D(0,0,0);
 
-      MatrixEffectMove moveEffect = new MatrixEffectMove(mMove);
       MatrixEffectScale scaleEffect = new MatrixEffectScale(mScale);
-      MatrixEffectQuaternion quatEffect1 = new MatrixEffectQuaternion(mQuat1, mCenter);
-      MatrixEffectQuaternion quatEffect2 = new MatrixEffectQuaternion(mQuat2, mCenter);
+      MatrixEffectQuaternion quatEffect1 = new MatrixEffectQuaternion(mQuat1, center);
+      MatrixEffectQuaternion quatEffect2 = new MatrixEffectQuaternion(mQuat2, center);
 
       for(int i=0; i<NUM_OBJECTS; i++)
         {
-        effects[i].apply(moveEffect);
         effects[i].apply(scaleEffect);
         effects[i].apply(quatEffect1);
         effects[i].apply(quatEffect2);
@@ -165,12 +162,9 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
     
     public void onSurfaceChanged(GL10 glUnused, int width, int height) 
       {
-      mScreenMin = width<height ? width:height;
-
-    	float factor    = 0.15f*mScreenMin/OBJ_SIZE;
+      mScreenMin  = width<height ? width:height;
+    	float factor= 0.15f*mScreenMin/OBJ_SIZE;
     	mScale.set(factor,factor,factor);
-      mCenter.set((float)OBJ_SIZE/2, (float)OBJ_SIZE/2, (float)OBJ_SIZE/2 );
-      mMove.set( (width -factor*OBJ_SIZE)/2 ,(height-factor*OBJ_SIZE)/2 , -factor*OBJ_SIZE);
       computeMoveVectors();
       mScreen.resize(width, height);
       }
@@ -217,7 +211,7 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
 
     private void computeMoveVectors()
       {
-      float size= 0.026f*OBJ_SIZE*mDistance;
+      float size= 0.020f*OBJ_SIZE*mDistance;
 
       for(int i=0; i<NUM_OBJECTS; i++)
         {
@@ -268,7 +262,5 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
         {
         android.util.Log.e("renderer", "Error, number: "+number+" checked: "+checked );
         }
-
-      //android.util.Log.d("renderer", "setting box "+number+" BLUR state to "+checked);
       }
 }
diff --git a/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java b/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java
index 5f9f74d..0071c54 100644
--- a/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java
+++ b/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java
@@ -28,7 +28,6 @@ import javax.microedition.khronos.opengles.GL10;
 import org.distorted.examples.R;
 
 import org.distorted.library.effect.FragmentEffectChroma;
-import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectRotate;
 import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.effect.VertexEffectSink;
@@ -62,9 +61,8 @@ class ObjectTreeRenderer implements GLSurfaceView.Renderer
    private DistortedNode mRoot;
    private MeshFlat mMeshFlat;
    private MeshCubes mMeshCubes;
-   private int lisaHeight, lisaWidth;
    private boolean mDepth;
-   private Static3D mScale, mMove;
+   private Static3D mScale;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -73,13 +71,11 @@ class ObjectTreeRenderer implements GLSurfaceView.Renderer
       mView   = v;
       mDepth  = true;
       mScale  = new Static3D(1,1,1);
-      mMove   = new Static3D(0,0,0);
       Dynamic1D chromaDyn = new Dynamic1D(5000,0.0f);
       chromaDyn.add(new Static1D(0.0f));
       chromaDyn.add(new Static1D(0.8f));
 
       mEffects= new DistortedEffects();
-      mEffects.apply(new MatrixEffectMove(mMove));
       mEffects.apply(new MatrixEffectScale(mScale));
       mEffects.apply(new FragmentEffectChroma(chromaDyn, new Static3D(0,0,1)));
 
@@ -118,24 +114,12 @@ class ObjectTreeRenderer implements GLSurfaceView.Renderer
 ///////////////////////////////////////////////////////////////////////////////////////////////////
     
    public void onSurfaceChanged(GL10 glUnused, int width, int height)
-      { 
-      if( (float)lisaHeight/lisaWidth > (float)height/width )
-        {
-        int w = (height*lisaWidth)/lisaHeight;
-        float factor = (float)height/lisaHeight;
-
-        mMove.set((width-w)/2,0,0);
-        mScale.set(factor,factor,factor);
-        }
-      else
-        {
-        int h = (width*lisaHeight)/lisaWidth;
-        float factor = (float)width/lisaWidth;
+      {
+      float horiRatio = (float)width / mLisaTexture.getWidth();
+      float vertRatio = (float)height/ mLisaTexture.getHeight();
+      float factor    = horiRatio > vertRatio ? vertRatio : horiRatio;
 
-        mMove.set(0,(height-h)/2,0);
-        mScale.set(factor,factor,factor);
-        }
-      
+      mScale.set( factor,factor,factor );
       mScreen.resize(width, height);
       }
 
@@ -170,8 +154,8 @@ class ObjectTreeRenderer implements GLSurfaceView.Renderer
         catch(IOException e) { }
         }  
       
-      lisaWidth     = bitmap1.getWidth();
-      lisaHeight    = bitmap1.getHeight();
+      int lisaWidth     = bitmap1.getWidth();
+      int lisaHeight    = bitmap1.getHeight();
       int gridWidth = bitmap2.getWidth();
       int gridHeight= bitmap2.getHeight();
 
@@ -200,16 +184,14 @@ class ObjectTreeRenderer implements GLSurfaceView.Renderer
       mScreen.attach(mRoot);
 
       float factor = lisaWidth/(2.0f*gridWidth);
-      MatrixEffectMove move = new MatrixEffectMove( new Static3D((lisaWidth-factor*gridWidth)/2,(lisaHeight-factor*gridHeight)/2, gridWidth/(2.0f*GRID)));
       MatrixEffectScale scale = new MatrixEffectScale( new Static3D(factor,factor,factor) );
-      gridEffects.apply(move);
       gridEffects.apply(scale);
 
       Dynamic1D rotDyn = new Dynamic1D(12000,0.0f);
       rotDyn.add(new Static1D(  0));
       rotDyn.add(new Static1D(360));
       rotDyn.setMode(Dynamic.MODE_JUMP);
-      MatrixEffectRotate rotate = new MatrixEffectRotate(rotDyn, new Static3D(1,0,0), new Static3D(gridWidth/2,gridHeight/2,gridWidth/(2*GRID)));
+      MatrixEffectRotate rotate = new MatrixEffectRotate(rotDyn, new Static3D(1,0,0), new Static3D(0,0,0));
       gridEffects.apply(rotate);
 
       Dynamic1D sinkDyn = new Dynamic1D(3000,0.0f);
diff --git a/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java b/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java
index 8a62f79..e11a4a5 100644
--- a/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java
+++ b/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java
@@ -60,7 +60,7 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
    private MeshFlat mMesh;
    private int mScreenW, mScreenH;
    private int mPrevRendered, mCurrRendered;
-   private Static3D mMove, mScale;
+   private Static3D mScale;
 
    private DistortedNode[] mCircleNode = new DistortedNode[NUM_CIRCLES];
    private DistortedEffects[] mEffects = new DistortedEffects[NUM_LEAVES];
@@ -96,16 +96,15 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
       mLeaf = new DistortedTexture(LEAF_SIZE,LEAF_SIZE);
       DistortedTexture surface = new DistortedTexture(3*LEAF_SIZE,3*LEAF_SIZE);
       mMesh = new MeshFlat(1,1);
-      mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
 
       DistortedEffects effects = new DistortedEffects();
-      effects.apply(new MatrixEffectMove(mMove));
       effects.apply(new MatrixEffectScale(mScale));
 
       mScreenW = 9*LEAF_SIZE;
       mScreenH = 9*LEAF_SIZE;
-      mRoot = new DistortedNode(new DistortedTexture(mScreenW,mScreenH), effects, mMesh);
+      DistortedTexture rootTexture = new DistortedTexture(mScreenW,mScreenH);
+      mRoot = new DistortedNode(rootTexture, effects, mMesh);
      
       Dynamic1D rot = new Dynamic1D(5000,0.0f);
       rot.setMode(Dynamic1D.MODE_JUMP);
@@ -113,11 +112,15 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
       rot.add(new Static1D(360));
 
       int[] colors    = new int[] {0,0,1,  0,0,0,  1,0,0,  1,1,0,  0,1,0}; // blue, black, red, yellow, green  
-      int[] positions = new int[] {0,4*LEAF_SIZE,  3*LEAF_SIZE,4*LEAF_SIZE,  6*LEAF_SIZE,4*LEAF_SIZE,  3*LEAF_SIZE/2,3*LEAF_SIZE/2,  9*LEAF_SIZE/2,3*LEAF_SIZE/2};
+      int[] positions = new int[] {-3*LEAF_SIZE  ,   LEAF_SIZE  ,
+                                              0  ,   LEAF_SIZE  ,
+                                    3*LEAF_SIZE  ,   LEAF_SIZE  ,
+                                   -3*LEAF_SIZE/2,-3*LEAF_SIZE/2,
+                                    3*LEAF_SIZE/2,-3*LEAF_SIZE/2 };
       
-      Static3D center = new Static3D(3*LEAF_SIZE/2, 3*LEAF_SIZE/2, 0);
+      Static3D center = new Static3D(0,0,0);
       Static3D axis   = new Static3D(0,0,1);
-      Static3D moveVector = new Static3D(0,LEAF_SIZE,0);
+      Static3D moveVector = new Static3D(-LEAF_SIZE,0,0);
 
       for(int j=0; j<NUM_LEAVES; j++)
         {
@@ -169,21 +172,11 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
     
    public void onSurfaceChanged(GL10 glUnused, int width, int height)
      {
-     if( (float)mScreenH/mScreenW > (float)height/width )
-       {
-       int w = (height*mScreenW)/mScreenH;
-       float factor = (float)height/mScreenH;
-       mMove.set((width-w)/2 ,0, 0);
-       mScale.set(factor,factor,factor);
-       }
-     else
-       {
-       int h = (width*mScreenH)/mScreenW;
-       float factor = (float)width/mScreenW;
-       mMove.set(0,(height-h)/2,0);
-       mScale.set(factor,factor,factor);
-       }
-      
+     float horiRatio = (float)width / mScreenW;
+     float vertRatio = (float)height/ mScreenH;
+     float factor    = horiRatio > vertRatio ? vertRatio : horiRatio;
+
+     mScale.set(factor,factor,factor);
      mScreen.resize(width, height);
      }
 
diff --git a/src/main/java/org/distorted/examples/postprocesstree/PostprocessTreeRenderer.java b/src/main/java/org/distorted/examples/postprocesstree/PostprocessTreeRenderer.java
index a0fe672..e6dcc8a 100644
--- a/src/main/java/org/distorted/examples/postprocesstree/PostprocessTreeRenderer.java
+++ b/src/main/java/org/distorted/examples/postprocesstree/PostprocessTreeRenderer.java
@@ -56,7 +56,7 @@ class PostprocessTreeRenderer implements GLSurfaceView.Renderer
    private DistortedTexture mLeaf;
    private DistortedScreen mScreen;
    private int mScreenW, mScreenH;
-   private Static3D mMove, mScale;
+   private Static3D mScale;
    private Static1D mRadius;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -79,7 +79,6 @@ class PostprocessTreeRenderer implements GLSurfaceView.Renderer
       mLeaf = new DistortedTexture(LEAF_SIZE,LEAF_SIZE);
 
       MeshFlat mesh = new MeshFlat(1,1);
-      mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
 
       DistortedEffects rootEffects  = new DistortedEffects();
@@ -89,7 +88,6 @@ class PostprocessTreeRenderer implements GLSurfaceView.Renderer
 
       DistortedNode root = new DistortedNode(new DistortedTexture(mScreenW,mScreenH), rootEffects, mesh);
 
-      rootEffects.apply(new MatrixEffectMove(mMove));
       rootEffects.apply(new MatrixEffectScale(mScale));
       rootEffects.apply(blurEffect);
 
@@ -98,24 +96,21 @@ class PostprocessTreeRenderer implements GLSurfaceView.Renderer
       rotate.add(new Static1D(  0));
       rotate.add(new Static1D(360));
 
-      Static3D outerCenter = new Static3D(OUTER*LEAF_SIZE/2, OUTER*LEAF_SIZE/2, 0);
-      Static3D innerCenter = new Static3D(INNER*LEAF_SIZE/2, INNER*LEAF_SIZE/2, 0);
-
+      Static3D center = new Static3D(0,0,0);
       Static3D axis   = new Static3D(0,0,1);
-      Static3D innerMoveVector = new Static3D(            0, (INNER-1)*LEAF_SIZE/2, 0);
-      Static3D outerMoveVector = new Static3D(3*LEAF_SIZE/2, (OUTER-1)*LEAF_SIZE/2, 0);
+      Static3D innerMoveVector = new Static3D( (1-INNER)*LEAF_SIZE/2, 0, 0);
+      Static3D outerMoveVector = new Static3D( (4-OUTER)*LEAF_SIZE/2, 0, 0);
 
       for(int j=0; j<NUM_LEAVES; j++)
         {
         outerLeafEffects[j] = new DistortedEffects();
-        outerLeafEffects[j].apply( new MatrixEffectRotate(new Static1D(j*(360/NUM_LEAVES)), axis, outerCenter) );
+        outerLeafEffects[j].apply( new MatrixEffectRotate(new Static1D(j*(360/NUM_LEAVES)), axis, center) );
         outerLeafEffects[j].apply(new MatrixEffectMove(outerMoveVector));
 
         root.attach(mLeaf, outerLeafEffects[j], mesh);
         }
 
-      innerEffects.apply( new MatrixEffectMove(new Static3D( (OUTER-INNER)*LEAF_SIZE/2,(OUTER-INNER)*LEAF_SIZE/2, 0)) );
-      innerEffects.apply( new MatrixEffectRotate(rotate, axis, innerCenter) );
+      innerEffects.apply( new MatrixEffectRotate(rotate, axis, center) );
       innerEffects.apply( new FragmentEffectChroma(new Static1D(0.5f), new Static3D(1,0,0) ) );
       innerEffects.apply(blurEffect);
 
@@ -125,7 +120,7 @@ class PostprocessTreeRenderer implements GLSurfaceView.Renderer
       for(int j=0; j<NUM_LEAVES; j++)
         {
         innerLeafEffects[j] = new DistortedEffects();
-        innerLeafEffects[j].apply( new MatrixEffectRotate(new Static1D(j*(360/NUM_LEAVES)), axis, innerCenter) );
+        innerLeafEffects[j].apply( new MatrixEffectRotate(new Static1D(j*(360/NUM_LEAVES)), axis, center) );
         innerLeafEffects[j].apply(new MatrixEffectMove(innerMoveVector));
 
         innerNode.attach( mLeaf, innerLeafEffects[j], mesh );
@@ -155,23 +150,11 @@ class PostprocessTreeRenderer implements GLSurfaceView.Renderer
     
    public void onSurfaceChanged(GL10 glUnused, int width, int height)
      {
-     float factor;
-
-     if( (float)mScreenH/mScreenW > (float)height/width )
-       {
-       int w = (height*mScreenW)/mScreenH;
-       factor = (float)height/mScreenH;
-       mMove.set((width-w)/2 ,0, 0);
-       }
-     else
-       {
-       int h = (width*mScreenH)/mScreenW;
-       factor = (float)width/mScreenW;
-       mMove.set(0,(height-h)/2,0);
-       }
+     float horiRatio = (float)width / mScreenW;
+     float vertRatio = (float)height/ mScreenH;
+     float factor    = horiRatio > vertRatio ? vertRatio : horiRatio;
 
      mScale.set(factor,factor,factor);
-
      mScreen.resize(width, height);
      }
 
diff --git a/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java b/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
index 8d85a64..11387a2 100644
--- a/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
+++ b/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
@@ -28,13 +28,11 @@ import javax.microedition.khronos.opengles.GL10;
 
 import org.distorted.examples.R;
 
-import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshBase;
 import org.distorted.library.mesh.MeshCubes;
 import org.distorted.library.type.Dynamic;
 import org.distorted.library.type.DynamicQuat;
@@ -54,9 +52,8 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
 
   private GLSurfaceView mView;
   private DistortedTexture mTexture;
-  private MeshBase mMesh;
   private DistortedScreen mScreen;
-  private Static3D mMove, mScale, mCenter;
+  private Static3D mScale;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -64,7 +61,6 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
     {
     mView    = v;
     mTexture = new DistortedTexture(1,1);
-    mMesh    = new MeshCubes(1,1,1);
 
     DistortedEffects effects = new DistortedEffects();
     DynamicQuat rot = new DynamicQuat();
@@ -88,16 +84,13 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
     rot.setDuration(8000);
     rot.setMode(Dynamic.MODE_LOOP);
 
-    mMove   = new Static3D(0,0,0);
     mScale  = new Static3D(1,1,1);
-    mCenter = new Static3D(0,0,0);
 
-    effects.apply( new MatrixEffectMove(mMove));
     effects.apply(new MatrixEffectScale(mScale));
-    effects.apply( new MatrixEffectQuaternion(rot,mCenter) );
+    effects.apply( new MatrixEffectQuaternion(rot,new Static3D(0,0,0)) );
 
     mScreen = new DistortedScreen();
-    mScreen.attach(mTexture,effects,mMesh);
+    mScreen.attach(mTexture,effects,new MeshCubes(1,1,1));
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -113,14 +106,9 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
     {
     float w = mTexture.getWidth();
     float h = mTexture.getHeight();
-    float d = mTexture.getDepth(mMesh);
-
     float factor = 0.5f*(width>height ? height/h:width/w);
 
-    mCenter.set(w/2,h/2,d/2);
-    mMove.set( (width-factor*w)/2 , (height-factor*h)/2 , -factor*d/2 );
     mScale.set(factor,factor,factor);
-
     mScreen.resize(width, height);
     }
 
diff --git a/src/main/java/org/distorted/examples/rubik/RubikRenderer.java b/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
index cd62243..aa34171 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikRenderer.java
@@ -49,7 +49,7 @@ class RubikRenderer implements GLSurfaceView.Renderer
     private GLSurfaceView mView;
     private DistortedTexture mTexture;
     private DistortedScreen mScreen;
-    private Static3D mMove, mScale, mCenter;
+    private Static3D mScale;
     private MeshCubes[][][] mCubes;
     private DistortedEffects[][][] mEffects;
 
@@ -72,14 +72,12 @@ class RubikRenderer implements GLSurfaceView.Renderer
       mEffects = new DistortedEffects[CUBE_SIZE][CUBE_SIZE][CUBE_SIZE];
       Static3D[][][] cubeVectors = new Static3D[CUBE_SIZE][CUBE_SIZE][CUBE_SIZE];
 
-      mMove  = new Static3D(0,0,0);
       mScale = new Static3D(1,1,1);
-      mCenter= new Static3D(0,0,0);
+      Static3D center= new Static3D(0,0,0);
 
-      MatrixEffectMove       move  = new MatrixEffectMove(mMove);
       MatrixEffectScale      scale = new MatrixEffectScale(mScale);
-      MatrixEffectQuaternion quat1 = new MatrixEffectQuaternion(mQuat1, mCenter);
-      MatrixEffectQuaternion quat2 = new MatrixEffectQuaternion(mQuat2, mCenter);
+      MatrixEffectQuaternion quat1 = new MatrixEffectQuaternion(mQuat1, center);
+      MatrixEffectQuaternion quat2 = new MatrixEffectQuaternion(mQuat2, center);
 
       // 3x2 bitmap = 6 squares:
       //
@@ -120,7 +118,6 @@ class RubikRenderer implements GLSurfaceView.Renderer
 
             mEffects[x][y][z] = new DistortedEffects();
 
-            mEffects[x][y][z].apply(move);
             mEffects[x][y][z].apply(scale);
             mEffects[x][y][z].apply(quat1);
             mEffects[x][y][z].apply(quat2);
@@ -143,14 +140,9 @@ class RubikRenderer implements GLSurfaceView.Renderer
 
       float w = mTexture.getWidth();
       float h = mTexture.getHeight();
-      float d = mTexture.getDepth(mCubes[0][0][0]);
-
       float factor = 0.6f*(width>height ? height/h:width/w)/CUBE_SIZE;
 
-      mCenter.set(w/2,h/2,d/2);
-      mMove.set( (width-factor*w)/2 , (height-factor*h)/2 , -factor*d/2 );
       mScale.set(factor,factor,factor);
-
       mScreen.resize(width, height);
       }
 
diff --git a/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java b/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
index b00c75a..c90a93e 100644
--- a/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
+++ b/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
@@ -200,14 +200,14 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
     
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void setupScreen(int w, int h)
+  private void setupScreen(int scrW, int scrH)
     {
-    double angleA = (90.0f - FOV_ANGLE/2)*Math.PI/180;
-    double angleB = (90.0f - FOV_ANGLE/2 +CRAWL_ANGLE)*Math.PI/180;
+    double angleA = (90.0f - FOV_ANGLE/2              ) * Math.PI/180;
+    double angleB = (90.0f - FOV_ANGLE/2 + CRAWL_ANGLE) * Math.PI/180;
 
     if( mCrawlBackgroundTexture!=null ) mCrawlBackgroundTexture.markForDeletion();
-    mCrawlBackgroundTexture = new DistortedTexture(w,(int)(h*Math.sin(angleA)/Math.sin(angleB)));
-       
+    mCrawlBackgroundTexture = new DistortedTexture(scrW,(int)(scrH*Math.sin(angleA)/Math.sin(angleB)));
+
     int randomA, randomX, randomY, randomTime;
     float randomS, randomAlpha1, randomAlpha2;
        
@@ -217,8 +217,8 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
 
     for(int i=0; i<NUM_STARS; i++)
       {
-      randomX = mRnd.nextInt(w);
-      randomY = mRnd.nextInt(h);
+      randomX = mRnd.nextInt(scrW) - scrW/2;
+      randomY = mRnd.nextInt(scrH) - scrH/2;
       randomS = 0.2f+ 0.8f*mRnd.nextFloat();
       randomA = (int)(180*mRnd.nextFloat());
       randomAlpha1 = 0.2f + 0.8f*mRnd.nextFloat();
@@ -239,14 +239,14 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
       mScreen.attach(mStarTexture, mStarEffects[i], mQuad);
       }
       
-    float scale = (0.5f*w/mGFFATexture.getWidth());
+    float scale = (0.5f*scrW/mGFFATexture.getWidth());
     
     Dynamic1D di = new Dynamic1D(6000,0.5f);
     di.add(new Static1D(1.0f));
     di.add(new Static1D(1.0f));
     di.add(new Static1D(0.0f));
     
-    mGFFAEffects.apply( new MatrixEffectMove(new Static3D(w/5,2*h/3,0)) );
+    mGFFAEffects.apply( new MatrixEffectMove(new Static3D(-scrW/3 + mGFFATexture.getWidth()/2 ,scrH/6,0)) );
     mGFFAEffects.apply( new MatrixEffectScale(scale) );
     mGFFAEffects.apply( new FragmentEffectAlpha(di) );
       
@@ -382,11 +382,7 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
         mGFFATexture.markForDeletion();
 
         int screenW=mScreen.getWidth();
-        int screenH=mScreen.getHeight();
-        
         int logoW = mLogoTexture.getWidth();
-        int logoH = mLogoTexture.getHeight();
-      
         int initSize= (int)(3.0f*screenW/logoW);
         int finaSize= (int)(0.1f*screenW/logoW);
       
@@ -394,10 +390,8 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
         di.add(new Static3D(initSize,initSize,1));
         di.add(new Static3D(finaSize,finaSize,1));
 
-        mLogoEffects.apply( new MatrixEffectMove(new Static3D(screenW/2,screenH/2,0)) );
         mLogoEffects.apply( new MatrixEffectScale(di) );
-        mLogoEffects.apply( new MatrixEffectMove(new Static3D(-logoW/2,-logoH/2,0)) );
-      
+
         mScreen.attach(mLogoTexture, mLogoEffects,mQuad);
         mLogoEffects.registerForMessages(this);
         }
@@ -409,10 +403,13 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
         int crawlW = mCrawlTexture.getWidth();
         int crawlH = mCrawlTexture.getHeight();
         int screenW= mScreen.getWidth();
+        int screenH= mScreen.getHeight();
+        int backW  = mCrawlBackgroundTexture.getWidth();
         int backH  = mCrawlBackgroundTexture.getHeight();
-        float scale= (float)screenW/crawlW;
+        float scale= (float)backW/crawlW;
 
-        mCrawlBackgroundEffects.apply( new MatrixEffectRotate(new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,0,0)) );
+        mCrawlBackgroundEffects.apply( new MatrixEffectMove(new Static3D( 0, (backH-screenH)/2, 0)) );
+        mCrawlBackgroundEffects.apply( new MatrixEffectRotate(new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(0,-backH/2,0)) );
 
         final int transpDist = 5;
         Static3D center = new Static3D( screenW/2 , transpDist*backH , 0 );
@@ -420,13 +417,12 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
         mCrawlBackgroundEffects.apply( new FragmentEffectAlpha(new Static1D(1-transpDist*0.6f), center, region, true) );
 
         Dynamic3D di = new Dynamic3D(70000,0.5f);
-        di.add(new Static3D(screenW/2,-scale*crawlH/2        , 0));
-        di.add(new Static3D(screenW/2,+scale*crawlH/2 + backH, 0));
+        di.add(new Static3D(0, -(scale*crawlH+backH)/2, 0));
+        di.add(new Static3D(0, +(scale*crawlH+backH)/2, 0));
 
         mCrawlEffects.apply( new MatrixEffectMove(di) );
         mCrawlEffects.apply( new MatrixEffectScale(new Static3D(scale,scale,scale)) );
-        mCrawlEffects.apply( new MatrixEffectMove(new Static3D(-crawlW/2,-crawlH/2,0)) );
-        
+
         mBackground = mScreen.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects,mQuad);
         mBackground.attach(mCrawlTexture, mCrawlEffects,mQuad);
         mBackground.glDisable(GLES31.GL_DEPTH_TEST);
diff --git a/src/main/java/org/distorted/examples/stencil/StencilRenderer.java b/src/main/java/org/distorted/examples/stencil/StencilRenderer.java
index 3389eb8..04f97e3 100644
--- a/src/main/java/org/distorted/examples/stencil/StencilRenderer.java
+++ b/src/main/java/org/distorted/examples/stencil/StencilRenderer.java
@@ -56,7 +56,7 @@ class StencilRenderer implements GLSurfaceView.Renderer
     private DistortedScreen mScreen;
     private DistortedTexture mCubeTex, mFloorTex, mFBOTex;
     private DistortedNode mCube1Node, mCube2Node, mFloorNode, mFBONode;
-    private Static3D mMove, mScale, mRotCenter, mFBOScale;
+    private Static3D mScale, mFBOScale;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -89,9 +89,7 @@ class StencilRenderer implements GLSurfaceView.Renderer
       MeshBase cube = new MeshCubes(1,1,1);
       MeshBase quad = new MeshQuad();
 
-      mMove       = new Static3D(0,0,0);
       mScale      = new Static3D(1,1,1);
-      mRotCenter  = new Static3D(0,0,0);
       mFBOScale   = new Static3D(1,1,1);
 
       mCubeTex   = new DistortedTexture(1,1);
@@ -137,10 +135,6 @@ class StencilRenderer implements GLSurfaceView.Renderer
       setScreen(true);
 
       float cw = mCubeTex.getWidth();
-      float ch = mCubeTex.getHeight();
-
-      float fw = mFloorTex.getWidth();
-      float fh = mFloorTex.getHeight();
 
       Static3D axisX = new Static3D(1,0,0);
       Static3D axisZ = new Static3D(0,0,1);
@@ -150,11 +144,12 @@ class StencilRenderer implements GLSurfaceView.Renderer
       rotDyn.add(new Static1D(  0));
       rotDyn.add(new Static1D(360));
 
+      Static3D rotCenter  = new Static3D(0,0,0);
+
       MatrixEffectScale  scale = new MatrixEffectScale(mScale);
-      MatrixEffectMove   move1 = new MatrixEffectMove( new Static3D( (fw-cw)/2, (fh-ch)/2, 0) );
-      MatrixEffectMove   move2 = new MatrixEffectMove( mMove );
-      MatrixEffectRotate rotaX = new MatrixEffectRotate(new Static1D(-60.0f), axisX, mRotCenter);
-      MatrixEffectRotate rotaZ = new MatrixEffectRotate(rotDyn, axisZ, mRotCenter);
+      MatrixEffectMove   move1 = new MatrixEffectMove( new Static3D( 0, 0, cw/2) );
+      MatrixEffectRotate rotaX = new MatrixEffectRotate(new Static1D(-60.0f), axisX, rotCenter);
+      MatrixEffectRotate rotaZ = new MatrixEffectRotate(rotDyn, axisZ, rotCenter);
 
       /////////////////////////////////////////////////////////////////////////////////////////////////////
       // First move the cube and its reflection to the middle of the floor. Then scale the floor, the cube
@@ -162,25 +157,22 @@ class StencilRenderer implements GLSurfaceView.Renderer
       // middle of the screen.
       /////////////////////////////////////////////////////////////////////////////////////////////////////
       // The cube
-      cube1Effects.apply( move2 );
       cube1Effects.apply( rotaX );
       cube1Effects.apply( rotaZ );
       cube1Effects.apply( scale );
       cube1Effects.apply( move1 );
       /////////////////////////////////////////////////////////////////////////////////////////////////////
       // Floor
-      floorEffects.apply( move2 );
       floorEffects.apply( rotaX );
       floorEffects.apply( rotaZ );
       floorEffects.apply( scale );
       /////////////////////////////////////////////////////////////////////////////////////////////////////
       // Reflection
-      cube2Effects.apply( move2 );
       cube2Effects.apply( rotaX );
       cube2Effects.apply( rotaZ );
       cube2Effects.apply( scale );
-      cube2Effects.apply( move1 );
       cube2Effects.apply( new MatrixEffectScale(new Static3D(1,1,-1)) );
+      cube2Effects.apply( move1 );
       cube2Effects.apply( new FragmentEffectBrightness(new Static1D(0.5f)) );
 
       /////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -202,17 +194,12 @@ class StencilRenderer implements GLSurfaceView.Renderer
       float cw = mCubeTex.getWidth();
       float ch = mCubeTex.getHeight();
 
-      float fw = mFloorTex.getWidth();
-      float fh = mFloorTex.getHeight();
-
       float bw = mFBOTex.getWidth();
       float bh = mFBOTex.getHeight();
 
       float scale = 0.4f*(width>height ? height/ch:width/cw);
 
-      mRotCenter.set(scale*fw/2,scale*fh/2,0);
       mScale.set(scale,scale,scale);
-      mMove.set((width-scale*fw)/2 , (height-scale*fh)/2, 0 );
       mFBOScale.set((float)width/bw, (float)height/bh, 1.0f );
 
       mFBONode.resize(width,height);
@@ -240,7 +227,7 @@ class StencilRenderer implements GLSurfaceView.Renderer
         }
 
       mCubeTex.setTexture(bitmap);
-      mFloorTex.setColor(0xff000000);  // ARGB
+      mFloorTex.setColorARGB(0xff000000);
 
       FragmentEffectBrightness.enable();
 
diff --git a/src/main/java/org/distorted/examples/transparency/TransparencyRenderer.java b/src/main/java/org/distorted/examples/transparency/TransparencyRenderer.java
index 9bb27bd..3ac6cd0 100644
--- a/src/main/java/org/distorted/examples/transparency/TransparencyRenderer.java
+++ b/src/main/java/org/distorted/examples/transparency/TransparencyRenderer.java
@@ -60,7 +60,7 @@ class TransparencyRenderer implements GLSurfaceView.Renderer
     private Static3D[]  mMoveVector;
     private Static1D[]  mAlphaVector;
     private DistortedScreen mScreen;
-    private Static3D mMove, mScale, mCenter;
+    private Static3D mScale;
     private PostprocessEffectBlur[] mBlur;
     private boolean[] mBlurApplied;
     private DistortedEffects[] mEffects;
@@ -92,14 +92,12 @@ class TransparencyRenderer implements GLSurfaceView.Renderer
 
       FragmentEffectAlpha[] alpha  = new FragmentEffectAlpha[NUM_OBJECTS];
 
-      mMove  = new Static3D(0,0,0);
       mScale = new Static3D(1.0f,1.0f,1.0f);
-      mCenter= new Static3D(0,0,0);
+      Static3D center= new Static3D(0,0,0);
 
-      MatrixEffectMove moveEffect        = new MatrixEffectMove(mMove);
       MatrixEffectScale scaleEffect      = new MatrixEffectScale(mScale);
-      MatrixEffectQuaternion quatEffect1 = new MatrixEffectQuaternion(mQuat1, mCenter);
-      MatrixEffectQuaternion quatEffect2 = new MatrixEffectQuaternion(mQuat2, mCenter);
+      MatrixEffectQuaternion quatEffect1 = new MatrixEffectQuaternion(mQuat1, center);
+      MatrixEffectQuaternion quatEffect2 = new MatrixEffectQuaternion(mQuat2, center);
 
 
       for(int i=0; i<NUM_OBJECTS; i++)
@@ -114,7 +112,6 @@ class TransparencyRenderer implements GLSurfaceView.Renderer
 
         mEffects[i].apply(mBlur[i]);
         mEffects[i].apply(alpha[i]);
-        mEffects[i].apply(moveEffect);
         mEffects[i].apply(scaleEffect);
         mEffects[i].apply(quatEffect1);
         mEffects[i].apply(quatEffect2);
@@ -194,7 +191,7 @@ class TransparencyRenderer implements GLSurfaceView.Renderer
       {
       for(int i=0; i<NUM_OBJECTS; i++)
         {
-        mTex[i].setColor(OBJECTS[NUM * i + 3]);
+        mTex[i].setColorARGB(OBJECTS[NUM * i + 3]);
         }
 
       PostprocessEffectBlur.enable();
@@ -219,8 +216,6 @@ class TransparencyRenderer implements GLSurfaceView.Renderer
 
       float factor = 0.65f*mScreenMin/OBJ_SIZE;
       mScale.set(factor,factor,factor);
-      mCenter.set((float)OBJ_SIZE/2, (float)OBJ_SIZE/2, 0 );
-      mMove.set( (width -factor*OBJ_SIZE)/2 ,(height-factor*OBJ_SIZE)/2 ,0);
 
       for(int i=0; i<NUM_OBJECTS; i++)
         {
diff --git a/src/main/java/org/distorted/examples/triblur/TriblurRenderer.java b/src/main/java/org/distorted/examples/triblur/TriblurRenderer.java
index 43047f1..0c49b5a 100644
--- a/src/main/java/org/distorted/examples/triblur/TriblurRenderer.java
+++ b/src/main/java/org/distorted/examples/triblur/TriblurRenderer.java
@@ -56,9 +56,9 @@ class TriblurRenderer implements GLSurfaceView.Renderer
 
     private static final int[] OBJECTS =
         {
-        -150, 0, 0,   255,   0,  0,  // x,y,z, R,G,B
+        -130, 0, 0,   255,   0,  0,  // x,y,z, R,G,B
            0, 0, 0,   255, 255,  0,  //
-        +150, 0, 0,     0, 255,  0,  //
+        +130, 0, 0,     0, 255,  0,  //
         };
 
     private static final int NUM_OBJECTS = OBJECTS.length/NUM;
@@ -72,7 +72,7 @@ class TriblurRenderer implements GLSurfaceView.Renderer
     private PostprocessEffectBlur[] mBlur;
     private PostprocessEffectGlow[] mGlow;
     private int[] mEffectStatus;
-    private Static3D mMove1, mMove2, mScale1, mScale2, mCenter;
+    private Static3D mScale1, mScale2;
 
     Static4D mQuat1, mQuat2;
     int mScreenMin;
@@ -105,18 +105,14 @@ class TriblurRenderer implements GLSurfaceView.Renderer
 
       DistortedEffects[] effects= new DistortedEffects[NUM_OBJECTS];
 
-      mMove1  = new Static3D(0,0,0);
-      mMove2  = new Static3D(0,0,0);
       mScale1 = new Static3D(1,1,1);
       mScale2 = new Static3D(1.5f,1.5f,1.5f);
-      mCenter = new Static3D(0,0,0);
+      Static3D center = new Static3D(0,0,0);
 
-      MatrixEffectMove moveEffect1 = new MatrixEffectMove(mMove1);
-      MatrixEffectMove moveEffect2 = new MatrixEffectMove(mMove2);
       MatrixEffectScale scaleEffect1 = new MatrixEffectScale(mScale1);
       MatrixEffectScale scaleEffect2 = new MatrixEffectScale(mScale2);
-      MatrixEffectQuaternion quatEffect1 = new MatrixEffectQuaternion(mQuat1, mCenter);
-      MatrixEffectQuaternion quatEffect2 = new MatrixEffectQuaternion(mQuat2, mCenter);
+      MatrixEffectQuaternion quatEffect1 = new MatrixEffectQuaternion(mQuat1, center);
+      MatrixEffectQuaternion quatEffect2 = new MatrixEffectQuaternion(mQuat2, center);
 
       for(int i=0; i<NUM_OBJECTS; i++)
         {
@@ -130,7 +126,6 @@ class TriblurRenderer implements GLSurfaceView.Renderer
 
         effects[i].apply(mBlur[i]);
         effects[i].apply(chroma[i]);
-        effects[i].apply( (i==0||i==NUM_OBJECTS-1) ?  moveEffect1 :  moveEffect2 );
         effects[i].apply( (i==0||i==NUM_OBJECTS-1) ? scaleEffect1 : scaleEffect2 );
         effects[i].apply(quatEffect1);
         effects[i].apply(quatEffect2);
@@ -220,9 +215,6 @@ class TriblurRenderer implements GLSurfaceView.Renderer
       float factor2 = 0.80f*factor1;
       mScale1.set(factor1,factor1,factor1);
       mScale2.set(factor2,factor2,factor2);
-      mCenter.set((float)OBJ_SIZE/2, (float)OBJ_SIZE/2, (float)OBJ_SIZE/2 );
-      mMove1.set( (width -factor1*OBJ_SIZE)/2 ,(height-factor1*OBJ_SIZE)/2 , -factor1*OBJ_SIZE);
-      mMove2.set( (width -factor2*OBJ_SIZE)/2 ,(height-factor2*OBJ_SIZE)/2 , -factor2*OBJ_SIZE);
       mScreen.resize(width, height);
       }
 
