commit 3fc9327a2359a88d817526e300e7c2aad18c3d11
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Thu May 11 16:47:21 2017 +0100

    Use Transform Feedback to (optionally) display the Normal vectors.

diff --git a/src/main/java/org/distorted/library/DistortedEffects.java b/src/main/java/org/distorted/library/DistortedEffects.java
index 8c1e6c7..d69d81a 100644
--- a/src/main/java/org/distorted/library/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/DistortedEffects.java
@@ -21,7 +21,6 @@ package org.distorted.library;
 
 import android.content.res.Resources;
 import android.opengl.GLES30;
-import android.opengl.Matrix;
 
 import org.distorted.library.message.EffectListener;
 import org.distorted.library.program.DistortedProgram;
@@ -38,7 +37,6 @@ import org.distorted.library.type.Data5D;
 import org.distorted.library.type.Static3D;
 
 import java.io.InputStream;
-import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.FloatBuffer;
@@ -80,22 +78,17 @@ public class DistortedEffects
     mQuadPositions.put(positionData).position(0);
     }
 
-  /// DEBUG ONLY /////
-  private static DistortedProgram mDebugProgram;
-
-  private static int mDebugObjDH;
-  private static int mDebugMVPMatrixH;
-  /// END DEBUG //////
-
-  private static float[] mMVPMatrix = new float[16];
-  private static float[] mTmpMatrix = new float[16];
+  /// NORMAL PROGRAM /////
+  private static DistortedProgram mNormalProgram;
+  private static int mNormalMVPMatrixH;
+  /// END PROGRAMS //////
 
   private static long mNextID =0;
   private long mID;
 
-  private EffectQueueMatrix      mM;
-  private EffectQueueFragment    mF;
-  private EffectQueueVertex      mV;
+  private EffectQueueMatrix   mM;
+  private EffectQueueFragment mF;
+  private EffectQueueVertex   mV;
 
   private boolean matrixCloned, vertexCloned, fragmentCloned;
 
@@ -142,7 +135,7 @@ public class DistortedEffects
     //android.util.Log.e("Effects", "vertHeader= "+mainVertHeader);
     //android.util.Log.e("Effects", "fragHeader= "+mainFragHeader);
 
-    String[] feedback = { "v_Position", "v_Normal", "v_ndcPosition" };
+    String[] feedback = { "v_Position", "v_endPosition" };
 
     mMainProgram = new DistortedProgram(mainVertStream,mainFragStream, mainVertHeader, mainFragHeader, Distorted.GLSL, feedback);
 
@@ -173,23 +166,22 @@ public class DistortedEffects
     mBlitTextureH  = GLES30.glGetUniformLocation( blitProgramH, "u_Texture");
     mBlitDepthH    = GLES30.glGetUniformLocation( blitProgramH, "u_Depth");
 
-    // DEBUG PROGRAM //////////////////////////////////////
-    final InputStream debugVertexStream   = resources.openRawResource(R.raw.test_vertex_shader);
-    final InputStream debugFragmentStream = resources.openRawResource(R.raw.test_fragment_shader);
+    // NORMAL PROGRAM //////////////////////////////////////
+    final InputStream normalVertexStream   = resources.openRawResource(R.raw.normal_vertex_shader);
+    final InputStream normalFragmentStream = resources.openRawResource(R.raw.normal_fragment_shader);
 
     try
       {
-      mDebugProgram = new DistortedProgram(debugVertexStream,debugFragmentStream, Distorted.GLSL_VERSION, Distorted.GLSL_VERSION, Distorted.GLSL);
+      mNormalProgram = new DistortedProgram(normalVertexStream,normalFragmentStream, Distorted.GLSL_VERSION, Distorted.GLSL_VERSION, Distorted.GLSL);
       }
     catch(Exception e)
       {
-      android.util.Log.e("EFFECTS", "exception trying to compile DEBUG program: "+e.getMessage());
+      android.util.Log.e("EFFECTS", "exception trying to compile NORMAL program: "+e.getMessage());
       throw new RuntimeException(e.getMessage());
       }
 
