commit 698ad0a80f31eba64924e8459645b69b4c4f1601
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Feb 26 22:23:45 2020 +0000

    Move the Effects.setStretch to Meshbase.setStretch

diff --git a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java
index efd4157..9cf9c38 100644
--- a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java
+++ b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java
@@ -68,7 +68,7 @@ class AroundTheWorldRenderer implements GLSurfaceView.Renderer
 
       mView = view;
       mManager = new AroundTheWorldEffectsManager();
-      mEffects = new DistortedEffects(1);
+      mEffects = new DistortedEffects();
       mEffects.apply(new MatrixEffectScale(mScale));
       mEffects.apply(new MatrixEffectMove(mMove));
 
@@ -136,12 +136,14 @@ class AroundTheWorldRenderer implements GLSurfaceView.Renderer
       mObjWidth = bitmap.getWidth();
       mObjHeight= bitmap.getHeight();
 
-      mEffects.setStretch(mObjWidth,mObjHeight,0);
-
       if( mTexture==null ) mTexture = new DistortedTexture();
       mTexture.setTexture(bitmap);
 
-      if( mMesh==null ) mMesh = new MeshRectangles(30,30*mObjHeight/mObjWidth);
+      if( mMesh==null )
+        {
+        mMesh = new MeshRectangles(30,30*mObjHeight/mObjWidth);
+        mMesh.setStretch(mObjWidth,mObjHeight,0);
+        }
 
       mScreen.detachAll();
       mScreen.attach(mTexture, mEffects, mMesh);
diff --git a/src/main/java/org/distorted/examples/bean/BeanRenderer.java b/src/main/java/org/distorted/examples/bean/BeanRenderer.java
index 38a9ec8..a228a2e 100644
--- a/src/main/java/org/distorted/examples/bean/BeanRenderer.java
+++ b/src/main/java/org/distorted/examples/bean/BeanRenderer.java
@@ -88,7 +88,7 @@ class BeanRenderer implements GLSurfaceView.Renderer
       mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
 
-      mEffects = new DistortedEffects(1);
+      mEffects = new DistortedEffects();
       mEffects.apply( new VertexEffectDistort(dynLeft , pointLeft , regionLeft) );
       mEffects.apply( new VertexEffectDistort(dynRight, pointRight, regionRight));
       mEffects.apply( new MatrixEffectScale(mScale) );
@@ -149,11 +149,13 @@ class BeanRenderer implements GLSurfaceView.Renderer
      mObjHeight = bitmap.getHeight();
      mObjWidth  = bitmap.getWidth();
 
-     mEffects.setStretch(mObjWidth,mObjHeight,0);
-
      if( mTexture==null ) mTexture = new DistortedTexture();
      mTexture.setTexture(bitmap);
-     if( mMesh==null ) mMesh = new MeshRectangles(25,25*mObjHeight/mObjWidth);
+     if( mMesh==null )
+       {
+       mMesh = new MeshRectangles(25,25*mObjHeight/mObjWidth);
+       mMesh.setStretch(mObjWidth,mObjHeight,0);
+       }
 
      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 8004958..25f4ef7 100644
--- a/src/main/java/org/distorted/examples/blur/BlurRenderer.java
+++ b/src/main/java/org/distorted/examples/blur/BlurRenderer.java
@@ -55,7 +55,7 @@ class BlurRenderer implements GLSurfaceView.Renderer
     private DistortedEffects mEffects, mBufferEffects;
     private DistortedScreen mScreen;
     private DistortedFramebuffer mBuffer;
-    private MeshRectangles mMesh;
+    private MeshRectangles mMesh, mMeshBuffer;
     private Static1D mRadiusSta;
     private int mObjHeight, mObjWidth;
     private Static3D mMove, mScale, mBufferMove, mBufferScale;
