commit 7cf57d72e238092806b3f833d85d16c1a38ac78d
Author: leszek <leszek@koltunski.pl>
Date:   Thu May 4 23:36:57 2017 +0100

    This version appears to be fully working on Nexus 5X (it transfers back all the vertices and, if there are no vertex effects, the vertices transferred back are identical to the ones passed).
    
    This however crashes with GL_INVALID_OPERATION during glDrawArrays() when run on Nexus 4.

diff --git a/src/main/java/org/distorted/library/DistortedEffects.java b/src/main/java/org/distorted/library/DistortedEffects.java
index 00fd3e0..9745b69 100644
--- a/src/main/java/org/distorted/library/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/DistortedEffects.java
@@ -310,36 +310,53 @@ 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.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mPosTBO[0]);
 
-//    GLES30.glBeginTransformFeedback(GLES30.GL_TRIANGLES);
+    GLES30.glBeginTransformFeedback(GLES30.GL_TRIANGLES);
     GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.dataLength);
-  //  GLES30.glEndTransformFeedback();
-  //  GLES30.glFlush();
+
+    int error = GLES30.glGetError();
+
+    if (error != GLES30.GL_NO_ERROR)
+      {
+      throw new RuntimeException("glError 0x" + Integer.toHexString(error));
+      }
+
+    GLES30.glEndTransformFeedback();
+    GLES30.glFlush();
 
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0 );
-/*
-int len = mesh.dataLength*MeshObject.BYTES_PER_FLOAT*MeshObject.POSITION_DATA_SIZE;
+
+int len = 3*(mesh.dataLength-2)*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();
 FloatBuffer bb = mesh.mMeshPositions;
 
-String msgB = "BEFORE: ", msgA = "AFTER : ";
+String msgB = "";
 for(int d=0; d<mesh.dataLength; d++)
   {
   msgB+="("+(2*halfW*bb.get(3*d+0))+","+(2*halfH*bb.get(3*d+1))+","+(2*halfZ*bb.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", msgB);
+
+String msgA = "";
+for(int d=0; d<3*(mesh.dataLength-2); 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)+")";
+  }
 android.util.Log.d( "Feedback", msgA);
 
+android.util.Log.e( "Feedback",msgA.equalsIgnoreCase(msgB) ? "identical":"not identical");
+
+
     /// DEBUG ONLY //////
     // displayBoundingRect(halfW, halfH, halfZ, surface, mM.getMVP(), fb, currTime );
     /// END DEBUG ///////
 
 GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER);
-*/
+
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/MeshObject.java b/src/main/java/org/distorted/library/MeshObject.java
index f86a73d..c4d9518 100644
--- a/src/main/java/org/distorted/library/MeshObject.java
+++ b/src/main/java/org/distorted/library/MeshObject.java
@@ -86,10 +86,11 @@ public abstract class MeshObject extends DistortedObject
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, dataLength*    TEX_DATA_SIZE*BYTES_PER_FLOAT, mMeshTexture  , GLES30.GL_STATIC_READ);
        }
 
-     if( mPosTBO[0]<0 )
+     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.
        {
        GLES30.glBindBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, mPosTBO[0]);
-       GLES30.glBufferData(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, dataLength*POSITION_DATA_SIZE*BYTES_PER_FLOAT, null, GLES30.GL_STATIC_READ);
+       GLES30.glBufferData(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 3*(dataLength-2)*POSITION_DATA_SIZE*BYTES_PER_FLOAT, null, GLES30.GL_STATIC_READ);
        GLES30.glBindBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0);
        }
 
