Project

General

Profile

« Previous | Next » 

Revision d07f2950

Added by Leszek Koltunski almost 8 years ago

Improve aborting Effects.

View differences:

src/main/java/org/distorted/library/Distorted.java
108 108
      int realMaxV = (maxV-11)/4;   // adjust this in case of changes to the shaders...
109 109
      int realMaxF = (maxF- 2)/4;   //
110 110
    
111
      if( EffectListVertex.getMax() > realMaxV )
111
      if( EffectQueueVertex.getMax() > realMaxV )
112 112
        {
113 113
        throw new VertexUniformsException("Too many effects in the vertex shader, max is "+realMaxV, realMaxV);
114 114
        }
115
      if( EffectListFragment.getMax() > realMaxF )
115
      if( EffectQueueFragment.getMax() > realMaxF )
116 116
        {
117 117
        throw new FragmentUniformsException("Too many effects in the fragment shader, max is "+realMaxF, realMaxF);
118 118
        }
......
204 204
   
205 205
    switch(type)
206 206
      {
207
      case GLES20.GL_VERTEX_SHADER  : header += ("#define NUM_VERTEX "  +EffectListVertex.getMax()+"\n");
207
      case GLES20.GL_VERTEX_SHADER  : header += ("#define NUM_VERTEX "  + EffectQueueVertex.getMax()+"\n");
208 208
     
209 209
                                      for(EffectNames name: EffectNames.values() )
210 210
                                        {
......
212 212
                                        header += ("#define "+name.name()+" "+name.ordinal()+"\n");  
213 213
                                        }
214 214
                                      break;
215
      case GLES20.GL_FRAGMENT_SHADER: header += ("#define NUM_FRAGMENT "+EffectListFragment.getMax()+"\n");
215
      case GLES20.GL_FRAGMENT_SHADER: header += ("#define NUM_FRAGMENT "+ EffectQueueFragment.getMax()+"\n");
216 216
     
217 217
                                      for(EffectNames name: EffectNames.values() )
218 218
                                        {
......
342 342
    mNormalH         = GLES20.glGetAttribLocation( mProgramH, "a_Normal"); 
343 343
    mTextureCoordH   = GLES20.glGetAttribLocation( mProgramH, "a_TexCoordinate");
344 344
    
345
    EffectListFragment.getUniforms(mProgramH);
346
    EffectListVertex.getUniforms(mProgramH);
347
    EffectListMatrix.getUniforms(mProgramH);
345
    EffectQueueFragment.getUniforms(mProgramH);
346
    EffectQueueVertex.getUniforms(mProgramH);
347
    EffectQueueMatrix.getUniforms(mProgramH);
348 348
    
349 349
    GLES20.glEnableVertexAttribArray(mPositionH);        
350 350
    GLES20.glEnableVertexAttribArray(mColorH);
......
379 379
    DistortedObjectList.release();
380 380
    DistortedNode.release();
381 381

  
382
    EffectListVertex.reset();
383
    EffectListFragment.reset();
384
    EffectListMatrix.reset();  // no need to reset Other EffectList
382
    EffectQueueVertex.reset();
383
    EffectQueueFragment.reset();
384
    EffectQueueMatrix.reset();  // no need to reset Other EffectQueue
385 385

  
386 386
    EffectMessageSender.stopSending();
387 387
   
......
408 408
 */
409 409
  public static int getMaxMatrix()
410 410
    {
411
    return EffectListMatrix.getMax();
411
    return EffectQueueMatrix.getMax();
412 412
    }
413 413
 
414 414
///////////////////////////////////////////////////////////////////////////////////////////////////
......
419 419
 */  
420 420
  public static int getMaxVertex()
421 421
    {
422
    return EffectListVertex.getMax();  
422
    return EffectQueueVertex.getMax();
423 423
    }
424 424
  
425 425
///////////////////////////////////////////////////////////////////////////////////////////////////
......
430 430
 */  
431 431
  public static int getMaxFragment()
432 432
    {
433
    return EffectListFragment.getMax();  
433
    return EffectQueueFragment.getMax();
434 434
    }
435 435
  
436 436
///////////////////////////////////////////////////////////////////////////////////////////////////
......
444 444
 */
445 445
  public static boolean setMaxMatrix(int max)
446 446
    {
447
    return EffectListMatrix.setMax(max);
447
    return EffectQueueMatrix.setMax(max);
448 448
    }
449 449
  
450 450
///////////////////////////////////////////////////////////////////////////////////////////////////
......
464 464
 */
465 465
  public static boolean setMaxVertex(int max)
466 466
    {
467
    return EffectListVertex.setMax(max);  
467
    return EffectQueueVertex.setMax(max);
468 468
    }
469 469

  
470 470
///////////////////////////////////////////////////////////////////////////////////////////////////
......
484 484
 */
485 485
  public static boolean setMaxFragment(int max)
486 486
    {
487
    return EffectListFragment.setMax(max);  
487
    return EffectQueueFragment.setMax(max);
488 488
    }
489 489
    
490 490
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/DistortedObject.java
12 12
{
13 13
    private static float[] mViewMatrix = new float[16];
14 14
   
15
    protected EffectListMatrix     mM;
16
    protected EffectListFragment   mF;
17
    protected EffectListVertex     mV;
18
    protected EffectListOther      mO;
15
    protected EffectQueueMatrix    mM;
16
    protected EffectQueueFragment  mF;
17
    protected EffectQueueVertex    mV;
18
    protected EffectQueueOther mO;
19 19

  
20 20
    protected boolean matrixCloned, vertexCloned, fragmentCloned;
21 21
 
......
60 60
        } 
61 61
      else
62 62
        {
63
        mM = new EffectListMatrix(d);
63
        mM = new EffectQueueMatrix(d);
64 64
        matrixCloned = false;  
65 65
        }
66 66
    
......
71 71
        } 
72 72
      else
73 73
        {
74
        mV = new EffectListVertex(d);
74
        mV = new EffectQueueVertex(d);
75 75
        vertexCloned = false;  
76 76
        }
77 77
    
......
82 82
        } 
83 83
      else
84 84
        {
85
        mF = new EffectListFragment(d);
85
        mF = new EffectQueueFragment(d);
86 86
        fragmentCloned = false;   
87 87
        }
88 88

  
89
      mO= new EffectListOther(d); // Other effects are never cloned.
89
      mO= new EffectQueueOther(d); // Other effects are never cloned.
90 90
      }
91 91
    
92 92
///////////////////////////////////////////////////////////////////////////////////////////////////
......
187 187
   * Copy constructor used to create a DistortedObject based on various parts of another object.
188 188
   * <p>
189 189
   * Whatever we do not clone gets created just like in the default constructor.
190
   * We only call this from the descendant's classes' constructors where we have to pay attention
191
   * to give it the appropriate type of a DistortedObject!
190 192
   *
191 193
   * @param dc    Source object to create our object from
192 194
   * @param flags A bitmask of values specifying what to copy.
193
   *              For example, CLONE_BITMAP | CLONE_PRESHADER.
