commit e54bfada4f11a8ad587ad1a1d210bb3e0e09df6d
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed May 20 15:43:30 2020 +0100

    Have VERTEX_QUATERNION, VERTEX_ROTATE and VERTEX_SHEAR modify inflate vectors.
    Split Vertex attribute array into two (the one modified by preapply effects and the one not)

diff --git a/src/main/java/org/distorted/library/effect/VertexEffectQuaternion.java b/src/main/java/org/distorted/library/effect/VertexEffectQuaternion.java
index 6b61893..9aedd5f 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectQuaternion.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectQuaternion.java
@@ -78,7 +78,20 @@ public class VertexEffectQuaternion extends VertexEffect
 
      + "n.x = qw*nx + qz*ny - qy*nz - qx*nw;          \n"
      + "n.y = qw*ny - qz*nx - qy*nw + qx*nz;          \n"
-     + "n.z = qw*nz - qz*nw + qy*nx - qx*ny;          \n";
+     + "n.z = qw*nz - qz*nw + qy*nx - qx*ny;          \n"
+
+     + "#ifdef PREAPPLY                                \n"
+
+     + "float ix =  - inf.z*qy + inf.y*qz + inf.x*qw;  \n"
+     + "float iy =  + inf.z*qx + inf.y*qw - inf.x*qz;  \n"
+     + "float iz =  + inf.z*qw - inf.y*qx + inf.x*qy;  \n"
+     + "float iw =  - inf.z*qz - inf.y*qy - inf.x*qx;  \n"
+
+     + "inf.x = qw*ix + qz*iy - qy*iz - qx*iw;         \n"
+     + "inf.y = qw*iy - qz*ix - qy*iw + qx*iz;         \n"
+     + "inf.z = qw*iz - qz*iw + qy*ix - qx*iy;         \n"
+
+     + "#endif                                         \n";
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectRotate.java b/src/main/java/org/distorted/library/effect/VertexEffectRotate.java
index bd08c9b..bcff625 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectRotate.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectRotate.java
@@ -95,7 +95,20 @@ public class VertexEffectRotate extends VertexEffect
 
     + "n.x = qw*nx + qz*ny - qy*nz - qx*nw;           \n"
     + "n.y = qw*ny - qz*nx - qy*nw + qx*nz;           \n"
-    + "n.z = qw*nz - qz*nw + qy*nx - qx*ny;           \n";
+    + "n.z = qw*nz - qz*nw + qy*nx - qx*ny;           \n"
+
+    + "#ifdef PREAPPLY                                \n"
+
+    + "float ix =  - inf.z*qy + inf.y*qz + inf.x*qw;  \n"
+    + "float iy =  + inf.z*qx + inf.y*qw - inf.x*qz;  \n"
+    + "float iz =  + inf.z*qw - inf.y*qx + inf.x*qy;  \n"
+    + "float iw =  - inf.z*qz - inf.y*qy - inf.x*qx;  \n"
+
+    + "inf.x = qw*ix + qz*iy - qy*iz - qx*iw;         \n"
+    + "inf.y = qw*iy - qz*ix - qy*iw + qx*iz;         \n"
+    + "inf.z = qw*iz - qz*iw + qy*ix - qx*iy;         \n"
+
+    + "#endif                                         \n";
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/effect/VertexEffectShear.java b/src/main/java/org/distorted/library/effect/VertexEffectShear.java
index 4254a6b..c0cabfb 100644
--- a/src/main/java/org/distorted/library/effect/VertexEffectShear.java
+++ b/src/main/java/org/distorted/library/effect/VertexEffectShear.java
@@ -73,7 +73,19 @@ public class VertexEffectShear extends VertexEffect
 
     + "n.x = new_nx;                                 \n"
     + "n.y = new_ny;                                 \n"
-    + "n.z = new_nz;                                 \n";
+    + "n.z = new_nz;                                 \n"
+
+    + "#ifdef PREAPPLY                               \n"
+
+    + "float new_ix = (1.0+sx*sy)*inf.x + sx*inf.y;  \n"
+    + "float new_iy = sy*inf.x + inf.y;              \n"
+    + "float new_iz = sz*inf.y + inf.z;              \n"
+
+    + "inf.x = new_ix;                               \n"
+    + "inf.y = new_iy;                               \n"
+    + "inf.z = new_iz;                               \n"
+
+    + "#endif                                        \n";
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/main/DistortedLibrary.java b/src/main/java/org/distorted/library/main/DistortedLibrary.java
index fd06115..8fefde1 100644
--- a/src/main/java/org/distorted/library/main/DistortedLibrary.java
+++ b/src/main/java/org/distorted/library/main/DistortedLibrary.java
@@ -307,7 +307,7 @@ public class DistortedLibrary
 
     fullVertHeader += "#define PREAPPLY\n";
 
-    String[] feedback = { "v_Position", "v_endPosition" };
+    String[] feedback = { "v_Position", "v_endPosition", "v_Inflate" };
 
     try
       {
diff --git a/src/main/java/org/distorted/library/mesh/MeshBase.java b/src/main/java/org/distorted/library/mesh/MeshBase.java
index 34bfd9c..a623ab5 100644
--- a/src/main/java/org/distorted/library/mesh/MeshBase.java
+++ b/src/main/java/org/distorted/library/mesh/MeshBase.java
@@ -52,9 +52,10 @@ public abstract class MeshBase
    static final int POS_ATTRIB   = 0;
    static final int NOR_ATTRIB   = POS_DATA_SIZE;
    static final int INF_ATTRIB   = POS_DATA_SIZE + NOR_DATA_SIZE;
-   static final int TEX_ATTRIB   = POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE;
-   static final int VERT_ATTRIBS = POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE + TEX_DATA_SIZE;  // number of attributes of a 'normal' vertex
-   static final int TRAN_ATTRIBS = POS_DATA_SIZE + POS_DATA_SIZE;                                  // number of attributes of a transform feedback vertex
+   static final int TEX_ATTRIB   = 0;
+   static final int VERT1_ATTRIBS= POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE;  // number of attributes of a vertex (the part changed by preapply)
+   static final int VERT2_ATTRIBS= TEX_DATA_SIZE;                                  // number of attributes of a vertex (the 'preapply invariant' part)
+   static final int TRAN_ATTRIBS = POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE;  // number of attributes of a transform feedback vertex
 
    private static final int BYTES_PER_FLOAT = 4;
 
@@ -63,12 +64,14 @@ public abstract class MeshBase
    private static final int OFFSET_INF = INF_ATTRIB*BYTES_PER_FLOAT;
    private static final int OFFSET_TEX = TEX_ATTRIB*BYTES_PER_FLOAT;
    private static final int TRAN_SIZE  = TRAN_ATTRIBS*BYTES_PER_FLOAT;
-   private static final int VERT_SIZE  = VERT_ATTRIBS*BYTES_PER_FLOAT;
+   private static final int VERT1_SIZE = VERT1_ATTRIBS*BYTES_PER_FLOAT;
+   private static final int VERT2_SIZE = VERT2_ATTRIBS*BYTES_PER_FLOAT;
 
-   private boolean mShowNormals;      // when rendering this mesh, draw normal vectors?
-   private InternalBuffer mVBO, mTFO; // main vertex buffer and transform feedback buffer
+   private boolean mShowNormals;              // when rendering this mesh, draw normal vectors?
+   private InternalBuffer mVBO1, mVBO2, mTFO; // main vertex buffer and transform feedback buffer
    private int mNumVertices;
-   private float[] mVertAttribs;      // packed: PosX,PosY,PosZ, NorX,NorY,NorZ, InfX,InfY,InfZ, TexS,TexT
+   private float[] mVertAttribs1;             // packed: PosX,PosY,PosZ, NorX,NorY,NorZ, InfX,InfY,InfZ
+   private float[] mVertAttribs2;             // packed: TexS,TexT
    private float mInflate;
    private boolean mNeedsAdjustment;
 
@@ -113,7 +116,8 @@ public abstract class MeshBase
      mNeedsAdjustment = false;
      mComponent       = new ArrayList<>();
 
-     mVBO = new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
+     mVBO1= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
+     mVBO2= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
      mTFO = new InternalBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, GLES30.GL_STATIC_READ);
      }
 
@@ -134,14 +138,19 @@ public abstract class MeshBase
        mComponent.add(comp);
        }
 