@@ -64,10 +64,11 @@ class BlurRenderer implements GLSurfaceView.Renderer
 
    BlurRenderer(GLSurfaceView v)
       {
-      mView   = v;
-      mMesh   = new MeshRectangles(1,1);
-      mScreen = new DistortedScreen();
-      mBuffer = new DistortedFramebuffer(SIZE,SIZE,1, DistortedFramebuffer.NO_DEPTH_NO_STENCIL);
+      mView       = v;
+      mMesh       = new MeshRectangles(1,1);
+      mMeshBuffer = new MeshRectangles(1,1);
+      mScreen     = new DistortedScreen();
+      mBuffer     = new DistortedFramebuffer(SIZE,SIZE,1, DistortedFramebuffer.NO_DEPTH_NO_STENCIL);
 
       mRadiusSta = new Static1D(5);
       Dynamic1D radiusDyn = new Dynamic1D();
@@ -78,11 +79,11 @@ class BlurRenderer implements GLSurfaceView.Renderer
       mBufferMove = new Static3D(0,0,0);
       mBufferScale= new Static3D(1,1,1);
 
-      mBufferEffects = new DistortedEffects(1);
+      mBufferEffects = new DistortedEffects();
       mBufferEffects.apply(new MatrixEffectScale(mBufferScale));
       mBufferEffects.apply(new MatrixEffectMove(mBufferMove));
 
-      mEffects = new DistortedEffects(1);
+      mEffects = new DistortedEffects();
       mEffects.apply( new PostprocessEffectBlur(radiusDyn) );
       mEffects.apply(new MatrixEffectScale(mScale));
       mEffects.apply(new MatrixEffectMove(mMove));
@@ -155,14 +156,14 @@ class BlurRenderer implements GLSurfaceView.Renderer
      mObjHeight = bitmap.getHeight();
      mObjWidth  = bitmap.getWidth();
 
-     mEffects.setStretch(mObjWidth,mObjHeight,0);
-     mBufferEffects.setStretch(SIZE,SIZE,0);
+     mMesh.setStretch(mObjWidth,mObjHeight,0);
+     mMeshBuffer.setStretch(SIZE,SIZE,0);
 
      if( mTexture==null ) mTexture = new DistortedTexture();
      mTexture.setTexture(bitmap);
 
      mScreen.detachAll();
-     mScreen.attach(mBuffer, mBufferEffects, mMesh);
+     mScreen.attach(mBuffer, mBufferEffects, mMeshBuffer);
      mBuffer.attach(new DistortedNode(mTexture,mEffects,mMesh));
 
      PostprocessEffectBlur.enable();
diff --git a/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java b/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java
index ec99405..88027f2 100644
--- a/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java
+++ b/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java
@@ -92,7 +92,7 @@ class CatAndDogRenderer implements GLSurfaceView.Renderer
       diRotate.add(new Static1D(  0));
       diRotate.add(new Static1D(360));
 
-      mEffects = new DistortedEffects(1);
+      mEffects = new DistortedEffects();
 
       mEffects.apply( new MatrixEffectRotate( diRotate, new Static3D(0,0,1), mRotate) );
       mEffects.apply( new MatrixEffectScale(diScale));
@@ -142,7 +142,7 @@ class CatAndDogRenderer implements GLSurfaceView.Renderer
       mObjWidth  = bitmap.getWidth();
       mRotate.set(mObjWidth/2,mObjHeight/2,0);
 
-      mEffects.setStretch(mObjWidth,mObjHeight,0);
+      mMesh.setStretch(mObjWidth,mObjHeight,0);
 
       if( mTexture==null ) mTexture = new DistortedTexture();
       mTexture.setTexture(bitmap);
diff --git a/src/main/java/org/distorted/examples/check/CheckRenderer.java b/src/main/java/org/distorted/examples/check/CheckRenderer.java
index f727e8e..de260ff 100644
--- a/src/main/java/org/distorted/examples/check/CheckRenderer.java
+++ b/src/main/java/org/distorted/examples/check/CheckRenderer.java
@@ -92,7 +92,7 @@ class CheckRenderer implements GLSurfaceView.Renderer
       mScale  = new Static3D(1,1,1);
       mCenter = new Static3D(0,0,0);
 
-      mEffects = new DistortedEffects(1);
+      mEffects = new DistortedEffects();
       mEffects.apply(new MatrixEffectScale(mScale));
       mEffects.apply(new MatrixEffectMove(mMove));
 
@@ -181,12 +181,14 @@ class CheckRenderer implements GLSurfaceView.Renderer
       mObjHeight = bitmap.getHeight();
       mObjWidth  = bitmap.getWidth();
 
-      mEffects.setStretch(mObjWidth,mObjHeight,0);
-
       if( mTexture==null ) mTexture = new DistortedTexture();
       mTexture.setTexture(bitmap);
 
-      if( mMesh==null ) mMesh = new MeshRectangles(30,30*mObjHeight/mObjWidth);
+      if( mMesh==null )
+        {
+        mMesh = new MeshRectangles(30,30*mObjHeight/mObjWidth);
+        mMesh.setStretch(mObjWidth,mObjHeight,0);
+        }
 
       mScreen.detachAll();
       mScreen.attach(mTexture,mEffects,mMesh);
diff --git a/src/main/java/org/distorted/examples/deform/DeformRenderer.java b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
index 1311c06..369029c 100644
--- a/src/main/java/org/distorted/examples/deform/DeformRenderer.java
+++ b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
@@ -81,7 +81,7 @@ class DeformRenderer implements GLSurfaceView.Renderer , EffectListener
       { 
       mView = view;
 
-      mEffects    = new DistortedEffects(1);
+      mEffects    = new DistortedEffects();
       mRegion     = new Static4D(0,0,0,0);
       mMove       = new Static3D(0,0,0);
       mTouchPoint = new Static3D(0,0,0);
@@ -192,8 +192,9 @@ class DeformRenderer implements GLSurfaceView.Renderer , EffectListener
      int h=height/2;
 
      if( mMesh!=null ) mMesh.markForDeletion();
-
      mMesh = new MeshRectangles(50,50*h/w);
+     mMesh.setStretch(w,h,0);
+
      Bitmap stretchBitmap = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
      stretchCanvas = new Canvas(stretchBitmap);
 
@@ -209,8 +210,6 @@ class DeformRenderer implements GLSurfaceView.Renderer , EffectListener
        stretchCanvas.drawRect(              0, h*i/NUM_LINES-1, w              , h*i/NUM_LINES+1, paint);
        }
 
-     mEffects.setStretch(w,h,0);
-
      if( mTexture==null ) mTexture = new DistortedTexture();
      mTexture.setTexture(stretchBitmap);
 
diff --git a/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java b/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java
index cd50484..d42b266 100644
--- a/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java
+++ b/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java
@@ -72,7 +72,7 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
       Static3D mPoint = new Static3D(305, 220, 0);
 
       mEffects = new DistortedEffects[NUM];
-      mEffects[0] = new DistortedEffects(1);
+      mEffects[0] = new DistortedEffects();
       for(int i=1; i<NUM; i++)
         mEffects[i] = new DistortedEffects(mEffects[0], DistortedLibrary.CLONE_VERTEX| DistortedLibrary.CLONE_FRAGMENT);
 
@@ -174,8 +174,6 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
      bmpHeight = bitmap0.getHeight();
      bmpWidth  = bitmap0.getWidth();
 
-     mEffects[0].setStretch(bmpWidth,bmpHeight,0);
-
      if( mTexture==null )
        {
        mTexture = new DistortedTexture[NUM];
@@ -188,7 +186,11 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
      mTexture[1].setTexture(bitmap1);
      mTexture[2].setTexture(bitmap2);
 
-     if( mMesh==null ) mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
+     if( mMesh==null )
+       {
+       mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
+       mMesh.setStretch(bmpWidth,bmpHeight,0);
+       }
 
      mScreen.detachAll();
      for(int i=NUM-1; i>=0; i--) mScreen.attach(mTexture[i], mEffects[i], mMesh);
diff --git a/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java b/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java
index 117b383..47f4400 100644
--- a/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java
+++ b/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java
@@ -83,7 +83,7 @@ class DifferentEffectsRenderer implements GLSurfaceView.Renderer
 
       mEffects = new DistortedEffects[NUM];
 
-      for(int i=0; i<NUM; i++) mEffects[i] = new DistortedEffects(1);
+      for(int i=0; i<NUM; i++) mEffects[i] = new DistortedEffects();
 
       Dynamic1D sink = new Dynamic1D(2000,0.0f);
       sink.add(new Static1D( 1));
@@ -173,12 +173,12 @@ class DifferentEffectsRenderer implements GLSurfaceView.Renderer
      bmpHeight = bitmap.getHeight();
      bmpWidth  = bitmap.getWidth();
 
-      for(int i=0; i<NUM; i++)
-        {
-        mEffects[i].setStretch(bmpWidth, bmpHeight, 0);
-        }
+     if( mMesh==null )
+       {
+       mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
+       mMesh.setStretch(bmpWidth, bmpHeight, 0);
+       }
 
-     if( mMesh==null ) mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
      if( mTexture==null ) mTexture  = new DistortedTexture();
      mTexture.setTexture(bitmap);
 
diff --git a/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java b/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java
index 2d60945..8bfc1bb 100644
--- a/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java
+++ b/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java
@@ -62,6 +62,7 @@ class DynamicRenderer implements GLSurfaceView.Renderer
      mView    = v;
      mMesh    = new MeshRectangles(1,1);
      mScreen  = new DistortedScreen();
+     mEffects = new DistortedEffects();
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -90,7 +91,7 @@ class DynamicRenderer implements GLSurfaceView.Renderer
 
      if( mTexture!=null ) mTexture.markForDeletion();
      mTexture= new DistortedTexture();
-     mEffects = new DistortedEffects(texW, texH, 0);
+     mMesh.setStretch(texW,texH,0);
      mBitmap = Bitmap.createBitmap(texW,texH, Bitmap.Config.ARGB_8888);
      mCanvas = new Canvas(mBitmap);
 
diff --git a/src/main/java/org/distorted/examples/earth/EarthRenderer.java b/src/main/java/org/distorted/examples/earth/EarthRenderer.java
index 3d74046..2f7cdc3 100644
--- a/src/main/java/org/distorted/examples/earth/EarthRenderer.java
+++ b/src/main/java/org/distorted/examples/earth/EarthRenderer.java
@@ -116,6 +116,7 @@ class EarthRenderer implements GLSurfaceView.Renderer
       scale.add(mScaleFactor);
 
       mMesh     = new MeshSphere(LEVEL);
+      mMesh.setStretch(SIZE,SIZE,SIZE);
       mTexture  = new DistortedTexture();
 
       mObjWidth = mObjHeight = mObjDepth = SIZE;
@@ -129,7 +130,7 @@ class EarthRenderer implements GLSurfaceView.Renderer
       quatInt1.add(mQuat1);
       quatInt2.add(mQuat2);
 
-      mEffects = new DistortedEffects(SIZE,SIZE,SIZE);
+      mEffects = new DistortedEffects();
       mEffects.apply( new MatrixEffectQuaternion(quatInt2, mCenter) );
       mEffects.apply( new MatrixEffectQuaternion(quatInt1, mCenter) );
       mEffects.apply( new MatrixEffectScale(scale));
diff --git a/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java b/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java
index 73debf9..0796a75 100644
--- a/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java
+++ b/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java
@@ -78,8 +78,10 @@ class EffectQueueRenderer implements GLSurfaceView.Renderer, EffectListener
     MatrixEffectScale scaleEffect = new MatrixEffectScale(mScale);
 
     mMesh = new MeshRectangles(MESH_QUALITY,MESH_QUALITY*texHeight/texWidth);
+    mMesh.setStretch(texWidth,texHeight,0);
+
     mTexture = new DistortedTexture();
-    mEffects = new DistortedEffects(texWidth,texHeight,0);
+    mEffects = new DistortedEffects();
     mEffects.apply(scaleEffect);
 
     mScreen = new DistortedScreen();
diff --git a/src/main/java/org/distorted/examples/flag/FlagRenderer.java b/src/main/java/org/distorted/examples/flag/FlagRenderer.java
index f93edc2..37fe00c 100644
--- a/src/main/java/org/distorted/examples/flag/FlagRenderer.java
+++ b/src/main/java/org/distorted/examples/flag/FlagRenderer.java
@@ -54,7 +54,7 @@ class FlagRenderer implements GLSurfaceView.Renderer
     private DistortedScreen mScreen;
     private Dynamic5D mWaveDyn;
     private Static5D mWaveSta1, mWaveSta2;
-    private int mObjWidth, mObjHeight;
+    private int mObjWidth, mObjHeight, mObjDepth;
     private Static3D mMove, mScale, mCenter;
 
     Static4D mQuat1, mQuat2;
@@ -73,13 +73,15 @@ class FlagRenderer implements GLSurfaceView.Renderer
       final Static4D mapLR = new Static4D(0.0f,0.0f,1.0f/GRIDX,1.0f      );
       final Static4D mapTB = new Static4D(0.0f,0.0f,1.0f      ,1.0f/GRIDY);
 
+      mObjWidth = 500;
+      mObjHeight= 300;
+      mObjDepth =   5;
+
       MeshCubes mesh = new MeshCubes(GRIDX,GRIDY,1, mapFB, mapFB, mapLR, mapLR, mapTB, mapTB);
+      mesh.setStretch(mObjWidth,mObjHeight,mObjDepth);
 
       mTexture = new DistortedTexture();
 
-      mObjWidth = 500;
-      mObjHeight= 300;
-
       mWaveDyn = new Dynamic5D(1000,0.0f);
       mWaveSta1= new Static5D(0,0,-180,0,0);  // all other values besides the
       mWaveSta2= new Static5D(0,0,+180,0,0);  // fourth will be set from the UI
@@ -91,10 +93,10 @@ class FlagRenderer implements GLSurfaceView.Renderer
       mQuat1 = new Static4D(           0,         0,           0,          1);  // unity quaternion
       mQuat2 = new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);  // something semi-random that looks good
 
-      Static3D waveCenter = new Static3D(mObjWidth, mObjHeight/2, 0);  // middle of the right edge
+      Static3D waveCenter = new Static3D(mObjWidth, mObjHeight/2, mObjDepth/2);  // middle of the right edge
       Static4D waveRegion = new Static4D(0,0,0,mObjWidth);
 
-      DistortedEffects effects = new DistortedEffects(mObjWidth,mObjHeight,1);
+      DistortedEffects effects = new DistortedEffects();
       effects.apply( new VertexEffectWave(mWaveDyn, waveCenter, waveRegion) );
 
       mMove  = new Static3D(0,0,0);
@@ -163,9 +165,9 @@ class FlagRenderer implements GLSurfaceView.Renderer
       {
       mScreenMin = width<height ? width:height;
       float factor = ( width*mObjHeight > height*mObjWidth ) ? (0.8f*height)/mObjHeight : (0.8f*width)/mObjWidth;
-      mMove.set((width-factor*mObjWidth)/2 , (height-factor*mObjHeight)/2 , 0);
+      mMove.set((width-factor*mObjWidth)/2 , (height-factor*mObjHeight)/2 , -factor*mObjDepth/2);
       mScale.set(factor,factor,factor);
-      mCenter.set(mObjWidth/2,mObjHeight/2, 0);
+      mCenter.set(mObjWidth/2,mObjHeight/2,mObjDepth/2);
       mScreen.resize(width, height);
       }
 
diff --git a/src/main/java/org/distorted/examples/generic/GenericActivity2.java b/src/main/java/org/distorted/examples/generic/GenericActivity2.java
index 4a0aa16..952a215 100644
--- a/src/main/java/org/distorted/examples/generic/GenericActivity2.java
+++ b/src/main/java/org/distorted/examples/generic/GenericActivity2.java
@@ -80,7 +80,7 @@ public class GenericActivity2 extends AppCompatActivity
     mShowNormal = false;
     mUseOIT     = false;
 
-    mEffects= new DistortedEffects(1);
+    mEffects= new DistortedEffects();
 
     int maxsize = numCols > numRows ? (numCols>numSlic ? numCols:numSlic) : (numRows>numSlic ? numRows:numSlic) ;
 
@@ -100,15 +100,16 @@ public class GenericActivity2 extends AppCompatActivity
 
                 mMesh = new MeshCubes(numCols, str, numSlic, mapFB, mapFB, mapLR, mapLR, mapTB, mapTB);
                 }
-              mEffects.setStretch(numCols,numRows,numSlic);
+              mMesh.setStretch(numCols,numRows,numSlic);
               break;
       case 1: mMesh = new MeshRectangles(numCols,numRows);
-              mEffects.setStretch(numCols,numRows,0);
+              mMesh.setStretch(numCols,numRows,0);
               break;
       case 2: mMesh = new MeshSphere(numRows);
-              mEffects.setStretch(numRows,numRows,numRows);
+              mMesh.setStretch(numRows,numRows,numRows);
               break;
       case 3: mMesh = new MeshQuad();
+              mMesh.setStretch(1,1,0);
               break;
       }
 