195
   *              For example, CLONE_BITMAP | CLONE_MATRIX.
194 196
   */
195 197
    public DistortedObject(DistortedObject dc, int flags)
196 198
      {
......
352 354
    
353 355
///////////////////////////////////////////////////////////////////////////////////////////////////
354 356
/**
355
 * Aborts all Effects. 
357
 * Aborts all Effects.
358
 * @return Number of effects aborted.
356 359
 */
357
    public void abortAllEffects()
360
    public int abortAllEffects()
358 361
      {
359
      mM.abortAll();
360
      mV.abortAll();
361
      mF.abortAll();
362
      mO.abortAll();
362
      return mM.abortAll() + mV.abortAll() + mF.abortAll() + mO.abortAll();
363 363
      }
364 364

  
365 365
///////////////////////////////////////////////////////////////////////////////////////////////////
366 366
/**
367
 * Aborts a subset of Effects.
367
 * Aborts all Effects of a given type, for example all MATRIX Effects.
368 368
 * 
369
 * @param mask Bitmask of the types of effects we want to abort, e.g. TYPE_PRE | TYPE_VERT | TYPE_FRAG.
369
 * @param type one of the constants defined in {@link EffectTypes}
370
 * @return Number of effects aborted.
370 371
 */
371
    public void abortAllEffects(int mask)
372
    public int abortEffects(EffectTypes type)
372 373
      {
373
      if( (mask & EffectTypes.MATRIX.type   ) != 0 ) mM.abortAll();
374
      if( (mask & EffectTypes.VERTEX.type   ) != 0 ) mV.abortAll();
375
      if( (mask & EffectTypes.FRAGMENT.type ) != 0 ) mF.abortAll();
376
      if( (mask & EffectTypes.OTHER.type    ) != 0 ) mO.abortAll();
374
      switch(type)
375
        {
376
        case MATRIX  : return mM.abortAll();
377
        case VERTEX  : return mV.abortAll();
378
        case FRAGMENT: return mF.abortAll();
379
        case OTHER   : return mO.abortAll();
380
        default      : return 0;
381
        }
377 382
      }
378 383
    
379 384
///////////////////////////////////////////////////////////////////////////////////////////////////
......
399 404
/**
400 405
 * Abort all Effects of a given type, for example all rotations.
401 406
 * 
402
 * @param effectType one of the constants defined in {@link EffectNames}
407
 * @param name one of the constants defined in {@link EffectNames}
403 408
 * @return <code>true</code> if a single Effect of type effectType has been found and aborted. 
404 409
 */
405
    public boolean abortEffectType(EffectNames effectType)
410
    public boolean abortEffects(EffectNames name)
406 411
      {
407
      switch(effectType.getType())
412
      switch(name.getType())
408 413
        {
409
        case MATRIX  : return mM.removeByType(effectType);
410
        case VERTEX  : return mV.removeByType(effectType);
411
        case FRAGMENT: return mF.removeByType(effectType);
412
        case OTHER   : return mO.removeByType(effectType);
413
        default           : return false;
414
        case MATRIX  : return mM.removeByType(name);
415
        case VERTEX  : return mV.removeByType(name);
416
        case FRAGMENT: return mF.removeByType(name);
417
        case OTHER   : return mO.removeByType(name);
418
        default      : return false;
414 419
        }
415 420
      }
416 421
    
src/main/java/org/distorted/library/EffectList.java
1
package org.distorted.library;
2

  
3
import java.util.Vector;
4

  
5
///////////////////////////////////////////////////////////////////////////////////////////////////
6

  
7
abstract class EffectList
8
  {
9
  protected byte mNumEffects;   // number of effects at the moment
10
  protected long mTotalEffects; // total number of effects ever created
11
  
12
  protected int[] mType;
13
  protected float[] mUniforms;
14
  protected Interpolator[] mInterP;  // center of the effect
15
  protected Interpolator[] mInterI;  // all other interpolated values
16
  protected long[] mCurrentDuration;
17
  protected byte[] mFreeIndexes;
18
  protected byte[] mIDIndex;
19
  protected long[] mID;
20
  
21
  protected long mTime=0;
22
  protected float mObjHalfX, mObjHalfY, mObjHalfZ;
23
  
24
  protected static int[] mMax = new int[EffectTypes.LENGTH];
25
  protected int mMaxIndex;
26
  protected static boolean mCreated;
27
 
28
  protected Vector<EffectListener> mListeners =null;
29
  protected int mNumListeners=0;  // ==mListeners.length(), but we only create mListeners if the first one gets added
30
  protected long mBitmapID;
31
  
32
  static
33
    {
34
    reset();
35
    }
36
  
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38
   
39
  public EffectList(DistortedObject obj, int numUniforms, int index) 
40
    {
41
    mNumEffects   = 0;
42
    mTotalEffects = 0;
43
    mMaxIndex     = index;
44

  
45
    if( obj!=null )
46
      {
47
      mObjHalfX = obj.getWidth() / 2.0f;
48
      mObjHalfY = obj.getHeight() / 2.0f;
49
      mObjHalfZ = obj.getDepth() / 2.0f;
50

  
51
      mBitmapID = obj.getID();
52
      }
53

  
54
    if( mMax[mMaxIndex]>0 )
55
      {
56
      mType            = new int[mMax[mMaxIndex]];
57
      mUniforms        = new float[numUniforms*mMax[mMaxIndex]];
58
      mInterI          = new Interpolator[mMax[mMaxIndex]];
59
      mInterP          = new Interpolator2D[mMax[mMaxIndex]];
60
      mCurrentDuration = new long[mMax[mMaxIndex]];
61
      mID              = new long[mMax[mMaxIndex]];
62
      mIDIndex         = new byte[mMax[mMaxIndex]];
63
      mFreeIndexes     = new byte[mMax[mMaxIndex]];
64
     
65
      for(byte i=0; i<mMax[mMaxIndex]; i++) mFreeIndexes[i] = i;
66
      }
67
   
68
    mCreated = true;  
69
    }
70

  
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72

  
73
  int getNumEffects()
74
    {
75
    return mNumEffects;  
76
    }
77

  
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

  
80
  void addListener(EffectListener el)
81
    {
82
    if( mListeners==null ) mListeners = new Vector<>(2,2);
83
   
84
    mListeners.add(el);
85
    mNumListeners++;
86
    }
87
 
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

  
90
  void removeListener(EffectListener el)
91
    {
92
    if( mNumListeners>0 )  
93
      {
94
      mListeners.remove(el);
95
      mNumListeners--;
96
      }
97
    }
98

  
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

  
101
  static void reset()
102
    {
103
    EffectTypes.reset(mMax);
104
    mCreated = false;  
105
    }
106
 
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108

  
109
  synchronized boolean removeByID(long id)
110
    {
111
    int i = getEffectIndex(id);
112
   
113
    if( i>=0 ) 
114
      {
115
      remove(i);
116
      return true;
117
      }
118
   
119
    return false; 
120
    }
121

  
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123

  
124
  synchronized boolean removeByType(EffectNames effect)
125
    {
126
    boolean ret = false;  
127
    int ord = effect.ordinal();  
128
     
129
    for(int i=0; i<mNumEffects; i++)
130
      {
131
      if( mType[i]==ord )
132
        {
133
        remove(i);
134
        ret = true;
135
        }
136
      }
137
   
138
    return ret;
139
    }
140
  
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142
  
143
  protected synchronized int getEffectIndex(long id)
144
    {
145
    int index = mIDIndex[(int)(id%mMax[mMaxIndex])];
146
    return (index<mNumEffects && mID[index]==id ? index : -1);
147
    }
148

  
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150
  
151
  synchronized void abortAll()
152
    {
153
    for(int i=0; i<mNumEffects; i++ )
154
      {
155
      mInterI[i] = null;
156
      mInterP[i] = null;
157
      } 
158
   
159
    mNumEffects= 0;  
160
    }
161

  
162
///////////////////////////////////////////////////////////////////////////////////////////////////
163
// this assumes 0<=effect<mNumEffects
164
  
165
  protected void remove(int effect)
166
    {
167
    mNumEffects--;     
168
    
169
    byte removedIndex = (byte)(mID[effect]%mMax[mMaxIndex]);
170
    byte removedPosition = mIDIndex[removedIndex];
171
    mFreeIndexes[mNumEffects] = removedIndex;
172
    
173
    long removedID = mID[effect];
174
    int removedType= mType[effect];
175
    
176
    for(int j=0; j<mMax[mMaxIndex]; j++)
177
      {
178
      if( mIDIndex[j] > removedPosition ) mIDIndex[j]--; 
179
      }
180
         
181
    for(int j=effect; j<mNumEffects; j++ ) 
182
      {
183
      mType[j]            = mType[j+1];
184
      mInterI[j]          = mInterI[j+1];
185
      mInterP[j]          = mInterP[j+1];
186
      mCurrentDuration[j] = mCurrentDuration[j+1];
187
      mID[j]              = mID[j+1];
188
    
189
      moveEffect(j);
190
      }
191
   
192
    mInterI[mNumEffects] = null;
193
    mInterP[mNumEffects] = null;
194
   
195
    for(int i=0; i<mNumListeners; i++) 
196
      EffectMessageSender.newMessage( mListeners.elementAt(i),
197
                                      EffectMessage.EFFECT_REMOVED, 
198
                                      (removedID<<EffectTypes.LENGTH)+EffectNames.getType(removedType).type,
199
                                      removedType,
200
                                      mBitmapID);  
201
    }
202
  
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
  
205
  protected long addBase(EffectNames eln)
206
    {    
207
    mType[mNumEffects]  = eln.ordinal();  
208
    mCurrentDuration[mNumEffects] = 0;
209
    
210
    int index = mFreeIndexes[mNumEffects];
211
    long id = mTotalEffects*mMax[mMaxIndex] + index;
212
    mID[mNumEffects] = id;
213
    mIDIndex[index] = mNumEffects;  
214
   
215
    mNumEffects++; 
216
    mTotalEffects++;
217
   
218
    return (id<<EffectTypes.LENGTH)+eln.getType().type;
219
    }
220
    
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222
// used only for debugging
223
  
224
  protected String printEffects(int max)
225
    {
226
    long[] indexes = new long[mMax[mMaxIndex]];
227
   
228
    for(int g=0; g<mMax[mMaxIndex]; g++)
229
      {
230
      indexes[g] = -1;  
231
      }
232
   
233
    String ret="(";
234
    int f;
235
   
236
    for(int g=0; g<max; g++) 
237
      {
238
      f = getEffectIndex(g);
239
      if( f>=0 ) indexes[f] = g;
240
      }
241
   
242
    for(int g=0; g<mMax[mMaxIndex]; g++)
243
      {
244
      ret += (g>0 ? ",":"")+(indexes[g]>=0 ? indexes[g] : " ");   
245
      }
246
   
247
    ret += ")";
248
   
249
    return ret;
250
    }
251

  
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253
// Only used for debugging
254
  
255
  protected boolean printByID(long id)
256
    {
257
    int index = getEffectIndex(id);
258
   
259
    if( index>=0 ) 
260
      {
261
      boolean interI = mInterI[index]==null; 
262
      boolean interP = mInterP[index]==null; 
263
      
264
      android.util.Log.e("EffectList", "numEffects="+mNumEffects+" effect id="+id+" index="+index+" duration="+mCurrentDuration[index]+" interI null="+interI+" interP null="+interP);
265
      
266
      if( interI==false )
267
        {
268
        android.util.Log.e("EffectList","interI: "+mInterI[index].print());  
269
        }
270
      if( interP==false )
271
        {
272
        android.util.Log.e("EffectList","interP: "+mInterP[index].print());  
273
        }
274
     
275
      return true;
276
      }
277
   
278
    android.util.Log.e("EffectList", "effect id="+id+" not found");
279

  
280
    return false;  
281
    }
282
 
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

  
285
  abstract void moveEffect(int index);
286
  }
287
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/EffectListFragment.java
1
package org.distorted.library;
2

  
3
import android.opengl.GLES20;
4

  
5
///////////////////////////////////////////////////////////////////////////////////////////////////
6

  
7
class EffectListFragment extends EffectList
8
  {
9
  private static final int NUM_UNIFORMS = 9;
10
  private static final int INDEX = EffectTypes.FRAGMENT.ordinal();
11
  private float[] mBuf;
12
  private static int mNumEffectsH;
13
  private static int mTypeH;
14
  private static int mUniformsH;
15
  
16
///////////////////////////////////////////////////////////////////////////////////////////////////
17
   
18
  public EffectListFragment(DistortedObject obj)
19
    { 
20
    super(obj,NUM_UNIFORMS,INDEX);
21
   
22
    if( mMax[INDEX]>0 )
23
      {
24
      mBuf= new float[4*mMax[INDEX]];
25
      }
26
    }
27
  
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29
// Only max Byte.MAX_VALUE concurrent effects per bitmap.
30
// If you want more, change type of the mNumEffects, mIDIndex and mFreeIndexes variables to shorts.
31
  
32
  static boolean setMax(int m)
33
    {
34
    if( (mCreated==false && !Distorted.isInitialized()) || m<=mMax[INDEX] )
35
      {
36
           if( m<0              ) m = 0;
37
      else if( m>Byte.MAX_VALUE ) m = Byte.MAX_VALUE;
38
      
39
      mMax[INDEX] = m;
40
      return true;
41
      }
42
   
43
    return false;
44
    }
45
 
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

  
48
  static int getMax()
49
    {
50
    return mMax[INDEX];
51
    }
52

  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54

  
55
  static void getUniforms(int mProgramH)
56
    {
57
    mNumEffectsH= GLES20.glGetUniformLocation( mProgramH, "fNumEffects");
58
    mTypeH      = GLES20.glGetUniformLocation( mProgramH, "fType");
59
    mUniformsH  = GLES20.glGetUniformLocation( mProgramH, "fUniforms");
60
    }
61

  
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63
  
64
  synchronized void compute(long currTime) 
65
    { 
66
    if( currTime==mTime ) return;
67
    if( mTime==0 ) mTime = currTime;
68
    long step = (currTime-mTime);
69
   
70
    for(int i=0; i<mNumEffects; i++)
71
      {
72
      if( mInterI[i]==null ) continue;    
73
      
74
      if( mInterP[i]!=null ) mInterP[i].interpolateMain(mBuf, 4*i, mCurrentDuration[i]);
75
        
76
      if( mInterI[i].interpolateMain(mUniforms ,NUM_UNIFORMS*i, mCurrentDuration[i], step) )      
77
        {
78
        for(int j=0; j<mNumListeners; j++)   
79
          EffectMessageSender.newMessage( mListeners.elementAt(j),
80
                                          EffectMessage.EFFECT_FINISHED, 
81
                                          (mID[i]<<EffectTypes.LENGTH)+EffectTypes.FRAGMENT.type,
82
                                          mType[i], 
83
                                          mBitmapID); 
84
      
85
        if( EffectNames.isUnity(mType[i], mUniforms, NUM_UNIFORMS*i) )
86
          {
87
          remove(i);
88
          i--;
89
          continue;
90
          }
91
        }
92
           
93
      mCurrentDuration[i] += step;
94
      }
95
   
96
    mTime = currTime;  
97
    }
98

  
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

  
101
  protected void moveEffect(int index)
102
    {
103
    mBuf[4*index  ] = mBuf[4*index+4];
104
    mBuf[4*index+1] = mBuf[4*index+5];
105
    mBuf[4*index+2] = mBuf[4*index+6];
106
    mBuf[4*index+3] = mBuf[4*index+7];
107
              
108
    mUniforms[NUM_UNIFORMS*index  ] = mUniforms[NUM_UNIFORMS*(index+1)  ];
109
    mUniforms[NUM_UNIFORMS*index+1] = mUniforms[NUM_UNIFORMS*(index+1)+1];
110
    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];  
111
    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];  
112
    }
