commit 08602667ea98c1877b7caa94c2d1deae1e41d5ab
Author: Leszek Koltunski <leszek@distoretedandroid.org>
Date:   Tue May 30 13:17:41 2017 +0100

    Beginnings of the GLOW unit test.

diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 562aea2..8000bc0 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -46,5 +46,6 @@
         <activity android:name=".blur.BlurActivity"/>
         <activity android:name=".multiblur.MultiblurActivity"/>
         <activity android:name=".stencil.StencilActivity"/>
+        <activity android:name=".glow.GlowActivity"/>
     </application>
 </manifest>
diff --git a/src/main/java/org/distorted/examples/TableOfContents.java b/src/main/java/org/distorted/examples/TableOfContents.java
index 08a6765..0e41e7b 100644
--- a/src/main/java/org/distorted/examples/TableOfContents.java
+++ b/src/main/java/org/distorted/examples/TableOfContents.java
@@ -64,6 +64,7 @@ import org.distorted.examples.mirror.MirrorActivity;
 import org.distorted.examples.blur.BlurActivity;
 import org.distorted.examples.multiblur.MultiblurActivity;
 import org.distorted.examples.stencil.StencilActivity;
+import org.distorted.examples.glow.GlowActivity;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -356,6 +357,15 @@ public class TableOfContents extends ListActivity
       activityMapping.put(i++, StencilActivity.class);
    }
 
+  {
+      final Map<String, Object> item = new HashMap<>();
+      item.put(ITEM_IMAGE, R.drawable.icon_example_glow);
+      item.put(ITEM_TITLE, (i+1)+". "+getText(R.string.example_glow));
+      item.put(ITEM_SUBTITLE, getText(R.string.example_glow_subtitle));
+      data.add(item);
+      activityMapping.put(i++, GlowActivity.class);
+   }
+
    final SimpleAdapter dataAdapter = new SimpleAdapter(this, data, R.layout.toc_item, new String[] {ITEM_IMAGE, ITEM_TITLE, ITEM_SUBTITLE}, new int[] {R.id.Image, R.id.Title, R.id.SubTitle});
    setListAdapter(dataAdapter);  
       
diff --git a/src/main/java/org/distorted/examples/glow/GlowActivity.java b/src/main/java/org/distorted/examples/glow/GlowActivity.java
new file mode 100644
index 0000000..1e72137
--- /dev/null
+++ b/src/main/java/org/distorted/examples/glow/GlowActivity.java
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.glow;
+
+import android.app.Activity;
+import android.os.Bundle;
+import org.distorted.library.Distorted;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class GlowActivity extends Activity
+{
+    private GlowSurfaceView mView;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    @Override
+    protected void onCreate(Bundle savedState)
+      {
+      super.onCreate(savedState);
+      mView = new GlowSurfaceView(this);
+      setContentView(mView);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onPause() 
+      {
+      mView.onPause();
+      Distorted.onPause();
+      super.onPause();
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onResume() 
+      {
+      super.onResume();
+      mView.onResume();
+      }
+ 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    @Override
+    protected void onDestroy() 
+      {
+      Distorted.onDestroy();  
+      super.onDestroy();
+      }
+}
diff --git a/src/main/java/org/distorted/examples/glow/GlowRenderer.java b/src/main/java/org/distorted/examples/glow/GlowRenderer.java
new file mode 100644
index 0000000..f6c6b14
--- /dev/null
+++ b/src/main/java/org/distorted/examples/glow/GlowRenderer.java
@@ -0,0 +1,166 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// 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.glow;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLSurfaceView;
+
+import org.distorted.examples.R;
+import org.distorted.library.Distorted;
+import org.distorted.library.DistortedEffects;
+import org.distorted.library.DistortedNode;
+import org.distorted.library.DistortedScreen;
+import org.distorted.library.DistortedTexture;
+import org.distorted.library.EffectNames;
+import org.distorted.library.EffectTypes;
+import org.distorted.library.MeshFlat;
+import org.distorted.library.MeshObject;
+import org.distorted.library.type.Dynamic1D;
+import org.distorted.library.type.Static1D;
+import org.distorted.library.type.Static3D;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class GlowRenderer implements GLSurfaceView.Renderer
+{
+   private static final int[] colors  = new int[] {0,0,1,  0,0,0,  1,0,0,  1,1,0,  0,1,0,  1,1,1}; // blue, black, red, yellow, green, white
+   private static final int LEAF_SIZE = 100;
+   private static final int NUM_LEAVES= colors.length/3;
+   
+   private GLSurfaceView mView;
+   private DistortedNode mRoot;
+   private DistortedTexture mLeaf;
+   private DistortedScreen mScreen;
+   private int mRootW, mRootH;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   GlowRenderer(GLSurfaceView v)
+      {     
+      mView = v;
+
+      mRootW = 3*LEAF_SIZE;
+      mRootH = 3*LEAF_SIZE;
+
+      mLeaf = new DistortedTexture(LEAF_SIZE,LEAF_SIZE);
+      DistortedTexture surface = new DistortedTexture(mRootW,mRootH);
+      MeshObject mesh = new MeshFlat(1,1);
+      DistortedEffects[] leafEffects = new DistortedEffects[NUM_LEAVES];
+
+      mRoot = new DistortedNode(surface, new DistortedEffects(), mesh);
+     
+      Static3D moveVector = new Static3D(0,LEAF_SIZE,0);
+      Static1D chromaLevel= new Static1D(0.5f);
+      Static3D center     = new Static3D(3*LEAF_SIZE/2, 3*LEAF_SIZE/2, 0);
+      Static3D axis       = new Static3D(0,0,1);
+
+      for(int j=0; j<NUM_LEAVES; j++)
+        {
+        leafEffects[j] = new DistortedEffects();
+        leafEffects[j].rotate( new Static1D(j*(360/NUM_LEAVES)), axis, center );
+        leafEffects[j].move(moveVector);
+        leafEffects[j].chroma( chromaLevel, new Static3D(colors[3*j],colors[3*j+1], colors[3*j+2]) );
+
+        mRoot.attach( mLeaf, leafEffects[j], mesh);
+        }
+
+      mScreen = new DistortedScreen(mView);
+      mScreen.attach(mRoot);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+   
+    public void onDrawFrame(GL10 glUnused) 
+      {
+      mScreen.render(System.currentTimeMillis());
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    public void onSurfaceChanged(GL10 glUnused, int width, int height) 
+      {
+      float qw = (float)width /mRootW;
+      float qh = (float)height/mRootH;
+      float factor = 0.6f* (qw<qh ? qw:qh);
+      int w = (int)(factor*mRootW);
+      int h = (int)(factor*mRootH);
+
+      Dynamic1D rot = new Dynamic1D(5000,0.0f);
+      rot.setMode(Dynamic1D.MODE_JUMP);
+      rot.add(new Static1D(  0));
+      rot.add(new Static1D(360));
+
+      Static3D center = new Static3D(3*LEAF_SIZE/2, 3*LEAF_SIZE/2, 0);
+      Static3D axis   = new Static3D(0,0,1);
+
+      DistortedEffects effects = mRoot.getEffects();
+      effects.abortEffects(EffectTypes.MATRIX);
+      effects.move( new Static3D((width-w)/2 ,(height-h)/2, 0) );
+      effects.scale( factor );
+      effects.rotate( rot, axis, center );
+
+      mScreen.resize(width, height);
+      }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+    public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
+      {
+      InputStream is = mView.getContext().getResources().openRawResource(R.raw.leaf);
+      Bitmap leaf;
+      
+      try 
+        {
+        leaf = BitmapFactory.decodeStream(is);
+        } 
+      finally 
+        {
+        try 
+          {
+          is.close();
+          } 
+        catch(IOException e) { }
+        }  
+      
+      mLeaf.setTexture(leaf);
+
+      DistortedEffects.enableEffect(EffectNames.CHROMA);
+      DistortedEffects.enableEffect(EffectNames.GLOW);
+
+      try
+        {
+        Distorted.onCreate(mView.getContext());
+        }
+      catch(Exception ex)
+        {
+        android.util.Log.e("Glow", ex.getMessage() );
+        }
+      }
+ 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+    
+}
diff --git a/src/main/java/org/distorted/examples/glow/GlowSurfaceView.java b/src/main/java/org/distorted/examples/glow/GlowSurfaceView.java
new file mode 100644
index 0000000..50b4b42
--- /dev/null
+++ b/src/main/java/org/distorted/examples/glow/GlowSurfaceView.java
@@ -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/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.examples.glow;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class GlowSurfaceView extends GLSurfaceView
+{
+    public GlowSurfaceView(Context context)
+      {
+      super(context);
+      setRenderer(new GlowRenderer(this));
+      }
+}
+
diff --git a/src/main/res/drawable-hdpi/icon_example_glow.png b/src/main/res/drawable-hdpi/icon_example_glow.png
new file mode 100644
index 0000000..3ff1318
Binary files /dev/null and b/src/main/res/drawable-hdpi/icon_example_glow.png differ
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 9ec9599..5649caf 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -145,6 +145,8 @@
     <string name="example_multiblur_subtitle">Blur multiple objects which obstruct each other.</string>
     <string name="example_stencil">Stencil Buffer</string>
     <string name="example_stencil_subtitle">Implement the classic stencil example from https://open.gl/depthstencils</string>
+    <string name="example_glow">Glow Effect</string>
+    <string name="example_glow_subtitle">See objects glowing with light.</string>
 
     <string name="example_movingeffects_toast">Click on \'RESET\' and define your path by touching the screen. Then click on one of the effects and see it move along your path.</string>
     <string name="example_rotate_toast">Rotate the scene by swiping the screen</string>