@@ -206,23 +207,23 @@ public class GenericActivity2 extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getWidth()
+  public float getWidth()
     {
-    return mEffects==null ? 0: mEffects.getStartchX();
+    return mMesh==null ? 0: mMesh.getStretchX();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getHeight()
+  public float getHeight()
     {
-    return mEffects==null ? 0: mEffects.getStartchY();
+    return mMesh==null ? 0: mMesh.getStretchY();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public int getDepth()
+  public float getDepth()
     {
-    return mEffects==null ? 0: mEffects.getStartchZ();
+    return mMesh==null ? 0: mMesh.getStretchZ();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/generic/GenericRenderer.java b/src/main/java/org/distorted/examples/generic/GenericRenderer.java
index 335f643..cca9b0b 100644
--- a/src/main/java/org/distorted/examples/generic/GenericRenderer.java
+++ b/src/main/java/org/distorted/examples/generic/GenericRenderer.java
@@ -35,7 +35,7 @@ import org.distorted.library.main.DistortedNode;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshBase;
-import org.distorted.library.mesh.MeshRectangles;
+import org.distorted.library.mesh.MeshQuad;
 import org.distorted.library.mesh.MeshSphere;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
@@ -55,10 +55,11 @@ class GenericRenderer implements GLSurfaceView.Renderer
 
     private GLSurfaceView mView;
     private DistortedTexture mObjectTexture, mBackgroundTexture, mCenterTexture, mRegionTexture;
-    private DistortedEffects mObjectEffects,mBackgroundEffects,mCenterEffects,mRegionEffects;
+    private DistortedEffects mObjectEffects;
     private DistortedScreen mScreen;
+    private MeshQuad mRegionQuad, mCenterQuad, mBackgroundQuad;
     private DistortedNode mCenterNode, mRegionNode;
-    private int mObjWidth, mObjHeight, mObjDepth;
+    private float mObjWidth, mObjHeight, mObjDepth;
     private Static3D mCenterPoint, mRegionPoint, mRegionScalePoint;
     private Static3D mRotateCen, mMoveObject, mScaleObject, mMoveCenter, mScaleCenter, mMoveRegion, mMoveBackground, mScaleBackground;
     private boolean mShowingCenter=false;
@@ -94,13 +95,15 @@ class GenericRenderer implements GLSurfaceView.Renderer
 
       mFactorObj = 1.0f;
 
-      mObjectEffects     = act.getEffects();
-      mBackgroundEffects = new DistortedEffects(1);
-      mCenterEffects     = new DistortedEffects(1);
-      mRegionEffects     = new DistortedEffects(1);
+      mObjectEffects   = act.getEffects();
+      DistortedEffects backgroundEffects = new DistortedEffects();
+      DistortedEffects centerEffects     = new DistortedEffects();
+      DistortedEffects regionEffects     = new DistortedEffects();
 
-      MeshBase mesh        = act.getMesh();
-      MeshRectangles quad  = new MeshRectangles(1,1);
+      MeshBase mesh   = act.getMesh();
+      mRegionQuad     = new MeshQuad();
+      mCenterQuad     = new MeshQuad();
+      mBackgroundQuad = new MeshQuad();
 
       mFactor = mesh instanceof MeshSphere ? 1.0f : 0.7f;
 
@@ -115,40 +118,40 @@ class GenericRenderer implements GLSurfaceView.Renderer
       mRegionPoint= new Static3D(0,0,0);
       mRegionScalePoint = new Static3D(0,0,0);
 
-      mCenterNode = new DistortedNode(mCenterTexture, mCenterEffects, quad);
-      mRegionNode = new DistortedNode(mRegionTexture, mRegionEffects, quad);
+      mCenterNode = new DistortedNode(mCenterTexture, centerEffects, mCenterQuad);
+      mRegionNode = new DistortedNode(mRegionTexture, regionEffects, mRegionQuad);
 
       mScreen = new DistortedScreen();
       mScreen.setProjection(FOV, NEAR);
-      mScreen.attach(mBackgroundTexture, mBackgroundEffects, quad );
-      mScreen.attach(mObjectTexture    , mObjectEffects    , mesh );
+      mScreen.attach(mBackgroundTexture, backgroundEffects, mBackgroundQuad );
+      mScreen.attach(mObjectTexture    , mObjectEffects   , mesh );
 
-      int regionSize = mRegionEffects.getStartchX();
+      float regionSize = mRegionQuad.getStretchX();
       mRotateCen = new Static3D(0 ,0, 0);
 
       MatrixEffectQuaternion quat1cen = new MatrixEffectQuaternion(mQuat1, mRotateCen);
       MatrixEffectQuaternion quat2cen = new MatrixEffectQuaternion(mQuat2, mRotateCen);
       MatrixEffectMove centerMove = new MatrixEffectMove(mCenterPoint);
 
-      mCenterEffects.apply( new MatrixEffectScale(mScaleCenter) );
-      mCenterEffects.apply( centerMove );
-      mCenterEffects.apply( new MatrixEffectMove(mMoveCenter) );
-      mCenterEffects.apply(quat2cen);
-      mCenterEffects.apply(quat1cen);
+      centerEffects.apply( new MatrixEffectScale(mScaleCenter) );
+      centerEffects.apply( centerMove );
+      centerEffects.apply( new MatrixEffectMove(mMoveCenter) );
+      centerEffects.apply(quat2cen);
+      centerEffects.apply(quat1cen);
 
-      mRegionEffects.apply( new MatrixEffectMove(new Static3D( -regionSize*0.5f , -regionSize*0.5f , 0)) );
-      mRegionEffects.apply( new MatrixEffectScale(mRegionScalePoint) );
-      mRegionEffects.apply( new MatrixEffectMove(mRegionPoint) );
-      mRegionEffects.apply( centerMove );
-      mRegionEffects.apply( new MatrixEffectMove(mMoveRegion) );
-      mRegionEffects.apply(quat2cen);
-      mRegionEffects.apply(quat1cen);
+      regionEffects.apply( new MatrixEffectMove(new Static3D( -regionSize*0.5f , -regionSize*0.5f , 0)) );
+      regionEffects.apply( new MatrixEffectScale(mRegionScalePoint) );
+      regionEffects.apply( new MatrixEffectMove(mRegionPoint) );
+      regionEffects.apply( centerMove );
+      regionEffects.apply( new MatrixEffectMove(mMoveRegion) );
+      regionEffects.apply(quat2cen);
+      regionEffects.apply(quat1cen);
 
       resetMatrixEffects();
 
       // quite tricky: move the background exactly to the FAR plane! (see InternalOutputSurface.setProjection() )
-      mBackgroundEffects.apply(new MatrixEffectScale(mScaleBackground) );
-      mBackgroundEffects.apply(new MatrixEffectMove(mMoveBackground) );
+      backgroundEffects.apply(new MatrixEffectScale(mScaleBackground) );
+      backgroundEffects.apply(new MatrixEffectMove(mMoveBackground) );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -216,7 +219,7 @@ class GenericRenderer implements GLSurfaceView.Renderer
 
     void setRegion(float x, float y, float z, float r)
       {
-      float factorReg = 2*mFactorObj*r/mRegionEffects.getStartchX();
+      float factorReg = 2*mFactorObj*r/mRegionQuad.getStretchX();
       mRegionPoint.set(mFactorObj*x,mFactorObj*y, mFactorObj*z);
       mRegionScalePoint.set(factorReg,factorReg,factorReg);
       }
@@ -243,7 +246,7 @@ class GenericRenderer implements GLSurfaceView.Renderer
       mScreenMin = width<height ? width:height;
 
       float factorCen;
-      int centerSize = mCenterEffects.getStartchX();
+      float centerSize = mCenterQuad.getStretchX();
 
       if( width*mObjHeight > height*mObjWidth ) // screen is more 'horizontal' than the Object
         {
@@ -267,7 +270,7 @@ class GenericRenderer implements GLSurfaceView.Renderer
       mScaleCenter.set(factorCen,factorCen,factorCen);
       mMoveRegion.set( (width -mFactorObj*mObjWidth )/2 ,(height-mFactorObj*mObjHeight)/2 , 12 );
 
-      int backgroundSize = mBackgroundEffects.getStartchX();
+      float backgroundSize = mBackgroundQuad.getStretchX();
       float factorBackX = ((float)width)/backgroundSize;
       float factorBackY = ((float)height)/backgroundSize;
 
diff --git a/src/main/java/org/distorted/examples/generic/GenericTab.java b/src/main/java/org/distorted/examples/generic/GenericTab.java
index 43612a5..365dc7d 100644
--- a/src/main/java/org/distorted/examples/generic/GenericTab.java
+++ b/src/main/java/org/distorted/examples/generic/GenericTab.java
@@ -20,6 +20,7 @@
 package org.distorted.examples.generic;
 
 import android.os.Bundle;
+import android.support.annotation.NonNull;
 import android.support.v4.app.Fragment;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -62,7 +63,7 @@ public class GenericTab extends Fragment implements AdapterView.OnItemSelectedLi
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   @Override
-  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+  public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
     {
     Bundle args = getArguments();
 
diff --git a/src/main/java/org/distorted/examples/girl/GirlRenderer.java b/src/main/java/org/distorted/examples/girl/GirlRenderer.java
index 85c0093..24922de 100644
--- a/src/main/java/org/distorted/examples/girl/GirlRenderer.java
+++ b/src/main/java/org/distorted/examples/girl/GirlRenderer.java
@@ -115,7 +115,7 @@ class GirlRenderer implements GLSurfaceView.Renderer
       diHips.add(dMiddle);
       diHips.add(dBegin);
 
-      mEffects = new DistortedEffects(1);
+      mEffects = new DistortedEffects();
 
       mEffects.apply( new VertexEffectSink   ( diSink, pLeft , sinkRegion) );
       mEffects.apply( new VertexEffectSink   ( diSink, pRight, sinkRegion) );
@@ -210,12 +210,14 @@ class GirlRenderer implements GLSurfaceView.Renderer
      bmpHeight = bitmap.getHeight();
      bmpWidth  = bitmap.getWidth();
 
-     mEffects.setStretch(bmpWidth,bmpHeight,0);
-
      if( mTexture==null ) mTexture = new DistortedTexture();
      mTexture.setTexture(bitmap);
 
-     if( mMesh==null ) mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
+     if( mMesh==null )
+       {
+       mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
+       mMesh.setStretch(bmpWidth,bmpHeight,0);
+       }
 
      mScreen.detachAll();
      mScreen.attach(mTexture,mEffects,mMesh);
diff --git a/src/main/java/org/distorted/examples/glow/GlowRenderer.java b/src/main/java/org/distorted/examples/glow/GlowRenderer.java
index 7656038..b3b3c5d 100644
--- a/src/main/java/org/distorted/examples/glow/GlowRenderer.java
+++ b/src/main/java/org/distorted/examples/glow/GlowRenderer.java
@@ -32,7 +32,7 @@ import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshRectangles;
+import org.distorted.library.mesh.MeshQuad;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
@@ -74,13 +74,16 @@ class GlowRenderer implements GLSurfaceView.Renderer
 
       mGlow  = new PostprocessEffectGlow(mRadius,mColor);
 
-      DistortedEffects effects = new DistortedEffects(mRootW,mRootH,0);
+      DistortedEffects effects = new DistortedEffects();
       effects.apply(new MatrixEffectScale(mScale));
       effects.apply(new MatrixEffectMove(mMove));
       effects.apply(mGlow);
 
+      MeshQuad quad = new MeshQuad();
+      quad.setStretch(mRootW,mRootH,0);
+
       mScreen = new DistortedScreen();
-      mScreen.attach(mLeaf, effects, new MeshRectangles(1,1) );
+      mScreen.attach(mLeaf, effects, quad );
       mScreen.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
       mScreen.showFPS();
       }
diff --git a/src/main/java/org/distorted/examples/inflate/InflateActivity2.java b/src/main/java/org/distorted/examples/inflate/InflateActivity2.java
index 543d295..aedf88a 100644
--- a/src/main/java/org/distorted/examples/inflate/InflateActivity2.java
+++ b/src/main/java/org/distorted/examples/inflate/InflateActivity2.java
@@ -122,12 +122,16 @@ public class InflateActivity2 extends Activity implements SeekBar.OnSeekBarChang
 
                   mMesh = new MeshCubes(mNumCols, str, mNumSlic, mapFB, mapFB, mapLR, mapLR, mapTB, mapTB);
                   }
+                mMesh.setStretch(mNumCols,mNumRows,mNumSlic);
                 break;
         case 1: mMesh = new MeshRectangles(mNumCols,mNumRows);
+                mMesh.setStretch(mNumCols,mNumRows,0);
                 break;
         case 2: mMesh = new MeshSphere(mNumRows);
+                mMesh.setStretch(mNumRows,mNumRows,mNumRows);
                 break;
         case 3: mMesh = new MeshQuad();
+                mMesh.setStretch(1,1,0);
                 break;
         }
 
diff --git a/src/main/java/org/distorted/examples/inflate/InflateRenderer.java b/src/main/java/org/distorted/examples/inflate/InflateRenderer.java
index 5b1eeba..326904d 100644
--- a/src/main/java/org/distorted/examples/inflate/InflateRenderer.java
+++ b/src/main/java/org/distorted/examples/inflate/InflateRenderer.java
@@ -50,7 +50,7 @@ class InflateRenderer implements GLSurfaceView.Renderer
     private DistortedEffects mEffects;
     private MeshBase mMesh;
     private DistortedScreen mScreen;
-    private int mObjWidth, mObjHeight, mObjDepth;
+    private float mObjWidth, mObjHeight, mObjDepth;
     private Static3D mMove, mScale, mCenter;
     private Static1D mAlpha;
 
@@ -74,9 +74,9 @@ class InflateRenderer implements GLSurfaceView.Renderer
       mTexture = act.getTexture();
       mMesh    = act.getMesh();
 
-      mObjWidth = act.getNumCols();
-      mObjHeight= act.getNumRows();
-      mObjDepth = act.getNumSlic();
+      mObjWidth = mMesh.getStretchX();
+      mObjHeight= mMesh.getStretchY();
+      mObjDepth = mMesh.getStretchZ();
 
       mQuat1 = new Static4D(0,0,0,1);  // unity
       mQuat2 = new Static4D(0,0,0,1);  // quaternions
@@ -87,7 +87,7 @@ class InflateRenderer implements GLSurfaceView.Renderer
       quatInt1.add(mQuat1);
       quatInt2.add(mQuat2);
 
-      mEffects = new DistortedEffects(mObjWidth,mObjHeight,mObjDepth);
+      mEffects = new DistortedEffects();
       mEffects.apply( new MatrixEffectQuaternion(quatInt2, mCenter) );
       mEffects.apply( new MatrixEffectQuaternion(quatInt1, mCenter) );
       mEffects.apply( new MatrixEffectScale(mScale));
diff --git a/src/main/java/org/distorted/examples/listener/ListenerRenderer.java b/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
index c033e37..089f463 100644
--- a/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
+++ b/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
@@ -163,11 +163,15 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
      if( mTexture==null ) mTexture = new DistortedTexture();
      mTexture.setTexture(bitmap);
 
-     if( mMesh==null ) mMesh = new MeshRectangles(50,50*bmpHeight/bmpWidth);
+     if( mMesh==null )
+       {
+       mMesh = new MeshRectangles(50,50*bmpHeight/bmpWidth);
+       mMesh.setStretch(bmpWidth,bmpHeight,0);
+       }
 
      if( mEffects==null )
        {
-       mEffects = new DistortedEffects(bmpWidth,bmpHeight,0);
+       mEffects = new DistortedEffects();
        mEffects.apply(new MatrixEffectScale(mScale));
        mEffects.apply(new MatrixEffectMove(mMove));
        }
diff --git a/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java b/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java
index 0c4afce..754b7fa 100644
--- a/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java
+++ b/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java
@@ -32,7 +32,7 @@ import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedFramebuffer;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedTexture;
-import org.distorted.library.mesh.MeshRectangles;
+import org.distorted.library.mesh.MeshQuad;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 
@@ -60,7 +60,7 @@ class MirrorRenderer implements GLSurfaceView.Renderer
    private DistortedTexture mTextureMirror, mTextureHead;
    private DistortedFramebuffer mOffScreen1, mOffScreen2;
    private DistortedScreen mScreen;
-   private MeshRectangles mQuad;
+   private MeshQuad mQuad1, mQuad2, mQuadMirror, mQuadHead;
    private Static3D mHeadPosition, mScaleMirror, mMoveOffscreen2, mScaleHead;
 
    private int mX;
@@ -72,14 +72,18 @@ class MirrorRenderer implements GLSurfaceView.Renderer
    MirrorRenderer(GLSurfaceView view)
       { 
       mView    = view;
-      mQuad    = new MeshRectangles(1,1);
       mScreen  = new DistortedScreen();
 
-      mEffectsMirror    = new DistortedEffects(1);
-      mEffectsHead      = new DistortedEffects(1);
-      mEffectsOffscreen1= new DistortedEffects(1);
-      mEffectsOffscreen2= new DistortedEffects(1);
-      mEffectsScreen    = new DistortedEffects(1);
+      mQuad1     = new MeshQuad();
+      mQuad2     = new MeshQuad();
+      mQuadMirror= new MeshQuad();
+      mQuadHead  = new MeshQuad();
+
+      mEffectsMirror    = new DistortedEffects();
+      mEffectsHead      = new DistortedEffects();
+      mEffectsOffscreen1= new DistortedEffects();
+      mEffectsOffscreen2= new DistortedEffects();
+      mEffectsScreen    = new DistortedEffects();
 
       mX = MirrorActivity.INIT_POSITION;
 
@@ -143,9 +147,8 @@ class MirrorRenderer implements GLSurfaceView.Renderer
         int offscreen2W = (int)(MIRROR_SCALE*mScreenW);
         int offscreen2H = (int)(MIRROR_SCALE*mScreenH);
 
-        mEffectsOffscreen1.setStretch(offscreen1W, offscreen1H, 0);
-        mEffectsOffscreen2.setStretch(offscreen2W, offscreen2H, 0);
-        mEffectsScreen.setStretch(offscreen1W, offscreen1H, 0);
+        mQuad1.setStretch(offscreen1W, offscreen1H, 0);
+        mQuad2.setStretch(offscreen2W, offscreen2H, 0);
 
         mOffScreen1 = new DistortedFramebuffer( offscreen1W, offscreen1H, 1, DistortedFramebuffer.NO_DEPTH_NO_STENCIL );
         mOffScreen2 = new DistortedFramebuffer( offscreen2W, offscreen2H, 1, DistortedFramebuffer.NO_DEPTH_NO_STENCIL );
@@ -158,13 +161,13 @@ class MirrorRenderer implements GLSurfaceView.Renderer
         mHeadPosition.set1( mScreenH*MIRROR_MARGIN*mMirrorW/mMirrorH );
         setPosition(mX);
 
-        mOffScreen1.attach( mTextureMirror, mEffectsMirror    , mQuad );
-        mOffScreen1.attach( mOffScreen2   , mEffectsOffscreen2, mQuad );
-        mOffScreen1.attach( mTextureHead  , mEffectsHead      , mQuad );
-        mOffScreen2.attach( mOffScreen1   , mEffectsOffscreen1, mQuad );
+        mOffScreen1.attach( mTextureMirror, mEffectsMirror    , mQuadMirror );
+        mOffScreen1.attach( mOffScreen2   , mEffectsOffscreen2, mQuad2      );
+        mOffScreen1.attach( mTextureHead  , mEffectsHead      , mQuadHead   );
+        mOffScreen2.attach( mOffScreen1   , mEffectsOffscreen1, mQuad1      );
 
         mScreen.detachAll();
-        mScreen.attach    ( mOffScreen1   , mEffectsScreen    , mQuad );
+        mScreen.attach    ( mOffScreen1   , mEffectsScreen    , mQuad1      );
         mScreen.resize(mScreenW,mScreenH);
         }
       }
@@ -198,8 +201,8 @@ class MirrorRenderer implements GLSurfaceView.Renderer
       mHeadW   = bitmapH.getWidth();
       mHeadH   = bitmapH.getHeight();
 
-      mEffectsMirror.setStretch(mMirrorW,mMirrorH,0);
-      mEffectsHead.setStretch(mHeadW, mHeadH,0);
+      mQuadMirror.setStretch(mMirrorW,mMirrorH,0);
+      mQuadHead.setStretch(mHeadW, mHeadH,0);
 
       if( mTextureMirror==null ) mTextureMirror = new DistortedTexture();
       if( mTextureHead  ==null ) mTextureHead   = new DistortedTexture();
diff --git a/src/main/java/org/distorted/examples/monalisa/MonaLisaRenderer.java b/src/main/java/org/distorted/examples/monalisa/MonaLisaRenderer.java
index 3a8241c..d4021ff 100644
--- a/src/main/java/org/distorted/examples/monalisa/MonaLisaRenderer.java
+++ b/src/main/java/org/distorted/examples/monalisa/MonaLisaRenderer.java
@@ -84,7 +84,7 @@ class MonaLisaRenderer implements GLSurfaceView.Renderer
       dRight.add( new Static3D(  0,  0, 0) );
       dRight.add( new Static3D( 20, 10, 0) );
 
-      mEffects = new DistortedEffects(1);
+      mEffects = new DistortedEffects();
       mEffects.apply( new VertexEffectDistort(dLeft , pLeft , rLeft ) );
       mEffects.apply( new VertexEffectDistort(dRight, pRight, rRight) );
 
@@ -150,6 +150,12 @@ class MonaLisaRenderer implements GLSurfaceView.Renderer
       bmpHeight = bitmap.getHeight();
       bmpWidth  = bitmap.getWidth();
 
+      // We could have gotten here after the activity went to the background
+      // for a brief amount of time; in this case mTexture is already created.
+      // Do not leak memory by creating it the second time around.
+      if( mTexture==null ) mTexture = new DistortedTexture();
+
+      // likewise the Mesh
       // This will make the Mesh stretched by bmpWidth x bmpHeight even before any effects
       // are applied to it (the Mesh - MeshRectangles - is flat, so the third parameter does not
       // not matter). bmpWight x bmpHeight is the size of the Bitmap, thus this means that we can
@@ -158,15 +164,11 @@ class MonaLisaRenderer implements GLSurfaceView.Renderer
       // around its center has to be centered at (bmpWidth/2, bmpHeight/2, 0).
       // Without this call, the default size of the Mesh is 1x1x0 ( or 1x1x1 in case of not-flat
       // Meshes) so we would need to be rotating around (0.5,0.5,0.0).
-      mEffects.setStretch(bmpWidth,bmpHeight,0);
-
-      // We could have gotten here after the activity went to the background
-      // for a brief amount of time; in this case mTexture is already created.
-      // Do not leak memory by creating it the second time around.
-      if( mTexture==null ) mTexture = new DistortedTexture();
-
-      // likewise the Mesh
-      if( mMesh==null ) mMesh = new MeshRectangles(9,9*bmpHeight/bmpWidth);
+      if( mMesh==null )
+        {
+        mMesh = new MeshRectangles(9,9*bmpHeight/bmpWidth);
+        mMesh.setStretch(bmpWidth,bmpHeight,0);
+        }
 
       // even if mTexture wasn't null, we still need to call setTexture() on it
       // because every time activity goes to background, its OpenGL resources
diff --git a/src/main/java/org/distorted/examples/movingeffects/MovingEffectsRenderer.java b/src/main/java/org/distorted/examples/movingeffects/MovingEffectsRenderer.java
index caaaf4a..ecc25db 100644
--- a/src/main/java/org/distorted/examples/movingeffects/MovingEffectsRenderer.java
+++ b/src/main/java/org/distorted/examples/movingeffects/MovingEffectsRenderer.java
@@ -65,7 +65,7 @@ class MovingEffectsRenderer implements GLSurfaceView.Renderer
      mPaint.setStyle(Style.FILL);
 
      mView   = v;
-     mEffects= new DistortedEffects(1);
+     mEffects= new DistortedEffects();
      mScreen = new DistortedScreen();
      mRefresh= true;
      }