-     mVBO = new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
+     mVBO1= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
+     mVBO2= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
      mTFO = new InternalBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, GLES30.GL_STATIC_READ);
 
      mNumVertices = original.mNumVertices;
-     mVertAttribs = new float[mNumVertices*VERT_ATTRIBS];
-     System.arraycopy(original.mVertAttribs,0,mVertAttribs,0,mNumVertices*VERT_ATTRIBS);
+     mVertAttribs1= new float[mNumVertices*VERT1_ATTRIBS];
+     mVertAttribs2= new float[mNumVertices*VERT2_ATTRIBS];
 
-     mVBO.invalidate();
+     System.arraycopy(original.mVertAttribs1,0,mVertAttribs1,0,mNumVertices*VERT1_ATTRIBS);
+     System.arraycopy(original.mVertAttribs2,0,mVertAttribs2,0,mNumVertices*VERT2_ATTRIBS);
+
+     mVBO1.invalidate();
+     mVBO2.invalidate();
      mTFO.invalidate();
      }
 
@@ -155,15 +164,16 @@ public abstract class MeshBase
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // when a derived class is done computing its mesh, it has to call this method.
 
-   void setAttribs(float[] vertexAttribs)
+   void setAttribs(float[] vert1Attribs, float[] vert2Attribs)
      {
-     mNumVertices = vertexAttribs.length/VERT_ATTRIBS;
-     mVertAttribs = vertexAttribs;
+     mNumVertices = vert1Attribs.length/VERT1_ATTRIBS;
+     mVertAttribs1= vert1Attribs;
+     mVertAttribs2= vert2Attribs;
 
      mComponent.add(new Component(mNumVertices));
 
-     mVBO.invalidate();
-     mTFO.invalidate();
+     mVBO1.invalidate();
+     mVBO2.invalidate();
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -211,18 +221,22 @@ public abstract class MeshBase
        }
 
      // allocate new attrib array
