commit a22c66287b616833b0ad72d81d40cc321e4bc920
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Fri May 5 16:48:18 2017 +0100

    Beginnings of support for DistortedEffects.drawPrivFeedback()

diff --git a/src/main/java/org/distorted/library/DistortedEffects.java b/src/main/java/org/distorted/library/DistortedEffects.java
index a087f97..d5b2de5 100644
--- a/src/main/java/org/distorted/library/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/DistortedEffects.java
@@ -52,9 +52,11 @@ import java.nio.FloatBuffer;
  */
 public class DistortedEffects
   {
-  /// MAIN PROGRAM ///
-  private static DistortedProgram mMainProgram;
-  private static int mMainTextureH;
+  static final int MAIN_PROGRAM = 0;
+  static final int FEED_PROGRAM = 1;
+  static final int NUM_PROGRAMS = 2;
+
+  // THIS IS FOR MAIN AND FEEDBACK PROGRAMS ///
   private static boolean[] mEffectEnabled = new boolean[EffectNames.size()];
 
   static
@@ -67,6 +69,10 @@ public class DistortedEffects
       }
     }
 
+  /// MAIN PROGRAM ///
+  private static DistortedProgram mMainProgram;
+  private static int mMainTextureH;
+
   /// BLIT PROGRAM ///
   private static DistortedProgram mBlitProgram;
   private static int mBlitTextureH;
@@ -80,12 +86,15 @@ public class DistortedEffects
     mQuadPositions.put(positionData).position(0);
     }
 
-  /// DEBUG ONLY /////
+  /// DEBUG PROGRAM /////
   private static DistortedProgram mDebugProgram;
 
   private static int mDebugObjDH;
   private static int mDebugMVPMatrixH;
-  /// END DEBUG //////
+
+  /// FEEDBACK PROGRAM //
+  private static DistortedProgram mFeedbackProgram;
+
 
   private static float[] mMVPMatrix = new float[16];
   private static float[] mTmpMatrix = new float[16];
