commit 163b8d7dbe36c50c0860151f5a6d84a020137e18
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Nov 20 12:33:40 2018 +0000

    Progress with Effects3D app - merge Matrix effects

diff --git a/src/main/java/org/distorted/library/main/DistortedBuffer.java b/src/main/java/org/distorted/library/main/DistortedBuffer.java
new file mode 100644
index 0000000..e940aee
--- /dev/null
+++ b/src/main/java/org/distorted/library/main/DistortedBuffer.java
@@ -0,0 +1,102 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2018 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/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.library.main;
+
+import android.opengl.GLES31;
+import java.nio.Buffer;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Implements OpenGL buffer object such as GL_ARRAY_BUFFER or GL_TRANSFORM_FEEDBACK_BUFFER.
+ * Main point: deal with Android lifecycle and recreate the buffer on loss of OpenGL context.
+ * <p>
+ * Not part of public API, do not document (public only because has to be used in Meshes)
+ *
+ * @y.exclude
+ */
+public class DistortedBuffer extends DistortedObject
+  {
+  int[] mIndex;
+
+  private int mTarget, mSize, mUsage;
+  private Buffer mBuffer;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  DistortedBuffer(int target, int usage)
+    {
+    super(DistortedObject.NOT_CREATED_YET,DistortedObject.TYPE_USER);
+
+    mIndex  = new int[1];
+    mTarget = target;
+    mUsage  = usage;
+
+    recreate();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void setData(int size, Buffer buffer)
+    {
+    mSize   = size;
+    mBuffer = buffer;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// must be called from a thread holding OpenGL Context
+
+  void create()
+    {
+    if( mIndex[0]<0 )
+      {
+      GLES31.glGenBuffers( 1, mIndex, 0);
+      GLES31.glBindBuffer( mTarget, mIndex[0]);
+      GLES31.glBufferData( mTarget, mSize, mBuffer, mUsage);
+      GLES31.glBindBuffer( mTarget, 0);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// must be called from a thread holding OpenGL Context
+
+  void delete()
+    {
+    if( mIndex[0]>=0 )
+      {
+      GLES31.glDeleteBuffers(1, mIndex, 0);
+      mIndex[0] = -1;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  void recreate()
+    {
+    mIndex[0] = -1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// debugging only
+
+  String printDetails()
+    {
+    return getClass().getSimpleName();
+    }
+  }
diff --git a/src/main/java/org/distorted/library/main/DistortedEffects.java b/src/main/java/org/distorted/library/main/DistortedEffects.java
index 06969d9..36fce8c 100644
--- a/src/main/java/org/distorted/library/main/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/main/DistortedEffects.java
@@ -424,7 +424,7 @@ public class DistortedEffects
 
   private void displayNormals(MeshObject mesh)
     {
-    GLES31.glBindBufferBase(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mAttTFO[0]);
+    GLES31.glBindBufferBase(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.getTFO() );
     GLES31.glBeginTransformFeedback( GLES31.GL_POINTS);
     DistortedRenderState.switchOffDrawing();
     GLES31.glDrawArrays( GLES31.GL_POINTS, 0, mesh.numVertices);
@@ -434,7 +434,7 @@ public class DistortedEffects
 
     mNormalProgram.useProgram();
     GLES31.glUniformMatrix4fv(mNormalMVPMatrixH, 1, false, mM.getMVP() , 0);
-    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.mAttTFO[0]);
+    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.getTFO() );
     GLES31.glVertexAttribPointer(mNormalProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, 0, 0);
     GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
     GLES31.glLineWidth(8.0f);
@@ -467,7 +467,7 @@ public class DistortedEffects
     GLES31.glUniform2ui(mMainOITSizeH, surface.mWidth, surface.mHeight);
     GLES31.glUniform1ui(mMainOITNumRecordsH, (int)(mBufferSize*surface.mWidth*surface.mHeight) );
 
-    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.mAttVBO[0]);
+    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.getVBO() );
     GLES31.glVertexAttribPointer(mMainOITProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET0);
     GLES31.glVertexAttribPointer(mMainOITProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET1);
     GLES31.glVertexAttribPointer(mMainOITProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET2);
@@ -505,7 +505,7 @@ public class DistortedEffects
     mMainProgram.useProgram();
     GLES31.glUniform1i(mMainTextureH, 0);
 
-    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.mAttVBO[0]);
+    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.getVBO() );
     GLES31.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET0);
     GLES31.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET1);
     GLES31.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET2);
diff --git a/src/main/java/org/distorted/library/main/EffectQueuePostprocess.java b/src/main/java/org/distorted/library/main/EffectQueuePostprocess.java
index 84e3ff0..5a79732 100644
--- a/src/main/java/org/distorted/library/main/EffectQueuePostprocess.java
+++ b/src/main/java/org/distorted/library/main/EffectQueuePostprocess.java
@@ -169,7 +169,7 @@ class EffectQueuePostprocess extends EffectQueue
 
       mPreProgram.useProgram();
 