@@ -141,10 +141,9 @@ class MovingEffectsRenderer implements GLSurfaceView.Renderer
      mBitmap  = Bitmap.createBitmap(texW,texH, Bitmap.Config.ARGB_8888);
      mCanvas  = new Canvas(mBitmap);
 
-     mEffects.setStretch(texW,texH,0);
-
      if( mMesh!=null ) mMesh.markForDeletion();
      mMesh = new MeshRectangles(80,80*texH/texW);
+     mMesh.setStretch(texW,texH,0);
 
      mScreen.detachAll();
      mScreen.attach(mTexture,mEffects,mMesh);
diff --git a/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java b/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java
index ccabca9..9987dcc 100644
--- a/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java
+++ b/src/main/java/org/distorted/examples/movingglow/MovingGlowRenderer.java
@@ -35,6 +35,7 @@ import org.distorted.library.main.DistortedNode;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshBase;
+import org.distorted.library.mesh.MeshQuad;
 import org.distorted.library.mesh.MeshRectangles;
 import org.distorted.library.message.EffectListener;
 import org.distorted.library.type.Dynamic1D;
@@ -78,10 +79,15 @@ class MovingGlowRenderer implements GLSurfaceView.Renderer,EffectListener
 
       mLeaf = new DistortedTexture();
       DistortedTexture surface = new DistortedTexture();