-    int debugProgramH = mDebugProgram.getProgramHandle();
-    mDebugObjDH      = GLES30.glGetUniformLocation( debugProgramH, "u_objD");
-    mDebugMVPMatrixH = GLES30.glGetUniformLocation( debugProgramH, "u_MVPMatrix");
+    int normalProgramH = mNormalProgram.getProgramHandle();
+    mNormalMVPMatrixH  = GLES30.glGetUniformLocation( normalProgramH, "u_MVPMatrix");
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -232,73 +224,23 @@ public class DistortedEffects
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  @SuppressWarnings("unused")
-  private void displayBoundingRect(float halfW, float halfH, DistortedOutputSurface surface, MeshObject mesh)
+  private void displayNormals(MeshObject mesh)
     {
     GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mAttTFO[0]);
     GLES30.glBeginTransformFeedback( GLES30.GL_POINTS);
-
     DistortedRenderState.switchOffDrawing();
     GLES30.glDrawArrays( GLES30.GL_POINTS, 0, mesh.numVertices);
     DistortedRenderState.restoreDrawing();
-
-    int error = GLES30.glGetError();
-
-    if( error != GLES30.GL_NO_ERROR )
-      {
-      throw new RuntimeException("DrawArrays: glError 0x" + Integer.toHexString(error));
-      }
-
-    // mapping the buffer range slows down rendering /////////////////////////
-    int size = (MeshObject.POS_DATA_SIZE+MeshObject.NOR_DATA_SIZE+MeshObject.NDC_DATA_SIZE)*mesh.numVertices;
-
-    Buffer mappedBuffer =  GLES30.glMapBufferRange(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 4*size, GLES30.GL_MAP_READ_BIT);
-    FloatBuffer fb = ((ByteBuffer) mappedBuffer).order(ByteOrder.nativeOrder()).asFloatBuffer();
-    GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER);
-    // end of slowdown //////////////////////////////////////////////////////
-
     GLES30.glEndTransformFeedback();
     GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
-/*
-    String msg = "";
-    for(int i=0; i<size; i++) msg += (" "+fb.get(i));
-    android.util.Log.d( "Feedback", msg);
-*/
-    float minx = Integer.MAX_VALUE;
-    float maxx = Integer.MIN_VALUE;
-    float miny = Integer.MAX_VALUE;
-    float maxy = Integer.MIN_VALUE;
-    float ndcX,ndcY;
-
-    for(int i=0; i<mesh.numVertices; i++)
-      {
-      ndcX = fb.get(8*i+6);
-      ndcY = fb.get(8*i+7);
-
-      if( ndcX<minx ) minx = ndcX;
-      if( ndcX>maxx ) maxx = ndcX;
-      if( ndcY<miny ) miny = ndcY;
-      if( ndcY>maxy ) maxy = ndcY;
-      }
-
-    minx = surface.mWidth *(minx+1)/2;   //
-    miny = surface.mHeight*(miny+1)/2;   // transform from NDC to
-    maxx = surface.mWidth *(maxx+1)/2;   // window coordinates
-    maxy = surface.mHeight*(maxy+1)/2;   //
 