-      GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.mAttVBO[0]);
+      GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.getVBO() );
       GLES31.glVertexAttribPointer(mPreProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET0);
       GLES31.glVertexAttribPointer(mPreProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET1);
       GLES31.glVertexAttribPointer(mPreProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET2);
diff --git a/src/main/java/org/distorted/library/main/MeshCubes.java b/src/main/java/org/distorted/library/main/MeshCubes.java
index a1bdca7..5778f96 100644
--- a/src/main/java/org/distorted/library/main/MeshCubes.java
+++ b/src/main/java/org/distorted/library/main/MeshCubes.java
@@ -713,32 +713,10 @@ public class MeshCubes extends MeshObject
      if( remainingVert!=0 )
        android.util.Log.e("MeshCubes", "remainingVert " +remainingVert );
 
-/*
-     float[] attribs_good =
-     { -0.5f, +0.5f, -0.5f,  +0.0f, +1.0f, +0.0f,  +0.0f, +0.0f,
-       -0.5f, +0.5f, -0.5f,  +0.0f, +1.0f, +0.0f,  +0.0f, +0.0f,
-       -0.5f, +0.5f, +0.5f,  +0.0f, +1.0f, +0.0f,  +0.0f, +1.0f,
-       +0.5f, +0.5f, -0.5f,  +0.0f, +1.0f, +0.0f,  +1.0f, +0.0f,
-       +0.5f, +0.5f, +0.5f,  +0.0f, +1.0f, +0.0f,  +1.0f, +1.0f };
-
-     float[] attribs_hmm =
-         {   -0.5f, -0.1f, -0.5f,  +0.0f, -1.0f, +0.0f,  +0.0f, +1.0f,
-             -0.5f, -0.1f, -0.5f,  +0.0f, -1.0f, +0.0f,  +0.0f, +1.0f,
-             -0.5f, -0.1f, +0.5f,  +0.0f, -1.0f, +0.0f,  +0.0f, +0.5f,
-             +0.5f, -0.1f, -0.5f,  +0.0f, -1.0f, +0.0f,  +1.0f, +1.0f,
-             +0.5f, -0.1f, +0.5f,  +0.0f, -1.0f, +0.0f,  +1.0f, +0.5f };
-
-     float[] attribs_bad =
-     { -0.5f, +0.0f, -0.5f,  +0.0f, +1.0f, +0.0f,  +0.0f, +1.0f,
-       -0.5f, +0.0f, -0.5f,  +0.0f, +1.0f, +0.0f,  +0.0f, +1.0f,
-       -0.5f, +0.0f, +0.5f,  +0.0f, +1.0f, +0.0f,  +0.0f, +0.5f,
-       +0.5f, +0.0f, -0.5f,  +0.0f, +1.0f, +0.0f,  +1.0f, +1.0f,
-       +0.5f, +0.0f, +0.5f,  +0.0f, +1.0f, +0.0f,  +1.0f, +0.5f };
-
-     numVertices=5;
-*/
      mVertAttribs = ByteBuffer.allocateDirect(numVertices*VERTSIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
      mVertAttribs.put(attribs).position(0);
+
+     setData(numVertices, mVertAttribs);
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/main/MeshFlat.java b/src/main/java/org/distorted/library/main/MeshFlat.java
index 1a89a1c..97104b8 100644
--- a/src/main/java/org/distorted/library/main/MeshFlat.java
+++ b/src/main/java/org/distorted/library/main/MeshFlat.java
@@ -52,7 +52,7 @@ public class MeshFlat extends MeshObject
                      (mCols>=2 && mRows>=2 ? 2*mRows-2 : 1);
        }
 
-     //android.util.Log.e("BITMAP","vertices="+numVertices+" rows="+mRows+" cols="+mCols);
+     //android.util.Log.e("MeshFlat","vertices="+numVertices+" rows="+mRows+" cols="+mCols);
 
      remainingVert = numVertices;
      }
@@ -77,13 +77,14 @@ public class MeshFlat extends MeshObject
 
      return vertex+1;
      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   private int repeatLast(int vertex, float[] attribs)
      {
      remainingVert--;
 
-     //android.util.Log.e("BITMAP", "repeating last vertex!");
+     //android.util.Log.e("MeshFlat", "repeating last vertex!");
 
      if( vertex>0 )
        {
@@ -114,7 +115,7 @@ public class MeshFlat extends MeshObject
      final float X = 1.0f/mCols;
      final float Y = 1.0f/mRows;
 
-     //android.util.Log.d("BITMAP", "buildGrid");
+     //android.util.Log.d("MeshFlat", "buildGrid");
 
      y = 0.0f;
 
@@ -144,7 +145,7 @@ public class MeshFlat extends MeshObject
        y+=Y;
        }
 
-     //android.util.Log.d("BITMAP", "buildGrid done");
+     //android.util.Log.d("MeshFlat", "buildGrid done");
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -185,9 +186,11 @@ public class MeshFlat extends MeshObject
     //android.util.Log.d("MeshFlat", "attribs: "+debug(attribs,8) );
 
     if( remainingVert!=0 )
-      android.util.Log.d("BITMAP", "remainingVert " +remainingVert );
+      android.util.Log.d("MeshFlat", "remainingVert " +remainingVert );
 
     mVertAttribs = ByteBuffer.allocateDirect(numVertices*VERTSIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
     mVertAttribs.put(attribs).position(0);
+
+    setData(numVertices, mVertAttribs);
     }
  }