-      MeshBase mesh = new MeshRectangles(1,1);
 
-      DistortedNode root = new DistortedNode(surface, new DistortedEffects(mRootW,mRootH,0), mesh);
-     
+      MeshQuad rootMesh = new MeshQuad();
+      rootMesh.setStretch(mRootW,mRootH,0);
+      MeshQuad leafMesh = new MeshQuad();
+      leafMesh.setStretch(LEAF_SIZE,LEAF_SIZE,0);
+
+      DistortedEffects rootEffects = new DistortedEffects();
+      DistortedNode root = new DistortedNode(surface, rootEffects, rootMesh);
+
       Static3D moveVector = new Static3D(0.55f*LEAF_SIZE, (mRootH-LEAF_SIZE)/2, 0);
       Static1D chromaLevel= new Static1D(0.5f);
       Static3D center     = new Static3D(mRootW/2, mRootH/2, 0);
@@ -91,11 +97,11 @@ class MovingGlowRenderer implements GLSurfaceView.Renderer,EffectListener
 
       for(int j=0; j<NUM_LEAVES; j++)
         {
-        mLeafEffects[j] = new DistortedEffects(LEAF_SIZE,LEAF_SIZE,0);
+        mLeafEffects[j] = new DistortedEffects();
         mLeafEffects[j].apply(leafMove);
         mLeafEffects[j].apply( new MatrixEffectRotate(new Static1D(j*(360/NUM_LEAVES)), axis, center) );
         mLeafEffects[j].apply( new FragmentEffectChroma(chromaLevel, new Static3D(colors[3*j],colors[3*j+1], colors[3*j+2])) );
-        DistortedNode node = new DistortedNode( mLeaf, mLeafEffects[j], mesh);
+        DistortedNode node = new DistortedNode( mLeaf, mLeafEffects[j], leafMesh);
         root.attach(node);
         }
 
diff --git a/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java b/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java
index 51dbaab..19e5f6f 100644
--- a/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java
+++ b/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java
@@ -94,13 +94,14 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
       for(int i=0; i<NUM_OBJECTS; i++)
         {
         mMoveVector[i] = new Static3D(0,0,0);
-        effects[i]     = new DistortedEffects(OBJ_SIZE,OBJ_SIZE,OBJ_SIZE);
+        effects[i]     = new DistortedEffects();
         mBlurStatus[i] = false;
         }
 
       mBlurVector = new Static1D(10);
 
       MeshCubes mesh = new MeshCubes(1,1,1);
+      mesh.setStretch(OBJ_SIZE,OBJ_SIZE,OBJ_SIZE);
 
       mTex1 = new DistortedTexture();
       mTex2 = new DistortedTexture();
diff --git a/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java b/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java
index c0146ed..e92ef49 100644
--- a/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java
+++ b/src/main/java/org/distorted/examples/objecttree/ObjectTreeRenderer.java
@@ -78,7 +78,7 @@ class ObjectTreeRenderer implements GLSurfaceView.Renderer
       chromaDyn.add(new Static1D(0.0f));
       chromaDyn.add(new Static1D(0.8f));
 
-      mEffects= new DistortedEffects(1);
+      mEffects= new DistortedEffects();
       mEffects.apply(new MatrixEffectScale(mScale));
       mEffects.apply(new MatrixEffectMove(mMove));
       mEffects.apply(new FragmentEffectChroma(chromaDyn, new Static3D(0,0,1)));
@@ -181,17 +181,24 @@ class ObjectTreeRenderer implements GLSurfaceView.Renderer
       int gridHeight= bitmap2.getHeight();
       int gridDepth = gridWidth/GRID;
 
-      mEffects.setStretch(lisaWidth,lisaHeight,0);
-
       if( mLisaTexture==null ) mLisaTexture = new DistortedTexture();
       if( mGridTexture==null ) mGridTexture = new DistortedTexture();
       mLisaTexture.setTexture(bitmap1);
       mGridTexture.setTexture(bitmap2);
 
-      DistortedEffects gridEffects = new DistortedEffects(gridWidth,gridHeight,gridDepth);
+      DistortedEffects gridEffects = new DistortedEffects();
+
+      if( mMeshRectangles ==null )
+        {
+        mMeshRectangles = new MeshRectangles(1,1);
+        mMeshRectangles.setStretch(lisaWidth,lisaHeight,0);
+        }
 
-      if( mMeshRectangles ==null ) mMeshRectangles = new MeshRectangles(1,1);
-      if( mMeshCubes==null) mMeshCubes= new MeshCubes(GRID,GRID,1, mapFB, mapFB, mapLR, mapLR, mapTB, mapTB);
+      if( mMeshCubes==null)
+        {
+        mMeshCubes= new MeshCubes(GRID,GRID,1, mapFB, mapFB, mapLR, mapLR, mapTB, mapTB);
+        mMeshCubes.setStretch(gridWidth,gridHeight,gridDepth);
+        }
 
       mRoot = new DistortedNode(mLisaTexture, mEffects, mMeshRectangles);
       mRoot.attach(mGridTexture,gridEffects,mMeshCubes);
diff --git a/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java b/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java
index 6675f14..f4d1b8b 100644
--- a/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java
+++ b/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java
@@ -35,7 +35,7 @@ import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedNode;
-import org.distorted.library.mesh.MeshRectangles;
+import org.distorted.library.mesh.MeshQuad;
 import org.distorted.library.type.Dynamic1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static1D;
@@ -57,7 +57,7 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
    private DistortedNode mRoot;
    private DistortedTexture mLeaf;
    private DistortedScreen mScreen;
-   private MeshRectangles mMesh;
+   private MeshQuad mLeafMesh;
    private int mScreenW, mScreenH;
    private int mPrevRendered, mCurrRendered;
    private Static3D mMove, mScale;
@@ -78,7 +78,7 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
          }
        else if( number>0 && number<=NUM_LEAVES )
          {
-         if( checked ) mCircleNode[color].attach( mLeaf, mEffects[number-1], mMesh);
+         if( checked ) mCircleNode[color].attach( mLeaf, mEffects[number-1], mLeafMesh);
          else          mCircleNode[color].detach(mEffects[number-1]);
          }
        }
@@ -98,15 +98,22 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
 
       mLeaf = new DistortedTexture();
       DistortedTexture surface = new DistortedTexture();
-      mMesh = new MeshRectangles(1,1);
+
+      mLeafMesh = new MeshQuad();
+      mLeafMesh.setStretch(LEAF_SIZE,LEAF_SIZE,0);
+      MeshQuad circleMesh = new MeshQuad();
+      circleMesh.setStretch(3*LEAF_SIZE,3*LEAF_SIZE,0);
+      MeshQuad rootMesh = new MeshQuad();
+      rootMesh.setStretch(mScreenW,mScreenH,0);
+
       mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
 