113
  
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115
  
116
  synchronized void send() 
117
    {
118
    GLES20.glUniform1i( mNumEffectsH, mNumEffects);
119
      
120
    if( mNumEffects>0 )
121
      {     
122
      GLES20.glUniform1iv( mTypeH    ,  mNumEffects, mType    ,0);
123
      GLES20.glUniform3fv( mUniformsH,3*mNumEffects, mUniforms,0);
124
      }  
125
    }
126

  
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

  
129
  synchronized void sendZero() 
130
    {
131
    GLES20.glUniform1i( mNumEffectsH, 0);
132
    }
133
    
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135
// Do various post-processing on already computed effects.
136
// 1) move all Points and scale all Region radii by a ModelView matrix
137
// 2) in case of macroblock, pre-compute some values so that we don't have to do it in the fragment shader.
138
  
139
  void postprocess(float[] MVmatrix)
140
    {
141
    if( mNumEffects>0 )
142
      {
143
      float tx,ty;   
144
      float w = (float)Math.sqrt(MVmatrix[0]*MVmatrix[0] + MVmatrix[4]*MVmatrix[4]);  // The scale factors are the lengths of the first 3 vectors of the upper-left 3x3 submatrix; here
145
      float h = (float)Math.sqrt(MVmatrix[1]*MVmatrix[1] + MVmatrix[5]*MVmatrix[5]);  // m[2]=m[6]=m[8]=m[9]=0 so it is really only the upper-left 2x2 matrix.
146
   
147
      for(int i=0; i<mNumEffects; i++)
148
        {   
149
        tx = mBuf[4*i  ]-mObjHalfX; // we have to invert y and move everything by (half of bmp width, half of bmp height)
150
        ty =-mBuf[4*i+1]+mObjHalfY; //
151
      
152
        mUniforms[NUM_UNIFORMS*i+4] = w*mBuf[4*i+2];                                  // in fragment shader rx and ry radii are the second and third values of the Region thus 9*i+4 and 9*i+5
153
        mUniforms[NUM_UNIFORMS*i+5] = h*mBuf[4*i+3];                                  // 
154
     // mUniforms[NUM_UNIFORMS*i+6] =                                                 // this value is not used in Fragment Shader   
155
        mUniforms[NUM_UNIFORMS*i+7] = MVmatrix[0]*tx + MVmatrix[4]*ty + MVmatrix[12]; // multiply the ModelView matrix times the (x,y,0,1) point, i.e. the (x,y) point on the surface of the bitmap.
156
        mUniforms[NUM_UNIFORMS*i+8] = MVmatrix[1]*tx + MVmatrix[5]*ty + MVmatrix[13]; //  
157
        
158
        if( mType[i]==EffectNames.MACROBLOCK.ordinal() ) // fill up the .y and .z components of the Interpolated values already to avoid having to compute this in the fragment shader
159
          {
160
          mUniforms[NUM_UNIFORMS*i+1] = 2.0f*mObjHalfX/mUniforms[NUM_UNIFORMS*i];
161
          mUniforms[NUM_UNIFORMS*i+2] = 2.0f*mObjHalfY/mUniforms[NUM_UNIFORMS*i];
162
          }
163
        }
164
      }
165
    }