-     float[] newAttribs = new float[VERT_ATTRIBS*mNumVertices];
+     float[] newAttribs1 = new float[VERT1_ATTRIBS*mNumVertices];
+     float[] newAttribs2 = new float[VERT2_ATTRIBS*mNumVertices];
      numVertices = origVertices;
 
      if( origVertices>0 )
        {
-       System.arraycopy(mVertAttribs,                             0, newAttribs,                         0, VERT_ATTRIBS*numVertices);
-       System.arraycopy(mVertAttribs, VERT_ATTRIBS*(origVertices-1), newAttribs, VERT_ATTRIBS*origVertices, VERT_ATTRIBS    );
+       System.arraycopy(mVertAttribs1,                              0, newAttribs1,                         0, VERT1_ATTRIBS*numVertices);
+       System.arraycopy(mVertAttribs2,                              0, newAttribs2,                         0, VERT2_ATTRIBS*numVertices);
+       System.arraycopy(mVertAttribs1, VERT1_ATTRIBS*(origVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS    );
+       System.arraycopy(mVertAttribs2, VERT2_ATTRIBS*(origVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS    );
        origVertices++;
 
        if( numVertices%2==1 )
          {
-         System.arraycopy(mVertAttribs, VERT_ATTRIBS*(origVertices-1), newAttribs, VERT_ATTRIBS*origVertices, VERT_ATTRIBS);
+         System.arraycopy(mVertAttribs1, VERT1_ATTRIBS*(origVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
+         System.arraycopy(mVertAttribs2, VERT2_ATTRIBS*(origVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
          origVertices++;
          }
        }
@@ -234,20 +248,24 @@ public abstract class MeshBase
 
        if( origVertices>0 )
          {
-         System.arraycopy(mesh.mVertAttribs, 0, newAttribs, VERT_ATTRIBS*origVertices, VERT_ATTRIBS    );
+         System.arraycopy(mesh.mVertAttribs1, 0, newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS    );
+         System.arraycopy(mesh.mVertAttribs2, 0, newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS    );
          origVertices++;
          }
-       System.arraycopy(mesh.mVertAttribs, 0, newAttribs, VERT_ATTRIBS*origVertices, VERT_ATTRIBS*numVertices);
+       System.arraycopy(mesh.mVertAttribs1, 0, newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS*numVertices);
+       System.arraycopy(mesh.mVertAttribs2, 0, newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS*numVertices);
        origVertices+=numVertices;
 
        if( i<numMeshes-1 )
          {
-         System.arraycopy(mesh.mVertAttribs, VERT_ATTRIBS*(numVertices-1), newAttribs, VERT_ATTRIBS*origVertices, VERT_ATTRIBS);
+         System.arraycopy(mesh.mVertAttribs1, VERT1_ATTRIBS*(numVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
+         System.arraycopy(mesh.mVertAttribs2, VERT2_ATTRIBS*(numVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
          origVertices++;
 
          if( numVertices%2==1 )
            {
-           System.arraycopy(mesh.mVertAttribs, VERT_ATTRIBS*(numVertices-1), newAttribs, VERT_ATTRIBS*origVertices, VERT_ATTRIBS);
+           System.arraycopy(mesh.mVertAttribs1, VERT1_ATTRIBS*(numVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
+           System.arraycopy(mesh.mVertAttribs2, VERT2_ATTRIBS*(numVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
            origVertices++;
            }
          }
@@ -258,9 +276,11 @@ public abstract class MeshBase
        android.util.Log.e("mesh", "join: origVertices: "+origVertices+" numVertices: "+mNumVertices);
        }
 
-     mVertAttribs = newAttribs;
+     mVertAttribs1 = newAttribs1;
+     mVertAttribs2 = newAttribs2;
 
-     mVBO.invalidate();
+     mVBO1.invalidate();
+     mVBO2.invalidate();
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -271,14 +291,13 @@ public abstract class MeshBase
  */
    public void copyTransformToVertex()
      {
-     float posX, posY, posZ, norX, norY, norZ;
-     FloatBuffer feedback=null;
-
-     ByteBuffer buffer = (ByteBuffer)GLES30.glMapBufferRange( GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, TRAN_SIZE*mNumVertices,
-                                                              GLES30.GL_MAP_READ_BIT);
+     ByteBuffer buffer = (ByteBuffer)GLES30.glMapBufferRange( GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0,
+                                                              TRAN_SIZE*mNumVertices, GLES30.GL_MAP_READ_BIT);
      if( buffer!=null )
        {
-       feedback = buffer.order(ByteOrder.nativeOrder()).asFloatBuffer();
+       FloatBuffer feedback = buffer.order(ByteOrder.nativeOrder()).asFloatBuffer();
+       feedback.get(mVertAttribs1,0,VERT1_ATTRIBS*mNumVertices);
+       mVBO1.update(mVertAttribs1);
        }
      else
        {
@@ -286,21 +305,6 @@ public abstract class MeshBase
        Log.e("mesh", "failed to map tf buffer, error="+error);
        }
 
-     if( feedback!=null )
-       {
-       for(int vertex=0; vertex<mNumVertices; vertex++)
-         {
-         mVertAttribs[vertex*VERT_ATTRIBS + POS_ATTRIB     ] = feedback.get(6*vertex  );
-         mVertAttribs[vertex*VERT_ATTRIBS + POS_ATTRIB + 1 ] = feedback.get(6*vertex+1);
-         mVertAttribs[vertex*VERT_ATTRIBS + POS_ATTRIB + 2 ] = feedback.get(6*vertex+2);
-         mVertAttribs[vertex*VERT_ATTRIBS + NOR_ATTRIB     ] = feedback.get(6*vertex+3);
-         mVertAttribs[vertex*VERT_ATTRIBS + NOR_ATTRIB + 1 ] = feedback.get(6*vertex+4);
-         mVertAttribs[vertex*VERT_ATTRIBS + NOR_ATTRIB + 2 ] = feedback.get(6*vertex+5);
-         }
-
-       mVBO.update(mVertAttribs);
-       }
-
      GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK);
 
      int numComp = mComponent.size();
@@ -379,13 +383,15 @@ public abstract class MeshBase
        DistortedLibrary.adjustVertices(this);
        }
 
-     int index = mVBO.createImmediately(mNumVertices*VERT_SIZE, mVertAttribs);
+     int index1 = mVBO1.createImmediately(mNumVertices*VERT1_SIZE, mVertAttribs1);
+     int index2 = mVBO2.createImmediately(mNumVertices*VERT2_SIZE, mVertAttribs2);
 
-     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, index );
-     GLES30.glVertexAttribPointer(program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, VERT_SIZE, OFFSET_POS);
-     GLES30.glVertexAttribPointer(program.mAttribute[1], NOR_DATA_SIZE, GLES30.GL_FLOAT, false, VERT_SIZE, OFFSET_NOR);
-     GLES30.glVertexAttribPointer(program.mAttribute[2], INF_DATA_SIZE, GLES30.GL_FLOAT, false, VERT_SIZE, OFFSET_INF);
-     GLES30.glVertexAttribPointer(program.mAttribute[3], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, VERT_SIZE, OFFSET_TEX);
+     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, index1 );
+     GLES30.glVertexAttribPointer(program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, VERT1_SIZE, OFFSET_POS);
+     GLES30.glVertexAttribPointer(program.mAttribute[1], NOR_DATA_SIZE, GLES30.GL_FLOAT, false, VERT1_SIZE, OFFSET_NOR);
+     GLES30.glVertexAttribPointer(program.mAttribute[2], INF_DATA_SIZE, GLES30.GL_FLOAT, false, VERT1_SIZE, OFFSET_INF);
+     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, index2 );
+     GLES30.glVertexAttribPointer(program.mAttribute[3], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, VERT2_SIZE, OFFSET_TEX);
      GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
      }
 
@@ -458,9 +464,11 @@ public abstract class MeshBase
  */
    public void markForDeletion()
      {
-     mVertAttribs = null;
+     mVertAttribs1 = null;
+     mVertAttribs2 = null;
 
-     mVBO.markForDeletion();
+     mVBO1.markForDeletion();
+     mVBO2.markForDeletion();
      mTFO.markForDeletion();
      }
 
@@ -538,10 +546,10 @@ public abstract class MeshBase
            movX = newMap.get0() - ratW*oldMap.get0();
            movY = newMap.get1() - ratH*oldMap.get1();
 
-           for( int index=vertex*VERT_ATTRIBS+TEX_ATTRIB ; vertex<=comp.mEndIndex; vertex++, index+=VERT_ATTRIBS)
+           for( int index=vertex*VERT2_ATTRIBS+TEX_ATTRIB ; vertex<=comp.mEndIndex; vertex++, index+=VERT2_ATTRIBS)
              {
-             mVertAttribs[index  ] = ratW*mVertAttribs[index  ] + movX;
-             mVertAttribs[index+1] = ratH*mVertAttribs[index+1] + movY;
+             mVertAttribs2[index  ] = ratW*mVertAttribs2[index  ] + movX;
+             mVertAttribs2[index+1] = ratH*mVertAttribs2[index+1] + movY;
              }
            comp.setMap(newMap);
            }
@@ -550,7 +558,7 @@ public abstract class MeshBase
        vertex= comp.mEndIndex+1;
        }
 
-     mVBO.invalidate();
+     mVBO2.invalidate();
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/mesh/MeshCubes.java b/src/main/java/org/distorted/library/mesh/MeshCubes.java
index bc28882..15aa518 100644
--- a/src/main/java/org/distorted/library/mesh/MeshCubes.java
+++ b/src/main/java/org/distorted/library/mesh/MeshCubes.java
@@ -391,7 +391,7 @@ public class MeshCubes extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void buildFrontBackGrid(boolean front, float[] attribs)
+  private void buildFrontBackGrid(boolean front, float[] attribs1, float[] attribs2)
      {
      int last, current;
      boolean seenLand=false;
@@ -413,7 +413,7 @@ public class MeshCubes extends MeshBase
 
            if( !seenLand && !front && ((currVert%2==1)^currentBlockIsNE) )
              {
-             repeatLast(attribs);
+             repeatLast(attribs1,attribs2);
              }
 
            createNormals(front,row,col);
@@ -422,27 +422,27 @@ public class MeshCubes extends MeshBase
              {
              if( (last!=current) || !lastBlockIsNE )
                {
-               if( seenLand  && (last != current) ) repeatLast(attribs);
-               addFrontVertex( 0, vectZ, col, row, attribs);
-               if( seenLand  && (last != current) ) repeatLast(attribs);
-               if( !lastBlockIsNE || (!front && !seenLand) ) repeatLast(attribs);
-               addFrontVertex( 1, vectZ, col, row+1, attribs);
+               if( seenLand  && (last != current) ) repeatLast(attribs1,attribs2);
+               addFrontVertex( 0, vectZ, col, row, attribs1,attribs2);
+               if( seenLand  && (last != current) ) repeatLast(attribs1,attribs2);
+               if( !lastBlockIsNE || (!front && !seenLand) ) repeatLast(attribs1,attribs2);
+               addFrontVertex( 1, vectZ, col, row+1, attribs1,attribs2);
                }
-             addFrontVertex( 2, vectZ, col+1, row  , attribs);
-             addFrontVertex( 3, vectZ, col+1, row+1, attribs);
+             addFrontVertex( 2, vectZ, col+1, row  , attribs1,attribs2);
+             addFrontVertex( 3, vectZ, col+1, row+1, attribs1,attribs2);
              }
            else
              {
              if( (last!=current) || lastBlockIsNE )
                {
-               if( seenLand  && (last != current) ) repeatLast(attribs);
-               addFrontVertex( 1, vectZ, col, row+1, attribs);
-               if( seenLand  && (last != current) ) repeatLast(attribs);
-               if( lastBlockIsNE || (!front && !seenLand) ) repeatLast(attribs);
-               addFrontVertex( 0, vectZ, col, row, attribs);
+               if( seenLand  && (last != current) ) repeatLast(attribs1,attribs2);
+               addFrontVertex( 1, vectZ, col, row+1, attribs1,attribs2);
+               if( seenLand  && (last != current) ) repeatLast(attribs1,attribs2);
+               if( lastBlockIsNE || (!front && !seenLand) ) repeatLast(attribs1,attribs2);
+               addFrontVertex( 0, vectZ, col, row, attribs1,attribs2);
                }
-             addFrontVertex( 3, vectZ, col+1, row+1, attribs);
-             addFrontVertex( 2, vectZ, col+1, row  , attribs);
+             addFrontVertex( 3, vectZ, col+1, row+1, attribs1,attribs2);
+             addFrontVertex( 2, vectZ, col+1, row  , attribs1,attribs2);
              }
 
            seenLand = true;
@@ -456,17 +456,17 @@ public class MeshCubes extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void buildSideGrid(float[] attribs)
+  private void buildSideGrid(float[] attribs1,float[] attribs2)
      {
      for(int i=0; i<mEdgeNum; i++)
        {
-       buildIthSide(mEdges.get(i), attribs);
+       buildIthSide(mEdges.get(i), attribs1, attribs2);
        }
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void buildIthSide(Edge curr, float[] attribs)
+  private void buildIthSide(Edge curr, float[] attribs1, float[] attribs2)
      {
      Edge prev, next;
      int col, row, side;
@@ -488,18 +488,18 @@ public class MeshCubes extends MeshBase
        side= curr.side;
        next = getNextEdge(curr);
      
-       addSideVertex(curr,true,slice+1,prev.side,attribs);
+       addSideVertex(curr,true,slice+1,prev.side,attribs1,attribs2);
 
        do
          {
          if( prev.side!=curr.side )
            {
-           addSideVertex(curr,true,slice+1,prev.side,attribs);
-           addSideVertex(curr,true,slice  ,prev.side,attribs);
+           addSideVertex(curr,true,slice+1,prev.side,attribs1,attribs2);
+           addSideVertex(curr,true,slice  ,prev.side,attribs1,attribs2);
            }
        
-         addSideVertex(curr,false,slice+1,next.side,attribs);
-         addSideVertex(curr,false,slice  ,next.side,attribs);
+         addSideVertex(curr,false,slice+1,next.side,attribs1,attribs2);
+         addSideVertex(curr,false,slice  ,next.side,attribs1,attribs2);
        
          prev = curr;
          curr = next;
@@ -507,7 +507,7 @@ public class MeshCubes extends MeshBase
          }
        while( curr.col!=col || curr.row!=row || curr.side!=side );
      
-       repeatLast(attribs);
+       repeatLast(attribs1,attribs2);
        }
      }
 
@@ -615,32 +615,32 @@ public class MeshCubes extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void addFrontVertex(int index, float vectZ, int col, int row, float[] attribs)
+  private void addFrontVertex(int index, float vectZ, int col, int row, float[] attribs1, float[] attribs2)
      {
      float x = (float)col/mCols;
      float y = (float)row/mRows;
 
-     attribs[VERT_ATTRIBS*currVert + POS_ATTRIB  ] = x-0.5f;
-     attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+1] = 0.5f-y;
-     attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+2] = vectZ;
+     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x-0.5f;
+     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = 0.5f-y;
+     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = vectZ;
 
-     attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB  ] = mNormalX[index];
-     attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+1] = mNormalY[index];
-     attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+2] = mNormalZ[index];
+     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = mNormalX[index];
+     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = mNormalY[index];
+     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = mNormalZ[index];
 
-     attribs[VERT_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
-     attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
-     attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = vectZ;
+     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
+     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
+     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = vectZ;
 
      if( vectZ>0 )
        {
-       attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[FRONT] +       x  * mTexMappingW[FRONT];
-       attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[FRONT] + (1.0f-y) * mTexMappingH[FRONT];
+       attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[FRONT] +       x  * mTexMappingW[FRONT];
+       attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[FRONT] + (1.0f-y) * mTexMappingH[FRONT];
        }
      else
        {
-       attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[BACK]  +       x  * mTexMappingW[BACK];
-       attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[BACK]  + (1.0f-y) * mTexMappingH[BACK];
+       attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[BACK]  +       x  * mTexMappingW[BACK];
+       attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[BACK]  + (1.0f-y) * mTexMappingH[BACK];
        }
 
      currVert++;
@@ -648,7 +648,7 @@ public class MeshCubes extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void addSideVertex(Edge curr, boolean back, int slice, int side, float[] attribs)
+  private void addSideVertex(Edge curr, boolean back, int slice, int side, float[] attribs1, float[] attribs2)
      {
      float x, y, z;
      int row, col;
@@ -661,20 +661,20 @@ public class MeshCubes extends MeshBase
                    y = 0.5f - (float)row/mRows;
                    z = 0.5f - (float)slice/mSlices;
 
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB  ] = x - 0.5f;
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+1] = y;
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+2] = z;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x - 0.5f;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = y;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = z;
 
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB  ] = side==NORTH ? 0.0f : (side==WEST?-R:R);
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+1] = 1.0f;
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = side==NORTH ? 0.0f : (side==WEST?-R:R);
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = 1.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
 
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = z;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = z;
 