-      DistortedEffects rootEffects = new DistortedEffects(mScreenW,mScreenH,0);
+      DistortedEffects rootEffects = new DistortedEffects();
       rootEffects.apply(new MatrixEffectScale(mScale));
       rootEffects.apply(new MatrixEffectMove(mMove));
 
-      mRoot = new DistortedNode(new DistortedTexture(), rootEffects, mMesh);
+      mRoot = new DistortedNode(new DistortedTexture(), rootEffects, rootMesh);
      
       Dynamic1D rot = new Dynamic1D(5000,0.0f);
       rot.setMode(Dynamic1D.MODE_JUMP);
@@ -122,22 +129,22 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
 
       for(int j=0; j<NUM_LEAVES; j++)
         {
-        mEffects[j] = new DistortedEffects(LEAF_SIZE,LEAF_SIZE,0);
+        mEffects[j] = new DistortedEffects();
         mEffects[j].apply(new MatrixEffectMove(moveVector));
         mEffects[j].apply( new MatrixEffectRotate(new Static1D(j*(360/NUM_LEAVES)), axis, center) );
         }
 
       for(int i=0; i<NUM_CIRCLES; i++)
         {
-        DistortedEffects effects = new DistortedEffects(3*LEAF_SIZE,3*LEAF_SIZE,0);
+        DistortedEffects effects = new DistortedEffects();
         effects.apply( new MatrixEffectRotate(rot, axis, center) );
         effects.apply( new MatrixEffectMove(new Static3D(positions[2*i], positions[2*i+1], 0)) );
         effects.apply( new FragmentEffectChroma(new Static1D(0.5f), new Static3D(colors[3*i],colors[3*i+1], colors[3*i+2])) );
 
-        mCircleNode[i] = new DistortedNode( surface, effects, mMesh);
+        mCircleNode[i] = new DistortedNode( surface, effects, circleMesh);
         mRoot.attach(mCircleNode[i]);
 
-        for(int j=0; j<NUM_LEAVES; j++) mCircleNode[i].attach(mLeaf, mEffects[j], mMesh);
+        for(int j=0; j<NUM_LEAVES; j++) mCircleNode[i].attach(mLeaf, mEffects[j], mLeafMesh);
         }
 
       mScreen = new DistortedScreen();
diff --git a/src/main/java/org/distorted/examples/plainmonalisa/RenderThread.java b/src/main/java/org/distorted/examples/plainmonalisa/RenderThread.java
index d7e35dc..0616347 100644
--- a/src/main/java/org/distorted/examples/plainmonalisa/RenderThread.java
+++ b/src/main/java/org/distorted/examples/plainmonalisa/RenderThread.java
@@ -95,7 +95,7 @@ class RenderThread extends Thread
     dRight.add( new Static3D(  0,  0, 0) );
     dRight.add( new Static3D( 20, 10, 0) );
 
-    mEffects = new DistortedEffects(1);
+    mEffects = new DistortedEffects();
     mEffects.apply( new VertexEffectDistort(dLeft , pLeft , rLeft ) );
     mEffects.apply( new VertexEffectDistort(dRight, pRight, rRight) );
 
@@ -262,12 +262,14 @@ class RenderThread extends Thread
     bmpHeight = bmp.getHeight();
     bmpWidth  = bmp.getWidth();
 
-    mEffects.setStretch(bmpWidth,bmpHeight,0);
-
     if( mTexture==null ) mTexture = new DistortedTexture();
     mTexture.setTexture(bmp);
 
-    if( mMesh==null ) mMesh = new MeshRectangles(9,9*bmpHeight/bmpWidth);
+    if( mMesh==null )
+      {
+      mMesh = new MeshRectangles(9,9*bmpHeight/bmpWidth);
+      mMesh.setStretch(bmpWidth,bmpHeight,0);
+      }
 
     mScreen.detachAll();
     mScreen.attach(mTexture,mEffects,mMesh);
diff --git a/src/main/java/org/distorted/examples/postprocesstree/PostprocessTreeRenderer.java b/src/main/java/org/distorted/examples/postprocesstree/PostprocessTreeRenderer.java
index 061dca4..8e5c621 100644
--- a/src/main/java/org/distorted/examples/postprocesstree/PostprocessTreeRenderer.java
+++ b/src/main/java/org/distorted/examples/postprocesstree/PostprocessTreeRenderer.java
@@ -34,6 +34,7 @@ import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedNode;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.main.DistortedTexture;
+import org.distorted.library.mesh.MeshQuad;
 import org.distorted.library.mesh.MeshRectangles;
 import org.distorted.library.type.Dynamic1D;
 import org.distorted.library.type.Static1D;
@@ -78,16 +79,22 @@ class PostprocessTreeRenderer implements GLSurfaceView.Renderer
 
       mLeaf = new DistortedTexture();
 
-      MeshRectangles mesh = new MeshRectangles(1,1);
+      MeshQuad rootMesh  = new MeshQuad();
+      rootMesh.setStretch(mScreenW,mScreenH,0);
+      MeshQuad innerMesh = new MeshQuad();
+      innerMesh.setStretch(INNER*LEAF_SIZE,INNER*LEAF_SIZE,0);
+      MeshQuad leafMesh  = new MeshQuad();
+      leafMesh.setStretch(LEAF_SIZE,LEAF_SIZE,0);
+
       mMove = new Static3D(0,0,0);
       mScale= new Static3D(1,1,1);
 
-      DistortedEffects rootEffects  = new DistortedEffects(mScreenW,mScreenH,0);
-      DistortedEffects innerEffects = new DistortedEffects(INNER*LEAF_SIZE,INNER*LEAF_SIZE,0);
+      DistortedEffects rootEffects  = new DistortedEffects();
+      DistortedEffects innerEffects = new DistortedEffects();
       DistortedEffects[] innerLeafEffects= new DistortedEffects[NUM_LEAVES];
       DistortedEffects[] outerLeafEffects= new DistortedEffects[NUM_LEAVES];
 
-      DistortedNode root = new DistortedNode(new DistortedTexture(), rootEffects, mesh);
+      DistortedNode root = new DistortedNode(new DistortedTexture(), rootEffects, rootMesh);
 
       rootEffects.apply(new MatrixEffectScale(mScale));
       rootEffects.apply(new MatrixEffectMove(mMove));
@@ -107,11 +114,11 @@ class PostprocessTreeRenderer implements GLSurfaceView.Renderer
 
       for(int j=0; j<NUM_LEAVES; j++)
         {
-        outerLeafEffects[j] = new DistortedEffects(LEAF_SIZE,LEAF_SIZE,0);
+        outerLeafEffects[j] = new DistortedEffects();
         outerLeafEffects[j].apply(new MatrixEffectMove(outerMoveVector));
         outerLeafEffects[j].apply( new MatrixEffectRotate(new Static1D(j*(360/NUM_LEAVES)), axis, outerCenter) );
 
-        root.attach(mLeaf, outerLeafEffects[j], mesh);
+        root.attach(mLeaf, outerLeafEffects[j], leafMesh);
         }
 
       innerEffects.apply( new MatrixEffectRotate(rotate, axis, innerCenter) );
@@ -119,16 +126,16 @@ class PostprocessTreeRenderer implements GLSurfaceView.Renderer
       innerEffects.apply( new FragmentEffectChroma(new Static1D(0.5f), new Static3D(1,0,0) ) );
       innerEffects.apply(blurEffect);
 
-      DistortedNode innerNode = new DistortedNode( new DistortedTexture(), innerEffects, mesh);
+      DistortedNode innerNode = new DistortedNode( new DistortedTexture(), innerEffects, innerMesh);
       root.attach(innerNode);
 
       for(int j=0; j<NUM_LEAVES; j++)
         {
-        innerLeafEffects[j] = new DistortedEffects(LEAF_SIZE,LEAF_SIZE,0);
+        innerLeafEffects[j] = new DistortedEffects();
         innerLeafEffects[j].apply(new MatrixEffectMove(innerMoveVector));
         innerLeafEffects[j].apply( new MatrixEffectRotate(new Static1D(j*(360/NUM_LEAVES)), axis, innerCenter) );
 
-        innerNode.attach( mLeaf, innerLeafEffects[j], mesh );
+        innerNode.attach( mLeaf, innerLeafEffects[j], leafMesh );
         }
 
       mScreen = new DistortedScreen();
diff --git a/src/main/java/org/distorted/examples/projection/ProjectionRenderer.java b/src/main/java/org/distorted/examples/projection/ProjectionRenderer.java
index c11d72d..8eed135 100644
--- a/src/main/java/org/distorted/examples/projection/ProjectionRenderer.java
+++ b/src/main/java/org/distorted/examples/projection/ProjectionRenderer.java
@@ -56,7 +56,7 @@ class ProjectionRenderer implements GLSurfaceView.Renderer
    ProjectionRenderer(GLSurfaceView view)
       { 
       mView   = view;
-      mEffects= new DistortedEffects(1);
+      mEffects= new DistortedEffects();
       mScreen = new DistortedScreen();
 
       mVector = new Static3D(0,0,0);
@@ -130,8 +130,6 @@ class ProjectionRenderer implements GLSurfaceView.Renderer
       mPoint3.set(  width/4, 3*height/4, 0);
       mPoint4.set(3*width/4, 3*height/4, 0);
 
-      mEffects.setStretch(width,height,0);
-
       // Avoid memory leaks: delete old texture if it exists (it might if we
       // got here after a brief amount of time spent in the background)
       if( mTexture!=null ) mTexture.markForDeletion();
@@ -140,9 +138,9 @@ class ProjectionRenderer implements GLSurfaceView.Renderer
       mTexture.setTexture(bmp);
 
       // likewise with the Mesh
-      if( mMesh!=null ) mMesh.markForDeletion();
-
+      if( mMesh!=null )  mMesh.markForDeletion();
       mMesh = new MeshRectangles(100,100*height/width);
+      mMesh.setStretch(width,height,0);
 
       mScreen.detachAll();
       mScreen.attach(mTexture,mEffects,mMesh);
diff --git a/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java b/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
index 0c94f0e..cd13379 100644
--- a/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
+++ b/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
@@ -63,7 +63,7 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
     mView    = v;
     mTexture = new DistortedTexture();
 
-    DistortedEffects effects = new DistortedEffects(1);
+    DistortedEffects effects = new DistortedEffects();
     DynamicQuat rot = new DynamicQuat();
 
     Random rnd = new Random(System.currentTimeMillis());
diff --git a/src/main/java/org/distorted/examples/rubik/RubikCube.java b/src/main/java/org/distorted/examples/rubik/RubikCube.java
index 26de816..248d114 100644
--- a/src/main/java/org/distorted/examples/rubik/RubikCube.java
+++ b/src/main/java/org/distorted/examples/rubik/RubikCube.java
@@ -130,6 +130,8 @@ class RubikCube
               tmpBottom= (y==       0 ? mapBottom:mapBlack);
 
               mCubes[x][y][z]           = new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom);