166
  
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
       
169
  synchronized long add(EffectNames eln, Interpolator inter, Float4D region, Interpolator2D point)
170
    {
171
    if( mMax[INDEX]>mNumEffects )
172
      {
173
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects); 
174
      mInterI[mNumEffects] = inter;
175
      mInterP[mNumEffects] = point;
176
      mBuf[4*mNumEffects+2] = (region==null || region.z<=0.0f) ? 1000*mObjHalfX : region.z;
177
      mBuf[4*mNumEffects+3] = (region==null || region.w<=0.0f) ? 1000*mObjHalfY : region.w;
178
   
179
      return addBase(eln); 
180
      }
181
      
182
    return -1;
183
    }
184
  
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186

  
187
  synchronized long add(EffectNames eln, Interpolator inter, Float4D region, float x, float y)
188
    {
189
    if( mMax[INDEX]>mNumEffects )
190
      {
191
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);    
192
      mInterI[mNumEffects] = inter;
193
      mInterP[mNumEffects] = null;
194
      mBuf[4*mNumEffects  ] = x;
195
      mBuf[4*mNumEffects+1] = y;
196
      mBuf[4*mNumEffects+2] = (region==null || region.z<=0.0f) ? 1000*mObjHalfX : region.z;
197
      mBuf[4*mNumEffects+3] = (region==null || region.w<=0.0f) ? 1000*mObjHalfY : region.w;
198
   
199
      return addBase(eln);
200
      }
201
      
202
    return -1;
203
    }
204
  
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206
       
207
  synchronized long add(EffectNames eln, Interpolator1D inter, Float3D c, Float4D region, Interpolator2D point)