-                   attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[TOP] +       x  * mTexMappingW[TOP];
-                   attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[TOP] + (0.5f-z) * mTexMappingH[TOP];
+                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[TOP] +       x  * mTexMappingW[TOP];
+                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[TOP] + (0.5f-z) * mTexMappingH[TOP];
 
                    break;
        case SOUTH: row = curr.row+1;
@@ -683,20 +683,20 @@ public class MeshCubes extends MeshBase
                    y = 0.5f - (float)row/mRows;
                    z = 0.5f - (float)slice/mSlices;
 
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB  ] = x - 0.5f;
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+1] = y;
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+2] = z;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x - 0.5f;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = y;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = z;
 
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB  ] = side==SOUTH ? 0.0f: (side==EAST?-R:R);
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+1] =-1.0f;
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = side==SOUTH ? 0.0f: (side==EAST?-R:R);
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] =-1.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
 
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = z;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = z;
 
-                   attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[BOTTOM] +       x  * mTexMappingW[BOTTOM];
-                   attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[BOTTOM] + (0.5f-z) * mTexMappingH[BOTTOM];
+                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[BOTTOM] +       x  * mTexMappingW[BOTTOM];
+                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[BOTTOM] + (0.5f-z) * mTexMappingH[BOTTOM];
 
                    break;
        case WEST : row = (back  ? (curr.row+1):(curr.row));
@@ -705,20 +705,20 @@ public class MeshCubes extends MeshBase
                    y = (float)row/mRows;
                    z = 0.5f - (float)slice/mSlices;
 
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB  ] = x;
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+1] = 0.5f - y;
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+2] = z;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = 0.5f - y;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = z;
 
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB  ] =-1.0f;
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+1] = side==WEST ? 0.0f : (side==NORTH?-R:R);
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] =-1.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = side==WEST ? 0.0f : (side==NORTH?-R:R);
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
 
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = z;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = z;
 
-                   attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[LEFT] + (0.5f-z) * mTexMappingW[LEFT];
-                   attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[LEFT] + (1.0f-y) * mTexMappingH[LEFT];
+                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[LEFT] + (0.5f-z) * mTexMappingW[LEFT];
+                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[LEFT] + (1.0f-y) * mTexMappingH[LEFT];
 
                    break;
        case EAST : row = (back  ? (curr.row):(curr.row+1));
@@ -727,20 +727,20 @@ public class MeshCubes extends MeshBase
                    y = (float)row/mRows;
                    z = 0.5f - (float)slice/mSlices;
 
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB  ] = x;
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+1] = 0.5f - y;
-                   attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+2] = z;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = x;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = 0.5f - y;
+                   attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = z;
 
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB  ] = 1.0f;
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+1] = side==EAST ? 0.0f : (side==SOUTH?-R:R);
-                   attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = 1.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = side==EAST ? 0.0f : (side==SOUTH?-R:R);
+                   attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = (slice==0 ? R : (slice==mSlices ? -R:0) );
 
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
-                   attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = z;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = mInflateX[row][col]/2.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = mInflateY[row][col]/2.0f;
+                   attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = z;
 
-                   attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[RIGHT] + (0.5f-z) * mTexMappingW[RIGHT];
-                   attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[RIGHT] + (1.0f-y) * mTexMappingH[RIGHT];
+                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = mTexMappingX[RIGHT] + (0.5f-z) * mTexMappingW[RIGHT];
+                   attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = mTexMappingY[RIGHT] + (1.0f-y) * mTexMappingH[RIGHT];
 
                    break;
        }
@@ -750,22 +750,22 @@ public class MeshCubes extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   private void repeatLast(float[] attribs)
+   private void repeatLast(float[] attribs1, float[] attribs2)
      {
-     attribs[VERT_ATTRIBS*currVert + POS_ATTRIB  ] = attribs[VERT_ATTRIBS*(currVert-1) + POS_ATTRIB  ];
-     attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+1] = attribs[VERT_ATTRIBS*(currVert-1) + POS_ATTRIB+1];
-     attribs[VERT_ATTRIBS*currVert + POS_ATTRIB+2] = attribs[VERT_ATTRIBS*(currVert-1) + POS_ATTRIB+2];
+     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(currVert-1) + POS_ATTRIB  ];
+     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(currVert-1) + POS_ATTRIB+1];
+     attribs1[VERT1_ATTRIBS*currVert + POS_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(currVert-1) + POS_ATTRIB+2];
 
-     attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB  ] = attribs[VERT_ATTRIBS*(currVert-1) + NOR_ATTRIB  ];
-     attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+1] = attribs[VERT_ATTRIBS*(currVert-1) + NOR_ATTRIB+1];
-     attribs[VERT_ATTRIBS*currVert + NOR_ATTRIB+2] = attribs[VERT_ATTRIBS*(currVert-1) + NOR_ATTRIB+2];
+     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(currVert-1) + NOR_ATTRIB  ];
+     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(currVert-1) + NOR_ATTRIB+1];
+     attribs1[VERT1_ATTRIBS*currVert + NOR_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(currVert-1) + NOR_ATTRIB+2];
 
-     attribs[VERT_ATTRIBS*currVert + INF_ATTRIB  ] = attribs[VERT_ATTRIBS*(currVert-1) + INF_ATTRIB  ];
-     attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+1] = attribs[VERT_ATTRIBS*(currVert-1) + INF_ATTRIB+1];
-     attribs[VERT_ATTRIBS*currVert + INF_ATTRIB+2] = attribs[VERT_ATTRIBS*(currVert-1) + INF_ATTRIB+2];
+     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(currVert-1) + INF_ATTRIB  ];
+     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(currVert-1) + INF_ATTRIB+1];
+     attribs1[VERT1_ATTRIBS*currVert + INF_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(currVert-1) + INF_ATTRIB+2];
 