+              mCubes[x][y][z].setStretch(STRETCH_SIZE,STRETCH_SIZE,STRETCH_SIZE);
+
               cubeVectors[x][y][z]      = new Static3D( STRETCH_SIZE*(x-nc), STRETCH_SIZE*(y-nc), STRETCH_SIZE*(z-nc) );
               mRotationAngle[x][y][z]   = new Dynamic1D();
               mRotationAxis[x][y][z]    = new Static3D(1,0,0);
@@ -138,7 +140,7 @@ class RubikCube
               mRotationAngle[x][y][z].add(new Static1D(0.0f));
               mRotate[x][y][z] = new MatrixEffectRotate( mRotationAngle[x][y][z], mRotationAxis[x][y][z], center);
 
-              mEffects[x][y][z] = new DistortedEffects(STRETCH_SIZE,STRETCH_SIZE,STRETCH_SIZE);
+              mEffects[x][y][z] = new DistortedEffects();
               mEffects[x][y][z].apply( new MatrixEffectMove(cubeVectors[x][y][z]) );
               mEffects[x][y][z].apply( mRotate[x][y][z] );
               mEffects[x][y][z].apply(quatEffect);
diff --git a/src/main/java/org/distorted/examples/save/SaveRenderer.java b/src/main/java/org/distorted/examples/save/SaveRenderer.java
index 3022176..c304591 100644
--- a/src/main/java/org/distorted/examples/save/SaveRenderer.java
+++ b/src/main/java/org/distorted/examples/save/SaveRenderer.java
@@ -93,7 +93,7 @@ class SaveRenderer implements GLSurfaceView.Renderer
     mMove = new Static3D(0,0,0);
     mScaleMain = new Static3D(1,1,1);
 
-    mEffects = new DistortedEffects(1);
+    mEffects = new DistortedEffects();
     mEffects.apply( new VertexEffectSink(diSink, pLeft , sinkRegion) );
     mEffects.apply( new VertexEffectSink(diSink, pRight, sinkRegion) );
     mEffects.apply( new MatrixEffectScale(mScaleMain));
@@ -245,9 +245,11 @@ class SaveRenderer implements GLSurfaceView.Renderer
     bmpHeight = bitmap.getHeight();
     bmpWidth  = bitmap.getWidth();
 
-    mEffects.setStretch(bmpWidth,bmpHeight,0);
-
-    if( mMesh==null ) mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
+    if( mMesh==null )
+      {
+      mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
+      mMesh.setStretch(bmpWidth,bmpHeight,0);
+      }
     if( mTexture==null ) mTexture = new DistortedTexture();
     mTexture.setTexture(bitmap);
 
diff --git a/src/main/java/org/distorted/examples/sink/SinkRenderer.java b/src/main/java/org/distorted/examples/sink/SinkRenderer.java
index 3ea1c3e..3ab5b88 100644
--- a/src/main/java/org/distorted/examples/sink/SinkRenderer.java
+++ b/src/main/java/org/distorted/examples/sink/SinkRenderer.java
@@ -65,7 +65,7 @@ class SinkRenderer implements GLSurfaceView.Renderer
     sink.add(new Static1D(1.0f));
     sink.add(new Static1D(0.2f));
 
-    mEffects = new DistortedEffects(1);
+    mEffects = new DistortedEffects();
     VertexEffectSink sinkEffect = new VertexEffectSink(sink, new Static3D(297, 280, 0), null);
     mEffects.apply(sinkEffect);
 
@@ -129,11 +129,14 @@ class SinkRenderer implements GLSurfaceView.Renderer
     bmpHeight = bitmap.getHeight();
     bmpWidth  = bitmap.getWidth();
 
-    mEffects.setStretch(bmpWidth,bmpHeight,0);
-
     if( mTexture==null ) mTexture = new DistortedTexture();
     mTexture.setTexture(bitmap);
-    if( mMesh==null ) mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
+    if( mMesh==null )
+      {
+      mMesh = new MeshRectangles(30,30*bmpHeight/bmpWidth);
+      mMesh.setStretch(bmpWidth,bmpHeight,0);
+      }
+
 
     mScreen.detachAll();
     mScreen.attach(mTexture,mEffects,mMesh);
diff --git a/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java b/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
index e4bb8fb..dccab64 100644
--- a/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
+++ b/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
@@ -34,7 +34,7 @@ import org.distorted.library.effect.MatrixEffectRotate;
 import org.distorted.library.effect.MatrixEffectScale;
 import org.distorted.library.main.DistortedNode;
 import org.distorted.library.main.DistortedScreen;
-import org.distorted.library.mesh.MeshRectangles;
+import org.distorted.library.mesh.MeshQuad;
 import org.distorted.library.type.Dynamic1D;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Static1D;
@@ -110,7 +110,7 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
   private DistortedEffects[] mStarEffects;
   private DistortedNode mBackground;
   private DistortedScreen mScreen;
-  private MeshRectangles mQuad;
+  private MeshQuad mGFFAQuad, mCrawlQuad, mCrawlBackgroundQuad, mLogoQuad, mStarQuad;
 
   private long alphaEffectID, scaleEffectID, moveEffectID;
   private Random mRnd = new Random(0);
@@ -122,17 +122,24 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
     {
     mView = v;
 
-    mQuad = new MeshRectangles(1,1);
+    mGFFAQuad            = new MeshQuad();
+    mStarQuad            = new MeshQuad();
+    mCrawlQuad           = new MeshQuad();
+    mCrawlBackgroundQuad = new MeshQuad();
+    mLogoQuad            = new MeshQuad();
 
-    mGFFAEffects            = new DistortedEffects(1);
-    mLogoEffects            = new DistortedEffects(1);
-    mCrawlEffects           = new DistortedEffects(1);
-    mCrawlBackgroundEffects = new DistortedEffects(1);
+    mGFFAQuad.setStretch(GFFA_WIDTH,GFFA_HEIGHT,0);
+    mCrawlQuad.setStretch(CRAWL_WIDTH,CRAWL_HEIGHT,0);
+
+    mGFFAEffects            = new DistortedEffects();
+    mLogoEffects            = new DistortedEffects();
+    mCrawlEffects           = new DistortedEffects();
+    mCrawlBackgroundEffects = new DistortedEffects();
 
     if( NUM_STARS>0 )
       {
       mStarEffects = new DistortedEffects[NUM_STARS];
-      mStarEffects[0] = new DistortedEffects(1);
+      mStarEffects[0] = new DistortedEffects();
 
       for (int i = 1; i < NUM_STARS; i++)
         mStarEffects[i] = new DistortedEffects(mStarEffects[0], DistortedLibrary.CLONE_VERTEX);
@@ -207,7 +214,7 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
     if( mCrawlBackgroundTexture!=null ) mCrawlBackgroundTexture.markForDeletion();
     mCrawlBackgroundTexture = new DistortedTexture();
 
-    mCrawlBackgroundEffects.setStretch(w,(int)(h*Math.sin(angleA)/Math.sin(angleB)),0);
+    mCrawlBackgroundQuad.setStretch(w,(int)(h*Math.sin(angleA)/Math.sin(angleB)),0);
 
     int randomA, randomX, randomY, randomTime;
     float randomS, randomAlpha1, randomAlpha2;
@@ -237,10 +244,10 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
       
       mStarEffects[i].apply( new FragmentEffectAlpha(di) );
       
-      mScreen.attach(mStarTexture, mStarEffects[i], mQuad);
+      mScreen.attach(mStarTexture, mStarEffects[i], mStarQuad);
       }
       
-    float scale = (0.5f*w/mGFFAEffects.getStartchX());
+    float scale = (0.5f*w/mGFFAQuad.getStretchX());
     
     Dynamic1D di = new Dynamic1D(6000,0.5f);
     di.add(new Static1D(1.0f));
@@ -255,7 +262,7 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
     mGFFAEffects.apply( new MatrixEffectMove(new Static3D(w/5,2*h/3,0)) );
     mGFFAEffects.apply( alpha );
       
-    mScreen.attach(mGFFATexture, mGFFAEffects, mQuad);
+    mScreen.attach(mGFFATexture, mGFFAEffects, mGFFAQuad);
     }
     
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -292,7 +299,6 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
     paint.setTypeface(tf);     
  
     ///// create GFFA ///////////////////
-    mGFFAEffects.setStretch(GFFA_WIDTH,GFFA_HEIGHT,0);
     if( mGFFATexture==null ) mGFFATexture  = new DistortedTexture();
     bitmapGFFA = Bitmap.createBitmap(GFFA_WIDTH,GFFA_HEIGHT,Bitmap.Config.ARGB_8888);
     bitmapGFFA.eraseColor(0x00000000);
@@ -306,12 +312,11 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
     mGFFATexture.setTexture(bitmapGFFA);
       
     ///// create Logo ///////////////////
-    mLogoEffects.setStretch(bitmapLogo.getWidth(),bitmapLogo.getHeight(),0);
+    mLogoQuad.setStretch(bitmapLogo.getWidth(),bitmapLogo.getHeight(),0);
     if( mLogoTexture==null ) mLogoTexture  = new DistortedTexture();
     mLogoTexture.setTexture(bitmapLogo);
 
     ///// create CRAWL //////////////////
-    mCrawlEffects.setStretch(CRAWL_WIDTH,CRAWL_HEIGHT,0);
     if( mCrawlTexture==null ) mCrawlTexture = new DistortedTexture();
     bitmapText = Bitmap.createBitmap(CRAWL_WIDTH,CRAWL_HEIGHT,Bitmap.Config.ARGB_8888);
     bitmapText.eraseColor(0x00000000);
@@ -326,7 +331,7 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
     mCrawlTexture.setTexture(bitmapText);
       
     ///// create Stars ///////////////////
-    mStarEffects[0].setStretch(bitmapStar.getWidth(),bitmapStar.getHeight(),0);
+    mStarQuad.setStretch(bitmapStar.getWidth(),bitmapStar.getHeight(),0);
     if( mStarTexture==null ) mStarTexture = new DistortedTexture();
     mStarTexture.setTexture(bitmapStar);
     }
@@ -385,8 +390,8 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
       int screenW=mScreen.getWidth();
       int screenH=mScreen.getHeight();
         