\ No newline at end of file
diff --git a/src/main/java/org/distorted/library/main/MeshObject.java b/src/main/java/org/distorted/library/main/MeshObject.java
index f7db6a0..c972689 100644
--- a/src/main/java/org/distorted/library/main/MeshObject.java
+++ b/src/main/java/org/distorted/library/main/MeshObject.java
@@ -20,7 +20,6 @@
 package org.distorted.library.main;
 
 import android.opengl.GLES31;
-
 import java.nio.FloatBuffer;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -31,7 +30,7 @@ import java.nio.FloatBuffer;
  * If you want to render to a particular shape, extend from here, construct the attrib FloatBuffer
  * and provide correct numVertices.
  */
-public abstract class MeshObject extends DistortedObject
+public abstract class MeshObject
    {
    private static final int BYTES_PER_FLOAT = 4;
 
@@ -49,9 +48,9 @@ public abstract class MeshObject extends DistortedObject
    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
-   int[] mAttTFO = new int[1]; // transform feedback
+   FloatBuffer mVertAttribs;   // packed: PosX,PosY,PosZ, NorX,NorY,NorZ, TexS,TexT
+
+   DistortedBuffer mVBO, mTFO; // main vertex buffer and transform feedback buffer
 
    final float zFactor;        // strange workaround for the fact that we need to somehow store the 'depth'
                                // of the Mesh. Used in DistortedEffects. See DistortedTexture.getDepth().
@@ -60,70 +59,37 @@ public abstract class MeshObject extends DistortedObject
 
    MeshObject(float factor)
      {
-     super(DistortedObject.NOT_CREATED_YET,DistortedObject.TYPE_USER);
-
-     zFactor = factor;
+     zFactor      = factor;
      mShowNormals = false;
-     recreate();
-     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// must be called from a thread holding OpenGL Context
-//
-// Do NOT release mVertAttribs etc as we will need them when we need to re-create the buffers after
-// a loss of OpenGL context!
-
-   void create()
-     {
-     if( mAttVBO[0]<0 )
-       {
-       GLES31.glGenBuffers(1, mAttVBO, 0);
-       GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mAttVBO[0]);
-       GLES31.glBufferData(GLES31.GL_ARRAY_BUFFER, numVertices*VERTSIZE, mVertAttribs, GLES31.GL_STATIC_READ);
-       GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
-       }
-     if( mAttTFO[0]<0 && Distorted.GLSL >= 300 )
-       {
-       GLES31.glGenBuffers(1, mAttTFO, 0);
-       GLES31.glBindBuffer(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, mAttTFO[0]);
-       GLES31.glBufferData(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, numVertices*TFSIZE, null, GLES31.GL_STATIC_READ);
-       GLES31.glBindBuffer(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0);
-       }
+     mVBO = new DistortedBuffer(GLES31.GL_ARRAY_BUFFER             , GLES31.GL_STATIC_READ);
+     mTFO = new DistortedBuffer(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, GLES31.GL_STATIC_READ);
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// must be called from a thread holding OpenGL Context
 
-   void delete()
+   void setData(int size, FloatBuffer buffer)
      {
-     if( mAttVBO[0]>=0 )
-       {
-       GLES31.glDeleteBuffers(1, mAttVBO, 0);
-       mAttVBO[0] = -1;
-       }
-     if( mAttTFO[0]>=0 )
-       {
-       GLES31.glDeleteBuffers(1, mAttTFO, 0);
-       mAttTFO[0] = -1;
-       }
+     mVBO.setData(size*VERTSIZE, buffer);
+     mTFO.setData(size*TFSIZE  , null  );
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   void recreate()
+   int getVBO()
      {
-     mAttVBO[0] = -1;
-     mAttTFO[0] = -1;
+     return mVBO.mIndex[0];
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// debugging only
 
-   String printDetails()
+   int getTFO()
      {
-     return getClass().getSimpleName()+" vertices:"+ numVertices;
+     return mTFO.mIndex[0];
      }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * When rendering this Mesh, do we want to render the Normal vectors as well?
@@ -136,6 +102,18 @@ public abstract class MeshObject extends DistortedObject
      {
      mShowNormals = (Distorted.GLSL >= 300 && show);
      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Release all internal resources.
+ */
+   public void markForDeletion()
+     {
+     mVertAttribs.clear();
+
+     mVBO.markForDeletion();
+     mTFO.markForDeletion();
+     }
    }
 
 
