commit 8beaa293b47889fd1c24ed4aa7233371b8681a10
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Tue May 2 16:22:31 2017 +0100

    Progress with moving the Transform Feedback functionality from the APP to the library.

diff --git a/src/main/java/org/distorted/examples/feedback/FeedbackActivity.java b/src/main/java/org/distorted/examples/feedback/FeedbackActivity.java
index 23003b8..9284308 100644
--- a/src/main/java/org/distorted/examples/feedback/FeedbackActivity.java
+++ b/src/main/java/org/distorted/examples/feedback/FeedbackActivity.java
@@ -46,6 +46,7 @@ public class FeedbackActivity extends Activity
     protected void onPause() 
       {
       mView.onPause();
+      Distorted.onPause();
       super.onPause();
       }
 
@@ -63,6 +64,7 @@ public class FeedbackActivity extends Activity
     @Override
     protected void onDestroy() 
       {
+      Distorted.onDestroy();
       super.onDestroy();
       }
     
diff --git a/src/main/java/org/distorted/examples/feedback/FeedbackRenderer.java b/src/main/java/org/distorted/examples/feedback/FeedbackRenderer.java
index f72ecef..96f243d 100644
--- a/src/main/java/org/distorted/examples/feedback/FeedbackRenderer.java
+++ b/src/main/java/org/distorted/examples/feedback/FeedbackRenderer.java
@@ -21,6 +21,8 @@ package org.distorted.examples.feedback;
 
 import android.opengl.GLSurfaceView;
 
+import org.distorted.library.Distorted;
+
 import javax.microedition.khronos.egl.EGLConfig;
 import javax.microedition.khronos.opengles.GL10;
 