-     attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB  ] = attribs[VERT_ATTRIBS*(currVert-1) + TEX_ATTRIB  ];
-     attribs[VERT_ATTRIBS*currVert + TEX_ATTRIB+1] = attribs[VERT_ATTRIBS*(currVert-1) + TEX_ATTRIB+1];
+     attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB  ] = attribs2[VERT2_ATTRIBS*(currVert-1) + TEX_ATTRIB  ];
+     attribs2[VERT2_ATTRIBS*currVert + TEX_ATTRIB+1] = attribs2[VERT2_ATTRIBS*(currVert-1) + TEX_ATTRIB+1];
 
      currVert++;
      }
@@ -774,16 +774,17 @@ public class MeshCubes extends MeshBase
 
   private void build()
      {
-     float[] attribs= new float[VERT_ATTRIBS*numVertices];
+     float[] attribs1= new float[VERT1_ATTRIBS*numVertices];
+     float[] attribs2= new float[VERT2_ATTRIBS*numVertices];
 
-     buildFrontBackGrid(true,attribs);
+     buildFrontBackGrid(true,attribs1,attribs2);
 
      if( mSlices>0 )
        {
-       repeatLast(attribs);
-       if( currVert%2==1 ) repeatLast(attribs);
-       buildSideGrid(attribs);
-       buildFrontBackGrid(false,attribs);
+       repeatLast(attribs1,attribs2);
+       if( currVert%2==1 ) repeatLast(attribs1,attribs2);
+       buildSideGrid(attribs1,attribs2);
+       buildFrontBackGrid(false,attribs1,attribs2);
        }
 
      mEdges.clear();
@@ -795,7 +796,7 @@ public class MeshCubes extends MeshBase
      if( currVert!=numVertices )
        android.util.Log.e("MeshCubes", "currVert " +currVert+" numVertices="+numVertices );
 
-     setAttribs(attribs);
+     setAttribs(attribs1,attribs2);
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/mesh/MeshJoined.java b/src/main/java/org/distorted/library/mesh/MeshJoined.java
index dac97b9..affe71a 100644
--- a/src/main/java/org/distorted/library/mesh/MeshJoined.java
+++ b/src/main/java/org/distorted/library/mesh/MeshJoined.java
@@ -25,7 +25,7 @@ public class MeshJoined extends MeshBase
   {
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Join a list of (probably already changed by Matrix Effects) Meshes into one.
+ * Join a list of (probably already changed by Vertex Effects) Meshes into one.
  * <p>
  * You need to try and keep the origin (0,0,0) in the center of gravity of the whole thing.
  */
@@ -39,7 +39,7 @@ public class MeshJoined extends MeshBase
 /**
  * deep copy.
  */
- public MeshJoined(MeshJoined mesh)
+  public MeshJoined(MeshJoined mesh)
    {
    super(mesh);
    }
@@ -48,7 +48,7 @@ public class MeshJoined extends MeshBase
 /**
  * deep copy.
  */
- public MeshJoined deepCopy()
+  public MeshJoined deepCopy()
    {
    return new MeshJoined(this);
    }
@@ -57,7 +57,7 @@ public class MeshJoined extends MeshBase
 /**
  * Return how many basic Meshes is this Mesh joined from.
  */
-   public int getNumComponents()
+  public int getNumComponents()
      {
      return numComponents();
      }
diff --git a/src/main/java/org/distorted/library/mesh/MeshQuad.java b/src/main/java/org/distorted/library/mesh/MeshQuad.java
index 7dc3136..1a12892 100644
--- a/src/main/java/org/distorted/library/mesh/MeshQuad.java
+++ b/src/main/java/org/distorted/library/mesh/MeshQuad.java
@@ -30,22 +30,22 @@ public class MeshQuad extends MeshBase
   {
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void addVertex( float x, float y, float[] attribs, int index)
+  private void addVertex( float x, float y, float[] attribs1, float[] attribs2, int index)
     {
-    attribs[VERT_ATTRIBS*index + POS_ATTRIB  ] = x-0.5f;
-    attribs[VERT_ATTRIBS*index + POS_ATTRIB+1] = 0.5f-y;
-    attribs[VERT_ATTRIBS*index + POS_ATTRIB+2] = 0.0f;
+    attribs1[VERT1_ATTRIBS*index + POS_ATTRIB  ] = x-0.5f;
+    attribs1[VERT1_ATTRIBS*index + POS_ATTRIB+1] = 0.5f-y;
+    attribs1[VERT1_ATTRIBS*index + POS_ATTRIB+2] = 0.0f;
 
-    attribs[VERT_ATTRIBS*index + NOR_ATTRIB  ] = 0.0f;
-    attribs[VERT_ATTRIBS*index + NOR_ATTRIB+1] = 0.0f;
-    attribs[VERT_ATTRIBS*index + NOR_ATTRIB+2] = 1.0f;
+    attribs1[VERT1_ATTRIBS*index + NOR_ATTRIB  ] = 0.0f;
+    attribs1[VERT1_ATTRIBS*index + NOR_ATTRIB+1] = 0.0f;
+    attribs1[VERT1_ATTRIBS*index + NOR_ATTRIB+2] = 1.0f;
 
-    attribs[VERT_ATTRIBS*index + INF_ATTRIB  ] = (x-0.5f);
-    attribs[VERT_ATTRIBS*index + INF_ATTRIB+1] = (0.5f-y);
-    attribs[VERT_ATTRIBS*index + INF_ATTRIB+2] = 0.01f   ;  // Inflated surface needs to be slightly in front
+    attribs1[VERT1_ATTRIBS*index + INF_ATTRIB  ] = (x-0.5f);
+    attribs1[VERT1_ATTRIBS*index + INF_ATTRIB+1] = (0.5f-y);
+    attribs1[VERT1_ATTRIBS*index + INF_ATTRIB+2] = 0.01f   ;  // Inflated surface needs to be slightly in front
 
-    attribs[VERT_ATTRIBS*index + TEX_ATTRIB  ] = x;
-    attribs[VERT_ATTRIBS*index + TEX_ATTRIB+1] = 1.0f-y;
+    attribs2[VERT2_ATTRIBS*index + TEX_ATTRIB  ] = x;
+    attribs2[VERT2_ATTRIBS*index + TEX_ATTRIB+1] = 1.0f-y;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -57,14 +57,16 @@ public class MeshQuad extends MeshBase
   public MeshQuad()
     {
     super();
-    float[] attribs= new float[VERT_ATTRIBS*4];
 
-    addVertex(0.0f,0.0f, attribs,0);
-    addVertex(0.0f,1.0f, attribs,1);
-    addVertex(1.0f,0.0f, attribs,2);
-    addVertex(1.0f,1.0f, attribs,3);
+    float[] attribs1= new float[VERT1_ATTRIBS*4];
+    float[] attribs2= new float[VERT2_ATTRIBS*4];
 
-    setAttribs(attribs);
+    addVertex(0.0f,0.0f, attribs1, attribs2, 0);
+    addVertex(0.0f,1.0f, attribs1, attribs2, 1);
+    addVertex(1.0f,0.0f, attribs1, attribs2, 2);
+    addVertex(1.0f,1.0f, attribs1, attribs2, 3);
+
+    setAttribs(attribs1,attribs2);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/mesh/MeshRectangles.java b/src/main/java/org/distorted/library/mesh/MeshRectangles.java
index 25fa60b..6c6c2dd 100644
--- a/src/main/java/org/distorted/library/mesh/MeshRectangles.java
+++ b/src/main/java/org/distorted/library/mesh/MeshRectangles.java
@@ -55,50 +55,50 @@ public class MeshRectangles extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int addVertex(int vertex, float x, float y, float[] attribs)
+  private int addVertex(int vertex, float x, float y, float[] attribs1, float[] attribs2)
      {
      remainingVert--;
 
-     attribs[VERT_ATTRIBS*vertex + POS_ATTRIB  ] = x-0.5f;
-     attribs[VERT_ATTRIBS*vertex + POS_ATTRIB+1] = 0.5f-y;
-     attribs[VERT_ATTRIBS*vertex + POS_ATTRIB+2] = 0.0f;
+     attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB  ] = x-0.5f;
+     attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+1] = 0.5f-y;
+     attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+2] = 0.0f;
 
-     attribs[VERT_ATTRIBS*vertex + NOR_ATTRIB  ] = 0.0f;
-     attribs[VERT_ATTRIBS*vertex + NOR_ATTRIB+1] = 0.0f;
-     attribs[VERT_ATTRIBS*vertex + NOR_ATTRIB+2] = 1.0f;
+     attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB  ] = 0.0f;
+     attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB+1] = 0.0f;
+     attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB+2] = 1.0f;
 