208
    {
209
    if( mMax[INDEX]>mNumEffects )
210
      {
211
      mInterI[mNumEffects] = inter;
212
      mInterP[mNumEffects] = point;
213
      mBuf[4*mNumEffects+2] = (region==null || region.z<=0.0f) ? 1000*mObjHalfX : region.z;
214
      mBuf[4*mNumEffects+3] = (region==null || region.w<=0.0f) ? 1000*mObjHalfY : region.w;
215
   
216
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.x;
217
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.y;
218
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.z;
219
     
220
      return addBase(eln); 
221
      }
222
      
223
    return -1;
224
    }
225
  
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

  
228
  synchronized long add(EffectNames eln, Interpolator1D inter, Float3D c, Float4D region, float x, float y)
229
    {
230
    if( mMax[INDEX]>mNumEffects )
231
      {
232
      mInterI[mNumEffects] = inter;
233
      mInterP[mNumEffects] = null;
234
      mBuf[4*mNumEffects  ] = x;
235
      mBuf[4*mNumEffects+1] = y;
236
      mBuf[4*mNumEffects+2] = (region==null || region.z<=0.0f) ? 1000*mObjHalfX : region.z;
237
      mBuf[4*mNumEffects+3] = (region==null || region.w<=0.0f) ? 1000*mObjHalfY : region.w;
238
      
239
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.x;
240
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.y;
241
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.z;
242
   
243
      return addBase(eln);
244
      }
245
       
246
    return -1;
247
    }
248
  
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250
       
251
  synchronized long add(EffectNames eln, float t, Float3D c, Float4D region, Interpolator2D point)
252
    {
253
    if( mMax[INDEX]>mNumEffects )
254
      {
255
      mInterI[mNumEffects] = null;
256
      mInterP[mNumEffects] = point;
257
      mBuf[4*mNumEffects+2] = (region==null || region.z<=0.0f) ? 1000*mObjHalfX : region.z;
258
      mBuf[4*mNumEffects+3] = (region==null || region.w<=0.0f) ? 1000*mObjHalfY : region.w;
259
   
260
      mUniforms[NUM_UNIFORMS*mNumEffects+0] = t;
261
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.x;
262
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.y;
263
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.z;
264
     
265
      return addBase(eln); 
266
      }
267
      
268
    return -1;
269
    }
270
  
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272

  
273
  synchronized long add(EffectNames eln, float t, Float3D c, Float4D region, float x, float y)
274
    {
275
    if( mMax[INDEX]>mNumEffects )
276
      {
277
      mInterI[mNumEffects] = null;
278
      mInterP[mNumEffects] = null;
279
      mBuf[4*mNumEffects  ] = x;
280
      mBuf[4*mNumEffects+1] = y;
281
      mBuf[4*mNumEffects+2] = (region==null || region.z<=0.0f) ? 1000*mObjHalfX : region.z;
282
      mBuf[4*mNumEffects+3] = (region==null || region.w<=0.0f) ? 1000*mObjHalfY : region.w;
283
      
284
      mUniforms[NUM_UNIFORMS*mNumEffects+0] = t;
285
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.x;
286
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.y;
287
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.z;
288
   
289
      return addBase(eln);
290
      }
291
      
292
    return -1;
293
    }
294
    
295
///////////////////////////////////////////////////////////////////////////////////////////////////
296
// end of FragmentEffect   
297
  }
src/main/java/org/distorted/library/EffectListMatrix.java
1
package org.distorted.library;
2

  
3
import android.opengl.GLES20;
4
import android.opengl.Matrix;
5

  
6
///////////////////////////////////////////////////////////////////////////////////////////////////
7

  
8
class EffectListMatrix extends EffectList
9
  {   
10
  private static final int NUM_UNIFORMS = 7;
11
  private static final int INDEX = EffectTypes.MATRIX.ordinal();
12
  private static float[] mMVPMatrix= new float[16];
13
  private static float[] mTmpMatrix= new float[16];
14
  
15
  private static int mBmpDH;      // This is a handle to half a bitmap dimensions
16
  private static int mDepthH;     // Handle to the max Depth, i.e (farplane-nearplane)/2
17
  private static int mMVPMatrixH; // pass in the transformation matrix
18
  private static int mMVMatrixH;  // pass in the modelview matrix.
19
  
20
///////////////////////////////////////////////////////////////////////////////////////////////////
21
   
22
  public EffectListMatrix(DistortedObject obj)
23
    { 
24
    super(obj,NUM_UNIFORMS, INDEX );
25
    }
26

  
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

  
29
  private static void multiplyByQuat(float[] matrix, float X, float Y, float Z, float W)
30
    {
31
    float xx= X * X;
32
    float xy= X * Y;
33
    float xz= X * Z;
34
    float xw= X * W;
35
    float yy= Y * Y;
36
    float yz= Y * Z;
37
    float yw= Y * W;
38
    float zz= Z * Z;
39
    float zw= Z * W;
40

  
41
    mTmpMatrix[0]  = 1 - 2 * ( yy + zz );
42
    mTmpMatrix[1]  =     2 * ( xy - zw );
43
    mTmpMatrix[2]  =     2 * ( xz + yw );
44
    mTmpMatrix[4]  =     2 * ( xy + zw );
45
    mTmpMatrix[5]  = 1 - 2 * ( xx + zz );
46
    mTmpMatrix[6]  =     2 * ( yz - xw );
47
    mTmpMatrix[8]  =     2 * ( xz - yw );
48
    mTmpMatrix[9]  =     2 * ( yz + xw );
49
    mTmpMatrix[10] = 1 - 2 * ( xx + yy );
50
    mTmpMatrix[3]  = mTmpMatrix[7] = mTmpMatrix[11] = mTmpMatrix[12] = mTmpMatrix[13] = mTmpMatrix[14] = 0;
51
    mTmpMatrix[15] = 1;
52
    
53
    Matrix.multiplyMM(mMVPMatrix, 0, matrix, 0, mTmpMatrix, 0);  
54
    for(int j=0; j<16; j++) matrix[j] = mMVPMatrix[j];   
55
    }
56
  
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58
// Only max Byte.MAX_VALUE concurrent effects per bitmap.
59
// If you want more, change type of the mNumEffects, mIDIndex and mFreeIndexes variables to shorts.
60
  
61
  static boolean setMax(int m)
62
    {
63
    if( (mCreated==false && !Distorted.isInitialized()) || m<=mMax[INDEX] )
64
      {
65
           if( m<0              ) m = 0;
66
      else if( m>Byte.MAX_VALUE ) m = Byte.MAX_VALUE;
67
      
68
      mMax[INDEX] = m;
69
      return true;
70
      }
71
   
72
    return false;
73
    }
74
 
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

  
77
  static int getMax()
78
    {
79
    return mMax[INDEX];
80
    }
81

  
82
///////////////////////////////////////////////////////////////////////////////////////////////////
83

  
84
  static void getUniforms(int mProgramH)
85
    {
86
    mBmpDH     = GLES20.glGetUniformLocation(mProgramH, "u_bmpD");
87
    mDepthH    = GLES20.glGetUniformLocation(mProgramH, "u_Depth");
88
    mMVPMatrixH= GLES20.glGetUniformLocation(mProgramH, "u_MVPMatrix");
89
    mMVMatrixH = GLES20.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
90
    }
91

  
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93
  
94
  synchronized void compute(long currTime) 
95
    {
96
    if( currTime==mTime ) return;
97
    if( mTime==0 ) mTime = currTime;
98
    long step = (currTime-mTime);
99
   
100
    for(int i=0; i<mNumEffects; i++)
101
      {
102
      if( mInterI[i]==null ) continue;    
103
           
104
      if( mInterP[i]!=null ) 
105
        {
106
        mInterP[i].interpolateMain(mUniforms, NUM_UNIFORMS*i, mCurrentDuration[i]);
107
        }
108
        
109
      if( mInterI[i].interpolateMain(mUniforms ,NUM_UNIFORMS*i+3, mCurrentDuration[i], step) )      
110
        {   
111
        for(int j=0; j<mNumListeners; j++)   
112
          EffectMessageSender.newMessage( mListeners.elementAt(j),
113
                                          EffectMessage.EFFECT_FINISHED, 
114
                                         (mID[i]<<EffectTypes.LENGTH)+EffectTypes.MATRIX.type,
115
                                          mType[i], 
116
                                          mBitmapID); 
117
       
118
        if( EffectNames.isUnity(mType[i], mUniforms, NUM_UNIFORMS*i+3) )
119
          {  
120
          remove(i);
121
          i--;
122
          continue;
123
          }
124
        }
125
    
126
      mCurrentDuration[i] += step;
127
      }
128
     
129
    mTime = currTime;  
130
    }  
131

  
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

  
134
  protected void moveEffect(int index)
135
    {
136
    mUniforms[NUM_UNIFORMS*index  ] = mUniforms[NUM_UNIFORMS*(index+1)  ];
137
    mUniforms[NUM_UNIFORMS*index+1] = mUniforms[NUM_UNIFORMS*(index+1)+1];
138
    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];
139
    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];