-      int logoW = mLogoEffects.getStartchX();
-      int logoH = mLogoEffects.getStartchY();
+      float logoW = mLogoQuad.getStretchX();
+      float logoH = mLogoQuad.getStretchY();
       
       int initSize= (int)(3.0f*screenW/logoW);
       int finaSize= (int)(0.1f*screenW/logoW);
@@ -402,18 +407,18 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
       mLogoEffects.apply( scale );
       mLogoEffects.apply( new MatrixEffectMove(new Static3D(screenW/2,screenH/2,0)) );
 
-      mScreen.attach(mLogoTexture, mLogoEffects,mQuad);
+      mScreen.attach(mLogoTexture, mLogoEffects, mLogoQuad);
       }
     else if( effectID == scaleEffectID )
       {
       mScreen.detach(mLogoEffects);
       mLogoTexture.markForDeletion();
         
-      int crawlW = mCrawlEffects.getStartchX();
-      int crawlH = mCrawlEffects.getStartchY();
-      int screenW= mScreen.getWidth();
-      int backH  = mCrawlBackgroundEffects.getStartchY();
-      float scale= (float)screenW/crawlW;
+      float crawlW = mCrawlQuad.getStretchX();
+      float crawlH = mCrawlQuad.getStretchY();
+      float screenW= mScreen.getWidth();
+      float backH  = mCrawlBackgroundQuad.getStretchY();
+      float scale  = screenW/crawlW;
 
       mCrawlBackgroundEffects.apply( new MatrixEffectRotate(new Static1D(CRAWL_ANGLE), new Static3D(1,0,0), new Static3D(screenW/2,0,0)) );
 
@@ -433,8 +438,8 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
       mCrawlEffects.apply( new MatrixEffectScale(new Static3D(scale,scale,scale)) );
       mCrawlEffects.apply( move );
 
-      mBackground = mScreen.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects,mQuad);
-      mBackground.attach(mCrawlTexture, mCrawlEffects,mQuad);
+      mBackground = mScreen.attach(mCrawlBackgroundTexture, mCrawlBackgroundEffects, mCrawlBackgroundQuad);
+      mBackground.attach(mCrawlTexture, mCrawlEffects, mCrawlQuad);
       mBackground.glDisable(GLES31.GL_DEPTH_TEST);
       mBackground.glDepthMask(false);
       }
diff --git a/src/main/java/org/distorted/examples/stencil/StencilRenderer.java b/src/main/java/org/distorted/examples/stencil/StencilRenderer.java
index 4ac7e66..0737fcc 100644
--- a/src/main/java/org/distorted/examples/stencil/StencilRenderer.java
+++ b/src/main/java/org/distorted/examples/stencil/StencilRenderer.java
@@ -85,8 +85,9 @@ class StencilRenderer implements GLSurfaceView.Renderer
       {
       mView = v;
 
-      MeshCubes cube = new MeshCubes(1,1,1);
-      MeshQuad  quad = new MeshQuad();
+      MeshCubes cube   = new MeshCubes(1,1,1);
+      MeshQuad  quaFlo = new MeshQuad();
+      MeshQuad  quaFBO = new MeshQuad();
 
       mMove       = new Static3D(0,0,0);
       mScale      = new Static3D(1,1,1);
@@ -97,17 +98,17 @@ class StencilRenderer implements GLSurfaceView.Renderer
       mFloorTex  = new DistortedTexture();
       mFBOTex    = new DistortedTexture();
 
-      DistortedEffects cube1Effects = new DistortedEffects(1);
-      DistortedEffects cube2Effects = new DistortedEffects(1);
-      DistortedEffects floorEffects = new DistortedEffects(1);
-      DistortedEffects FBOEffects   = new DistortedEffects(1);
+      DistortedEffects cube1Effects = new DistortedEffects();
+      DistortedEffects cube2Effects = new DistortedEffects();
+      DistortedEffects floorEffects = new DistortedEffects();
+      DistortedEffects FBOEffects   = new DistortedEffects();
 
-      floorEffects.setStretch(2,2,0);
+      quaFlo.setStretch(2,2,0);
 
-      mCube1Node = new DistortedNode(mCubeTex , cube1Effects, cube );
-      mCube2Node = new DistortedNode(mCubeTex , cube2Effects, cube );
-      mFloorNode = new DistortedNode(mFloorTex, floorEffects, quad );
-      mFBONode   = new DistortedNode(mFBOTex  , FBOEffects  , quad );
+      mCube1Node = new DistortedNode(mCubeTex , cube1Effects, cube   );
+      mCube2Node = new DistortedNode(mCubeTex , cube2Effects, cube   );
+      mFloorNode = new DistortedNode(mFloorTex, floorEffects, quaFlo );
+      mFBONode   = new DistortedNode(mFBOTex  , FBOEffects  , quaFBO );
 
       ///////////////// The Meat of this App - shamelessly ripped off https://open.gl/depthstencils ///////////////////////
       /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -137,11 +138,11 @@ class StencilRenderer implements GLSurfaceView.Renderer
 
       setScreen(true);
 
-      float cw = cube1Effects.getStartchX();
-      float ch = cube1Effects.getStartchY();
+      float cw = cube.getStretchX();
+      float ch = cube.getStretchY();
 
-      float fw = floorEffects.getStartchX();
-      float fh = floorEffects.getStartchY();
+      float fw = quaFlo.getStretchX();
+      float fh = quaFlo.getStretchY();
 
       Static3D axisX = new Static3D(1,0,0);
       Static3D axisZ = new Static3D(0,0,1);
@@ -200,14 +201,14 @@ class StencilRenderer implements GLSurfaceView.Renderer
     
     public void onSurfaceChanged(GL10 glUnused, int width, int height) 
       {
-      float cw = mCube1Node.getEffects().getStartchX();
-      float ch = mCube1Node.getEffects().getStartchY();
+      float cw = mCube1Node.getMesh().getStretchX();
+      float ch = mCube1Node.getMesh().getStretchY();
 
-      float fw = mFloorNode.getEffects().getStartchX();
-      float fh = mFloorNode.getEffects().getStartchY();
+      float fw = mFloorNode.getMesh().getStretchX();
+      float fh = mFloorNode.getMesh().getStretchY();
 
-      float bw = mFBONode.getEffects().getStartchX();
-      float bh = mFBONode.getEffects().getStartchY();
+      float bw = mFBONode.getMesh().getStretchX();
+      float bh = mFBONode.getMesh().getStretchY();
 
       float scale = 0.4f*(width>height ? height/ch:width/cw);
 
diff --git a/src/main/java/org/distorted/examples/transparency/TransparencyRenderer.java b/src/main/java/org/distorted/examples/transparency/TransparencyRenderer.java
index 07d38f1..e5e20aa 100644
--- a/src/main/java/org/distorted/examples/transparency/TransparencyRenderer.java
+++ b/src/main/java/org/distorted/examples/transparency/TransparencyRenderer.java
@@ -75,6 +75,7 @@ class TransparencyRenderer implements GLSurfaceView.Renderer
       mView = v;
 
       MeshRectangles mesh = new MeshRectangles(1,1);
+      mesh.setStretch(OBJ_SIZE,OBJ_SIZE,0);
 
       mQuat1 = new Static4D(0,0,0,1);  // unity
       mQuat2 = new Static4D(0,0,0,1);  // quaternions
@@ -109,8 +110,7 @@ class TransparencyRenderer implements GLSurfaceView.Renderer
         mBlur[i]         = new PostprocessEffectBlur(new Static1D(0));
         mBlurApplied[i]  = true;
         alpha[i]         = new FragmentEffectAlpha(mAlphaVector[i]);
-        mEffects[i]      = new DistortedEffects(OBJ_SIZE,OBJ_SIZE,0);
-
+        mEffects[i]      = new DistortedEffects();
         mEffects[i].apply(mBlur[i]);
         mEffects[i].apply(alpha[i]);
         mEffects[i].apply(new MatrixEffectMove(mMoveVector[i]));
diff --git a/src/main/java/org/distorted/examples/triblur/TriblurRenderer.java b/src/main/java/org/distorted/examples/triblur/TriblurRenderer.java
index 83bcbd6..6c558ec 100644
--- a/src/main/java/org/distorted/examples/triblur/TriblurRenderer.java
+++ b/src/main/java/org/distorted/examples/triblur/TriblurRenderer.java
@@ -84,6 +84,7 @@ class TriblurRenderer implements GLSurfaceView.Renderer
       mView = v;
 
       MeshCubes mesh = new MeshCubes(1,1,1);
+      mesh.setStretch(OBJ_SIZE,OBJ_SIZE,OBJ_SIZE);
 
       mTex = new DistortedTexture();
 
@@ -126,8 +127,7 @@ class TriblurRenderer implements GLSurfaceView.Renderer
         mBlur[i]         = new PostprocessEffectBlur(mEffectVector[i]);
         mGlow[i]         = new PostprocessEffectGlow(mEffectVector[i], new Static4D(1.0f,1.0f,1.0f,0.5f) );
         chroma[i]        = new FragmentEffectChroma( new Static1D(0.3f), chromaVector[i]);
-        effects[i]       = new DistortedEffects(OBJ_SIZE,OBJ_SIZE,OBJ_SIZE);
-
+        effects[i]       = new DistortedEffects();
         effects[i].apply(mBlur[i]);
         effects[i].apply(chroma[i]);
 
diff --git a/src/main/java/org/distorted/examples/wind/WindRenderer.java b/src/main/java/org/distorted/examples/wind/WindRenderer.java
index f5e2551..a51a06b 100644
--- a/src/main/java/org/distorted/examples/wind/WindRenderer.java
+++ b/src/main/java/org/distorted/examples/wind/WindRenderer.java
@@ -53,7 +53,7 @@ class WindRenderer implements GLSurfaceView.Renderer
    private WindEffectsManager mManager;
    private WindGust mGust;
    private Static3D mMove, mScale;
-   private int mObjWidth, mObjHeight;
+   private float mObjWidth, mObjHeight;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -62,7 +62,8 @@ class WindRenderer implements GLSurfaceView.Renderer
       mView = view;
 
       MeshCubes cubes = new MeshCubes(50,30,1);
-      DistortedEffects effects = new DistortedEffects(50,30,1);
+      DistortedEffects effects = new DistortedEffects();
+      cubes.setStretch(50,30,1);
 
       mTexture = new DistortedTexture();
       mManager = new WindEffectsManager(50,30);
@@ -71,8 +72,8 @@ class WindRenderer implements GLSurfaceView.Renderer
 
       mScreen.attach(mTexture,effects,cubes);
 
-      mObjWidth = effects.getStartchX();
-      mObjHeight= effects.getStartchY();
+      mObjWidth = cubes.getStretchX();
+      mObjHeight= cubes.getStretchY();
 
       mManager.apply(effects);
 
