| 
      1
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      2
     | 
    
      // Copyright 2016 Leszek Koltunski                                                               //
 
     | 
  
  
    | 
      3
     | 
    
      //                                                                                               //
 
     | 
  
  
    | 
      4
     | 
    
      // This file is part of Distorted.                                                               //
 
     | 
  
  
    | 
      5
     | 
    
      //                                                                                               //
 
     | 
  
  
    | 
      6
     | 
    
      // Distorted is free software: you can redistribute it and/or modify                             //
 
     | 
  
  
    | 
      7
     | 
    
      // it under the terms of the GNU General Public License as published by                          //
 
     | 
  
  
    | 
      8
     | 
    
      // the Free Software Foundation, either version 2 of the License, or                             //
 
     | 
  
  
    | 
      9
     | 
    
      // (at your option) any later version.                                                           //
 
     | 
  
  
    | 
      10
     | 
    
      //                                                                                               //
 
     | 
  
  
    | 
      11
     | 
    
      // Distorted is distributed in the hope that it will be useful,                                  //
 
     | 
  
  
    | 
      12
     | 
    
      // but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
 
     | 
  
  
    | 
      13
     | 
    
      // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
 
     | 
  
  
    | 
      14
     | 
    
      // GNU General Public License for more details.                                                  //
 
     | 
  
  
    | 
      15
     | 
    
      //                                                                                               //
 
     | 
  
  
    | 
      16
     | 
    
      // You should have received a copy of the GNU General Public License                             //
 
     | 
  
  
    | 
      17
     | 
    
      // along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
 
     | 
  
  
    | 
      18
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      19
     | 
    
      
 
     | 
  
  
    | 
      20
     | 
    
      package org.distorted.examples.listener;
 
     | 
  
  
    | 
      21
     | 
    
      
 
     | 
  
  
    | 
      22
     | 
    
      import java.io.IOException;
 
     | 
  
  
    | 
      23
     | 
    
      import java.io.InputStream;
 
     | 
  
  
    | 
      24
     | 
    
      import java.util.Random;
 
     | 
  
  
    | 
      25
     | 
    
      
 
     | 
  
  
    | 
      26
     | 
    
      import javax.microedition.khronos.egl.EGLConfig;
 
     | 
  
  
    | 
      27
     | 
    
      import javax.microedition.khronos.opengles.GL10;
 
     | 
  
  
    | 
      28
     | 
    
      
 
     | 
  
  
    | 
      29
     | 
    
      import org.distorted.examples.R;
 
     | 
  
  
    | 
      30
     | 
    
      
 
     | 
  
  
    | 
      31
     | 
    
      import org.distorted.library.effect.EffectType;
 
     | 
  
  
    | 
      32
     | 
    
      import org.distorted.library.effect.MatrixEffectScale;
 
     | 
  
  
    | 
      33
     | 
    
      import org.distorted.library.effect.VertexEffectDistort;
 
     | 
  
  
    | 
      34
     | 
    
      import org.distorted.library.main.DistortedLibrary;
 
     | 
  
  
    | 
      35
     | 
    
      import org.distorted.library.main.DistortedScreen;
 
     | 
  
  
    | 
      36
     | 
    
      import org.distorted.library.mesh.MeshRectangles;
 
     | 
  
  
    | 
      37
     | 
    
      import org.distorted.library.main.DistortedTexture;
 
     | 
  
  
    | 
      38
     | 
    
      import org.distorted.library.main.DistortedEffects;
 
     | 
  
  
    | 
      39
     | 
    
      import org.distorted.library.type.Dynamic3D;
 
     | 
  
  
    | 
      40
     | 
    
      import org.distorted.library.type.Static3D;
 
     | 
  
  
    | 
      41
     | 
    
      import org.distorted.library.type.Static4D;
 
     | 
  
  
    | 
      42
     | 
    
      import org.distorted.library.message.EffectListener;
 
     | 
  
  
    | 
      43
     | 
    
      
 
     | 
  
  
    | 
      44
     | 
    
      import android.graphics.Bitmap;
 
     | 
  
  
    | 
      45
     | 
    
      import android.graphics.BitmapFactory;
 
     | 
  
  
    | 
      46
     | 
    
      import android.opengl.GLSurfaceView;
 
     | 
  
  
    | 
      47
     | 
    
      
 
     | 
  
  
    | 
      48
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      49
     | 
    
      // Show how to use the setMax, notifyWhenFinished / effectFinished APIs
 
     | 
  
  
    | 
      50
     | 
    
      
 
     | 
  
  
    | 
      51
     | 
    
      class ListenerRenderer implements GLSurfaceView.Renderer, EffectListener, DistortedLibrary.ExceptionListener
 
     | 
  
  
    | 
      52
     | 
    
      {
     | 
  
  
    | 
      53
     | 
    
         private final int NUM_CONCURRENT_BUBBLES = 12;
 
     | 
  
  
    | 
      54
     | 
    
      
 
     | 
  
  
    | 
      55
     | 
    
         private GLSurfaceView mView;
 
     | 
  
  
    | 
      56
     | 
    
         private DistortedEffects mEffects;
 
     | 
  
  
    | 
      57
     | 
    
         private DistortedScreen mScreen;
 
     | 
  
  
    | 
      58
     | 
    
         private DistortedTexture mTexture;
 
     | 
  
  
    | 
      59
     | 
    
         private MeshRectangles mMesh;
 
     | 
  
  
    | 
      60
     | 
    
         private Random mRnd;
 
     | 
  
  
    | 
      61
     | 
    
         private Static3D mScale;
 
     | 
  
  
    | 
      62
     | 
    
         private float mBmpRatio;
 
     | 
  
  
    | 
      63
     | 
    
      
 
     | 
  
  
    | 
      64
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      65
     | 
    
      
 
     | 
  
  
    | 
      66
     | 
    
         ListenerRenderer(GLSurfaceView v)
 
     | 
  
  
    | 
      67
     | 
    
            {
     | 
  
  
    | 
      68
     | 
    
            mView = v;
 
     | 
  
  
    | 
      69
     | 
    
      
 
     | 
  
  
    | 
      70
     | 
    
            mTexture = new DistortedTexture();
 
     | 
  
  
    | 
      71
     | 
    
            mScreen  = new DistortedScreen();
 
     | 
  
  
    | 
      72
     | 
    
            mRnd     = new Random(0);
 
     | 
  
  
    | 
      73
     | 
    
            mScale   = new Static3D(1,1,1);
 
     | 
  
  
    | 
      74
     | 
    
            mEffects = new DistortedEffects();
 
     | 
  
  
    | 
      75
     | 
    
            mEffects.apply(new MatrixEffectScale(mScale));
 
     | 
  
  
    | 
      76
     | 
    
      
 
     | 
  
  
    | 
      77
     | 
    
            for(int i=0; i<NUM_CONCURRENT_BUBBLES; i++)
 
     | 
  
  
    | 
      78
     | 
    
              {
     | 
  
  
    | 
      79
     | 
    
              VertexEffectDistort newEffect = createNewBubble();
 
     | 
  
  
    | 
      80
     | 
    
      
 
     | 
  
  
    | 
      81
     | 
    
              if( !mEffects.apply(newEffect) )
 
     | 
  
  
    | 
      82
     | 
    
                {
     | 
  
  
    | 
      83
     | 
    
                android.util.Log.e("listener", "failed to add bubble - this should never happen!");
     | 
  
  
    | 
      84
     | 
    
                }
 
     | 
  
  
    | 
      85
     | 
    
              }
 
     | 
  
  
    | 
      86
     | 
    
            }
 
     | 
  
  
    | 
      87
     | 
    
      
 
     | 
  
  
    | 
      88
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      89
     | 
    
      
 
     | 
  
  
    | 
      90
     | 
    
         private VertexEffectDistort createNewBubble()
 
     | 
  
  
    | 
      91
     | 
    
            {
     | 
  
  
    | 
      92
     | 
    
            float radius =  0.10f + 0.70f*mRnd.nextFloat() ; // pop up a bubble of size (radius,height)
 
     | 
  
  
    | 
      93
     | 
    
            float height = -0.10f + 0.20f*mRnd.nextFloat() ; //
 
     | 
  
  
    | 
      94
     | 
    
            float pointx =  0.80f * (mRnd.nextFloat()-0.5f); // at a random place on the bitmap (but not near the edge)
 
     | 
  
  
    | 
      95
     | 
    
            float pointy =  0.80f * (mRnd.nextFloat()-0.5f); //
 
     | 
  
  
    | 
      96
     | 
    
            int duration =   1000 + mRnd.nextInt(3000);      // for anytime from 1 to 4 seconds
 
     | 
  
  
    | 
      97
     | 
    
      
 
     | 
  
  
    | 
      98
     | 
    
            // '1.0f' i.e. from (0,0,0) to (0,0,height) and back to (0,0,0) - full circle.
 
     | 
  
  
    | 
      99
     | 
    
            Dynamic3D dDistort = new Dynamic3D(duration,1.0f);
 
     | 
  
  
    | 
      100
     | 
    
            dDistort.add(new Static3D(0,0,     0));
 
     | 
  
  
    | 
      101
     | 
    
            dDistort.add(new Static3D(0,0,height));
 
     | 
  
  
    | 
      102
     | 
    
      
 
     | 
  
  
    | 
      103
     | 
    
            Static3D center = new Static3D(pointx,pointy,0);
 
     | 
  
  
    | 
      104
     | 
    
            Static4D region = new Static4D(0,0,0,radius);
 
     | 
  
  
    | 
      105
     | 
    
            VertexEffectDistort distort = new VertexEffectDistort(dDistort,center,region);
 
     | 
  
  
    | 
      106
     | 
    
      
 
     | 
  
  
    | 
      107
     | 
    
            // We want to know when this effect finishes so that we can add a new one.
 
     | 
  
  
    | 
      108
     | 
    
            distort.notifyWhenFinished(this);
 
     | 
  
  
    | 
      109
     | 
    
      
 
     | 
  
  
    | 
      110
     | 
    
            return distort;
 
     | 
  
  
    | 
      111
     | 
    
            }
 
     | 
  
  
    | 
      112
     | 
    
         
 
     | 
  
  
    | 
      113
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      114
     | 
    
      // An effect just finished, i.e. its Dynamic 'dDistort' reached its end point.
 
     | 
  
  
    | 
      115
     | 
    
      // The ID of the finished effect is 'effectID' but here we know it must be one of the Distorts
 
     | 
  
  
    | 
      116
     | 
    
      // and we don't care which one it is - just remove the finished effect from the Effect queues and
 
     | 
  
  
    | 
      117
     | 
    
      // add a new one right back in.
 
     | 
  
  
    | 
      118
     | 
    
      
 
     | 
  
  
    | 
      119
     | 
    
         public void effectFinished(final long effectID)
 
     | 
  
  
    | 
      120
     | 
    
           {
     | 
  
  
    | 
      121
     | 
    
           mEffects.abortById(effectID);
 
     | 
  
  
    | 
      122
     | 
    
      
 
     | 
  
  
    | 
      123
     | 
    
           VertexEffectDistort newEffect = createNewBubble();
 
     | 
  
  
    | 
      124
     | 
    
      
 
     | 
  
  
    | 
      125
     | 
    
           if( !mEffects.apply(newEffect) )
 
     | 
  
  
    | 
      126
     | 
    
             {
     | 
  
  
    | 
      127
     | 
    
             android.util.Log.e("Listener", "failed to add new bubble - this should never happen!");
     | 
  
  
    | 
      128
     | 
    
             }
 
     | 
  
  
    | 
      129
     | 
    
           }
 
     | 
  
  
    | 
      130
     | 
    
         
 
     | 
  
  
    | 
      131
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      132
     | 
    
      
 
     | 
  
  
    | 
      133
     | 
    
         public void onDrawFrame(GL10 glUnused)
 
     | 
  
  
    | 
      134
     | 
    
            {
     | 
  
  
    | 
      135
     | 
    
            mScreen.render( System.currentTimeMillis() );
 
     | 
  
  
    | 
      136
     | 
    
            }
 
     | 
  
  
    | 
      137
     | 
    
      
 
     | 
  
  
    | 
      138
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      139
     | 
    
          
 
     | 
  
  
    | 
      140
     | 
    
         public void onSurfaceChanged(GL10 glUnused, int width, int height)
 
     | 
  
  
    | 
      141
     | 
    
           {
     | 
  
  
    | 
      142
     | 
    
           if( width<height ) mScale.set( width,   width*mBmpRatio, width  );
 
     | 
  
  
    | 
      143
     | 
    
           else               mScale.set( height/mBmpRatio, height, height );
 
     | 
  
  
    | 
      144
     | 
    
      
 
     | 
  
  
    | 
      145
     | 
    
           mScreen.resize(width, height);
 
     | 
  
  
    | 
      146
     | 
    
           }
 
     | 
  
  
    | 
      147
     | 
    
      
 
     | 
  
  
    | 
      148
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      149
     | 
    
          
 
     | 
  
  
    | 
      150
     | 
    
         public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
 
     | 
  
  
    | 
      151
     | 
    
           {
     | 
  
  
    | 
      152
     | 
    
           InputStream is = mView.getContext().getResources().openRawResource(R.raw.water);
 
     | 
  
  
    | 
      153
     | 
    
           Bitmap bitmap;
 
     | 
  
  
    | 
      154
     | 
    
              
 
     | 
  
  
    | 
      155
     | 
    
           try
 
     | 
  
  
    | 
      156
     | 
    
             {
     | 
  
  
    | 
      157
     | 
    
             bitmap = BitmapFactory.decodeStream(is);
 
     | 
  
  
    | 
      158
     | 
    
             }
 
     | 
  
  
    | 
      159
     | 
    
           finally
 
     | 
  
  
    | 
      160
     | 
    
             {
     | 
  
  
    | 
      161
     | 
    
             try
 
     | 
  
  
    | 
      162
     | 
    
               {
     | 
  
  
    | 
      163
     | 
    
               is.close();
 
     | 
  
  
    | 
      164
     | 
    
               }
 
     | 
  
  
    | 
      165
     | 
    
             catch(IOException e) { }
     | 
  
  
    | 
      166
     | 
    
             }
 
     | 
  
  
    | 
      167
     | 
    
      
 
     | 
  
  
    | 
      168
     | 
    
           mBmpRatio = (float)bitmap.getHeight()/bitmap.getWidth();
 
     | 
  
  
    | 
      169
     | 
    
           mTexture.setTexture(bitmap);
 
     | 
  
  
    | 
      170
     | 
    
      
 
     | 
  
  
    | 
      171
     | 
    
           if( mMesh==null ) mMesh = new MeshRectangles(50, (int)(50*mBmpRatio) );
 
     | 
  
  
    | 
      172
     | 
    
      
 
     | 
  
  
    | 
      173
     | 
    
           mScreen.detachAll();
 
     | 
  
  
    | 
      174
     | 
    
           mScreen.attach(mTexture,mEffects,mMesh);
 
     | 
  
  
    | 
      175
     | 
    
      
 
     | 
  
  
    | 
      176
     | 
    
           // Normally we can only hold no more than 5 (see EffectType.reset()) Vertex
 
     | 
  
  
    | 
      177
     | 
    
           // effects at any given time. Here we want 12, so we need to increase the default.
 
     | 
  
  
    | 
      178
     | 
    
           // We need to call this before we call onCreate; best done here.
 
     | 
  
  
    | 
      179
     | 
    
           // After onCreate we can also call this but only to decrease this value!
 
     | 
  
  
    | 
      180
     | 
    
           //
 
     | 
  
  
    | 
      181
     | 
    
           // One more than we have bubbles at any given time because it can sometimes
 
     | 
  
  
    | 
      182
     | 
    
           // happen that the old bubble is not yet removed when we add a new one.
 
     | 
  
  
    | 
      183
     | 
    
           DistortedLibrary.setMax(EffectType.VERTEX,NUM_CONCURRENT_BUBBLES+1);
 
     | 
  
  
    | 
      184
     | 
    
           VertexEffectDistort.enable();
 
     | 
  
  
    | 
      185
     | 
    
      
 
     | 
  
  
    | 
      186
     | 
    
           DistortedLibrary.onCreate(mView.getContext(), this);
 
     | 
  
  
    | 
      187
     | 
    
           }
 
     | 
  
  
    | 
      188
     | 
    
      
 
     | 
  
  
    | 
      189
     | 
    
      ///////////////////////////////////////////////////////////////////////////////////////////////////
 
     | 
  
  
    | 
      190
     | 
    
      
 
     | 
  
  
    | 
      191
     | 
    
         public void distortedException(Exception ex)
 
     | 
  
  
    | 
      192
     | 
    
           {
     | 
  
  
    | 
      193
     | 
    
           android.util.Log.e("Listener", ex.getMessage() );
     | 
  
  
    | 
      194
     | 
    
           }
 
     | 
  
  
    | 
      195
     | 
    
      }
 
     |