140
    mUniforms[NUM_UNIFORMS*index+4] = mUniforms[NUM_UNIFORMS*(index+1)+4];
141
    mUniforms[NUM_UNIFORMS*index+5] = mUniforms[NUM_UNIFORMS*(index+1)+5];
142
    mUniforms[NUM_UNIFORMS*index+6] = mUniforms[NUM_UNIFORMS*(index+1)+6];
143
    }
144

  
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146
// here construct the ModelView Matrix
147

  
148
  synchronized void send(float[] viewMatrix, DistortedProjection dp) 
149
    {
150
    Matrix.setIdentityM(viewMatrix, 0);
151
    Matrix.translateM(viewMatrix, 0, -dp.width/2, dp.height/2, -dp.distance);
152
    
153
    float x,y,z, sx,sy,sz=1.0f;
154
   
155
    for(int i=0; i<mNumEffects; i++)
156
      {
157
      if (mType[i] == EffectNames.ROTATE.ordinal() )
158
        {
159
        x = mUniforms[NUM_UNIFORMS*i  ];
160
        y = mUniforms[NUM_UNIFORMS*i+1];
161
        z = mUniforms[NUM_UNIFORMS*i+2];
162
     
163
        Matrix.translateM(viewMatrix, 0, x,-y, z); 
164
        Matrix.rotateM( viewMatrix, 0, mUniforms[NUM_UNIFORMS*i+3], mUniforms[NUM_UNIFORMS*i+4], mUniforms[NUM_UNIFORMS*i+5], mUniforms[NUM_UNIFORMS*i+6]);  
165
        Matrix.translateM(viewMatrix, 0,-x, y,-z);  
166
        }
167
      else if(mType[i] == EffectNames.QUATERNION.ordinal() )
168
        {
169
        x = mUniforms[NUM_UNIFORMS*i  ];
170
        y = mUniforms[NUM_UNIFORMS*i+1];
171
        z = mUniforms[NUM_UNIFORMS*i+2];
172
     	
173
        Matrix.translateM(viewMatrix, 0, x,-y, z); 
174
        multiplyByQuat(viewMatrix, mUniforms[NUM_UNIFORMS*i+3], mUniforms[NUM_UNIFORMS*i+4], mUniforms[NUM_UNIFORMS*i+5], mUniforms[NUM_UNIFORMS*i+6]);
175
        Matrix.translateM(viewMatrix, 0,-x, y,-z);  
176
        }
177
      else if(mType[i] == EffectNames.MOVE.ordinal() )
178
        {
179
        sx = mUniforms[NUM_UNIFORMS*i+3];   
180
        sy = mUniforms[NUM_UNIFORMS*i+4];   
181
        sz = mUniforms[NUM_UNIFORMS*i+5];   
182
        
183
        Matrix.translateM(viewMatrix, 0, sx,-sy, sz);   
184
        }
185
      else if(mType[i] == EffectNames.SCALE.ordinal() )
186
        {
187
        sx = mUniforms[NUM_UNIFORMS*i+3];   
188
        sy = mUniforms[NUM_UNIFORMS*i+4];   
189
        sz = mUniforms[NUM_UNIFORMS*i+5];   
190

  
191
        Matrix.scaleM(viewMatrix, 0, sx, sy, sz);  
192
        }
193
      else if(mType[i] == EffectNames.SHEAR.ordinal() )
194
        {
195
        x  = mUniforms[NUM_UNIFORMS*i  ];
196
        y  = mUniforms[NUM_UNIFORMS*i+1];
197
        z  = mUniforms[NUM_UNIFORMS*i+2];
198
        
199
        sx = mUniforms[NUM_UNIFORMS*i+3];   
200
        sy = mUniforms[NUM_UNIFORMS*i+4];   
201
        sz = mUniforms[NUM_UNIFORMS*i+5];   
202
        
203
        Matrix.translateM(viewMatrix, 0, x,-y, z); 
204
      
205
        viewMatrix[4] += sx*viewMatrix[0]; // Multiply viewMatrix by 1 x 0 0 , i.e. X-shear. TODO: change this so it is symmetric w respect to all the axis.
206
        viewMatrix[5] += sx*viewMatrix[1]; //                        0 1 0 0 
207
        viewMatrix[6] += sx*viewMatrix[2]; //                        0 0 1 0
208
        viewMatrix[7] += sx*viewMatrix[3]; //                        0 0 0 1
209
      
210
        viewMatrix[0] += sy*viewMatrix[4]; // Multiply viewMatrix by 1 0 0 0 , i.e. Y-shear. TODO: change this so it is symmetric w respect to all the axis.
211
        viewMatrix[1] += sy*viewMatrix[5]; //                        y 1 0 0
212
        viewMatrix[2] += sy*viewMatrix[6]; //                        0 0 1 0
213
        viewMatrix[3] += sy*viewMatrix[7]; //                        0 0 0 1      
214
      
215
        // TODO: implement Z-shear.
216
        
217
        Matrix.translateM(viewMatrix, 0,-x, y, -z);
218
        }
219
      }
220
   
221
    Matrix.translateM(viewMatrix, 0, mObjHalfX,-mObjHalfY, -mObjHalfZ);
222
    Matrix.multiplyMM(mMVPMatrix, 0, dp.projectionMatrix, 0, viewMatrix, 0);
223
    
224
    GLES20.glUniform3f( mBmpDH , mObjHalfX, mObjHalfY, mObjHalfZ);
225
    GLES20.glUniform1f( mDepthH, dp.depth);   
226
    GLES20.glUniformMatrix4fv(mMVMatrixH , 1, false, viewMatrix, 0);
227
    GLES20.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix, 0);