-    mDebugProgram.useProgram();
-
-    Matrix.setIdentityM( mTmpMatrix, 0);
-    Matrix.translateM  ( mTmpMatrix, 0, minx-surface.mWidth/2, maxy-surface.mHeight/2, -surface.mDistance);
-    Matrix.scaleM      ( mTmpMatrix, 0, (maxx-minx)/(2*halfW), (maxy-miny)/(2*halfH), 1.0f);
-    Matrix.translateM  ( mTmpMatrix, 0, halfW,-halfH, 0);
-    Matrix.multiplyMM  ( mMVPMatrix, 0, surface.mProjectionMatrix, 0, mTmpMatrix, 0);
-
-    GLES30.glUniform2f(mDebugObjDH, 2*halfW, 2*halfH);
-    GLES30.glUniformMatrix4fv(mDebugMVPMatrixH, 1, false, mMVPMatrix , 0);
-
-    GLES30.glVertexAttribPointer(mDebugProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    mNormalProgram.useProgram();
+    GLES30.glUniformMatrix4fv(mNormalMVPMatrixH, 1, false, mM.getMVP() , 0);
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mAttTFO[0]);
+    GLES30.glVertexAttribPointer(mNormalProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, 0);
+    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
+    GLES30.glLineWidth(8.0f);
+    GLES30.glDrawArrays(GLES30.GL_LINES, 0, 2*mesh.numVertices);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -329,7 +271,7 @@ public class DistortedEffects
 
     GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.numVertices);
 
-    displayBoundingRect(halfW,halfH,surface,mesh);
+    if( mesh.mShowNormals ) displayNormals(mesh);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/EffectQueueMatrix.java b/src/main/java/org/distorted/library/EffectQueueMatrix.java
index 647ccd3..2ddb4ad 100644
--- a/src/main/java/org/distorted/library/EffectQueueMatrix.java
+++ b/src/main/java/org/distorted/library/EffectQueueMatrix.java
@@ -250,6 +250,13 @@ class EffectQueueMatrix extends EffectQueue
     mUniforms[NUM_UNIFORMS*index+6] = mUniforms[NUM_UNIFORMS*(index+1)+6];
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  float[] getMVP()
+    {
+    return mMVPMatrix;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   synchronized void send(DistortedOutputSurface projection, float halfX, float halfY, float halfZ)
diff --git a/src/main/java/org/distorted/library/MeshObject.java b/src/main/java/org/distorted/library/MeshObject.java
index e5b049a..3f5d491 100644
--- a/src/main/java/org/distorted/library/MeshObject.java
+++ b/src/main/java/org/distorted/library/MeshObject.java
@@ -38,15 +38,16 @@ public abstract class MeshObject extends DistortedObject
    static final int POS_DATA_SIZE= 3;
    static final int NOR_DATA_SIZE= 3;
    static final int TEX_DATA_SIZE= 2;
-   static final int NDC_DATA_SIZE= 2;
 
    static final int OFFSET0 =                                                           0;
    static final int OFFSET1 = (POS_DATA_SIZE                            )*BYTES_PER_FLOAT;
    static final int OFFSET2 = (POS_DATA_SIZE+NOR_DATA_SIZE              )*BYTES_PER_FLOAT;
 
-   static final int TFSIZE  = (POS_DATA_SIZE+NOR_DATA_SIZE+NDC_DATA_SIZE)*BYTES_PER_FLOAT;
+   static final int TFSIZE  = (POS_DATA_SIZE+POS_DATA_SIZE              )*BYTES_PER_FLOAT;
    static final int VERTSIZE= (POS_DATA_SIZE+NOR_DATA_SIZE+TEX_DATA_SIZE)*BYTES_PER_FLOAT;
 
+   boolean mShowNormals;
+
    int numVertices;
    FloatBuffer mVertAttribs;   // packed: PosX,PosY,PosZ, NorX, NorY,NorZ, TexS, TexT
    int[] mAttVBO = new int[1]; // server-side packed vertex attributes
@@ -62,6 +63,7 @@ public abstract class MeshObject extends DistortedObject
      super(DistortedObject.NOT_CREATED_YET,DistortedObject.TYPE_USER);
 
      zFactor = factor;
+     mShowNormals = false;
      recreate();
      }
 