@@ -28,20 +30,21 @@ import javax.microedition.khronos.opengles.GL10;
 
 class FeedbackRenderer implements GLSurfaceView.Renderer
 {
-
+    private GLSurfaceView mView;
+    private TransformFeedback mTF;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     FeedbackRenderer(GLSurfaceView v)
       {
-
+      mView = v;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
     public void onDrawFrame(GL10 glUnused) 
       {
-      TransformFeedback tf = new TransformFeedback();
+      mTF.render();
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -55,6 +58,15 @@ class FeedbackRenderer implements GLSurfaceView.Renderer
     
     public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
       {
+      try
+        {
+        Distorted.onCreate(mView.getContext());
+        }
+      catch(Exception ex)
+        {
+        android.util.Log.e("MonaLisa", ex.getMessage() );
+        }
 
+      mTF = new TransformFeedback(mView.getContext());
       }
 }
diff --git a/src/main/java/org/distorted/examples/feedback/TransformFeedback.java b/src/main/java/org/distorted/examples/feedback/TransformFeedback.java
index 23f36e8..d17df96 100644
--- a/src/main/java/org/distorted/examples/feedback/TransformFeedback.java
+++ b/src/main/java/org/distorted/examples/feedback/TransformFeedback.java
@@ -1,99 +1,79 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 package org.distorted.examples.feedback;
 
-import android.opengl.EGL14;
+import android.content.Context;
+import android.content.res.Resources;
 import android.opengl.GLES30;
 import android.util.Log;
 
+import org.distorted.library.Distorted;
+import org.distorted.library.program.DistortedProgram;
+
+import java.io.InputStream;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.FloatBuffer;
 
-/**
- * Created by izzy on 6/24/15. TransformFeedback is a example of how
- *  to do transform feedback on Android using OpenGLES 3.0. Closely
- *  follows the example found at https://open.gl/feedback.
- *
- * Assumes you have a working instance of GLSurfaceVew. Remember to call
- *  setEGLContextClientVersion(3) to set the OpenGLES context to API 3.0
- *  and have the appropriate OpenGLES specified in the Android manifest file.
- */
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
+public class TransformFeedback
+    {
+    private static DistortedProgram mFeedbackProgram;
+    private static int mProgramHandle;
 
-public class TransformFeedback {
-    private final String TAG = "TransformFeedback";
-
-
-// Vertex shader
-    private final String vertexShaderSrc =
-            "#version 300 es \n" +
-            "in float inValue;\n" +
-            "out float outValue;\n" +
-
-            "void main() {\n" +
-            "    outValue = sqrt(inValue);\n" +
-            "}";
-
-// Need a fragmentShader or glLinkProgram will throw
-    private final String fragmentShaderCode =
-            "#version 300 es \n" +
-            "precision mediump float;\n" +
-            "out vec4 fragColor;\n" +
-            "void main() {\n" +
-            "  fragColor = vec4(1.0,1.0,1.0,1.0);\n" +
-            "}";
-
-    private final int mProgram;
-
-    /**
-     * The TransformFeedback constructor contains all the code to initialize
-     *  and draw the TransformFeedback, so create an instance of TransformFeedback
-     *  i.e. 'new TransformFeedBack()' in your 'GLRenderer.OnDrawFrame()' method.
-     */
-    public TransformFeedback(){
-
-        // Compile shaders
-        int vertexShader   = loadShader(GLES30.GL_VERTEX_SHADER  , vertexShaderSrc   );
-        int fragmentShader = loadShader(GLES30.GL_FRAGMENT_SHADER, fragmentShaderCode);
-
-        // Create program and attach shaders
-        mProgram = GLES30.glCreateProgram();
-        GLES30.glAttachShader(mProgram, vertexShader);
-        GLES30.glAttachShader(mProgram, fragmentShader);
-
-        // Tell GL where the feedbackVaryings are in the shader before Linking
-        //  the shaders together to form a program.
-        final String[] feedbackVaryings = { "outValue" };
-        GLES30.glTransformFeedbackVaryings(mProgram, feedbackVaryings, GLES30.GL_INTERLEAVED_ATTRIBS);
-        checkGlError(TAG + " glTransformFeedbackVaryings");
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-        // Link program and look for errors
-        GLES30.glLinkProgram(mProgram);
+    public TransformFeedback(final Context context)
+        {
+        final Resources resources = context.getResources();
+        final InputStream vertStream = resources.openRawResource(org.distorted.library.R.raw.feedback_vertex_shader);
+        final InputStream fragStream = resources.openRawResource(org.distorted.library.R.raw.feedback_fragment_shader);
 
-        int[] linkSuccessful = new int[1];
-        GLES30.glGetProgramiv(mProgram, GLES30.GL_LINK_STATUS, linkSuccessful, 0);
+        String vertHeader= Distorted.GLSL_VERSION;
+        String fragHeader= Distorted.GLSL_VERSION;
+        String[] feedback = { "outValue" };
 
-        if (linkSuccessful[0] != 1){
-            Log.d(TAG, "glLinkProgram failed");
+        try
+          {
+          mFeedbackProgram = new DistortedProgram(vertStream,fragStream, vertHeader, fragHeader, Distorted.GLSL, feedback );
+          mProgramHandle = mFeedbackProgram.getProgramHandle();
+          }
+        catch(Exception ex)
+          {
+          Log.e("TransformFeedback", "exception creating feedback program: "+ex.getMessage());
+          }
         }
-        checkGlError(TAG + " glLinkProgram");
 
-        /***********
-         * Begin Rendering process
-         *  everything before this can be moved to an initialization stage
-         ***********/
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-        // Bring the program into use
-        GLES30.glUseProgram(mProgram);
-        checkGlError(TAG + " glUseProgram");
+    void render()
+        {
+        GLES30.glUseProgram(mProgramHandle);
+        checkGlError("glUseProgram");
 
         // Create data to fill VBO
         float[] floatData = { 1.0f, 4.0f, 9.0f, 16.0f, 25.0f, 100.0f };
         int bufferLength = floatData.length * 4;
-        FloatBuffer data = ByteBuffer.allocateDirect(bufferLength)
-                .order(ByteOrder.nativeOrder()).asFloatBuffer();
+        FloatBuffer data = ByteBuffer.allocateDirect(bufferLength).order(ByteOrder.nativeOrder()).asFloatBuffer();
         data.put(floatData).position(0);
 
         // Create VBO and fill with data
@@ -101,13 +81,13 @@ public class TransformFeedback {
         GLES30.glGenBuffers(1, vbo, 0);
         GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbo[0]);
         GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, bufferLength, data, GLES30.GL_STATIC_READ);
-        checkGlError(TAG + " glBufferData GL_ARRAY_BUFFER");
+        checkGlError("glBufferData GL_ARRAY_BUFFER");
 
         // Link created VBO to shader attribute "inValue"
-        int inputAttrib = GLES30.glGetAttribLocation(mProgram, "inValue");
+        int inputAttrib = GLES30.glGetAttribLocation(mProgramHandle, "inValue");
         GLES30.glEnableVertexAttribArray(inputAttrib);
         GLES30.glVertexAttribPointer(inputAttrib, 1, GLES30.GL_FLOAT, false, 4, 0);
-        checkGlError(TAG + " glVertexAttribPointer");
+        checkGlError("glVertexAttribPointer");
 
         // Create transform feedback buffer object and bind to transform feedback
         //  this creates space in a buffer object for the TransformFeedback.
@@ -117,7 +97,7 @@ public class TransformFeedback {
         GLES30.glBufferData(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, bufferLength, null, GLES30.GL_STATIC_READ);
         GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, tbo[0]); //very important
 
-        checkGlError(TAG + " glBindBufferBase");
+        checkGlError("glBindBufferBase");
 
         // Disable Rasterizer if you just need the data
         GLES30.glEnable(GLES30.GL_RASTERIZER_DISCARD);
@@ -125,7 +105,7 @@ public class TransformFeedback {
         // Start the TransformFeedback, Draw the Arrays, then End the Transform Feedback
         GLES30.glBeginTransformFeedback(GLES30.GL_POINTS);
         GLES30.glDrawArrays(GLES30.GL_POINTS, 0, bufferLength);
-        checkGlError(TAG + " glDrawArrays");
+        checkGlError("glDrawArrays");
         GLES30.glEndTransformFeedback();
 
         // Reenable Rasterizer if you need it, which you do if you are drawing anything.
@@ -133,12 +113,12 @@ public class TransformFeedback {
 
         // Flush out anything in GL before mapping the buffer.
         GLES30.glFlush();
-        checkGlError(TAG + " pre-glMapBufferRange ");
+        checkGlError("pre-glMapBufferRange ");
 
         // Map the transform feedback buffer to local address space.
         Buffer mappedBuffer =  GLES30.glMapBufferRange(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER,
                 0, bufferLength, GLES30.GL_MAP_READ_BIT);
-        checkGlError(TAG + " glMapBufferRange");
+        checkGlError("glMapBufferRange");
 
         // Read out the data, here we write to logcat.
         if (mappedBuffer!=null){
@@ -146,53 +126,24 @@ public class TransformFeedback {
             bb.order(ByteOrder.nativeOrder());
             FloatBuffer transformedData = bb.asFloatBuffer();
 
-            Log.d(TAG, String.format("output values = %f %f %f %f %f %f\n",
+            Log.d( "TransofrmFeedback", String.format("output values = %f %f %f %f %f %f\n",
                     transformedData.get(), transformedData.get(), transformedData.get(),
                     transformedData.get(), transformedData.get(), transformedData.get() ));
         }
         // Don't forget to Unmap the Transform Feeback Buffer.
         GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-    private static void checkGlError(String op)
-      {
-      int error = GLES30.glGetError();
-
-      if (error != GLES30.GL_NO_ERROR)
-        {
-        String msg = op + ": glError 0x" + Integer.toHexString(error);
-        throw new RuntimeException(msg);
         }
-      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    private static int loadShader(final int shaderType, final String shaderSource)
-      {
-      int shaderHandle = GLES30.glCreateShader(shaderType);
-
-      if (shaderHandle != 0)
+    private static void checkGlError(String op)
         {
-        GLES30.glShaderSource(shaderHandle, shaderSource);
-        GLES30.glCompileShader(shaderHandle);
-        final int[] compileStatus = new int[1];
-        GLES30.glGetShaderiv(shaderHandle, GLES30.GL_COMPILE_STATUS, compileStatus, 0);
+        int error = GLES30.glGetError();
 
-        if (compileStatus[0] != GLES30.GL_TRUE )
+        if (error != GLES30.GL_NO_ERROR)
           {
-          GLES30.glDeleteShader(shaderHandle);
-          shaderHandle = 0;
+          String msg = op + ": glError 0x" + Integer.toHexString(error);
+          throw new RuntimeException(msg);
           }
         }
-
-      if (shaderHandle == 0)
-        {
-        String error = GLES30.glGetShaderInfoLog(shaderHandle);
-        android.util.Log.e("Program", "error compiling :"+error);
-        }
-
-      return shaderHandle;
-      }
 }