-     attribs[VERT_ATTRIBS*vertex + INF_ATTRIB  ] = (x-0.5f);
-     attribs[VERT_ATTRIBS*vertex + INF_ATTRIB+1] = (0.5f-y);
-     attribs[VERT_ATTRIBS*vertex + INF_ATTRIB+2] = 0.01f   ;  // Inflated surface needs to be slightly in front
+     attribs1[VERT1_ATTRIBS*vertex + INF_ATTRIB  ] = (x-0.5f);
+     attribs1[VERT1_ATTRIBS*vertex + INF_ATTRIB+1] = (0.5f-y);
+     attribs1[VERT1_ATTRIBS*vertex + INF_ATTRIB+2] = 0.01f   ;  // Inflated surface needs to be slightly in front
 
-     attribs[VERT_ATTRIBS*vertex + TEX_ATTRIB  ] = x;
-     attribs[VERT_ATTRIBS*vertex + TEX_ATTRIB+1] = 1.0f-y;
+     attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB  ] = x;
+     attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB+1] = 1.0f-y;
 
      return vertex+1;
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int repeatLast(int vertex, float[] attribs)
+  private int repeatLast(int vertex, float[] attribs1, float[] attribs2)
      {
      if( vertex>0 )
        {
        remainingVert--;
 
-       attribs[VERT_ATTRIBS*vertex + POS_ATTRIB  ] = attribs[VERT_ATTRIBS*(vertex-1) + POS_ATTRIB  ];
-       attribs[VERT_ATTRIBS*vertex + POS_ATTRIB+1] = attribs[VERT_ATTRIBS*(vertex-1) + POS_ATTRIB+1];
-       attribs[VERT_ATTRIBS*vertex + POS_ATTRIB+2] = attribs[VERT_ATTRIBS*(vertex-1) + POS_ATTRIB+2];
+       attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(vertex-1) + POS_ATTRIB  ];
+       attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(vertex-1) + POS_ATTRIB+1];
+       attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(vertex-1) + POS_ATTRIB+2];
 
-       attribs[VERT_ATTRIBS*vertex + NOR_ATTRIB  ] = attribs[VERT_ATTRIBS*(vertex-1) + NOR_ATTRIB  ];
-       attribs[VERT_ATTRIBS*vertex + NOR_ATTRIB+1] = attribs[VERT_ATTRIBS*(vertex-1) + NOR_ATTRIB+1];
-       attribs[VERT_ATTRIBS*vertex + NOR_ATTRIB+2] = attribs[VERT_ATTRIBS*(vertex-1) + NOR_ATTRIB+2];
+       attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(vertex-1) + NOR_ATTRIB  ];
+       attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(vertex-1) + NOR_ATTRIB+1];
+       attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(vertex-1) + NOR_ATTRIB+2];
 
-       attribs[VERT_ATTRIBS*vertex + INF_ATTRIB  ] = attribs[VERT_ATTRIBS*(vertex-1) + INF_ATTRIB  ];
-       attribs[VERT_ATTRIBS*vertex + INF_ATTRIB+1] = attribs[VERT_ATTRIBS*(vertex-1) + INF_ATTRIB+1];
-       attribs[VERT_ATTRIBS*vertex + INF_ATTRIB+2] = attribs[VERT_ATTRIBS*(vertex-1) + INF_ATTRIB+2];
+       attribs1[VERT1_ATTRIBS*vertex + INF_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(vertex-1) + INF_ATTRIB  ];
+       attribs1[VERT1_ATTRIBS*vertex + INF_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(vertex-1) + INF_ATTRIB+1];
+       attribs1[VERT1_ATTRIBS*vertex + INF_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(vertex-1) + INF_ATTRIB+2];
 
-       attribs[VERT_ATTRIBS*vertex + TEX_ATTRIB  ] = attribs[VERT_ATTRIBS*(vertex-1) + TEX_ATTRIB  ];
-       attribs[VERT_ATTRIBS*vertex + TEX_ATTRIB+1] = attribs[VERT_ATTRIBS*(vertex-1) + TEX_ATTRIB+1];
+       attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB  ] = attribs2[VERT2_ATTRIBS*(vertex-1) + TEX_ATTRIB  ];
+       attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB+1] = attribs2[VERT2_ATTRIBS*(vertex-1) + TEX_ATTRIB+1];
 
        vertex++;
        }