@@ -104,9 +113,7 @@ public class DistortedEffects
   static void createProgram(Resources resources)
   throws FragmentCompilationException,VertexCompilationException,VertexUniformsException,FragmentUniformsException,LinkingException
     {
-    final InputStream mainVertStream = resources.openRawResource(R.raw.main_vertex_shader);
-    final InputStream mainFragStream = resources.openRawResource(R.raw.main_fragment_shader);
-
+    //// BOTH MAIN AND FEEDBACK PROGRAMS ///////
     String mainVertHeader= Distorted.GLSL_VERSION;
     String mainFragHeader= Distorted.GLSL_VERSION;
 
@@ -141,17 +148,38 @@ public class DistortedEffects
     //android.util.Log.e("Effects", "vertHeader= "+mainVertHeader);
     //android.util.Log.e("Effects", "fragHeader= "+mainFragHeader);
 
-    String[] feedback = { "v_Position" };
+    //////////////////////////////////////////////////////////////////////////////////////
+    ////////// MAIN PROGRAM //////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////
+    final InputStream mainVertStream = resources.openRawResource(R.raw.main_vertex_shader);
+    final InputStream mainFragStream = resources.openRawResource(R.raw.main_fragment_shader);
 
-    mMainProgram = new DistortedProgram(mainVertStream,mainFragStream, mainVertHeader, mainFragHeader, Distorted.GLSL, feedback);
+    mMainProgram = new DistortedProgram(mainVertStream,mainFragStream, mainVertHeader, mainFragHeader, Distorted.GLSL);
 
     int mainProgramH = mMainProgram.getProgramHandle();
     EffectQueueFragment.getUniforms(mainProgramH);
-    EffectQueueVertex.getUniforms(mainProgramH);
-    EffectQueueMatrix.getUniforms(mainProgramH);
+    EffectQueueVertex.getUniforms(MAIN_PROGRAM,mainProgramH);
+    EffectQueueMatrix.getUniforms(MAIN_PROGRAM,mainProgramH);
     mMainTextureH= GLES30.glGetUniformLocation( mainProgramH, "u_Texture");
 
-    // BLIT PROGRAM ////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////
+    ////////// FEEDBACK PROGRAM //////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////
+    final InputStream feedVertStream = resources.openRawResource(R.raw.main_vertex_shader);
+    final InputStream feedFragStream = resources.openRawResource(R.raw.feedback_fragment_shader);
+
+    String[] feedback = { "v_Position" };
+
+    mFeedbackProgram = new DistortedProgram(feedVertStream,feedFragStream, mainVertHeader, Distorted.GLSL_VERSION, Distorted.GLSL, feedback);
+
+    int feedProgramH = mFeedbackProgram.getProgramHandle();
+    EffectQueueFragment.getUniforms(feedProgramH);
+    EffectQueueVertex.getUniforms(FEED_PROGRAM,feedProgramH);
+    EffectQueueMatrix.getUniforms(FEED_PROGRAM,feedProgramH);
+
+    //////////////////////////////////////////////////////////////////////////////////////
+    ////////// BLIT PROGRAM //////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////
     final InputStream blitVertStream = resources.openRawResource(R.raw.blit_vertex_shader);
     final InputStream blitFragStream = resources.openRawResource(R.raw.blit_fragment_shader);
 
@@ -172,7 +200,9 @@ public class DistortedEffects
     mBlitTextureH  = GLES30.glGetUniformLocation( blitProgramH, "u_Texture");
     mBlitDepthH    = GLES30.glGetUniformLocation( blitProgramH, "u_Depth");
 
-    // DEBUG ONLY //////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////
+    ////////// DEBUG PROGRAM /////////////////////////////////////////////////////////////
+    //////////////////////////////////////////////////////////////////////////////////////
     final InputStream debugVertexStream   = resources.openRawResource(R.raw.test_vertex_shader);
     final InputStream debugFragmentStream = resources.openRawResource(R.raw.test_fragment_shader);
 
@@ -189,7 +219,6 @@ public class DistortedEffects
     int debugProgramH = mDebugProgram.getProgramHandle();
     mDebugObjDH = GLES30.glGetUniformLocation( debugProgramH, "u_objD");
     mDebugMVPMatrixH = GLES30.glGetUniformLocation( debugProgramH, "u_MVPMatrix");
-    // END DEBUG  //////////////////////////////////////
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -282,13 +311,10 @@ public class DistortedEffects
     GLES30.glVertexAttribPointer(mDebugProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions);
     GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
     }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void drawPriv(float halfW, float halfH, MeshObject mesh, DistortedOutputSurface surface, long currTime)
     {
-    int error;
-
     mM.compute(currTime);
     mV.compute(currTime);
     mF.compute(currTime);
@@ -300,9 +326,8 @@ public class DistortedEffects
     mMainProgram.useProgram();
     GLES30.glUniform1i(mMainTextureH, 0);
     surface.setAsOutput(currTime);
-    mM.send(surface,halfW,halfH,halfZ);
-    mM.send(surface,halfW,halfH,halfZ);
-    mV.send(halfW,halfH,halfZ);
+    mM.send(MAIN_PROGRAM,surface,halfW,halfH,halfZ);
+    mV.send(MAIN_PROGRAM,halfW,halfH,halfZ);
     mF.send(halfW,halfH);
 
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mPosVBO[0]);
@@ -312,30 +337,50 @@ public class DistortedEffects
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mTexVBO[0]);
     GLES30.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE     , GLES30.GL_FLOAT, false, 0, 0);
 
-    GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mPosTBO[0]);
+    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.dataLength);
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0 );
+    }
 
-    GLES30.glBeginTransformFeedback(GLES30.GL_TRIANGLES);
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    error = GLES30.glGetError();
-    if (error != GLES30.GL_NO_ERROR)
-      {
-      throw new RuntimeException("1 glError 0x" + Integer.toHexString(error));
-      }
+  void drawPrivFeedback(float halfW, float halfH, MeshObject mesh, DistortedOutputSurface surface, long currTime)
+    {
+    mM.compute(currTime);
+    mV.compute(currTime);
+    mF.compute(currTime);
 
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.dataLength);
+    float halfZ = halfW*mesh.zFactor;
+
+    GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
 