@@ -132,5 +134,18 @@ public abstract class MeshObject extends DistortedObject
  * This is used to be able to quickly compute, in window coordinates, the Mesh'es bounding rectangle.
  */
    abstract float[] getBoundingVertices();
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * When rendering this Mesh, do we want to render the Normal vectors as well?
+ *
+ * @param show Controls if we render the Normal vectors or not.
+ */
+   public void setShowNormals(boolean show)
+     {
+     mShowNormals = show;
+     }
    }
 
+
+
diff --git a/src/main/res/raw/main_vertex_shader.glsl b/src/main/res/raw/main_vertex_shader.glsl
index dac81d5..9974d0e 100644
--- a/src/main/res/raw/main_vertex_shader.glsl
+++ b/src/main/res/raw/main_vertex_shader.glsl
@@ -24,7 +24,7 @@ in vec3 a_Position;                  // Per-vertex position.
 in vec3 a_Normal;                    // Per-vertex normal vector.
 in vec2 a_TexCoordinate;             // Per-vertex texture coordinate.
 out vec3 v_Position;                 //
-out vec2 v_ndcPosition;              // for Transform Feedback only
+out vec3 v_endPosition;              // for Transform Feedback only
 out vec3 v_Normal;                   //
 out vec2 v_TexCoordinate;            //
 #else
@@ -32,7 +32,7 @@ attribute vec3 a_Position;           // Per-vertex position.
 attribute vec3 a_Normal;             // Per-vertex normal vector.
 attribute vec2 a_TexCoordinate;      // Per-vertex texture coordinate.
 varying vec3 v_Position;             //
-varying vec2 v_ndcPosition;          // for Transform Feedback only
+varying vec3 v_endPosition;          // for Transform Feedback only
 varying vec3 v_Normal;               //
 varying vec2 v_TexCoordinate;        //
 #endif
@@ -527,7 +527,6 @@ void main()
   {
   vec3 v = 2.0*u_objD*a_Position;
   vec3 n = a_Normal;
-  vec4 mvpPos;
 
 #if NUM_VERTEX>0
   int j=0;
@@ -559,9 +558,8 @@ void main()
 #endif
    
   v_Position      = v;
+  v_endPosition   = v + (0.3*u_objD.x)*n;
   v_TexCoordinate = a_TexCoordinate;
   v_Normal        = normalize(vec3(u_MVMatrix*vec4(n,0.0)));
-  mvpPos          = u_MVPMatrix*vec4(v,1.0);
-  v_ndcPosition   = vec2(mvpPos.x/mvpPos.w,mvpPos.y/mvpPos.w);
-  gl_Position     = mvpPos;
+  gl_Position     = u_MVPMatrix*vec4(v,1.0);
   }                               