@@ -108,7 +108,7 @@ public class MeshRectangles extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void buildGrid(float[] attribs)
+  private void buildGrid(float[] attribs1, float[] attribs2)
      {
      boolean lastBlockIsNE = false;
      boolean currentBlockIsNE;
@@ -130,14 +130,14 @@ public class MeshRectangles extends MeshBase
 
          if( col==0 || (lastBlockIsNE^currentBlockIsNE) )
            {
-           if( row!=0 && col==0 ) vertex = repeatLast(vertex,attribs);
-           vertex= addVertex( vertex, x, y+(currentBlockIsNE?0:Y), attribs);
-           if( row!=0 && col==0 ) vertex = repeatLast(vertex,attribs);
-           if( lastBlockIsNE^currentBlockIsNE)  vertex = repeatLast(vertex,attribs);
-           vertex= addVertex( vertex, x, y+(currentBlockIsNE?Y:0), attribs);
+           if( row!=0 && col==0 ) vertex = repeatLast(vertex,attribs1,attribs2);
+           vertex= addVertex( vertex, x, y+(currentBlockIsNE?0:Y), attribs1,attribs2);
+           if( row!=0 && col==0 ) vertex = repeatLast(vertex,attribs1,attribs2);
+           if( lastBlockIsNE^currentBlockIsNE)  vertex = repeatLast(vertex,attribs1,attribs2);
+           vertex= addVertex( vertex, x, y+(currentBlockIsNE?Y:0), attribs1,attribs2);
            }
-         vertex= addVertex( vertex, x+X, y+(currentBlockIsNE?0:Y), attribs);
-         vertex= addVertex( vertex, x+X, y+(currentBlockIsNE?Y:0), attribs);
+         vertex= addVertex( vertex, x+X, y+(currentBlockIsNE?0:Y), attribs1,attribs2);
+         vertex= addVertex( vertex, x+X, y+(currentBlockIsNE?Y:0), attribs1,attribs2);
 
          lastBlockIsNE = currentBlockIsNE;
          x+=X;
@@ -156,36 +156,37 @@ public class MeshRectangles extends MeshBase
  * @param cols Number of columns in the grid.
  * @param rows Number of rows in the grid.
  */
- public MeshRectangles(int cols, int rows)
+  public MeshRectangles(int cols, int rows)
     {
     super();
     computeNumberOfVertices(cols,rows);
 
-    float[] attribs= new float[VERT_ATTRIBS*numVertices];
+    float[] attribs1= new float[VERT1_ATTRIBS*numVertices];
+    float[] attribs2= new float[VERT2_ATTRIBS*numVertices];
 
-    buildGrid(attribs);
+    buildGrid(attribs1,attribs2);
 
     if( remainingVert!=0 )
       android.util.Log.d("MeshRectangles", "remainingVert " +remainingVert );
 
-    setAttribs(attribs);
+    setAttribs(attribs1,attribs2);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * deep copy.
  */
- public MeshRectangles(MeshRectangles mesh)
-   {
-   super(mesh);
-   }
+  public MeshRectangles(MeshRectangles mesh)
+    {
+    super(mesh);
+    }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * deep copy.
  */
- public MeshRectangles deepCopy()
-   {
-   return new MeshRectangles(this);
-   }
+  public MeshRectangles deepCopy()
+    {
+    return new MeshRectangles(this);
+    }
  }
\ No newline at end of file
diff --git a/src/main/java/org/distorted/library/mesh/MeshSphere.java b/src/main/java/org/distorted/library/mesh/MeshSphere.java
index 45ce7bc..a92b099 100644
--- a/src/main/java/org/distorted/library/mesh/MeshSphere.java
+++ b/src/main/java/org/distorted/library/mesh/MeshSphere.java
@@ -77,24 +77,24 @@ public class MeshSphere extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void repeatVertex(float[] attribs)
+  private void repeatVertex(float[] attribs1, float[] attribs2)
     {
     if( currentVert>0 )
       {
-      attribs[VERT_ATTRIBS*currentVert + POS_ATTRIB  ] = attribs[VERT_ATTRIBS*(currentVert-1) + POS_ATTRIB  ];
-      attribs[VERT_ATTRIBS*currentVert + POS_ATTRIB+1] = attribs[VERT_ATTRIBS*(currentVert-1) + POS_ATTRIB+1];
-      attribs[VERT_ATTRIBS*currentVert + POS_ATTRIB+2] = attribs[VERT_ATTRIBS*(currentVert-1) + POS_ATTRIB+2];
+      attribs1[VERT1_ATTRIBS*currentVert + POS_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(currentVert-1) + POS_ATTRIB  ];
+      attribs1[VERT1_ATTRIBS*currentVert + POS_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(currentVert-1) + POS_ATTRIB+1];
+      attribs1[VERT1_ATTRIBS*currentVert + POS_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(currentVert-1) + POS_ATTRIB+2];
 
-      attribs[VERT_ATTRIBS*currentVert + NOR_ATTRIB  ] = attribs[VERT_ATTRIBS*(currentVert-1) + NOR_ATTRIB  ];
-      attribs[VERT_ATTRIBS*currentVert + NOR_ATTRIB+1] = attribs[VERT_ATTRIBS*(currentVert-1) + NOR_ATTRIB+1];
-      attribs[VERT_ATTRIBS*currentVert + NOR_ATTRIB+2] = attribs[VERT_ATTRIBS*(currentVert-1) + NOR_ATTRIB+2];
+      attribs1[VERT1_ATTRIBS*currentVert + NOR_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(currentVert-1) + NOR_ATTRIB  ];
+      attribs1[VERT1_ATTRIBS*currentVert + NOR_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(currentVert-1) + NOR_ATTRIB+1];
+      attribs1[VERT1_ATTRIBS*currentVert + NOR_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(currentVert-1) + NOR_ATTRIB+2];
 
-      attribs[VERT_ATTRIBS*currentVert + INF_ATTRIB  ] = attribs[VERT_ATTRIBS*(currentVert-1) + INF_ATTRIB  ];
-      attribs[VERT_ATTRIBS*currentVert + INF_ATTRIB+1] = attribs[VERT_ATTRIBS*(currentVert-1) + INF_ATTRIB+1];
-      attribs[VERT_ATTRIBS*currentVert + INF_ATTRIB+2] = attribs[VERT_ATTRIBS*(currentVert-1) + INF_ATTRIB+2];
+      attribs1[VERT1_ATTRIBS*currentVert + INF_ATTRIB  ] = attribs1[VERT1_ATTRIBS*(currentVert-1) + INF_ATTRIB  ];
+      attribs1[VERT1_ATTRIBS*currentVert + INF_ATTRIB+1] = attribs1[VERT1_ATTRIBS*(currentVert-1) + INF_ATTRIB+1];
+      attribs1[VERT1_ATTRIBS*currentVert + INF_ATTRIB+2] = attribs1[VERT1_ATTRIBS*(currentVert-1) + INF_ATTRIB+2];
 
-      attribs[VERT_ATTRIBS*currentVert + TEX_ATTRIB  ] = attribs[VERT_ATTRIBS*(currentVert-1) + TEX_ATTRIB  ];
-      attribs[VERT_ATTRIBS*currentVert + TEX_ATTRIB+1] = attribs[VERT_ATTRIBS*(currentVert-1) + TEX_ATTRIB+1];
+      attribs2[VERT2_ATTRIBS*currentVert + TEX_ATTRIB  ] = attribs2[VERT2_ATTRIBS*(currentVert-1) + TEX_ATTRIB  ];
+      attribs2[VERT2_ATTRIBS*currentVert + TEX_ATTRIB+1] = attribs2[VERT2_ATTRIBS*(currentVert-1) + TEX_ATTRIB+1];
 
       currentVert++;
       }
@@ -151,7 +151,7 @@ public class MeshSphere extends MeshBase
 // (      0, level-1, level) -> (lonV3,latV3 )
 // (level-1,       0, level) -> (lonV2,latV12)
 
-  private void addVertex(float[] attribs, int column, int row, int level,
+  private void addVertex(float[] attribs1, float[] attribs2, int column, int row, int level,
                          double lonV1, double lonV2, double latV12, double latV3)
     {
     double quotX = (double)column/level;
@@ -184,20 +184,20 @@ public class MeshSphere extends MeshBase
 
     double texY = 0.5 + latitude/P;
 
-    attribs[VERT_ATTRIBS*currentVert + POS_ATTRIB  ] = x;  //
-    attribs[VERT_ATTRIBS*currentVert + POS_ATTRIB+1] = y;  //
-    attribs[VERT_ATTRIBS*currentVert + POS_ATTRIB+2] = z;  //
-                                                           //  In case of this Mesh so it happens that
-    attribs[VERT_ATTRIBS*currentVert + NOR_ATTRIB  ] = 2*x;//  the vertex coords, normal vector, and
-    attribs[VERT_ATTRIBS*currentVert + NOR_ATTRIB+1] = 2*y;//  inflate vector have identical (x,y,z).
-    attribs[VERT_ATTRIBS*currentVert + NOR_ATTRIB+2] = 2*z;//
-                                                           //  TODO: think about some more efficient
-    attribs[VERT_ATTRIBS*currentVert + INF_ATTRIB  ] = x;  //  representation.
-    attribs[VERT_ATTRIBS*currentVert + INF_ATTRIB+1] = y;  //
-    attribs[VERT_ATTRIBS*currentVert + INF_ATTRIB+2] = z;  //
-
-    attribs[VERT_ATTRIBS*currentVert + TEX_ATTRIB  ] = (float)texX;
-    attribs[VERT_ATTRIBS*currentVert + TEX_ATTRIB+1] = (float)texY;
+    attribs1[VERT1_ATTRIBS*currentVert + POS_ATTRIB  ] = x;  //
+    attribs1[VERT1_ATTRIBS*currentVert + POS_ATTRIB+1] = y;  //
+    attribs1[VERT1_ATTRIBS*currentVert + POS_ATTRIB+2] = z;  //
+                                                             //  In case of this Mesh so it happens that
+    attribs1[VERT1_ATTRIBS*currentVert + NOR_ATTRIB  ] = 2*x;//  the vertex coords, normal vector, and
+    attribs1[VERT1_ATTRIBS*currentVert + NOR_ATTRIB+1] = 2*y;//  inflate vector have identical (x,y,z).
+    attribs1[VERT1_ATTRIBS*currentVert + NOR_ATTRIB+2] = 2*z;//
+                                                             //  TODO: think about some more efficient
+    attribs1[VERT1_ATTRIBS*currentVert + INF_ATTRIB  ] = x;  //  representation.
+    attribs1[VERT1_ATTRIBS*currentVert + INF_ATTRIB+1] = y;  //
+    attribs1[VERT1_ATTRIBS*currentVert + INF_ATTRIB+2] = z;  //
+
+    attribs2[VERT2_ATTRIBS*currentVert + TEX_ATTRIB  ] = (float)texX;
+    attribs2[VERT2_ATTRIBS*currentVert + TEX_ATTRIB+1] = (float)texY;
 
     currentVert++;
 
@@ -209,32 +209,32 @@ public class MeshSphere extends MeshBase
 
     if( currentVert>=3 && texX==0.0 )
       {
-      double tex1 = attribs[VERT_ATTRIBS*(currentVert-2) + TEX_ATTRIB];
-      double tex2 = attribs[VERT_ATTRIBS*(currentVert-3) + TEX_ATTRIB];
+      double tex1 = attribs2[VERT2_ATTRIBS*(currentVert-2) + TEX_ATTRIB];
+      double tex2 = attribs2[VERT2_ATTRIBS*(currentVert-3) + TEX_ATTRIB];
 
       // if the triangle is not degenerate and last vertex was on the western hemisphere
       if( tex1!=tex2 && tex1>0.5 )
         {
-        attribs[VERT_ATTRIBS*(currentVert-1) + TEX_ATTRIB] = 1.0f;
+        attribs2[VERT2_ATTRIBS*(currentVert-1) + TEX_ATTRIB] = 1.0f;
         }
       }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void buildFace(float[] attribs, int level, int face, double lonV1, double lonV2, double latV12, double latV3)
+  private void buildFace(float[] attribs1, float[] attribs2, int level, int face, double lonV1, double lonV2, double latV12, double latV3)
     {
     for(int row=0; row<level; row++)
       {
       for (int column=0; column<level-row; column++)
         {
-        addVertex(attribs, column, row  , level, lonV1, lonV2, latV12, latV3);
-        if (column==0 && !(face==0 && row==0 ) ) repeatVertex(attribs);
-        addVertex(attribs, column, row+1, level, lonV1, lonV2, latV12, latV3);
+        addVertex(attribs1, attribs2, column, row  , level, lonV1, lonV2, latV12, latV3);
+        if (column==0 && !(face==0 && row==0 ) ) repeatVertex(attribs1, attribs2);
+        addVertex(attribs1, attribs2, column, row+1, level, lonV1, lonV2, latV12, latV3);
         }
 
-      addVertex(attribs, level-row, row , level, lonV1, lonV2, latV12, latV3);
-      if( row!=level-1 || face!=NUMFACES-1 ) repeatVertex(attribs);
+      addVertex(attribs1, attribs2, level-row, row , level, lonV1, lonV2, latV12, latV3);
+      if( row!=level-1 || face!=NUMFACES-1 ) repeatVertex(attribs1, attribs2);
       }
     }
 
@@ -254,18 +254,20 @@ public class MeshSphere extends MeshBase
   public MeshSphere(int level)
     {
     super();
+
     computeNumberOfVertices(level);
-    float[] attribs= new float[VERT_ATTRIBS*numVertices];
+    float[] attribs1= new float[VERT1_ATTRIBS*numVertices];
+    float[] attribs2= new float[VERT2_ATTRIBS*numVertices];
 
     for(int face=0; face<NUMFACES; face++ )
       {
-      buildFace(attribs, level, face, FACES[face][0], FACES[face][1], FACES[face][2], FACES[face][3]);
+      buildFace(attribs1, attribs2, level, face, FACES[face][0], FACES[face][1], FACES[face][2], FACES[face][3]);
       }
 
     if( currentVert!=numVertices )
       android.util.Log.d("MeshSphere", "currentVert= " +currentVert+" numVertices="+numVertices );
 
-    setAttribs(attribs);
+    setAttribs(attribs1, attribs2);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/mesh/MeshTriangles.java b/src/main/java/org/distorted/library/mesh/MeshTriangles.java
index 3336789..6af5ec6 100644
--- a/src/main/java/org/distorted/library/mesh/MeshTriangles.java
+++ b/src/main/java/org/distorted/library/mesh/MeshTriangles.java
@@ -30,24 +30,24 @@ public class MeshTriangles extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int addVertex(int vertex, float x, float y, float[] attribs)
+  private int addVertex(int vertex, float x, float y, float[] attribs1, float[] attribs2)
      {
      remainingVert--;
 
-     attribs[VERT_ATTRIBS*vertex + POS_ATTRIB  ] = x-0.5f;
-     attribs[VERT_ATTRIBS*vertex + POS_ATTRIB+1] = y-0.5f;
-     attribs[VERT_ATTRIBS*vertex + POS_ATTRIB+2] = 0.0f;
+     attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB  ] = x-0.5f;
+     attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+1] = y-0.5f;
+     attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+2] = 0.0f;
 
-     attribs[VERT_ATTRIBS*vertex + NOR_ATTRIB  ] = 0.0f;
-     attribs[VERT_ATTRIBS*vertex + NOR_ATTRIB+1] = 0.0f;
-     attribs[VERT_ATTRIBS*vertex + NOR_ATTRIB+2] = 1.0f;
+     attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB  ] = 0.0f;
+     attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB+1] = 0.0f;
+     attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB+2] = 1.0f;
 
