commit fe59d375cdbd1f77756d890244aa3dcac1137e3f
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Fri Feb 10 16:11:57 2017 +0000

    Change the the render() API!
    
    THis introduces some regressions with the Effects3D app.

diff --git a/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java b/src/main/java/org/distorted/examples/aroundtheworld/AroundTheWorldRenderer.java
index 70d07e7..3c1e242 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 android.opengl.GLSurfaceView;
 import org.distorted.examples.R;
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshFlat;
 import org.distorted.library.DistortedTexture;
@@ -46,8 +45,6 @@ class AroundTheWorldRenderer implements GLSurfaceView.Renderer
 {
    private GLSurfaceView mView;
    private DistortedEffects mEffects;
-   private DistortedTexture mTexture;
-   private MeshFlat mMesh;
    private DistortedScreen mScreen;
    private AroundTheWorldEffectsManager mManager;
    private int mObjWidth, mObjHeight;
@@ -78,7 +75,7 @@ class AroundTheWorldRenderer implements GLSurfaceView.Renderer
    public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -130,10 +127,13 @@ class AroundTheWorldRenderer implements GLSurfaceView.Renderer
       mObjWidth = bitmap.getWidth();
       mObjHeight= bitmap.getHeight();
 
-      mTexture = new DistortedTexture(mObjWidth,mObjHeight);
-      mTexture.setTexture(bitmap);
+      DistortedTexture texture = new DistortedTexture(mObjWidth,mObjHeight);
+      texture.setTexture(bitmap);
 
-      mMesh = new MeshFlat(30,30*mObjHeight/mObjWidth);
+      MeshFlat mesh = new MeshFlat(30,30*mObjHeight/mObjWidth);
+
+      mScreen.detachAll();
+      mScreen.attach(texture, mEffects, mesh );
 
       try
         {
diff --git a/src/main/java/org/distorted/examples/bean/BeanRenderer.java b/src/main/java/org/distorted/examples/bean/BeanRenderer.java
index dd013c0..f648f61 100644
--- a/src/main/java/org/distorted/examples/bean/BeanRenderer.java
+++ b/src/main/java/org/distorted/examples/bean/BeanRenderer.java
@@ -28,7 +28,6 @@ import javax.microedition.khronos.opengles.GL10;
 import org.distorted.examples.R;
 
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.EffectTypes;
 import org.distorted.library.Distorted;
@@ -48,10 +47,8 @@ import android.opengl.GLSurfaceView;
 class BeanRenderer implements GLSurfaceView.Renderer 
 {
    private GLSurfaceView mView;
-   private DistortedTexture mTexture;
    private DistortedEffects mEffects;
    private DistortedScreen mScreen;
-   private MeshFlat mMesh;
    private int bmpHeight, bmpWidth;
     
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -98,7 +95,7 @@ class BeanRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -152,9 +149,12 @@ class BeanRenderer implements GLSurfaceView.Renderer
       bmpHeight = bitmap.getHeight();
       bmpWidth  = bitmap.getWidth();
       
-      mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-      mTexture.setTexture(bitmap);
-      mMesh = new MeshFlat(25,25*bmpHeight/bmpWidth);
+      DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+      texture.setTexture(bitmap);
+      MeshFlat mesh = new MeshFlat(25,25*bmpHeight/bmpWidth);
+
+      mScreen.detachAll();
+      mScreen.attach(texture,mEffects,mesh);
 
       try
         {
diff --git a/src/main/java/org/distorted/examples/blur/BlurRenderer.java b/src/main/java/org/distorted/examples/blur/BlurRenderer.java
index faf9ab3..baa0c1d 100644
--- a/src/main/java/org/distorted/examples/blur/BlurRenderer.java
+++ b/src/main/java/org/distorted/examples/blur/BlurRenderer.java
@@ -27,7 +27,6 @@ import android.opengl.GLSurfaceView;
 import org.distorted.examples.R;
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.EffectTypes;
@@ -47,7 +46,6 @@ import javax.microedition.khronos.opengles.GL10;
 class BlurRenderer implements GLSurfaceView.Renderer
 {
     private GLSurfaceView mView;
-    private DistortedTexture mTexture;
     private DistortedEffects mEffects;
     private DistortedScreen mScreen;
     private MeshFlat mMesh;
@@ -84,7 +82,7 @@ class BlurRenderer implements GLSurfaceView.Renderer
    public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -138,8 +136,11 @@ class BlurRenderer implements GLSurfaceView.Renderer
       bmpHeight = bitmap.getHeight();
       bmpWidth  = bitmap.getWidth();
 
-      mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-      mTexture.setTexture(bitmap);
+      DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+      texture.setTexture(bitmap);
+
+      mScreen.detachAll();
+      mScreen.attach(texture,mEffects,mMesh);
 
       try
         {
@@ -147,7 +148,7 @@ class BlurRenderer implements GLSurfaceView.Renderer
         }
       catch(Exception ex)
         {
-        android.util.Log.e("Renderer", ex.getMessage() );
+        android.util.Log.e("Blur", ex.getMessage() );
         }
       }
 }
diff --git a/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java b/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java
index cdde0d4..eeb8221 100644
--- a/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java
+++ b/src/main/java/org/distorted/examples/catanddog/CatAndDogRenderer.java
@@ -28,7 +28,6 @@ import javax.microedition.khronos.opengles.GL10;
 import org.distorted.examples.R;
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.MeshFlat;
@@ -50,7 +49,6 @@ class CatAndDogRenderer implements GLSurfaceView.Renderer
 {
     private GLSurfaceView mView;
     private DistortedEffects mEffects;
-    private DistortedTexture mTexture;
     private MeshFlat mMesh;
     private DistortedScreen mScreen;
     private int bmpHeight, bmpWidth;
@@ -87,7 +85,7 @@ class CatAndDogRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -115,8 +113,11 @@ class CatAndDogRenderer implements GLSurfaceView.Renderer
       bmpHeight = bitmap.getHeight();
       bmpWidth  = bitmap.getWidth();
 
-      mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-      mTexture.setTexture(bitmap);
+      DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+      texture.setTexture(bitmap);
+
+      mScreen.detachAll();
+      mScreen.attach(texture,mEffects,mMesh);
 
       try
         {
diff --git a/src/main/java/org/distorted/examples/check/CheckRenderer.java b/src/main/java/org/distorted/examples/check/CheckRenderer.java
index 9a8b8b2..407f7c0 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.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.MeshFlat;
@@ -57,9 +56,7 @@ class CheckRenderer implements GLSurfaceView.Renderer
     private static String compilationTitle;
 
     private GLSurfaceView mView;
-    private DistortedTexture mTexture;
     private DistortedEffects mEffects;
-    private MeshFlat mMesh;
     private DistortedScreen mScreen;
     private int bmpHeight, bmpWidth;
 
@@ -83,7 +80,7 @@ class CheckRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -137,9 +134,12 @@ class CheckRenderer implements GLSurfaceView.Renderer
       bmpHeight = bitmap.getHeight();
       bmpWidth  = bitmap.getWidth();
 
-      mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-      mTexture.setTexture(bitmap);
-      mMesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
+      DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+      texture.setTexture(bitmap);
+      MeshFlat mesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
+
+      mScreen.detachAll();
+      mScreen.attach(texture,mEffects,mesh);
 
       // Try adding 2 Vertex Effects to the Bitmap.
       // This will fail if we have set maxVertexEffects to something < 2.
diff --git a/src/main/java/org/distorted/examples/cubes/CubesRenderer.java b/src/main/java/org/distorted/examples/cubes/CubesRenderer.java
index d161052..040ef0e 100644
--- a/src/main/java/org/distorted/examples/cubes/CubesRenderer.java
+++ b/src/main/java/org/distorted/examples/cubes/CubesRenderer.java
@@ -28,7 +28,6 @@ import javax.microedition.khronos.opengles.GL10;
 import org.distorted.examples.R;
 
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.MeshObject;
@@ -90,7 +89,7 @@ class CubesRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -144,7 +143,10 @@ class CubesRenderer implements GLSurfaceView.Renderer
         }  
       
       mTexture.setTexture(bitmap);
-      
+
+      mScreen.detachAll();
+      mScreen.attach(mTexture,mEffects,mMesh);
+
       try
         {
         Distorted.onCreate(mView.getContext());
diff --git a/src/main/java/org/distorted/examples/deform/DeformRenderer.java b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
index ffa644d..aeb8e9a 100644
--- a/src/main/java/org/distorted/examples/deform/DeformRenderer.java
+++ b/src/main/java/org/distorted/examples/deform/DeformRenderer.java
@@ -24,7 +24,6 @@ import javax.microedition.khronos.opengles.GL10;
 
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.MeshObject;
@@ -182,19 +181,16 @@ class DeformRenderer implements GLSurfaceView.Renderer
    public void onDrawFrame(GL10 glUnused)
      {
      GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-    
-     long time = System.currentTimeMillis();
-      
-     mScreen.renderTo(stretchTexture, stretchMesh,stretchEffects,time);
-      
+
      mPaint.setColor(0xffffffff);
      fpsCanvas.drawRect(0, 0, fpsW, fpsH, mPaint);
      mPaint.setColor(0xff000000);
      fpsCanvas.drawText(fpsString, fpsW/2, 5*fpsH/6, mPaint);
-      
      fpsTexture.setTexture(fpsBitmap);
-     mScreen.renderTo(fpsTexture, fpsMesh,fpsEffects,time);
-      
+
+     long time = System.currentTimeMillis();
+
+     mScreen.render(time);
      computeFPS(time);
      }
 
@@ -215,6 +211,10 @@ class DeformRenderer implements GLSurfaceView.Renderer
        stretchEffects.move( new Static3D(scrWidth/4,scrHeight/4,0) );
        fpsEffects.move( new Static3D(5,5,0) );
        bitmapCreated=true;
+
+       mScreen.detachAll();
+       mScreen.attach(stretchTexture,stretchEffects,stretchMesh);
+       mScreen.attach(fpsTexture,fpsEffects,fpsMesh);
        }
      else
        {
diff --git a/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java b/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java
index f715cf7..040cc99 100644
--- a/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java
+++ b/src/main/java/org/distorted/examples/differentbitmaps/DifferentBitmapsRenderer.java
@@ -28,7 +28,6 @@ import javax.microedition.khronos.opengles.GL10;
 import org.distorted.examples.R;
 
 import org.distorted.library.Distorted;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.DistortedEffects;
@@ -51,9 +50,7 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
    private static final int NUM = 3;
    
    private GLSurfaceView mView;
-   private DistortedTexture[] mTexture;
    private DistortedEffects[] mEffects;
-   private MeshFlat mMesh;
    private DistortedScreen mScreen;
    private int bmpHeight, bmpWidth;
     
@@ -109,10 +106,7 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      
-      long time = System.currentTimeMillis();
-      
-      for(int i=NUM-1; i>=0; i--) mScreen.renderTo(mTexture[i], mMesh, mEffects[i], time);
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -164,15 +158,18 @@ class DifferentBitmapsRenderer implements GLSurfaceView.Renderer
       bmpHeight = bitmap0.getHeight();
       bmpWidth  = bitmap0.getWidth();
       
-      mTexture = new DistortedTexture[NUM];
+      DistortedTexture[] texture = new DistortedTexture[NUM];
       for(int i=0; i<NUM; i++)
-        mTexture[i] = new DistortedTexture(bmpWidth,bmpHeight);
+        texture[i] = new DistortedTexture(bmpWidth,bmpHeight);
       
-      mTexture[0].setTexture(bitmap0);
-      mTexture[1].setTexture(bitmap1);
-      mTexture[2].setTexture(bitmap2);
+      texture[0].setTexture(bitmap0);
+      texture[1].setTexture(bitmap1);
+      texture[2].setTexture(bitmap2);
+
+      MeshFlat mesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
 
-      mMesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
+      mScreen.detachAll();
+      for(int i=NUM-1; i>=0; i--) mScreen.attach(texture[i], mEffects[i], mesh);
 
       try
         {
diff --git a/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java b/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java
index 7078744..024f224 100644
--- a/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java
+++ b/src/main/java/org/distorted/examples/differenteffects/DifferentEffectsRenderer.java
@@ -29,7 +29,6 @@ import org.distorted.examples.R;
 
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshFlat;
 import org.distorted.library.DistortedTexture;
@@ -53,8 +52,6 @@ class DifferentEffectsRenderer implements GLSurfaceView.Renderer
    
    private GLSurfaceView mView;
    private DistortedEffects[] mEffects;
-   private DistortedTexture mTexture;
-   private MeshFlat mMesh;
    private DistortedScreen mScreen;
    private int bmpHeight, bmpWidth;
     
@@ -103,10 +100,7 @@ class DifferentEffectsRenderer implements GLSurfaceView.Renderer
    public void onDrawFrame(GL10 glUnused)
      {
      GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      
-     long time = System.currentTimeMillis();
-   
-     for(int i=NUM-1; i>=0; i--) mScreen.renderTo(mTexture, mMesh, mEffects[i], time);
+     mScreen.render( System.currentTimeMillis() );
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -170,10 +164,12 @@ class DifferentEffectsRenderer implements GLSurfaceView.Renderer
      bmpHeight = bitmap.getHeight();
      bmpWidth  = bitmap.getWidth();
 
-     mMesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
-     mTexture  = new DistortedTexture(bmpWidth,bmpHeight);
+     MeshFlat mesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
+     DistortedTexture texture  = new DistortedTexture(bmpWidth,bmpHeight);
+     texture.setTexture(bitmap);
 
-     mTexture.setTexture(bitmap);
+     mScreen.detachAll();
+     for(int i=NUM-1; i>=0; i--) mScreen.attach(texture, mEffects[i], mesh);
 
      try
        {
diff --git a/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java b/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java
index b96207b..335323e 100644
--- a/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java
+++ b/src/main/java/org/distorted/examples/dynamic/DynamicRenderer.java
@@ -30,7 +30,6 @@ import android.opengl.GLES30;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshFlat;
 import org.distorted.library.DistortedTexture;
@@ -61,10 +60,10 @@ class DynamicRenderer implements GLSurfaceView.Renderer
      mPaint.setColor(0xff447da7);
      mPaint.setStyle(Style.FILL);
       
-     mView   = v;
-     mMesh = new MeshFlat(1,1);
+     mView    = v;
+     mMesh    = new MeshFlat(1,1);
      mEffects = new DistortedEffects();
-     mScreen = new DistortedScreen();
+     mScreen  = new DistortedScreen();
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -92,6 +91,8 @@ class DynamicRenderer implements GLSurfaceView.Renderer
      mBitmap = Bitmap.createBitmap(texW,texH, Bitmap.Config.ARGB_8888);
      mCanvas = new Canvas(mBitmap);
 
+     mScreen.detachAll();
+     mScreen.attach(mTexture,mEffects,mMesh);
      mScreen.resize(texW,texH);
      mView.onSurfaceChanged(texW,texH);
      }
@@ -107,7 +108,7 @@ class DynamicRenderer implements GLSurfaceView.Renderer
      mCanvas.drawRect(0, 0, texW, texH, mPaint);
      mView.drawCurve(mCanvas,time);
      mTexture.setTexture(mBitmap);
-     mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+     mScreen.render( System.currentTimeMillis() );
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java b/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java
index 231a3ba..f3196f6 100644
--- a/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java
+++ b/src/main/java/org/distorted/examples/effectqueue/EffectQueueRenderer.java
@@ -30,7 +30,6 @@ import android.opengl.GLES30;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshFlat;
 import org.distorted.library.DistortedTexture;
@@ -106,6 +105,9 @@ class EffectQueueRenderer implements GLSurfaceView.Renderer, EffectListener
       }
     mTexture.setTexture(bitmap);
 
+    mScreen.detachAll();
+    mScreen.attach(mTexture,mEffects,mMesh);
+
     try
       {
       Distorted.onCreate(mView.getContext());
@@ -131,7 +133,7 @@ class EffectQueueRenderer implements GLSurfaceView.Renderer, EffectListener
   public void onDrawFrame(GL10 glUnused)
     {   
     GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT | GLES30.GL_DEPTH_BUFFER_BIT);
-    mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+    mScreen.render( System.currentTimeMillis() );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java b/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java
index a2d4f0f..8a88c42 100644
--- a/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java
+++ b/src/main/java/org/distorted/examples/effects3d/Effects3DActivity.java
@@ -249,13 +249,6 @@ public class Effects3DActivity extends Activity
     mSupportsRegion = supports;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static boolean supportsRegion()
-    {
-    return mSupportsRegion;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public static void setSupportsCenter(boolean supports)
@@ -263,13 +256,6 @@ public class Effects3DActivity extends Activity
     mSupportsCenter = supports;
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static boolean supportsCenter()
-    {
-    return mSupportsCenter;
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public Bitmap getBitmap()
diff --git a/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java b/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java
index c4ba7aa..d42b75d 100644
--- a/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java
+++ b/src/main/java/org/distorted/examples/effects3d/Effects3DRenderer.java
@@ -27,7 +27,7 @@ import android.opengl.GLSurfaceView;
 import org.distorted.examples.R;
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
+import org.distorted.library.DistortedNode;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.MeshFlat;
@@ -52,6 +52,7 @@ class Effects3DRenderer implements GLSurfaceView.Renderer
     private DistortedTexture mObjectTexture, mBackgroundTexture, mCenterTexture, mRegionTexture;
     private DistortedEffects mObjectEffects, mBackgroundEffects, mCenterEffects, mRegionEffects;
     private DistortedScreen mScreen;
+    private DistortedNode mCenterNode, mRegionNode;
     private MeshFlat mQuad;
     private MeshObject mObjectMesh;
     private int mObjWidth, mObjHeight, mObjDepth;
@@ -111,7 +112,17 @@ class Effects3DRenderer implements GLSurfaceView.Renderer
       mRegionScalePoint = new Static3D(0,0,0);
       mRegionScaleInter.add(mRegionScalePoint);
 
+      mCenterNode = new DistortedNode(mCenterTexture, mCenterEffects, mQuad);
+      mRegionNode = new DistortedNode(mRegionTexture, mRegionEffects, mQuad);
+
       mScreen = new DistortedScreen();
+      mScreen.attach(mBackgroundTexture, mBackgroundEffects, mQuad      );
+      mScreen.attach(mObjectTexture    , mObjectEffects    , mObjectMesh);
+
+    //if( Effects3DActivity.supportsCenter() )
+        mScreen.attach(mCenterNode);
+    //if( Effects3DActivity.supportsRegion() )
+        mScreen.attach(mRegionNode);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -135,17 +146,7 @@ class Effects3DRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused)
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-
-      long time = System.currentTimeMillis();
-
-      mScreen.renderTo(mBackgroundTexture,mQuad      ,mBackgroundEffects,time);
-      mScreen.renderTo(mObjectTexture    , mObjectMesh,mObjectEffects    ,time);
-
-      if( Effects3DActivity.supportsCenter() )
-        {
-        mScreen.renderTo(mCenterTexture,mQuad,mCenterEffects, time);
-        if( Effects3DActivity.supportsRegion() ) mScreen.renderTo(mRegionTexture,mQuad,mRegionEffects,time);
-        }
+      mScreen.render(System.currentTimeMillis());
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/fbo/FBORenderer.java b/src/main/java/org/distorted/examples/fbo/FBORenderer.java
index 55037ae..0ca7254 100644
--- a/src/main/java/org/distorted/examples/fbo/FBORenderer.java
+++ b/src/main/java/org/distorted/examples/fbo/FBORenderer.java
@@ -81,7 +81,7 @@ class FBORenderer implements GLSurfaceView.Renderer
    public void onDrawFrame(GL10 glUnused)
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mRoot,System.currentTimeMillis());
+      mScreen.render(System.currentTimeMillis());
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -152,6 +152,9 @@ class FBORenderer implements GLSurfaceView.Renderer
       mRoot = new DistortedNode(lisa, mEffects,new MeshFlat(1,1));
       mRoot.attach(grid,gridEffects,new MeshCubes(10,10,false));
 
+      mScreen.detachAll();
+      mScreen.attach(mRoot);
+
       float factor = lisaWidth/(2.0f*gridWidth);
 
       gridEffects.move( new Static3D( (lisaWidth-factor*gridWidth)/2,(lisaHeight-factor*gridHeight)/2,0) );
diff --git a/src/main/java/org/distorted/examples/flag/FlagRenderer.java b/src/main/java/org/distorted/examples/flag/FlagRenderer.java
index 8ccf44b..b672951 100644
--- a/src/main/java/org/distorted/examples/flag/FlagRenderer.java
+++ b/src/main/java/org/distorted/examples/flag/FlagRenderer.java
@@ -27,7 +27,6 @@ import android.opengl.GLSurfaceView;
 import org.distorted.examples.R;
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshCubes;
 import org.distorted.library.DistortedTexture;
@@ -53,7 +52,6 @@ class FlagRenderer implements GLSurfaceView.Renderer
     private DistortedEffects mEffects;
     private DistortedTexture mTexture;
     private DistortedScreen mScreen;
-    private MeshCubes mMesh;
     private DynamicQuat mQuatInt1, mQuatInt2;
     private Dynamic5D mWaveDyn;
     private Static5D mWaveSta1, mWaveSta2;
@@ -69,7 +67,6 @@ class FlagRenderer implements GLSurfaceView.Renderer
       mView = v;
 
       mEffects = new DistortedEffects();
-      mMesh = new MeshCubes(50,30,false);
       mTexture = new DistortedTexture(500,300);
 
       mObjWidth = mTexture.getWidth();
@@ -98,6 +95,7 @@ class FlagRenderer implements GLSurfaceView.Renderer
       mEffects.wave(mWaveDyn, waveCenter, waveRegion);
 
       mScreen = new DistortedScreen();
+      mScreen.attach(mTexture,mEffects, new MeshCubes(50,30,false) );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -144,7 +142,7 @@ class FlagRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/girl/GirlRenderer.java b/src/main/java/org/distorted/examples/girl/GirlRenderer.java
index df34734..129d2b0 100644
--- a/src/main/java/org/distorted/examples/girl/GirlRenderer.java
+++ b/src/main/java/org/distorted/examples/girl/GirlRenderer.java
@@ -28,7 +28,6 @@ import javax.microedition.khronos.opengles.GL10;
 import org.distorted.examples.R;
 
 import org.distorted.library.Distorted;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshFlat;
 import org.distorted.library.DistortedTexture;
@@ -50,10 +49,8 @@ import android.opengl.GLSurfaceView;
 class GirlRenderer implements GLSurfaceView.Renderer 
 {
     private GLSurfaceView mView;
-    private DistortedTexture mTexture;
     private DistortedEffects mEffects;
     private DistortedScreen mScreen;
-    private MeshFlat mMesh;
     private Static3D v0,v1,v2,v3;
     private Static1D dBegin, dMiddle, dEnd, s0;
     private int bmpHeight, bmpWidth;
@@ -155,7 +152,7 @@ class GirlRenderer implements GLSurfaceView.Renderer
    public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -209,9 +206,12 @@ class GirlRenderer implements GLSurfaceView.Renderer
       bmpHeight = bitmap.getHeight();
       bmpWidth  = bitmap.getWidth();
 
-      mMesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
-      mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-      mTexture.setTexture(bitmap);
+      MeshFlat mesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
+      DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+      texture.setTexture(bitmap);
+
+      mScreen.detachAll();
+      mScreen.attach(texture,mEffects,mesh);
 
       try
         {
diff --git a/src/main/java/org/distorted/examples/listener/ListenerRenderer.java b/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
index 6a7b271..d662528 100644
--- a/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
+++ b/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
@@ -29,7 +29,6 @@ import javax.microedition.khronos.opengles.GL10;
 import org.distorted.examples.R;
 
 import org.distorted.library.Distorted;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshFlat;
 import org.distorted.library.DistortedTexture;
@@ -54,10 +53,8 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
    private final int NUM_BUBBLES = 12;
 
    private GLSurfaceView mView;
-   private DistortedTexture mTexture;
    private DistortedEffects mEffects;
    private DistortedScreen mScreen;
-   private MeshFlat mMesh;
    private int bmpHeight, bmpWidth;
    private Random mRnd;
 
@@ -107,7 +104,7 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -161,9 +158,12 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
       bmpHeight = bitmap.getHeight();
       bmpWidth  = bitmap.getWidth();
 
-      mMesh = new MeshFlat(50,50*bmpHeight/bmpWidth);
-      mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-      mTexture.setTexture(bitmap);
+      MeshFlat mesh = new MeshFlat(50,50*bmpHeight/bmpWidth);
+      DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+      texture.setTexture(bitmap);
+
+      mScreen.detachAll();
+      mScreen.attach(texture,mEffects,mesh);
 
       for(int i=0; i<NUM_BUBBLES; i++) randomizeNewBubble();
       
diff --git a/src/main/java/org/distorted/examples/matrix3d/Matrix3DRenderer.java b/src/main/java/org/distorted/examples/matrix3d/Matrix3DRenderer.java
index 3c7e4be..edd343d 100644
--- a/src/main/java/org/distorted/examples/matrix3d/Matrix3DRenderer.java
+++ b/src/main/java/org/distorted/examples/matrix3d/Matrix3DRenderer.java
@@ -23,10 +23,7 @@ import android.opengl.GLES30;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.library.Distorted;
-import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
-import org.distorted.library.MeshObject;
 import org.distorted.library.DistortedTexture;
 
 import javax.microedition.khronos.egl.EGLConfig;
@@ -38,9 +35,7 @@ class Matrix3DRenderer implements GLSurfaceView.Renderer
 {
     private GLSurfaceView mView;
     private DistortedTexture mTexture;
-    private DistortedEffects mEffects;
     private DistortedScreen mScreen;
-    private MeshObject mMesh;
 
     private int mWidth, mHeight;
 
@@ -49,13 +44,10 @@ class Matrix3DRenderer implements GLSurfaceView.Renderer
     Matrix3DRenderer(GLSurfaceView v)
       {
       mView = v;
-
       Matrix3DActivity act = (Matrix3DActivity)v.getContext();
-
-      mEffects= act.getEffects();
       mTexture= act.getTexture();
-      mMesh = act.getMesh();
       mScreen = new DistortedScreen();
+      mScreen.attach(mTexture,act.getEffects(),act.getMesh());
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -63,7 +55,7 @@ class Matrix3DRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused)
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java b/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java
index 6ef57b8..70199f8 100644
--- a/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java
+++ b/src/main/java/org/distorted/examples/mirror/MirrorRenderer.java
@@ -114,11 +114,9 @@ class MirrorRenderer implements GLSurfaceView.Renderer
 
       long time = System.currentTimeMillis();
 
-      mOffScreen1.renderTo( mTextureMirror, mQuad, mEffectsMirror    , time );
-      mOffScreen1.renderTo( mOffScreen2   , mQuad, mEffectsOffscreen2, time );
-      mOffScreen1.renderTo( mTextureHead  , mQuad, mEffectsHead      , time );
-      mOffScreen2.renderTo( mOffScreen1   , mQuad, mEffectsOffscreen1, time );
-      mScreen.renderTo    ( mOffScreen1   , mQuad, mEffectsNull      , time );
+      mOffScreen1.render(time);
+      mOffScreen2.render(time);
+      mScreen.render(time);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -149,6 +147,13 @@ class MirrorRenderer implements GLSurfaceView.Renderer
         mHeadPosition.set2( mScreenH*(1.0f-MIRROR_MARGIN*mMirrorW/mMirrorH) - headScale* mHeadH);
         setPosition(mX);
 
+        mOffScreen1.attach( mTextureMirror, mEffectsMirror    , mQuad );
+        mOffScreen1.attach( mOffScreen2   , mEffectsOffscreen2, mQuad );
+        mOffScreen1.attach( mTextureHead  , mEffectsHead      , mQuad );
+        mOffScreen2.attach( mOffScreen1   , mEffectsOffscreen1, mQuad );
+
+        mScreen.detachAll();
+        mScreen.attach    ( mOffScreen1   , mEffectsNull      , mQuad );
         mScreen.resize(mScreenW,mScreenH);
         }
       }
diff --git a/src/main/java/org/distorted/examples/monalisa/MonaLisaRenderer.java b/src/main/java/org/distorted/examples/monalisa/MonaLisaRenderer.java
index d7e305f..756de9b 100644
--- a/src/main/java/org/distorted/examples/monalisa/MonaLisaRenderer.java
+++ b/src/main/java/org/distorted/examples/monalisa/MonaLisaRenderer.java
@@ -28,7 +28,6 @@ import javax.microedition.khronos.opengles.GL10;
 import org.distorted.examples.R;
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.MeshFlat;
@@ -47,10 +46,8 @@ import android.opengl.GLSurfaceView;
 class MonaLisaRenderer implements GLSurfaceView.Renderer 
 {
     private GLSurfaceView mView;
-    private DistortedTexture mTexture;
     private DistortedEffects mEffects;
     private DistortedScreen mScreen;
-    private MeshFlat mMesh;
     private int bmpHeight, bmpWidth;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -83,7 +80,7 @@ class MonaLisaRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -135,9 +132,12 @@ class MonaLisaRenderer implements GLSurfaceView.Renderer
       bmpHeight = bitmap.getHeight();
       bmpWidth  = bitmap.getWidth();
 
-      mMesh = new MeshFlat(9,9*bmpHeight/bmpWidth);
-      mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-      mTexture.setTexture(bitmap);
+      MeshFlat mesh = new MeshFlat(9,9*bmpHeight/bmpWidth);
+      DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+      texture.setTexture(bitmap);
+
+      mScreen.detachAll();
+      mScreen.attach(texture,mEffects,mesh);
 
       try
         {
diff --git a/src/main/java/org/distorted/examples/movingeffects/MovingEffectsRenderer.java b/src/main/java/org/distorted/examples/movingeffects/MovingEffectsRenderer.java
index 07113d3..791aa78 100644
--- a/src/main/java/org/distorted/examples/movingeffects/MovingEffectsRenderer.java
+++ b/src/main/java/org/distorted/examples/movingeffects/MovingEffectsRenderer.java
@@ -29,7 +29,6 @@ import android.graphics.Paint.Style;
 import android.opengl.GLES30;
 import android.opengl.GLSurfaceView;
 
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.DistortedEffects;
@@ -46,7 +45,6 @@ class MovingEffectsRenderer implements GLSurfaceView.Renderer
    private Paint mPaint;
    private int texW, texH;
 
-   private MeshFlat mMesh;
    private DistortedEffects mEffects;
    private DistortedTexture mTexture;
    private DistortedScreen mScreen;
@@ -127,11 +125,12 @@ class MovingEffectsRenderer implements GLSurfaceView.Renderer
      texW = width;
      texH = height;
 
-     mMesh = new MeshFlat(80,80*texH/texW);
      mTexture = new DistortedTexture(texW,texH);
      mBitmap  = Bitmap.createBitmap(texW,texH, Bitmap.Config.ARGB_8888);
      mCanvas  = new Canvas(mBitmap);
 
+     mScreen.detachAll();
+     mScreen.attach(mTexture,mEffects,new MeshFlat(80,80*texH/texW));
      mScreen.resize(texW, texH);
      mView.onSurfaceChanged(texW,texH);
 
@@ -154,7 +153,7 @@ class MovingEffectsRenderer implements GLSurfaceView.Renderer
        mRefresh = false;
        }
       
-     mScreen.renderTo(mTexture, mMesh, mEffects, time );
+     mScreen.render(time);
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java b/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java
index 2861bae..76db32b 100644
--- a/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java
+++ b/src/main/java/org/distorted/examples/multiblur/MultiblurRenderer.java
@@ -27,12 +27,10 @@ import android.opengl.GLSurfaceView;
 import org.distorted.examples.R;
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.DistortedTexture;
 import org.distorted.library.EffectTypes;
 import org.distorted.library.MeshCubes;
-import org.distorted.library.MeshObject;
 import org.distorted.library.type.DynamicQuat;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
@@ -67,7 +65,6 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
     private DistortedTexture mTex1, mTex2;
     private DistortedEffects[] mEffects;
     private Static3D[] mMoveVector;
-    private MeshObject mMesh;
     private DistortedScreen mScreen;
     private DynamicQuat mQuatInt1, mQuatInt2;
 
@@ -88,7 +85,7 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
 
       mEffects[0].blur(new Static1D(10));
 
-      mMesh = new MeshCubes(1,1,false);
+      MeshCubes mesh = new MeshCubes(1,1,false);
 
       mTex1 = new DistortedTexture(OBJ_SIZE,OBJ_SIZE);
       mTex2 = new DistortedTexture(OBJ_SIZE,OBJ_SIZE);
@@ -103,6 +100,9 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
       mQuatInt2.add(mQuat2);
 
       mScreen = new DistortedScreen();
+
+      for(int i=0; i<NUM_OBJECTS; i++)
+        mScreen.attach( i<NUM_OBJECTS/2 ? mTex1:mTex2, mEffects[i], mesh);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -110,11 +110,7 @@ class MultiblurRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-
-      long time = System.currentTimeMillis();
-
-      for(int i=0; i<NUM_OBJECTS; i++)
-        mScreen.renderTo( i<NUM_OBJECTS/2 ? mTex1:mTex2, mMesh, mEffects[i], time );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java b/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java
index dea66f9..5daa943 100644
--- a/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java
+++ b/src/main/java/org/distorted/examples/olimpic/OlimpicRenderer.java
@@ -113,6 +113,7 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
         }
 
       mScreen = new DistortedScreen();
+      mScreen.attach(mRoot);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -120,7 +121,7 @@ class OlimpicRenderer implements GLSurfaceView.Renderer
     public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mRoot,System.currentTimeMillis());
+      mScreen.render(System.currentTimeMillis());
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/plainmonalisa/RenderThread.java b/src/main/java/org/distorted/examples/plainmonalisa/RenderThread.java
index 284c1c9..334e307 100644
--- a/src/main/java/org/distorted/examples/plainmonalisa/RenderThread.java
+++ b/src/main/java/org/distorted/examples/plainmonalisa/RenderThread.java
@@ -32,7 +32,6 @@ import android.view.SurfaceView;
 
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshFlat;
 import org.distorted.library.DistortedTexture;
@@ -63,10 +62,8 @@ class RenderThread extends Thread
   private EglCore eglCore;
   private EGLSurface eglSurface;
 
-  private DistortedTexture mTexture;
   private DistortedEffects mEffects;
   private DistortedScreen mScreen;
-  private MeshFlat mMesh;
   private int bmpHeight, bmpWidth;
   private SurfaceView mView;
 
@@ -212,10 +209,12 @@ class RenderThread extends Thread
     bmpHeight = bmp.getHeight();
     bmpWidth  = bmp.getWidth();
 
-    mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-    mTexture.setTexture(bmp);
+    DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+    texture.setTexture(bmp);
+    MeshFlat mesh = new MeshFlat(9,9*bmpHeight/bmpWidth);  // more-or-less square Grid with 9 columns.
 
-    mMesh = new MeshFlat(9,9*bmpHeight/bmpWidth);  // more-or-less square Grid with 9 columns.
+    mScreen.detachAll();
+    mScreen.attach(texture,mEffects,mesh);
 
     try
       {
@@ -268,7 +267,7 @@ class RenderThread extends Thread
     eglCore.makeCurrent(eglSurface);
 
     GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-    mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+    mScreen.render( System.currentTimeMillis() );
 
     eglCore.swapBuffers(eglSurface);
     }
diff --git a/src/main/java/org/distorted/examples/projection/ProjectionRenderer.java b/src/main/java/org/distorted/examples/projection/ProjectionRenderer.java
index 66bba0f..51c48bd 100644
--- a/src/main/java/org/distorted/examples/projection/ProjectionRenderer.java
+++ b/src/main/java/org/distorted/examples/projection/ProjectionRenderer.java
@@ -24,7 +24,6 @@ import javax.microedition.khronos.opengles.GL10;
 
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshFlat;
 import org.distorted.library.DistortedTexture;
@@ -43,10 +42,8 @@ import android.opengl.GLSurfaceView;
 class ProjectionRenderer implements GLSurfaceView.Renderer
 {
    private GLSurfaceView mView;
-   private DistortedTexture mTexture;
    private DistortedEffects mEffects;
    private DistortedScreen mScreen;
-   private MeshFlat mMesh;
 
    private float mF, mX, mY;
    private int mWidth, mHeight;
@@ -92,7 +89,7 @@ class ProjectionRenderer implements GLSurfaceView.Renderer
    public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -106,8 +103,8 @@ class ProjectionRenderer implements GLSurfaceView.Renderer
       mEffects.abortAllEffects();
 
       Paint paint = new Paint();
-      mTexture    = new DistortedTexture(width,height);
-      mMesh = new MeshFlat(50,50*height/width);
+      DistortedTexture texture= new DistortedTexture(width,height);
+      MeshFlat mesh = new MeshFlat(50,50*height/width);
       Bitmap bmp  = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);
       Canvas bmpCanvas = new Canvas(bmp);
 
@@ -124,7 +121,7 @@ class ProjectionRenderer implements GLSurfaceView.Renderer
         bmpCanvas.drawRect(                   0, height*i/NUMLINES -1,  width               ,  height*i/NUMLINES + 1, paint);
         }
 
-      mTexture.setTexture(bmp);
+      texture.setTexture(bmp);
 
       int min = width<height ? width:height;
 
@@ -136,6 +133,8 @@ class ProjectionRenderer implements GLSurfaceView.Renderer
       mEffects.distort(vector, new Static3D(  width/4, 3*height/4, 0), region);
       mEffects.distort(vector, new Static3D(3*width/4, 3*height/4, 0), region);
 
+      mScreen.detachAll();
+      mScreen.attach(texture,mEffects,mesh);
       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 76e2505..1c13976 100644
--- a/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
+++ b/src/main/java/org/distorted/examples/quaternion/QuaternionRenderer.java
@@ -29,7 +29,6 @@ import javax.microedition.khronos.opengles.GL10;
 import org.distorted.examples.R;
 
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.EffectTypes;
 import org.distorted.library.type.Dynamic;
@@ -55,7 +54,6 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
   private DistortedTexture mTexture;
   private DistortedEffects mEffects;
   private DistortedScreen mScreen;
-  private MeshCubes mMesh;
   private DynamicQuat mRot;
     
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -63,7 +61,6 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
   QuaternionRenderer(GLSurfaceView v)
     {
     mView    = v;
-    mMesh    = new MeshCubes(1,1,false);
     mTexture = new DistortedTexture(1,1);
     mEffects = new DistortedEffects();
     mRot     = new DynamicQuat();
@@ -88,6 +85,7 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
     mRot.setMode(Dynamic.MODE_LOOP);
 
     mScreen = new DistortedScreen();
+    mScreen.attach(mTexture,mEffects,new MeshCubes(1,1,false));
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -95,7 +93,7 @@ class QuaternionRenderer implements GLSurfaceView.Renderer
   public void onDrawFrame(GL10 glUnused) 
     {
     GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-    mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+    mScreen.render( System.currentTimeMillis() );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/examples/save/SaveRenderer.java b/src/main/java/org/distorted/examples/save/SaveRenderer.java
index 4e96ca6..917b446 100644
--- a/src/main/java/org/distorted/examples/save/SaveRenderer.java
+++ b/src/main/java/org/distorted/examples/save/SaveRenderer.java
@@ -54,9 +54,7 @@ import android.os.Environment;
 class SaveRenderer implements GLSurfaceView.Renderer
   {
   private GLSurfaceView mView;
-  private DistortedTexture mTexture;
   private DistortedEffects mEffects;
-  private MeshFlat mMesh;
   private DistortedFramebuffer mOffscreen;
   private DistortedScreen mScreen;
   private Static1D s0;
@@ -158,7 +156,7 @@ class SaveRenderer implements GLSurfaceView.Renderer
       {
       mEffects.abortEffects(EffectTypes.MATRIX);
       mEffects.scale(mScaleFactor);
-      mOffscreen.renderTo(mTexture, mMesh, mEffects, time );
+      mOffscreen.render(time);
       applyMatrixEffects(scrWidth,scrHeight);
 
       int fW =(int)(mScale*bmpWidth);
@@ -182,7 +180,7 @@ class SaveRenderer implements GLSurfaceView.Renderer
       isSaving = false;
       }
 
-    mScreen.renderTo(mTexture, mMesh, mEffects, time );
+    mScreen.render(time);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -246,12 +244,17 @@ class SaveRenderer implements GLSurfaceView.Renderer
     bmpHeight = bitmap.getHeight();
     bmpWidth  = bitmap.getWidth();
 
-    mMesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
-    mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-    mTexture.setTexture(bitmap);
+    MeshFlat mesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
+    DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+    texture.setTexture(bitmap);
 
     mOffscreen = new DistortedFramebuffer( (int)(mScale*bmpWidth) , (int)(mScale*bmpHeight) );
 
+    mOffscreen.detachAll();
+    mOffscreen.attach(texture,mEffects,mesh);
+    mScreen.detachAll();
+    mScreen.attach(texture,mEffects,mesh);
+
     try
       {
       Distorted.onCreate(mView.getContext());
diff --git a/src/main/java/org/distorted/examples/sink/SinkRenderer.java b/src/main/java/org/distorted/examples/sink/SinkRenderer.java
index 162142e..4eb406e 100644
--- a/src/main/java/org/distorted/examples/sink/SinkRenderer.java
+++ b/src/main/java/org/distorted/examples/sink/SinkRenderer.java
@@ -29,7 +29,6 @@ import org.distorted.examples.R;
 
 import org.distorted.library.Distorted;
 import org.distorted.library.DistortedEffects;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshFlat;
 import org.distorted.library.DistortedTexture;
@@ -48,10 +47,8 @@ import android.opengl.GLSurfaceView;
 class SinkRenderer implements GLSurfaceView.Renderer 
   {
   private GLSurfaceView mView;
-  private DistortedTexture mTexture;
   private DistortedEffects mEffects;
   private DistortedScreen mScreen;
-  private MeshFlat mMesh;
   private int bmpHeight, bmpWidth;
     
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -75,7 +72,7 @@ class SinkRenderer implements GLSurfaceView.Renderer
   public void onDrawFrame(GL10 glUnused) 
     {
     GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-    mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+    mScreen.render( System.currentTimeMillis() );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -129,9 +126,12 @@ class SinkRenderer implements GLSurfaceView.Renderer
     bmpHeight = bitmap.getHeight();
     bmpWidth  = bitmap.getWidth();
 
-    mMesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
-    mTexture = new DistortedTexture(bmpWidth,bmpHeight);
-    mTexture.setTexture(bitmap);
+    MeshFlat mesh = new MeshFlat(30,30*bmpHeight/bmpWidth);
+    DistortedTexture texture = new DistortedTexture(bmpWidth,bmpHeight);
+    texture.setTexture(bitmap);
+
+    mScreen.detachAll();
+    mScreen.attach(texture,mEffects,mesh);
 
     try
       {
diff --git a/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java b/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
index 4c8bd52..40a3cd7 100644
--- a/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
+++ b/src/main/java/org/distorted/examples/starwars/StarWarsRenderer.java
@@ -150,7 +150,7 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
   public void onDrawFrame(GL10 glUnused) 
     {
     GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-    mScreen.renderTo(mRoot,System.currentTimeMillis());
+    mScreen.render(System.currentTimeMillis());
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -172,6 +172,8 @@ class StarWarsRenderer implements GLSurfaceView.Renderer, EffectListener
 
       setupScreen(width,height);
 
+      mScreen.detachAll();
+      mScreen.attach(mRoot);
       mScreen.resize(width, height);
       }
     }
diff --git a/src/main/java/org/distorted/examples/wind/WindRenderer.java b/src/main/java/org/distorted/examples/wind/WindRenderer.java
index 6291002..d808925 100644
--- a/src/main/java/org/distorted/examples/wind/WindRenderer.java
+++ b/src/main/java/org/distorted/examples/wind/WindRenderer.java
@@ -26,7 +26,6 @@ import android.opengl.GLSurfaceView;
 
 import org.distorted.examples.R;
 import org.distorted.library.Distorted;
-import org.distorted.library.DistortedFramebuffer;
 import org.distorted.library.DistortedScreen;
 import org.distorted.library.MeshCubes;
 import org.distorted.library.DistortedEffects;
@@ -48,7 +47,6 @@ class WindRenderer implements GLSurfaceView.Renderer
    private DistortedEffects mEffects;
    private DistortedTexture mTexture;
    private DistortedScreen mScreen;
-   private MeshCubes mMesh;
    private WindEffectsManager mManager;
    private int mObjWidth, mObjHeight;
    private int mWind;
@@ -59,12 +57,13 @@ class WindRenderer implements GLSurfaceView.Renderer
       { 
       mView = view;
 
-      mMesh    = new MeshCubes(50,30,false);
       mEffects = new DistortedEffects();
       mTexture = new DistortedTexture(50,30);
       mManager = new WindEffectsManager(mTexture);
       mScreen  = new DistortedScreen();
 
+      mScreen.attach(mTexture,mEffects,new MeshCubes(50,30,false));
+
       mObjWidth = mTexture.getWidth();
       mObjHeight= mTexture.getHeight();
       }
@@ -82,7 +81,7 @@ class WindRenderer implements GLSurfaceView.Renderer
    public void onDrawFrame(GL10 glUnused) 
       {
       GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
-      mScreen.renderTo(mTexture, mMesh, mEffects, System.currentTimeMillis() );
+      mScreen.render( System.currentTimeMillis() );
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