diff --git a/src/main/res/raw/normal_fragment_shader.glsl b/src/main/res/raw/normal_fragment_shader.glsl
new file mode 100644
index 0000000..b2b55b7
--- /dev/null
+++ b/src/main/res/raw/normal_fragment_shader.glsl
@@ -0,0 +1,34 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                          //
+//                                                                                          //
+// This file is part of Distorted.                                                          //
+//                                                                                          //
+// Distorted is free software: you can redistribute it and/or modify                        //
+// it under the terms of the GNU General Public License as published by                     //
+// the Free Software Foundation, either version 2 of the License, or                        //
+// (at your option) any later version.                                                      //
+//                                                                                          //
+// Distorted is distributed in the hope that it will be useful,                             //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
+// GNU General Public License for more details.                                             //
+//                                                                                          //
+// You should have received a copy of the GNU General Public License                        //
+// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+precision lowp float;
+
+#if __VERSION__ != 100
+out vec4 fragColor;
+#define FRAG_COLOR fragColor
+#else
+#define FRAG_COLOR gl_FragColor
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+void main()
+  {
+  FRAG_COLOR = vec4(1.0,0.0,0.0,1.0);
+  }
\ No newline at end of file
diff --git a/src/main/res/raw/normal_vertex_shader.glsl b/src/main/res/raw/normal_vertex_shader.glsl
new file mode 100644
index 0000000..5e01c12
--- /dev/null
+++ b/src/main/res/raw/normal_vertex_shader.glsl
@@ -0,0 +1,35 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2016 Leszek Koltunski                                                          //
+//                                                                                          //
+// This file is part of Distorted.                                                          //
+//                                                                                          //
+// Distorted is free software: you can redistribute it and/or modify                        //
+// it under the terms of the GNU General Public License as published by                     //
+// the Free Software Foundation, either version 2 of the License, or                        //
+// (at your option) any later version.                                                      //
+//                                                                                          //
+// Distorted is distributed in the hope that it will be useful,                             //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
+// GNU General Public License for more details.                                             //
+//                                                                                          //
+// You should have received a copy of the GNU General Public License                        // 
+// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+precision lowp float;
+
+#if __VERSION__ != 100
+in vec3 a_Position;
+#else
+attribute vec3 a_Position;
+#endif
+
+uniform mat4 u_MVPMatrix;
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+void main()
+  {
+  gl_Position = u_MVPMatrix*vec4( a_Position, 1.0);
+  }
\ No newline at end of file
diff --git a/src/main/res/raw/test_fragment_shader.glsl b/src/main/res/raw/test_fragment_shader.glsl
deleted file mode 100644
index f2fb503..0000000
--- a/src/main/res/raw/test_fragment_shader.glsl
+++ /dev/null
@@ -1,34 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                          //
-//                                                                                          //
-// This file is part of Distorted.                                                          //
-//                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
-// it under the terms of the GNU General Public License as published by                     //
-// the Free Software Foundation, either version 2 of the License, or                        //
-// (at your option) any later version.                                                      //
-//                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
-// GNU General Public License for more details.                                             //
-//                                                                                          //
-// You should have received a copy of the GNU General Public License                        //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
-//////////////////////////////////////////////////////////////////////////////////////////////
-
-precision lowp float;
-
-#if __VERSION__ != 100
-out vec4 fragColor;
-#define FRAG_COLOR fragColor
-#else
-#define FRAG_COLOR gl_FragColor
-#endif
-
-//////////////////////////////////////////////////////////////////////////////////////////////
-
-void main()
-  {
-  FRAG_COLOR = vec4(1.0,0.0,0.0,0.2);
-  }
\ No newline at end of file
diff --git a/src/main/res/raw/test_vertex_shader.glsl b/src/main/res/raw/test_vertex_shader.glsl
deleted file mode 100644
index bf52c1d..0000000
--- a/src/main/res/raw/test_vertex_shader.glsl
+++ /dev/null
@@ -1,36 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                          //
-//                                                                                          //
-// This file is part of Distorted.                                                          //
-//                                                                                          //
-// Distorted is free software: you can redistribute it and/or modify                        //
-// it under the terms of the GNU General Public License as published by                     //
-// the Free Software Foundation, either version 2 of the License, or                        //
-// (at your option) any later version.                                                      //
-//                                                                                          //
-// Distorted is distributed in the hope that it will be useful,                             //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                           //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            //
-// GNU General Public License for more details.                                             //
-//                                                                                          //
-// You should have received a copy of the GNU General Public License                        // 
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                       //
-//////////////////////////////////////////////////////////////////////////////////////////////
-
-precision lowp float;
-
-#if __VERSION__ != 100
-in vec2 a_Position;        // Per-vertex position information we will pass in.
-#else
-attribute vec2 a_Position; // Per-vertex position information we will pass in.
-#endif
-
-uniform vec2 u_objD;       // object width X object height.
-uniform mat4 u_MVPMatrix;  // the combined model/view/projection matrix.
-
-//////////////////////////////////////////////////////////////////////////////////////////////
-
-void main()
-  {
-  gl_Position = u_MVPMatrix*vec4( u_objD*a_Position, 0.0, 1.0);
-  }
\ No newline at end of file