-    error = GLES30.glGetError();
+    mFeedbackProgram.useProgram();
+    surface.setAsOutput(currTime);
+    mM.send(FEED_PROGRAM,surface,halfW,halfH,halfZ);
+    mV.send(FEED_PROGRAM,halfW,halfH,halfZ);
+
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mPosVBO[0]);
+    GLES30.glVertexAttribPointer(mFeedbackProgram.mAttribute[0], MeshObject.POSITION_DATA_SIZE, GLES30.GL_FLOAT, false, 0, 0);
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mNorVBO[0]);
+    GLES30.glVertexAttribPointer(mFeedbackProgram.mAttribute[1], MeshObject.NORMAL_DATA_SIZE  , GLES30.GL_FLOAT, false, 0, 0);
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mTexVBO[0]);
+    GLES30.glVertexAttribPointer(mFeedbackProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE     , GLES30.GL_FLOAT, false, 0, 0);
+
+    GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mPosTBO[0]);
+    GLES30.glEnable(GLES30.GL_RASTERIZER_DISCARD);
+    GLES30.glBeginTransformFeedback(GLES30.GL_POINTS);
+    GLES30.glDrawArrays(GLES30.GL_POINTS, 0, mesh.dataLength);
+
+    int error = GLES30.glGetError();
     if (error != GLES30.GL_NO_ERROR)
       {
       throw new RuntimeException("2 glError 0x" + Integer.toHexString(error));
       }
 
     GLES30.glEndTransformFeedback();
-    GLES30.glFlush();
-
+    GLES30.glDisable(GLES30.GL_RASTERIZER_DISCARD);
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0 );
-
-int len = 3*(mesh.dataLength-2)*MeshObject.BYTES_PER_FLOAT*MeshObject.POSITION_DATA_SIZE;
+/*
+int len = mesh.dataLength*MeshObject.BYTES_PER_FLOAT*MeshObject.POSITION_DATA_SIZE;
 
 Buffer mappedBuffer =  GLES30.glMapBufferRange(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, len, GLES30.GL_MAP_READ_BIT);
 FloatBuffer fb = ((ByteBuffer) mappedBuffer).order(ByteOrder.nativeOrder()).asFloatBuffer();
@@ -349,22 +394,41 @@ for(int d=0; d<mesh.dataLength; d++)
 android.util.Log.d( "Feedback", msgB);
 
 String msgA = "";
-for(int d=0; d<3*(mesh.dataLength-2); d++)
+for(int d=0; d<mesh.dataLength; d++)
   {
-  if( d==0 || d==1 || ((d-2)%3)==0)
-     msgA+="("+fb.get(3*d+0)+","+fb.get(3*d+1)+","+fb.get(3*d+2)+")";
+  msgA+="("+fb.get(3*d+0)+","+fb.get(3*d+1)+","+fb.get(3*d+2)+")";
   }
 android.util.Log.d( "Feedback", msgA);
 
 android.util.Log.e( "Feedback",msgA.equalsIgnoreCase(msgB) ? "identical":"not identical");
 
+GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER);
+*/
 
     /// DEBUG ONLY //////
     // displayBoundingRect(halfW, halfH, halfZ, surface, mM.getMVP(), fb, currTime );
     /// END DEBUG ///////
 
-GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER);
+GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
+
+
+
+
+    mMainProgram.useProgram();
+    GLES30.glUniform1i(mMainTextureH, 0);
+    mM.sendFeedback(MAIN_PROGRAM,surface,halfW,halfH,halfZ);
+    mV.sendZero(MAIN_PROGRAM);
+    mF.send(halfW,halfH);
 
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mPosTBO[0]);
+    GLES30.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POSITION_DATA_SIZE, GLES30.GL_FLOAT, false, 0, 0);
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mNorVBO[0]);
+    GLES30.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NORMAL_DATA_SIZE  , GLES30.GL_FLOAT, false, 0, 0);
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mTexVBO[0]);
+    GLES30.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE     , GLES30.GL_FLOAT, false, 0, 0);
+
+    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.dataLength);
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0 );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/DistortedNode.java b/src/main/java/org/distorted/library/DistortedNode.java
index b0f2e76..7e9c13b 100644
--- a/src/main/java/org/distorted/library/DistortedNode.java
+++ b/src/main/java/org/distorted/library/DistortedNode.java
@@ -264,7 +264,7 @@ public class DistortedNode implements DistortedSlave
     if( input.setAsInput() )
       {
       mState.apply();
-      mEffects.drawPriv(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
+      mEffects.drawPrivFeedback(mSurface.getWidth()/2.0f, mSurface.getHeight()/2.0f, mMesh, surface, currTime);
       return 1;
       }
 
diff --git a/src/main/java/org/distorted/library/EffectQueueMatrix.java b/src/main/java/org/distorted/library/EffectQueueMatrix.java
index 2ddb4ad..7263502 100644
--- a/src/main/java/org/distorted/library/EffectQueueMatrix.java
+++ b/src/main/java/org/distorted/library/EffectQueueMatrix.java
@@ -46,9 +46,9 @@ class EffectQueueMatrix extends EffectQueue
   private static float[] mTmpMatrix = new float[16];
   private static float[] mViewMatrix= new float[16];
 
-  private static int mObjDH;      // This is a handle to half a Object dimensions
-  private static int mMVPMatrixH; // pass in the transformation matrix
-  private static int mMVMatrixH;  // pass in the modelview matrix.
+  private static int[] mObjDH       = new int[DistortedEffects.NUM_PROGRAMS];
+  private static int[] mMVPMatrixH  = new int[DistortedEffects.NUM_PROGRAMS];
+  private static int[] mMVMatrixH   = new int[DistortedEffects.NUM_PROGRAMS];
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
@@ -191,11 +191,11 @@ class EffectQueueMatrix extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  static void getUniforms(int mProgramH)
+  static void getUniforms(int index,int mProgramH)
     {
-    mObjDH     = GLES30.glGetUniformLocation(mProgramH, "u_objD");
-    mMVPMatrixH= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix");
-    mMVMatrixH = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
+    mObjDH[index]     = GLES30.glGetUniformLocation(mProgramH, "u_objD");
+    mMVPMatrixH[index]= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix");
+    mMVMatrixH[index] = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrix");
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -259,13 +259,24 @@ class EffectQueueMatrix extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  synchronized void send(DistortedOutputSurface projection, float halfX, float halfY, float halfZ)
+  synchronized void send(int index,DistortedOutputSurface projection, float halfX, float halfY, float halfZ)
     {
     constructMatrices(projection,halfX,halfY,halfZ);
 
-    GLES30.glUniform3f( mObjDH , halfX, halfY, halfZ);
-    GLES30.glUniformMatrix4fv(mMVMatrixH , 1, false, mViewMatrix, 0);
-    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
+    GLES30.glUniform3f( mObjDH[index] , halfX, halfY, halfZ);
+    GLES30.glUniformMatrix4fv(mMVMatrixH[index] , 1, false, mViewMatrix, 0);
+    GLES30.glUniformMatrix4fv(mMVPMatrixH[index], 1, false, mMVPMatrix , 0);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  synchronized void sendFeedback(int index,DistortedOutputSurface projection, float halfX, float halfY, float halfZ)
+    {
+    constructMatrices(projection,halfX,halfY,halfZ);
+
+    GLES30.glUniform3f( mObjDH[index] , 0.5f, 0.5f, 0.5f);
+    GLES30.glUniformMatrix4fv(mMVMatrixH[index] , 1, false, mViewMatrix, 0);
+    GLES30.glUniformMatrix4fv(mMVPMatrixH[index], 1, false, mMVPMatrix , 0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/EffectQueueVertex.java b/src/main/java/org/distorted/library/EffectQueueVertex.java
index e25acfd..9f2f8b9 100644
--- a/src/main/java/org/distorted/library/EffectQueueVertex.java
+++ b/src/main/java/org/distorted/library/EffectQueueVertex.java
@@ -45,9 +45,9 @@ class EffectQueueVertex extends EffectQueue
   private static final int NUM_UNIFORMS = 12;
   private static final int NUM_CACHE    =  3;
   private static final int INDEX = EffectTypes.VERTEX.ordinal();
-  private static int mNumEffectsH;
-  private static int mTypeH;
-  private static int mUniformsH;
+  private static int[] mNumEffectsH = new int[DistortedEffects.NUM_PROGRAMS];
+  private static int[] mTypeH       = new int[DistortedEffects.NUM_PROGRAMS];
+  private static int[] mUniformsH   = new int[DistortedEffects.NUM_PROGRAMS];
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
@@ -58,11 +58,11 @@ class EffectQueueVertex extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  static void getUniforms(int mProgramH)
+  static void getUniforms(int index, int mProgramH)
     {
-    mNumEffectsH= GLES30.glGetUniformLocation( mProgramH, "vNumEffects");
-    mTypeH      = GLES30.glGetUniformLocation( mProgramH, "vType");
-    mUniformsH  = GLES30.glGetUniformLocation( mProgramH, "vUniforms");
+    mNumEffectsH[index]= GLES30.glGetUniformLocation( mProgramH, "vNumEffects");
+    mTypeH[index]      = GLES30.glGetUniformLocation( mProgramH, "vType");
+    mUniformsH[index]  = GLES30.glGetUniformLocation( mProgramH, "vUniforms");
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -133,9 +133,9 @@ class EffectQueueVertex extends EffectQueue
    
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  synchronized void send(float halfX, float halfY, float halfZ)
+  synchronized void send(int index, float halfX, float halfY, float halfZ)
     {
-    GLES30.glUniform1i( mNumEffectsH, mNumEffects);
+    GLES30.glUniform1i( mNumEffectsH[index], mNumEffects);
       
     if( mNumEffects>0 )
       {
@@ -146,11 +146,18 @@ class EffectQueueVertex extends EffectQueue
         mUniforms[NUM_UNIFORMS*i+7] = mCache[NUM_CACHE*i+2]-halfZ;
         }
 
-      GLES30.glUniform1iv( mTypeH    ,                 mNumEffects, mName    ,0);
-      GLES30.glUniform4fv( mUniformsH,(NUM_UNIFORMS/4)*mNumEffects, mUniforms,0);
+      GLES30.glUniform1iv( mTypeH[index]    ,                 mNumEffects, mName    ,0);
+      GLES30.glUniform4fv( mUniformsH[index],(NUM_UNIFORMS/4)*mNumEffects, mUniforms,0);
       }
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  synchronized void sendZero(int index)
+    {
+    GLES30.glUniform1i( mNumEffectsH[index], 0);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Do various post-processing on already computed effects.
 // 1) here unlike in the fragment queue, we don't have to multiply the points by ModelView matrix because that gets done in the shader.
diff --git a/src/main/java/org/distorted/library/MeshObject.java b/src/main/java/org/distorted/library/MeshObject.java
index c4d9518..397f009 100644
--- a/src/main/java/org/distorted/library/MeshObject.java
+++ b/src/main/java/org/distorted/library/MeshObject.java
@@ -71,26 +71,25 @@ public abstract class MeshObject extends DistortedObject
        {
        GLES30.glGenBuffers(1, mPosVBO, 0);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mPosVBO[0]);
-       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*POSITION_DATA_SIZE*BYTES_PER_FLOAT, mMeshPositions, GLES30.GL_STATIC_READ);
+       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*POSITION_DATA_SIZE*BYTES_PER_FLOAT, mMeshPositions, GLES30.GL_STATIC_DRAW);
        }
      if( mNorVBO[0]<0 )
        {
        GLES30.glGenBuffers(1, mNorVBO, 0);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mNorVBO[0]);
-       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*  NORMAL_DATA_SIZE*BYTES_PER_FLOAT, mMeshNormals  , GLES30.GL_STATIC_READ);
+       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*  NORMAL_DATA_SIZE*BYTES_PER_FLOAT, mMeshNormals  , GLES30.GL_STATIC_DRAW);
        }
      if( mTexVBO[0]<0 )
        {
        GLES30.glGenBuffers(1, mTexVBO, 0);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mTexVBO[0]);
-       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*    TEX_DATA_SIZE*BYTES_PER_FLOAT, mMeshTexture  , GLES30.GL_STATIC_READ);
+       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*    TEX_DATA_SIZE*BYTES_PER_FLOAT, mMeshTexture  , GLES30.GL_STATIC_DRAW);
        }
 
-     if( mPosTBO[0]<0 ) // Buffer for Transform Feedback. Since we are rendering with GL_TRIANGLE_STRIP, after passing N vertices
-                        // we will get (N-2) triangles back, each 3 vertices of 12 bytes.
+     if( mPosTBO[0]<0 )
        {
        GLES30.glBindBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, mPosTBO[0]);
-       GLES30.glBufferData(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 3*(dataLength-2)*POSITION_DATA_SIZE*BYTES_PER_FLOAT, null, GLES30.GL_STATIC_READ);
+       GLES30.glBufferData(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, dataLength*POSITION_DATA_SIZE*BYTES_PER_FLOAT, null, GLES30.GL_STATIC_READ);
        GLES30.glBindBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0);
        }
 