-     attribs[VERT_ATTRIBS*vertex + INF_ATTRIB  ] = (x-0.5f);
-     attribs[VERT_ATTRIBS*vertex + INF_ATTRIB+1] = (y-0.5f);
-     attribs[VERT_ATTRIBS*vertex + INF_ATTRIB+2] = 0.01f   ;  // Inflated surface needs to be slightly in front
+     attribs1[VERT1_ATTRIBS*vertex + INF_ATTRIB  ] = (x-0.5f);
+     attribs1[VERT1_ATTRIBS*vertex + INF_ATTRIB+1] = (y-0.5f);
+     attribs1[VERT1_ATTRIBS*vertex + INF_ATTRIB+2] = 0.01f   ;  // Inflated surface needs to be slightly in front
 
-     attribs[VERT_ATTRIBS*vertex + TEX_ATTRIB  ] = x;
-     attribs[VERT_ATTRIBS*vertex + TEX_ATTRIB+1] = y;
+     attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB  ] = x;
+     attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB+1] = y;
 
      return vertex+1;
      }
@@ -62,23 +62,23 @@ public class MeshTriangles extends MeshBase
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private int buildRow(int vertex,float sx, float sy, int length, float dx, float dy, float[] attribs)
+  private int buildRow(int vertex,float sx, float sy, int length, float dx, float dy, float[] attribs1, float[] attribs2)
     {
     for(int i=0; i<length; i++)
       {
-      vertex = addVertex(vertex, sx   , sy   , attribs);
-      vertex = addVertex(vertex, sx+dx, sy+dy, attribs);
+      vertex = addVertex(vertex, sx   , sy   , attribs1, attribs2);
+      vertex = addVertex(vertex, sx+dx, sy+dy, attribs1, attribs2);
       sx += 2*dx;
       }
 
-    vertex = addVertex(vertex, sx, sy, attribs);
+    vertex = addVertex(vertex, sx, sy, attribs1, attribs2);
 
     return vertex;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void buildGrid(float[] attribs, int level)
+  private void buildGrid(float[] attribs1, float[] attribs2, int level)
      {
      float sx = 0.0f;
      float sy = 0.0f;
@@ -88,7 +88,7 @@ public class MeshTriangles extends MeshBase
 
      for(int row=level; row>=1; row--)
        {
-       vertex = buildRow(vertex,sx,sy,row,dx,dy,attribs);
+       vertex = buildRow(vertex,sx,sy,row,dx,dy,attribs1,attribs2);
 
        sx += 2*dx*(row-0.5f);
        sy += dy;
@@ -111,13 +111,15 @@ public class MeshTriangles extends MeshBase
 
      computeNumberOfVertices(level);
 
-     float[] attribs= new float[VERT_ATTRIBS*numVertices];
-     buildGrid(attribs,level);
+     float[] attribs1= new float[VERT1_ATTRIBS*numVertices];
+     float[] attribs2= new float[VERT2_ATTRIBS*numVertices];
+
+     buildGrid(attribs1, attribs2, level);
 
      if( remainingVert!=0 )
        android.util.Log.d("MeshTriangles", "remainingVert " +remainingVert );
 
-     setAttribs(attribs);
+     setAttribs(attribs1, attribs2);
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/res/raw/main_vertex_shader.glsl b/src/main/res/raw/main_vertex_shader.glsl
index 2e4af7b..8606282 100644
--- a/src/main/res/raw/main_vertex_shader.glsl
+++ b/src/main/res/raw/main_vertex_shader.glsl
@@ -28,6 +28,11 @@ in vec2 a_TexCoordinate;             // Per-vertex texture coordinate.
 
 out vec3 v_Position;                 //
 out vec3 v_endPosition;              // for Transform Feedback only
+
+#ifdef PREAPPLY
+out vec3 v_Inflate;                  // Transform Feedback for preapply effects
+#endif
+
 out vec3 v_Normal;                   //
 out vec2 v_TexCoordinate;            //
 
@@ -95,6 +100,10 @@ void main()
   vec3 v = a_Position + u_Inflate*a_Inflate;
   vec3 n = a_Normal;
 
+#ifdef PREAPPLY
+  vec3 inf = a_Inflate;
+#endif
+
 #if NUM_VERTEX>0
   int effect=0;
 
@@ -110,6 +119,7 @@ void main()
 
 #ifdef PREAPPLY
   v_endPosition   = n;
+  v_Inflate       = inf;
 #else
   v_endPosition   = v + 0.5*n;
 #endif