228
    }
229

  
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231
// here construct the ModelView Matrix, but without any effects
232

  
233
  synchronized void sendNoEffects(DistortedProjection dp) 
234
    {
235
    Matrix.setIdentityM(mTmpMatrix, 0);
236
    Matrix.translateM(mTmpMatrix, 0, mObjHalfX-dp.width/2, dp.height/2-mObjHalfY, mObjHalfZ-dp.distance);
237
    Matrix.multiplyMM(mMVPMatrix, 0, dp.projectionMatrix, 0, mTmpMatrix, 0);
238
    
239
    GLES20.glUniform3f( mBmpDH , mObjHalfX, mObjHalfY, mObjHalfZ);
240
    GLES20.glUniform1f( mDepthH, dp.depth);  
241
    GLES20.glUniformMatrix4fv(mMVMatrixH , 1, false, mTmpMatrix, 0);
242
    GLES20.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix, 0);
243
    }
244

  
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246
  
247
  synchronized long add(EffectNames eln, Interpolator3D p, Interpolator i)
248
    {
249
    if( mMax[INDEX]>mNumEffects )
250
      {
251
      mInterP[mNumEffects] = p;
252
      mInterI[mNumEffects] = i;
253
      
254
      return addBase(eln);
255
      }
256
      
257
    return -1;
258
    }
259

  
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261
  
262
  synchronized long add(EffectNames eln, float x, float y, float z, Interpolator i)
263
    {
264
    if( mMax[INDEX]>mNumEffects )
265
      {
266
      mInterP[mNumEffects] = null;
267
      mInterI[mNumEffects] = i;
268
      
269
      mUniforms[NUM_UNIFORMS*mNumEffects  ] = x;
270
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = y;
271
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = z;
272
            
273
      return addBase(eln);
274
      }
275
      
276
    return -1;
277
    }
278

  
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280
  
281
  synchronized long add(EffectNames eln, float x, float y, float z, Interpolator1D i, float aX, float aY, float aZ)
282
    {
283
    if( mMax[INDEX]>mNumEffects )
284
      {
285
      mInterP[mNumEffects] = null;
286
      mInterI[mNumEffects] = i;
287
      
288
      mUniforms[NUM_UNIFORMS*mNumEffects  ] = x;
289
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = y;
290
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = z;
291
      
292
      mUniforms[NUM_UNIFORMS*mNumEffects+4] = aX;
293
      mUniforms[NUM_UNIFORMS*mNumEffects+5] = aY;  
294
      mUniforms[NUM_UNIFORMS*mNumEffects+6] = aZ;  
295
      
296
      return addBase(eln);
297
      }
298
      
299
    return -1;
300
    }
301

  
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303
  
304
  synchronized long add(EffectNames eln, Interpolator3D p, Interpolator1D i, float aX, float aY, float aZ)
305
    {
306
    if( mMax[INDEX]>mNumEffects )
307
      {
308
      mInterP[mNumEffects] = p;
309
      mInterI[mNumEffects] = i;
310
      
311
      mUniforms[NUM_UNIFORMS*mNumEffects+4] = aX;
312
      mUniforms[NUM_UNIFORMS*mNumEffects+5] = aY;  
313
      mUniforms[NUM_UNIFORMS*mNumEffects+6] = aZ;  
314
      
315
      return addBase(eln);
316
      }
317
      
318
    return -1;
319
    }
320
  
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322
  
323
  synchronized long add(EffectNames eln, float x, float y, float z, float aA, float aX, float aY, float aZ)
324
    {
325
    if( mMax[INDEX]>mNumEffects )
326
      {
327
      mInterP[mNumEffects] = null; 
328
      mInterI[mNumEffects] = null;
329
      
330
      mUniforms[NUM_UNIFORMS*mNumEffects  ] =  x;
331
      mUniforms[NUM_UNIFORMS*mNumEffects+1] =  y;  
332
      mUniforms[NUM_UNIFORMS*mNumEffects+2] =  z;  
333
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = aA;  
334
      mUniforms[NUM_UNIFORMS*mNumEffects+4] = aX;
335
      mUniforms[NUM_UNIFORMS*mNumEffects+5] = aY;  
336
      mUniforms[NUM_UNIFORMS*mNumEffects+6] = aZ;  
337
      
338
      return addBase(eln);   
339
      }
340
      
341
    return -1;
342
    }
343

  
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345
  }
src/main/java/org/distorted/library/EffectListOther.java
1
package org.distorted.library;
2

  
3
///////////////////////////////////////////////////////////////////////////////////////////////////
4

  
5
import java.util.Vector;
6

  
7
/**
8
 * Do NOT base this on EffectList - this is an entirely different animal than the first 3 EffectLists.
9
 * The Effects in here will be executed after all the shaders have been executed - thus there are no
10
 * uniforms to send, no real queues to maintain.
11
 * <p>
12
 * Only 2 effects here ATM:
13
 * - save current Surface to a PNG file
14
 * - save current animation to a .MP4 file
15
 *
16
 * In contrast to the other EffectLists, only one instance of each allowed at any given moment - thus
17
 * this is not even a real EffectList, it is named so only for consistency with the others.
18
 */
19
public class EffectListOther
20
  {
21
  private Vector<EffectListener> mListeners =null;
22
  private int mNumListeners=0;  // ==mListeners.length(), but we only create mListeners if the first one gets added
23

  
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

  
26
  public EffectListOther(DistortedObject obj)
27
    {
28

  
29
    }
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

  
33
  synchronized void send()
34
    {
35

  
36
    }
37

  
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

  
40
  synchronized void abortAll()
41
    {
42

  
43
    }
44

  
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46

  
47
  void addListener(EffectListener el)
48
    {
49
    if( mListeners==null ) mListeners = new Vector<>(2,2);
50

  
51
    mListeners.add(el);
52
    mNumListeners++;
53
    }
54

  
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

  
57
  void removeListener(EffectListener el)
58
    {
59
    if( mNumListeners>0 )
60
      {
61
      mListeners.remove(el);
62
      mNumListeners--;
63
      }
64
    }
65

  
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

  
68
  synchronized boolean removeByID(long id)
69
    {
70
    //....
71

  
72
    return false;
73
    }
74

  
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

  
77
  synchronized boolean removeByType(EffectNames effect)
78
    {
79
    // ...
80

  
81
    return false;
82
    }
83

  
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

  
86
  protected boolean printByID(long id)
87
    {
88
    return false;
89
    }
90

  
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

  
93
  synchronized long add(EffectNames eln, String filename)
94
    {
95
    return 0;
96
    }
97
  }
