commit e052248f61cb30743af369fa1724bd471ff1f64e
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Mar 3 13:08:25 2020 +0000

    Port Listener to the new setStretch-less API.

diff --git a/src/main/java/org/distorted/examples/listener/ListenerRenderer.java b/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
index f11eb11..47c2f3a 100644
--- a/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
+++ b/src/main/java/org/distorted/examples/listener/ListenerRenderer.java
@@ -46,6 +46,7 @@ import android.graphics.BitmapFactory;
 import android.opengl.GLSurfaceView;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// Show how to use the setMax, notifyWhenFinished / effectFinished APIs
 
 class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener 
 {
@@ -56,9 +57,9 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
    private DistortedScreen mScreen;
    private DistortedTexture mTexture;
    private MeshRectangles mMesh;
-   private int bmpHeight, bmpWidth;
    private Random mRnd;
    private Static3D mScale;
+   private float mBmpRatio;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -66,38 +67,62 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
       {
       mView = v;
 
-      mScreen = new DistortedScreen();
-      mRnd = new Random(0);
-      mScale= new Static3D(1,1,1);
+      mTexture = new DistortedTexture();
+      mScreen  = new DistortedScreen();
+      mRnd     = new Random(0);
+      mScale   = new Static3D(1,1,1);
+      mEffects = new DistortedEffects();
+      mEffects.apply(new MatrixEffectScale(mScale));
+
+      for(int i=0; i<NUM_CONCURRENT_BUBBLES; i++)
+        {
+        VertexEffectDistort newEffect = createNewBubble();
+
+        if( !mEffects.apply(newEffect) )
+          {
+          android.util.Log.e("listener", "failed to add bubble - this should never happen!");
+          }
+        }
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   private boolean addNewBubble()
+   private VertexEffectDistort createNewBubble()
       {
-      int radius   = (int)(( 0.10f + 0.70f*mRnd.nextFloat())*bmpWidth); // pop up a bubble of size (radius,height)
-      int height   = (int)((-0.10f + 0.20f*mRnd.nextFloat())*bmpWidth); //
-      int pointx   = (int)(0.8f * bmpWidth * (mRnd.nextFloat()-0.5f));  // at a random place on the bitmap (but not near the edge)
-      int pointy   = (int)(0.8f * bmpHeight* (mRnd.nextFloat()-0.5f));  //
-      int duration = 1000 + mRnd.nextInt(3000);                         // for anytime from 1 to 4 seconds
+      float radius =  0.10f + 0.70f*mRnd.nextFloat() ; // pop up a bubble of size (radius,height)
+      float height = -0.10f + 0.20f*mRnd.nextFloat() ; //
+      float pointx =  0.80f * (mRnd.nextFloat()-0.5f); // at a random place on the bitmap (but not near the edge)
+      float pointy =  0.80f * (mRnd.nextFloat()-0.5f); //
+      int duration =   1000 + mRnd.nextInt(3000);      // for anytime from 1 to 4 seconds
 
+      // '1.0f' i.e. from (0,0,0) to (0,0,height) and back to (0,0,0) - full circle.
       Dynamic3D dDistort = new Dynamic3D(duration,1.0f);
       dDistort.add(new Static3D(0,0,     0));
       dDistort.add(new Static3D(0,0,height));
 
-      VertexEffectDistort distort = new VertexEffectDistort(dDistort, new Static3D(pointx,pointy,0), new Static4D(0,0,0,radius));
+      Static3D center = new Static3D(pointx,pointy,0);
+      Static4D region = new Static4D(0,0,0,radius);
+      VertexEffectDistort distort = new VertexEffectDistort(dDistort,center,region);
+
+      // We want to know when this effect finishes so that we can add a new one.
       distort.notifyWhenFinished(this);
 
-      return mEffects.apply(distort);
+      return distort;
       }
    
 ///////////////////////////////////////////////////////////////////////////////////////////////////
+// An effect just finished, i.e. its Dynamic 'dDistort' reached its end point.
+// The ID of the finished effect is 'effectID' but here we know it must be one of the Distorts
+// and we don't care which one it is - just remove the finished effect from the Effect queues and
+// add a new one right back in.
 
    public void effectFinished(final long effectID)
      {
      mEffects.abortById(effectID);
 
-     if( !addNewBubble() )
+     VertexEffectDistort newEffect = createNewBubble();
+
+     if( !mEffects.apply(newEffect) )
        {
        android.util.Log.e("Listener", "failed to add new bubble - this should never happen!");
        }
@@ -105,7 +130,7 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
    
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void onDrawFrame(GL10 glUnused) 
+   public void onDrawFrame(GL10 glUnused)
       {
       mScreen.render( System.currentTimeMillis() );
       }
@@ -114,11 +139,9 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
     
    public void onSurfaceChanged(GL10 glUnused, int width, int height)
      {
-     float horiRatio = (float)width / mMesh.getStretchX();
-     float vertRatio = (float)height/ mMesh.getStretchY();
-     float factor    = horiRatio > vertRatio ? vertRatio : horiRatio;
+     float min= width>height ? height : width;
 
-     mScale.set( factor,factor,factor );
+     mScale.set( min, min*mBmpRatio, min );
      mScreen.resize(width, height);
      }
 
@@ -142,31 +165,21 @@ class ListenerRenderer implements GLSurfaceView.Renderer,EffectListener
        catch(IOException e) { }
        }
 
-     bmpHeight = bitmap.getHeight();
-     bmpWidth  = bitmap.getWidth();
-
-     if( mTexture==null ) mTexture = new DistortedTexture();
+     mBmpRatio = (float)bitmap.getHeight()/bitmap.getWidth();
      mTexture.setTexture(bitmap);
 
-     if( mMesh==null )
-       {
-       mMesh = new MeshRectangles(50,50*bmpHeight/bmpWidth);
-       mMesh.setStretch(bmpWidth,bmpHeight,0);
-       }
-
-     if( mEffects==null )
-       {
-       mEffects = new DistortedEffects();
-       mEffects.apply(new MatrixEffectScale(mScale));
-       }
+     if( mMesh==null ) mMesh = new MeshRectangles(50, (int)(50*mBmpRatio) );
 
      mScreen.detachAll();
      mScreen.attach(mTexture,mEffects,mMesh);
 
-     for(int i = 0; i< NUM_CONCURRENT_BUBBLES; i++) addNewBubble();
-
-     // one more than we have bubbles at any given time because it can sometimes
-     // happen that the old bubble is not yet removed when we add a new one
+     // Normally we can only hold no more than 5 (see EffectType.reset()) Vertex
+     // effects at any given time. Here we want 12, so we need to increase the default.
+     // We need to call this before we call onCreate; best done here.
+     // After onCreate we can also call this but only to decrease this value!
+     //
+     // One more than we have bubbles at any given time because it can sometimes
+     // happen that the old bubble is not yet removed when we add a new one.
      DistortedLibrary.setMax(EffectType.VERTEX,NUM_CONCURRENT_BUBBLES+1);
      VertexEffectDistort.enable();
 