src/main/java/org/distorted/library/EffectListVertex.java
1
package org.distorted.library;
2

  
3
import android.opengl.GLES20;
4

  
5
///////////////////////////////////////////////////////////////////////////////////////////////////
6

  
7
class EffectListVertex extends EffectList
8
  { 
9
  private static final int NUM_UNIFORMS = 9;
10
  private static final int INDEX = EffectTypes.VERTEX.ordinal();
11
  private static int mNumEffectsH;
12
  private static int mTypeH;
13
  private static int mUniformsH;
14
  
15
///////////////////////////////////////////////////////////////////////////////////////////////////
16
   
17
  public EffectListVertex(DistortedObject obj)
18
    { 
19
    super(obj,NUM_UNIFORMS,INDEX);
20
    }
21
  
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23
// Only max Byte.MAX_VALUE concurrent effects per bitmap.
24
// If you want more, change type of the mNumEffects, mIDIndex and mFreeIndexes variables to shorts.
25
  
26
  static boolean setMax(int m)
27
    {
28
    if( (mCreated==false && !Distorted.isInitialized()) || m<=mMax[INDEX] )
29
      {
30
           if( m<0              ) m = 0;
31
      else if( m>Byte.MAX_VALUE ) m = Byte.MAX_VALUE;
32
      
33
      mMax[INDEX] = m;
34
      return true;
35
      }
36
   
37
    return false;
38
    }
39
 
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

  
42
  static int getMax()
43
    {
44
    return mMax[INDEX];
45
    }
46

  
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48

  
49
  static void getUniforms(int mProgramH)
50
    {
51
    mNumEffectsH= GLES20.glGetUniformLocation( mProgramH, "vNumEffects");
52
    mTypeH      = GLES20.glGetUniformLocation( mProgramH, "vType");
53
    mUniformsH  = GLES20.glGetUniformLocation( mProgramH, "vUniforms");
54
    }
55

  
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57
  
58
  synchronized void compute(long currTime) 
59
    {
60
    if( currTime==mTime ) return;
61
    if( mTime==0 ) mTime = currTime;
62
    long step = (currTime-mTime);
63
   
64
    for(int i=0; i<mNumEffects; i++)
65
      {
66
      if( mInterI[i]==null ) continue;    
67
      
68
      if( mInterP[i]!=null ) 
69
        {
70
        mInterP[i].interpolateMain(mUniforms, NUM_UNIFORMS*i+7, mCurrentDuration[i]);
71
      
72
        mUniforms[NUM_UNIFORMS*i+7] = mUniforms[NUM_UNIFORMS*i+7]-mObjHalfX;
73
        mUniforms[NUM_UNIFORMS*i+8] =-mUniforms[NUM_UNIFORMS*i+8]+mObjHalfY;
74
        }
75
        
76
      if( mInterI[i].interpolateMain(mUniforms ,NUM_UNIFORMS*i, mCurrentDuration[i], step) )      
77
        {
78
        for(int j=0; j<mNumListeners; j++)   
79
          EffectMessageSender.newMessage( mListeners.elementAt(j),
80
                                          EffectMessage.EFFECT_FINISHED, 
81
                                         (mID[i]<<EffectTypes.LENGTH)+EffectTypes.VERTEX.type,
82
                                          mType[i], 
83
                                          mBitmapID); 
84
      
85
        if( EffectNames.isUnity(mType[i], mUniforms, NUM_UNIFORMS*i) )
86
          {
87
          remove(i);
88
          i--;
89
          continue;
90
          }
91
        }
92
     
93
      mCurrentDuration[i] += step;
94
      }
95
     
96
    mTime = currTime;  
97
    }  
98
  
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

  
101
  protected void moveEffect(int index)
102
    {
103
    mUniforms[NUM_UNIFORMS*index  ] = mUniforms[NUM_UNIFORMS*(index+1)  ];
104
    mUniforms[NUM_UNIFORMS*index+1] = mUniforms[NUM_UNIFORMS*(index+1)+1];
105
    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];
106
    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];
107
    mUniforms[NUM_UNIFORMS*index+4] = mUniforms[NUM_UNIFORMS*(index+1)+4];
108
    mUniforms[NUM_UNIFORMS*index+5] = mUniforms[NUM_UNIFORMS*(index+1)+5];
109
    mUniforms[NUM_UNIFORMS*index+6] = mUniforms[NUM_UNIFORMS*(index+1)+6];
110
    mUniforms[NUM_UNIFORMS*index+7] = mUniforms[NUM_UNIFORMS*(index+1)+7];
111
    mUniforms[NUM_UNIFORMS*index+8] = mUniforms[NUM_UNIFORMS*(index+1)+8];
112
    }
113
   
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

  
116
  synchronized void send() 
117
    {
118
    GLES20.glUniform1i( mNumEffectsH, mNumEffects);
119
      
120
    if( mNumEffects>0 )
121
      {     
122
      GLES20.glUniform1iv( mTypeH    ,  mNumEffects, mType    ,0);
123
      GLES20.glUniform3fv( mUniformsH,3*mNumEffects, mUniforms,0);
124
      }
125
    }
126

  
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

  
129
  synchronized void sendZero() 
130
    {
131
    GLES20.glUniform1i( mNumEffectsH, 0);
132
    }
133
  
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135
// Do various post-processing on already computed effects.
136
// 1) here unlike in the fragment queue, we don't have to multiply the points by ModelView matrix because that gets done in the shader.
137
// 2) in case of swirl, pre-compute the sine and cosine of its rotation angle
138
  
139
  void postprocess()
140
    {
141
    double d;  
142
     
143
    for(int i=0; i<mNumEffects; i++)
144
      {      
145
      if( mType[i]==EffectNames.SWIRL.ordinal() )
146
        {
147
        d = Math.PI*mUniforms[NUM_UNIFORMS*i]/180;  
148
        mUniforms[NUM_UNIFORMS*i+1] = (float)Math.sin(d);
149
        mUniforms[NUM_UNIFORMS*i+2] = (float)Math.cos(d);
150
        }
151
      }
152
    }
153
  
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
  
156
  synchronized long add(EffectNames eln, Interpolator inter, Float4D region, Interpolator2D point)
157
    {
158
    if( mMax[INDEX]>mNumEffects )
159
      {
160
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);    
161
      
162
      mInterI[mNumEffects] = inter;
163
      mInterP[mNumEffects] = point;
164

  
165
      return addPriv(eln,region);
166
      }
167
      
168
    return -1;
169
    }
170
   
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172
  
173
  synchronized long add(EffectNames eln, Interpolator inter, Float4D region, float x, float y)
174
    {
175
    if( mMax[INDEX]>mNumEffects )
176
      {
177
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);    
178
      
179
      mInterI[mNumEffects] = inter;
180
      mInterP[mNumEffects] = null;
181
      mUniforms[NUM_UNIFORMS*mNumEffects+7] = x-mObjHalfX;
182
      mUniforms[NUM_UNIFORMS*mNumEffects+8] =-y+mObjHalfY;  
183
     
184
      return addPriv(eln,region);
185
      }
186
      
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff