Project

General

Profile

« Previous | Next » 

Revision 310e14fb

Added by Leszek Koltunski over 7 years ago

Some progress with Effect classes.

Big mess - nothing compiles now; classes moved around.

View differences:

src/main/java/org/distorted/library/Distorted.java
23 23
import android.content.Context;
24 24
import android.content.pm.ConfigurationInfo;
25 25
import android.content.res.Resources;
26

  
27
import org.distorted.library.effect.EffectMessageSender;
28
import org.distorted.library.effect.EffectQueue;
29
import org.distorted.library.effect.EffectQueuePostprocess;
26 30
import org.distorted.library.program.*;
27 31

  
28 32
///////////////////////////////////////////////////////////////////////////////////////////////////
......
84 88
    }
85 89

  
86 90
///////////////////////////////////////////////////////////////////////////////////////////////////
87

  
88
  static boolean isInitialized()
91
/**
92
 * Have we called onCreate yet, ie have we initialized the library?
93
 * @return <code>true</code> if the library is initilized and ready for action.
94
 */
95
  public static boolean isInitialized()
89 96
    {
90 97
    return mInitialized;
91 98
    }
src/main/java/org/distorted/library/DistortedEffects.java
22 22
import android.content.res.Resources;
23 23
import android.opengl.GLES30;
24 24

  
25
import org.distorted.library.effect.EffectQueue;
26
import org.distorted.library.effect.EffectQueueFragment;
27
import org.distorted.library.effect.EffectQueueMatrix;
28
import org.distorted.library.effect.EffectQueueVertex;
25 29
import org.distorted.library.message.EffectListener;
26 30
import org.distorted.library.program.DistortedProgram;
27 31
import org.distorted.library.program.FragmentCompilationException;
......
92 96
  private static long mNextID =0;
93 97
  private long mID;
94 98

  
95
  private EffectQueueMatrix   mM;
99
  private EffectQueueMatrix mM;
96 100
  private EffectQueueFragment mF;
97
  private EffectQueueVertex   mV;
101
  private EffectQueueVertex mV;
98 102

  
99 103
  private boolean matrixCloned, vertexCloned, fragmentCloned;
100 104

  
src/main/java/org/distorted/library/DistortedEffectsPostprocess.java
19 19

  
20 20
package org.distorted.library;
21 21

  
22
import org.distorted.library.effect.EffectQueue;
23
import org.distorted.library.effect.EffectQueuePostprocess;
22 24
import org.distorted.library.message.EffectListener;
23 25
import org.distorted.library.type.Data1D;
24 26
import org.distorted.library.type.Data4D;
src/main/java/org/distorted/library/DistortedOutputSurface.java
26 26

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

  
29
abstract class DistortedOutputSurface extends DistortedSurface implements DistortedSlave
29
public abstract class DistortedOutputSurface extends DistortedSurface implements DistortedSlave
30 30
{
31 31
//////////// DEBUG FLAGS /////////////////////////////////////////////
32 32
/**
src/main/java/org/distorted/library/DistortedRenderState.java
28 28
 * This is a member of DistortedNode. Remembers the OpenGL state we want to set just before rendering
29 29
 * the Node.
30 30
 */
31
class DistortedRenderState
31
public class DistortedRenderState
32 32
{
33 33
  // TODO: figure this out dynamically; this assumes 8 bit stencil buffer.
34 34
  private static final int STENCIL_MASK = (1<<8)-1;
src/main/java/org/distorted/library/EffectMessageSender.java
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.library;
21

  
22
import org.distorted.library.message.EffectListener;
23
import org.distorted.library.message.EffectMessage;
24

  
25
import java.util.Vector;
26

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

  
29
final class EffectMessageSender extends Thread
30
  {
31
  private class Message
32
    {
33
    EffectListener mListener;
34
    EffectMessage mMessage;
35
    long mEffectID;
36
    int mEffectName;
37
    long mBitmapID;
38

  
39
    Message(EffectListener l, EffectMessage m, long id, int name, long bmpID)
40
      {
41
      mListener   = l;
42
      mMessage    = m;
43
      mEffectID   = id;
44
      mEffectName = name;
45
      mBitmapID   = bmpID;
46
      }
47
    }
48
  
49
  private static Vector<Message> mList =null;
50
  private static EffectMessageSender mThis=null;
51
  private static volatile boolean mNotify  = false;
52
  private static volatile boolean mRunning = false;
53

  
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55
   
56
  private EffectMessageSender() 
57
    {
58
    }
59

  
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

  
62
  static void startSending()
63
    {
64
    mRunning = true;
65

  
66
    if( mThis==null )
67
      {
68
      mList = new Vector<>();
69
      mThis = new EffectMessageSender();
70
      mThis.start();
71
      }
72
    else  
73
      {  
74
      synchronized(mThis)
75
        {
76
        mThis.notify();
77
        }
78
      }
79
    }
80

  
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82
  
83
  static void stopSending()
84
    {
85
    mRunning = false;
86

  
87
    if( mThis!=null )
88
      {
89
      synchronized(mThis)
90
        {
91
        mThis.notify();
92
        }
93
      }
94
    }
95
  
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97
  
98
  public void run()
99
    {
100
    Message tmp;  
101
     
102
    while(mRunning)
103
      {
104
      //android.util.Log.i("SENDER", "sender thread running...");
105

  
106
      while( mList.size()>0 )
107
        {
108
        tmp = mList.remove(0);
109
        tmp.mListener.effectMessage(tmp.mMessage, tmp.mEffectID, EffectNames.getName(tmp.mEffectName),tmp.mBitmapID);
110
        }
111

  
112
      synchronized(mThis)
113
        {
114
        if (!mNotify)
115
          {
116
          try  { mThis.wait(); }
117
          catch(InterruptedException ex) { }
118
          }
119
        mNotify = false;
120
        }
121
      }
122

  
123
    mThis = null;
124
    mList.clear();
125

  
126
    //android.util.Log.i("SENDER", "sender thread finished...");
127
    }
128
  
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130
        
131
  static void newMessage(EffectListener l, EffectMessage m, long id, int name, long bmpID)
132
    {
133
    Message msg = mThis.new Message(l,m,id,name,bmpID);
134
    mList.add(msg);
135

  
136
    synchronized(mThis)
137
      {
138
      mNotify = true;
139
      mThis.notify();
140
      }
141
    }
142
  }
143
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/EffectNames.java
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.library;
21

  
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23
/**
24
 * Names of Effects one can add to the DistortedEffects queues.
25
 * <p>
26
 * Effect's 'Type' is one of the constants defined in {@link EffectTypes}.
27
 * </p>
28
 * <p>
29
 * Effect's 'Uniforms' are a vector of 7 (matrix effects) 12 (vertex) or 8 (fragment) floats, which
30
 * together form full information how to compute a given effect.
31
 * Typically, some of those values will be Interpolated in CPU (by one of the 'EffectQueueX.compute()'
32
 * methods) and the effect of such Interpolation sent to the Shaders.
33
 * </p>
34
 * <p>
35
 * Effect's 'Unity' is such a particular vector of its 'interpolated values' which makes the
36
 * effect NULL. For example, if the effect is 'MOVE' by a 3-dimensional vector, then a 'NULL
37
 * MOVE' is a MOVE by vector (0,0,0), thus (0,0,0) is the unity of the MOVE effect.
38
 * This is used by the EffectQueue classes to decide if the final form of the Effect is NULL - and
39
 * thus if it can safely be removed from Effect Queues without affecting the visual in any way.
40
 * </p>
41
 */
42
public enum EffectNames
43
  {
44
  // EFFECT NAME /////// EFFECT TYPE ////////////// UNITY /////////////// DIM // REGION // CENTER
45

  
46
  /////////////////////////////////////////////////////////////////////////////////
47
  // MATRIX EFFECTS.
48
  // Always 7 Uniforms: 4 per-effect interpolated values + 3 dimensional center.
49
 /**
50
   * Rotate the whole Object around a center point (in angle-axis notation).
51
   * <p>
52
   * Uniforms: (angle,axisX,axisY,axisZ,centerX,centerY,centerZ)
53
   * <p>
54
   * Unity: angle==0
55
   */
56
  ROTATE           ( EffectTypes.MATRIX  ,   new float[] {0.0f}           , 4, false, true ),
57
 /**
58
   * Rotate the whole Object around a center point (in quaternion notation).
59
   * <p>
60
   * Uniforms: (quatX,quatY,quatZ,quatW,centerX,centerY,centerZ)
61
   * <p>
62
   * Unity: (quatX,quatY,quatZ) = (0,0,0)
63
   */
64
  QUATERNION       ( EffectTypes.MATRIX  ,   new float[] {0.0f,0.0f,0.0f} , 4, false, true ),
65
 /**
66
   * Move the whole Object by a vector.
67
   * <p>
68
   * Uniforms: (vectorX,vectorY,vectorZ,UNUSED,UNUSED,UNUSED,UNUSED)
69
   * <p>
70
   * Unity: (vectorX,vectorY,vectorZ) = (0,0,0)
71
   */
72
  MOVE             ( EffectTypes.MATRIX  ,   new float[] {0.0f,0.0f,0.0f} , 3, false, false ),
73
 /**
74
   * Scale the whole Object independently in all 3 dimensions.
75
   * <p>
76
   * Uniforms: (scaleX,scaleY,scaleZ,UNUSED,UNUSED,UNUSED,UNUSED)
77
   * <p>
78
   * Unity: (scaleX,scaleY,scaleZ) = (1,1,1)
79
   */
80
  SCALE            ( EffectTypes.MATRIX  ,   new float[] {1.0f,1.0f,1.0f} , 3, false, false ),
81
 /**
82
   * Shear the whole Object in 3 dimensions around a center point.
83
   * <p>
84
   * Uniforms: (shearX,shearY,shearZ,UNUSED,centerX,centerY,centerZ)
85
   * <p>
86
   * Unity:  (shearX,shearY,shearZ) = (0,0,0)
87
   */
88
  SHEAR            ( EffectTypes.MATRIX  ,   new float[] {0.0f,0.0f,0.0f} , 3, false, true ),
89
  // add new Matrix effects here...
90

  
91
 /////////////////////////////////////////////////////////////////////////////////
92
 // VERTEX EFFECTS
93
 // Always 12 Uniforms: 5 per-effect interpolated values, 3-dimensional center of
94
 // the effect, 4-dimensional Region
95
 /**
96
   * Apply a 3D vector of force to area around a point on the surface of the Object.
97
   * <p>
98
   * Uniforms: (forceX,forceY,forceZ,UNUSED,
99
   *            UNUSED,centerX,centerY,centerZ,
100
   *            regionX,regionY,regionRX,regionRY)
101
   * <p>
102
   * Unity: (forceX,forceY,forceZ) = (0,0,0)
103
   */
104
  DISTORT          ( EffectTypes.VERTEX  ,   new float[] {0.0f,0.0f,0.0f} , 3, true, true ),
105
 /**
106
   * Deform the whole Object by applying a 3D vector of force to a center point.
107
   * <p>
108
   * Uniforms: (forceX,forceY,forceZ,UNUSED,
109
   *            UNUSED,centerX,centerY,centerZ,
110
   *            regionX,regionY,regionRX,regionRY)
111
   * <p>
112
   * Unity: (forceX,forceY,forceZ) = (0,0,0)
113
   */
114
  DEFORM           ( EffectTypes.VERTEX  ,   new float[] {0.0f,0.0f,0.0f} , 3, true, true ),
115
 /**
116
   * Pull (or push away) all points around a center point to (from) it.
117
   * <p>
118
   * Uniforms: (sinkFactor,UNUSED,UNUSED,UNUSED,
119
   *            UNUSED,centerX,centerY,centerZ,
120
   *            regionX,regionY,regionRX,regionRY)
121
   * <p>
122
   * Unity: sinkFactor = 1
123
   */
124
  SINK             ( EffectTypes.VERTEX  ,   new float[] {1.0f}           , 1, true, true ),
125
  /**
126
   * Pull (or push away) all points around a line to (from) it.
127
   * <p>
128
   * Uniforms: (pinchFactor,lineAngle,UNUSED,UNUSED,
129
   *            UNUSED,centerX,centerY,centerZ,
130
   *            regionX,regionY,regionRX,regionRY)
131
   * <p>
132
   * Unity: sinkFactor = 1
133
   */
134
  PINCH            ( EffectTypes.VERTEX  ,   new float[] {1.0f}           , 2, true, true ),
135
 /**
136
   * Smoothly rotate a limited area around a center point.
137
   * <p>
138
   * Uniforms: (swirlAngle,UNUSED,UNUSED,UNUSED,
139
   *            UNUSED, centerX,centerY,centerZ,
140
   *            regionX,regionY,regionRX,regionRY)
141
   * <p>
142
   * Unity: swirlAngle = 0
143
   */
144
  SWIRL            ( EffectTypes.VERTEX  ,   new float[] {0.0f}           , 1, true, true ),
145
  /**
146
   * Directional sinusoidal wave effect. The direction of the wave is given by the 'angle'
147
   * parameters. Details: {@link DistortedEffects#wave(org.distorted.library.type.Data5D,org.distorted.library.type.Data3D)}
148
   * <p>
149
   * Uniforms: (amplitude,length,phase,angleAlpha,
150
   *            angleBeta, centerX,centerY,centerZ,
151
   *            regionX,regionY,regionRX,regionRY)
152
   * <p>
153
   * Unity: amplitude  = 0
154
   */
155
  WAVE             ( EffectTypes.VERTEX  ,   new float[] {0.0f}           , 5, true, true ),
156
  // add new Vertex Effects here...
157

  
158
 /////////////////////////////////////////////////////////////////////////////////
159
 // FRAGMENT EFFECTS
160
 // Always 8 Uniforms: 4-per effect interpolated values, 4 dimensional Region.
161
 /**
162
   * Make a given Region (partially) transparent.
163
   * <p>
164
   * Uniforms: (transparencyLevel,UNUSED,UNUSED,UNUSED, regionX, regionY, regionRX, regionRY)
165
   * <p>
166
   * Unity: transparencyLevel = 1
167
   */
168
  ALPHA            ( EffectTypes.FRAGMENT,   new float[] {1.0f}           , 1, true, false ),
169
 /**
170
   * Make a given Region (partially) transparent.
171
   * Effect smoothly fades towards the edges of the region.
172
   * <p>
173
   * Uniforms: (transparencyLevel,UNUSED,UNUSED,UNUSED, regionX, regionY, regionRX, regionRY)
174
   * Unity: transparencyLevel = 1
175
   */
176
  SMOOTH_ALPHA     ( EffectTypes.FRAGMENT,   new float[] {1.0f}           , 1, true, false ),
177
 /**
178
   * Blend current color in the texture with a given color.
179
   * <p>
180
   * Uniforms: (blendLevel,colorR,colorG,colorB, regionX, regionY, regionRX, regionRY)
181
   * <p>
182
   * Unity: blendLevel = 0
183
   */
184
  CHROMA           ( EffectTypes.FRAGMENT,   new float[] {0.0f}           , 4, true, false ),
185
 /**
186
   * Smoothly blend current color in the texture with a given color.
187
   * <p>
188
   * Uniforms: (blendLevel,colorR,colorG,colorB, regionX, regionY, regionRX, regionRY)
189
   * Unity: blendLevel = 0
190
   */
191
  SMOOTH_CHROMA    ( EffectTypes.FRAGMENT,   new float[] {0.0f}           , 4, true, false ),
192
 /**
193
   * Change brightness level of a given Region.
194
   * <p>
195
   * Uniforms: (brightnessLevel,UNUSED,UNUSED,UNUSED, regionX, regionY, regionRX, regionRY)
196
   * <p>
197
   * Unity: brightnessLevel = 1
198
   */
199
  BRIGHTNESS       ( EffectTypes.FRAGMENT,   new float[] {1.0f}           , 1, true, false ),
200
 /**
201
   * Smoothly change brightness level of a given Region.
202
   * <p>
203
   * Uniforms: (brightnessLevel,UNUSED,UNUSED,UNUSED, regionX, regionY, regionRX, regionRY)
204
   * <p>
205
   * Unity: brightnessLevel = 1
206
   */
207
  SMOOTH_BRIGHTNESS( EffectTypes.FRAGMENT,   new float[] {1.0f}           , 1, true, false ),
208
 /**
209
   * Change saturation level of a given Region.
210
   * <p>
211
   * Uniforms: (saturationLevel,UNUSED,UNUSED,UNUSED, regionX, regionY, regionRX, regionRY)
212
   * <p>
213
   * Unity: saturationLevel = 1
214
   */
215
  SATURATION       ( EffectTypes.FRAGMENT,   new float[] {1.0f}           , 1, true, false ),
216
 /**
217
   * Smoothly change saturation level of a given Region.
218
   * <p>
219
   * Uniforms: (saturationLevel,UNUSED,UNUSED,UNUSED, regionX, regionY, regionRX, regionRY)
220
   * <p>
221
   * Unity: saturationLevel = 1
222
   */
223
  SMOOTH_SATURATION( EffectTypes.FRAGMENT,   new float[] {1.0f}           , 1, true, false ),
224
 /**
225
   * Change contrast level of a given Region.
226
   * <p>
227
   * Uniforms: (contrastLevel,UNUSED,UNUSED,UNUSED, regionX, regionY, regionRX, regionRY)
228
   * <p>
229
   * Unity: contrastLevel = 1
230
   */
231
  CONTRAST         ( EffectTypes.FRAGMENT,   new float[] {1.0f}           , 1, true, false ),
232
 /**
233
   * Smoothly change contrast level of a given Region.
234
   * <p>
235
   * Uniforms: (contrastLevel,UNUSED,UNUSED,UNUSED, regionX, regionY, regionRX, regionRY)
236
   * <p>
237
   * Unity: contrastLevel = 1
238
   */
239
  SMOOTH_CONTRAST  ( EffectTypes.FRAGMENT,   new float[] {1.0f}           , 1, true, false ),
240
  // add new Fragment effects here...
241

  
242
  /////////////////////////////////////////////////////////////////////////////////
243
  // POSTPROCESSING EFFECTS.
244
  // Always 5 Uniforms: 5 per-effect interpolated values.
245
 /**
246
   * Blur the area around the center.
247
   * <p>
248
   * Uniforms: (radius,UNUSED,UNUSED,UNUSED,UNUSED)
249
   * <p>
250
   * Unity: radius = 0
251
   */
252
  BLUR             ( EffectTypes.POSTPROCESS,new float[] {0.0f}          , 1, false, false ),
253
/**
254
   * Make the object Glow with a certain color and configurable radius of the halo around it.
255
   * <p>
256
   * Uniforms: (A,R,G,B,radius)
257
   * <p>
258
   * Unity: radius = 0
259
   */
260
  GLOW             ( EffectTypes.POSTPROCESS,new float[] {0.0f}          , 5, false, false );
261

  
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263
  
264
  private static final int MAXDIM = 4;  // maximum supported dimension of the Unity of an Effect
265
                                        // (not to be confused with dimension of the Effect itself!)
266
  private final EffectTypes type;
267
  private final float[] unity;
268
  private final int dimension;
269
  private final boolean supportsR;
270
  private final boolean supportsC;
271

  
272
  private static final float[] unities;
273
  private static final int[] unityDimensions;
274
  private static final int[] dimensions;
275
  private static final boolean[] supportsRegion;
276
  private static final boolean[] supportsCenter;
277
  private static final EffectNames[] names;
278

  
279
  static
280
    {
281
    int len = values().length;
282
    int i=0;
283
    
284
    unityDimensions = new int[len];
285
    dimensions      = new int[len];
286
    supportsRegion  = new boolean[len];
287
    supportsCenter  = new boolean[len];
288
    unities         = new float[MAXDIM*len];
289
    names           = new EffectNames[len];
290

  
291
    for(EffectNames name: EffectNames.values())
292
      {
293
      unityDimensions[i] = (name.unity==null ? 0 : name.unity.length);
294
      dimensions[i]      = name.dimension;
295
      supportsRegion[i]  = name.supportsR;
296
      supportsCenter[i]  = name.supportsC;
297
      names[i]           = name;
298

  
299
      switch(unityDimensions[i])
300
        {
301
        case 4: unities[MAXDIM*i+3] = name.unity[3];
302
        case 3: unities[MAXDIM*i+2] = name.unity[2];
303
        case 2: unities[MAXDIM*i+1] = name.unity[1];
304
        case 1: unities[MAXDIM*i  ] = name.unity[0];
305
        case 0: break;
306
        }
307
      
308
      i++;  
309
      }
310
    }
311
  
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313
  
314
  EffectNames(EffectTypes type, float[] unity, int dimension, boolean supportsR, boolean supportsC)
315
    {
316
    this.type      = type;
317
    this.unity     = unity;
318
    this.dimension = dimension;
319
    this.supportsR = supportsR;
320
    this.supportsC = supportsC;
321
    }
322

  
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

  
325
  static EffectTypes getType(int ordinal)
326
    {
327
    return names[ordinal].type;
328
    }
329

  
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331

  
332
  static EffectNames getName(int ordinal)
333
    {
334
    return names[ordinal];
335
    }
336

  
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338
  
339
  static boolean isUnity(int ordinal, float[] buffer, int index)
340
    {
341
    switch(unityDimensions[ordinal])
342
      {
343
      case 0: return true;
344
      case 1: return buffer[index  ]==unities[MAXDIM*ordinal  ];
345
      case 2: return buffer[index  ]==unities[MAXDIM*ordinal  ] &&
346
                     buffer[index+1]==unities[MAXDIM*ordinal+1];
347
      case 3: return buffer[index  ]==unities[MAXDIM*ordinal  ] &&
348
                     buffer[index+1]==unities[MAXDIM*ordinal+1] && 
349
                     buffer[index+2]==unities[MAXDIM*ordinal+2];
350
      case 4: return buffer[index  ]==unities[MAXDIM*ordinal  ] &&
351
                     buffer[index+1]==unities[MAXDIM*ordinal+1] && 
352
                     buffer[index+2]==unities[MAXDIM*ordinal+2] &&
353
                     buffer[index+3]==unities[MAXDIM*ordinal+3];
354
      }
355
   
356
    return false;
357
    }
358

  
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

  
361
  static int size()
362
    {
363
    return values().length;
364
    }
365

  
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367
// PUBLIC API
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369
/**
370
 * Returns the Type of an individual Effect. For example, EffectNames.ROTATION.getType() will
371
 * return EffectTypes.MATRIX.
372
 * @return type of the effect.
373
 */
374
  public EffectTypes getType()
375
    {
376
    return type;
377
    }
378

  
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

  
381
/**
382
 * Returns the dimension of an Effect (in other words, the number of interpolated values).
383
 * @return dimension of the Effect.
384
 */
385
  public int getDimension() { return dimensions[ordinal()]; }
386

  
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

  
389
/**
390
 * Do we support being masked by a Region?
391
 * @return true if the Effect supports being masked with a Region.
392
 */
393
  public boolean supportsRegion() { return supportsRegion[ordinal()]; }
394

  
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396

  
397
/**
398
 * Does this Effect have a center?
399
 * @return true if the Effect has a center.
400
 */
401
  public boolean supportsCenter() { return supportsCenter[ordinal()]; }
402

  
403
  }
src/main/java/org/distorted/library/EffectQueue.java
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.library;
21

  
22
import org.distorted.library.message.EffectListener;
23
import org.distorted.library.message.EffectMessage;
24
import org.distorted.library.type.Dynamic;
25

  
26
import java.util.Vector;
27

  
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29

  
30
abstract class EffectQueue
31
  {
32
  protected byte mNumEffects;   // number of effects at the moment
33
  protected long mTotalEffects; // total number of effects ever created
34
  protected int[] mName;
35
  protected float[] mUniforms;
36
  protected float[] mCache;
37
  protected Dynamic[][] mInter;
38
  protected long[] mCurrentDuration;
39
  protected byte[] mFreeIndexes;
40
  protected byte[] mIDIndex;
41
  protected long[] mID;
42
  protected long mTime=0;
43
  protected static int[] mMax = new int[EffectTypes.LENGTH];
44
  protected int mMaxIndex;
45
  protected Vector<EffectListener> mListeners =null;
46
  protected int mNumListeners=0;  // ==mListeners.length(), but we only create mListeners if the first one gets added
47
  protected long mObjectID;
48

  
49
  private static boolean mCreated;
50

  
51
  static
52
    {
53
    onDestroy();
54
    }
55
  
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57
   
58
  EffectQueue(long id, int numUniforms, int numCache, int index)
59
    {
60
    mNumEffects   = 0;
61
    mTotalEffects = 0;
62
    mMaxIndex     = index;
63
    mObjectID     = id;
64

  
65
    int max = mMax[mMaxIndex];
66

  
67
    if( max>0 )
68
      {
69
      mName            = new int[max];
70
      mUniforms        = new float[numUniforms*max];
71
      mInter           = new Dynamic[3][max];
72
      mCurrentDuration = new long[max];
73
      mID              = new long[max];
74
      mIDIndex         = new byte[max];
75
      mFreeIndexes     = new byte[max];
76
     
77
      for(byte i=0; i<max; i++) mFreeIndexes[i] = i;
78

  
79
      if( numCache>0 )
80
        {
81
        mCache = new float[numCache*max];
82
        }
83
      }
84
   
85
    mCreated = true;  
86
    }
87

  
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

  
90
  @SuppressWarnings("unused")
91
  int getNumEffects()
92
    {
93
    return mNumEffects;  
94
    }
95

  
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97
// Only max Byte.MAX_VALUE concurrent effects per DistortedEffects object.
98
// If you want more, change type of the mNumEffects, mIDIndex and mFreeIndexes variables to shorts.
99
// (although probably this many uniforms will not fit in the shaders anyway!)
100

  
101
  static boolean setMax(int index, int m)
102
    {
103
    if( (!mCreated && !Distorted.isInitialized()) || m<=mMax[index] )
104
      {
105
      if( m<0              ) m = 0;
106
      else if( m>Byte.MAX_VALUE ) m = Byte.MAX_VALUE;
107

  
108
      mMax[index] = m;
109
      return true;
110
      }
111

  
112
    return false;
113
    }
114

  
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

  
117
  static int getMax(int index)
118
    {
119
    return mMax[index];
120
    }
121

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

  
124
  void registerForMessages(EffectListener el)
125
    {
126
    if( mListeners==null ) mListeners = new Vector<>(2,2);
127

  
128
    if( !mListeners.contains(el) )
129
      {
130
      mListeners.add(el);
131
      mNumListeners++;
132
      }
133
    }
134
 
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

  
137
  void deregisterForMessages(EffectListener el)
138
    {
139
    if( mListeners.remove(el) )
140
      {
141
      mNumListeners--;
142
      }
143
    }
144

  
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

  
147
  static void onDestroy()
148
    {
149
    EffectTypes.reset(mMax);
150
    mCreated = false;  
151
    }
152
 
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

  
155
  synchronized int removeByID(long id)
156
    {
157
    int i = getEffectIndex(id);
158
   
159
    if( i>=0 ) 
160
      {
161
      remove(i);
162
      return 1;
163
      }
164
   
165
    return 0;
166
    }
167

  
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

  
170
  synchronized int removeByType(EffectNames effect)
171
    {
172
    int ret = 0;
173
    int ord = effect.ordinal();  
174
     
175
    for(int i=0; i<mNumEffects; i++)
176
      {
177
      if( mName[i]==ord )
178
        {
179
        remove(i);
180
        i--;
181
        ret++;
182
        }
183
      }
184
   
185
    return ret;
186
    }
187
  
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189
  
190
  private synchronized int getEffectIndex(long id)
191
    {
192
    int index = mIDIndex[(int)(id%mMax[mMaxIndex])];
193
    return (index<mNumEffects && mID[index]==id ? index : -1);
194
    }
195

  
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197
// we do want to notify Listeners if they called 'abortAll' themselves but don't want to notify
198
// them if it is the library itself which is releasing resources.
199

  
200
  synchronized int abortAll(boolean notify)
201
    {
202
    int ret = mNumEffects;
203
    long removedID;
204
    int removedName;
205

  
206
    for(int i=0; i<ret; i++ )
207
      {
208
      mInter[0][i] = null;
209
      mInter[1][i] = null;
210
      mInter[2][i] = null;
211

  
212
      if( notify )
213
        {
214
        removedID = mID[i];
215
        removedName= mName[i];
216

  
217
        for(int j=0; j<mNumListeners; j++)
218
          EffectMessageSender.newMessage( mListeners.elementAt(j),
219
                                          EffectMessage.EFFECT_REMOVED,
220
                                          (removedID<<EffectTypes.LENGTH)+EffectNames.getType(removedName).type,
221
                                          removedName,
222
                                          mObjectID);
223
        }
224
      }
225

  
226
    mNumEffects= 0;
227

  
228
    return ret;
229
    }
230

  
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232
// this assumes 0<=effect<mNumEffects
233
  
234
  protected void remove(int effect)
235
    {
236
    mNumEffects--;     
237
    
238
    byte removedIndex = (byte)(mID[effect]%mMax[mMaxIndex]);
239
    byte removedPosition = mIDIndex[removedIndex];
240
    mFreeIndexes[mNumEffects] = removedIndex;
241
    
242
    long removedID = mID[effect];
243
    int removedName= mName[effect];
244
    
245
    for(int j=0; j<mMax[mMaxIndex]; j++)
246
      {
247
      if( mIDIndex[j] > removedPosition ) mIDIndex[j]--; 
248
      }
249
         
250
    for(int j=effect; j<mNumEffects; j++ ) 
251
      {
252
      mName[j]            = mName[j+1];
253
      mInter[0][j]        = mInter[0][j+1];
254
      mInter[1][j]        = mInter[1][j+1];
255
      mInter[2][j]        = mInter[2][j+1];
256
      mCurrentDuration[j] = mCurrentDuration[j+1];
257
      mID[j]              = mID[j+1];
258
    
259
      moveEffect(j);
260
      }
261
   
262
    mInter[0][mNumEffects] = null;
263
    mInter[1][mNumEffects] = null;
264
    mInter[2][mNumEffects] = null;
265

  
266
    for(int i=0; i<mNumListeners; i++) 
267
      EffectMessageSender.newMessage( mListeners.elementAt(i),
268
                                      EffectMessage.EFFECT_REMOVED,
269
                                      (removedID<<EffectTypes.LENGTH)+EffectNames.getType(removedName).type,
270
                                      removedName,
271
                                      mObjectID);
272
    }
273
  
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275
  
276
  protected long addBase(EffectNames name)
277
    {    
278
    mName[mNumEffects]  = name.ordinal();
279
    mCurrentDuration[mNumEffects] = 0;
280
    
281
    int index = mFreeIndexes[mNumEffects];
282
    long id = mTotalEffects*mMax[mMaxIndex] + index;
283
    mID[mNumEffects] = id;
284
    mIDIndex[index] = mNumEffects;  
285
   
286
    mNumEffects++; 
287
    mTotalEffects++;
288
   
289
    return (id<<EffectTypes.LENGTH)+name.getType().type;
290
    }
291
    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293
// used only for debugging
294

  
295
  @SuppressWarnings("unused")
296
  protected String printEffects(int max)
297
    {
298
    long[] indexes = new long[mMax[mMaxIndex]];
299
   
300
    for(int g=0; g<mMax[mMaxIndex]; g++)
301
      {
302
      indexes[g] = -1;  
303
      }
304
   
305
    String ret="(";
306
    int f;
307
   
308
    for(int g=0; g<max; g++) 
309
      {
310
      f = getEffectIndex(g);
311
      if( f>=0 ) indexes[f] = g;
312
      }
313
   
314
    for(int g=0; g<mMax[mMaxIndex]; g++)
315
      {
316
      ret += (g>0 ? ",":"")+(indexes[g]>=0 ? indexes[g] : " ");   
317
      }
318
   
319
    ret += ")";
320
   
321
    return ret;
322
    }
323

  
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325
// Only used for debugging
326
  
327
  protected boolean printByID(long id)
328
    {
329
    int index = getEffectIndex(id);
330
   
331
    if( index>=0 ) 
332
      {
333
      boolean inter0 = mInter[0][index]==null;
334
      boolean inter1 = mInter[1][index]==null;
335
      boolean inter2 = mInter[2][index]==null;
336

  
337
      android.util.Log.e("EffectQueue", "numEffects="+mNumEffects+" effect id="+id+" index="+index+
338
                         " duration="+mCurrentDuration[index]+" inter[0] null="+inter0+" inter[1] null="+inter1+" inter[2] null="+inter2);
339

  
340
      if( !inter0 ) android.util.Log.e("EffectQueue","inter[0]: "+mInter[0][index].print());
341
      if( !inter1 ) android.util.Log.e("EffectQueue","inter[1]: "+mInter[1][index].print());
342
      if( !inter2 ) android.util.Log.e("EffectQueue","inter[2]: "+mInter[2][index].print());
343

  
344
      return true;
345
      }
346
   
347
    android.util.Log.e("EffectQueue", "effect id="+id+" not found");
348

  
349
    return false;  
350
    }
351
 
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

  
354
  abstract void moveEffect(int index);
355
  }
356
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/EffectQueueFragment.java
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.library;
21

  
22
import android.opengl.GLES30;
23

  
24
import org.distorted.library.message.EffectMessage;
25
import org.distorted.library.type.Data1D;
26
import org.distorted.library.type.Data3D;
27
import org.distorted.library.type.Data4D;
28
import org.distorted.library.type.Dynamic1D;
29
import org.distorted.library.type.Dynamic3D;
30
import org.distorted.library.type.Dynamic4D;
31
import org.distorted.library.type.Static1D;
32
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34

  
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

  
37
class EffectQueueFragment extends EffectQueue
38
  {
39
  private static final int NUM_UNIFORMS = 8;
40
  private static final int NUM_CACHE    = 4;
41
  private static final int INDEX = EffectTypes.FRAGMENT.ordinal();
42
  private static int mNumEffectsH;
43
  private static int mTypeH;
44
  private static int mUniformsH;
45
  
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47
   
48
  EffectQueueFragment(long id)
49
    { 
50
    super(id,NUM_UNIFORMS,NUM_CACHE,INDEX);
51
    }
52

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

  
55
  static void getUniforms(int mProgramH)
56
    {
57
    mNumEffectsH= GLES30.glGetUniformLocation( mProgramH, "fNumEffects");
58
    mTypeH      = GLES30.glGetUniformLocation( mProgramH, "fType");
59
    mUniformsH  = GLES30.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
      mCurrentDuration[i] += step;
73

  
74
      if( mInter[0][i]!=null && mInter[0][i].interpolateMain(mUniforms ,NUM_UNIFORMS*i, mCurrentDuration[i], step) )
75
        {
76
        for(int j=0; j<mNumListeners; j++)   
77
          EffectMessageSender.newMessage( mListeners.elementAt(j),
78
                                          EffectMessage.EFFECT_FINISHED,
79
                                          (mID[i]<<EffectTypes.LENGTH)+EffectTypes.FRAGMENT.type,
80
                                          mName[i],
81
                                          mObjectID);
82
      
83
        if( EffectNames.isUnity(mName[i], mUniforms, NUM_UNIFORMS*i) )
84
          {
85
          remove(i);
86
          i--;
87
          continue;
88
          }
89
        else mInter[0][i] = null;
90
        }
91

  
92
      if( mInter[1][i]!=null ) mInter[1][i].interpolateMain( mCache   , NUM_CACHE*i     , mCurrentDuration[i], step);
93
      if( mInter[2][i]!=null ) mInter[2][i].interpolateMain( mUniforms, NUM_UNIFORMS*i+1, 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

  
108
    mCache[NUM_CACHE*index  ] = mCache[NUM_CACHE*(index+1)  ];
109
    mCache[NUM_CACHE*index+1] = mCache[NUM_CACHE*(index+1)+1];
110
    mCache[NUM_CACHE*index+2] = mCache[NUM_CACHE*(index+1)+2];
111
    mCache[NUM_CACHE*index+3] = mCache[NUM_CACHE*(index+1)+3];
112
    }
113
  
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115
  
116
  synchronized void send(float halfX, float halfY)
117
    {
118
    GLES30.glUniform1i( mNumEffectsH, mNumEffects);
119

  
120
    if( mNumEffects>0 )
121
      {
122
      for(int i=0; i<mNumEffects; i++)
123
        {
124
        mUniforms[NUM_UNIFORMS*i+4] = mCache[NUM_CACHE*i  ]-halfX;
125
        mUniforms[NUM_UNIFORMS*i+5] =-mCache[NUM_CACHE*i+1]+halfY;
126
        mUniforms[NUM_UNIFORMS*i+6] = mCache[NUM_CACHE*i+2];
127
        mUniforms[NUM_UNIFORMS*i+7] = mCache[NUM_CACHE*i+3];
128
        }
129

  
130
      GLES30.glUniform1iv( mTypeH    ,                 mNumEffects, mName    ,0);
131
      GLES30.glUniform4fv( mUniformsH,(NUM_UNIFORMS/4)*mNumEffects, mUniforms,0);
132
      }  
133
    }
134

  
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136
// alpha, brightness, contrast, saturation
137

  
138
  synchronized long add(EffectNames eln, Data1D data)
139
    {
140
    if( mMax[INDEX]>mNumEffects )
141
      {
142
      if( data instanceof Dynamic1D)
143
        {
144
        mInter[0][mNumEffects] = (Dynamic1D)data;
145
        }
146
      else if( data instanceof Static1D )
147
        {
148
        mInter[0][mNumEffects] = null;
149
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)data).getX();
150
        }
151
      else return -1;
152

  
153
      mInter[1][mNumEffects] = null;
154
      mCache[NUM_CACHE*mNumEffects+2] = Float.MAX_VALUE;
155
      mCache[NUM_CACHE*mNumEffects+3] = Float.MAX_VALUE;
156

  
157
      mInter[2][mNumEffects] = null;
158

  
159
      return addBase(eln); 
160
      }
161
      
162
    return -1;
163
    }
164
  
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166
// alpha, brightness, contrast, saturation
167

  
168
  synchronized long add(EffectNames eln, Data1D data, Data4D region)
169
    {
170
    if( mMax[INDEX]>mNumEffects )
171
      {
172
      if( data instanceof Dynamic1D)
173
        {
174
        mInter[0][mNumEffects] = (Dynamic1D)data;
175
        }
176
      else if( data instanceof Static1D )
177
        {
178
        mInter[0][mNumEffects] = null;
179
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)data).getX();
180
        }
181
      else return -1;
182

  
183
      if( region instanceof Dynamic4D)
184
        {
185
        mInter[1][mNumEffects] = (Dynamic4D)region;
186
        }
187
      else if( region instanceof Static4D )
188
        {
189
        mInter[1][mNumEffects]  = null;
190
        mCache[NUM_CACHE*mNumEffects  ] = ((Static4D)region).getX();
191
        mCache[NUM_CACHE*mNumEffects+1] = ((Static4D)region).getY();
192
        mCache[NUM_CACHE*mNumEffects+2] = ((Static4D)region).getZ();
193
        mCache[NUM_CACHE*mNumEffects+3] = ((Static4D)region).getW();
194
        }
195
      else return -1;
196

  
197
      mInter[2][mNumEffects] = null;
198

  
199
      return addBase(eln);
200
      }
201
      
202
    return -1;
203
    }
204
  
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206
// chroma
207

  
208
  synchronized long add(EffectNames eln, Data1D level, Data3D color, Data4D region)
209
    {
210
    if( mMax[INDEX]>mNumEffects )
211
      {
212
      if( level instanceof Dynamic1D)
213
        {
214
        mInter[0][mNumEffects] = (Dynamic1D)level;
215
        }
216
      else if( level instanceof Static1D )
217
        {
218
        mInter[0][mNumEffects] = null;
219
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)level).getX();
220
        }
221
      else return -1;
222

  
223
      if( color instanceof Dynamic3D)
224
        {
225
        mInter[2][mNumEffects] = (Dynamic3D)color;
226
        }
227
      else if( color instanceof Static3D )
228
        {
229
        mInter[2][mNumEffects] = null;
230
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static3D)color).getX();
231
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static3D)color).getY();
232
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static3D)color).getZ();
233
        }
234
      else return -1;
235

  
236
      if( region instanceof Dynamic4D)
237
        {
238
        mInter[1][mNumEffects] = (Dynamic4D)region;
239
        }
240
      else if( region instanceof Static4D )
241
        {
242
        mInter[1][mNumEffects]  = null;
243
        mCache[NUM_CACHE*mNumEffects  ] = ((Static4D)region).getX();
244
        mCache[NUM_CACHE*mNumEffects+1] = ((Static4D)region).getY();
245
        mCache[NUM_CACHE*mNumEffects+2] = ((Static4D)region).getZ();
246
        mCache[NUM_CACHE*mNumEffects+3] = ((Static4D)region).getW();
247
        }
248
      else return -1;
249

  
250
      return addBase(eln); 
251
      }
252
      
253
    return -1;
254
    }
255
  
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257
// chroma
258

  
259
  synchronized long add(EffectNames eln, Data1D level, Data3D color)
260
    {
261
    if( mMax[INDEX]>mNumEffects )
262
      {
263
      if( level instanceof Dynamic1D)
264
        {
265
        mInter[0][mNumEffects] = (Dynamic1D)level;
266
        }
267
      else if( level instanceof Static1D )
268
        {
269
        mInter[0][mNumEffects] = null;
270
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)level).getX();
271
        }
272
      else return -1;
273

  
274
      if( color instanceof Dynamic3D)
275
        {
276
        mInter[2][mNumEffects] = (Dynamic3D)color;
277
        }
278
      else if( color instanceof Static3D )
279
        {
280
        mInter[2][mNumEffects] = null;
281
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static3D)color).getX();
282
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static3D)color).getY();
283
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static3D)color).getZ();
284
        }
285
      else return -1;
286

  
287
      mInter[1][mNumEffects]  = null;
288
      mCache[NUM_CACHE*mNumEffects+2] = Float.MAX_VALUE;
289
      mCache[NUM_CACHE*mNumEffects+3] = Float.MAX_VALUE;
290

  
291
      return addBase(eln);
292
      }
293
       
294
    return -1;
295
    }
296

  
297
///////////////////////////////////////////////////////////////////////////////////////////////////
298
// end of FragmentEffect   
299
  }
src/main/java/org/distorted/library/EffectQueueMatrix.java
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.library;
21

  
22
import android.opengl.GLES30;
23
import android.opengl.Matrix;
24

  
25
import org.distorted.library.message.EffectMessage;
26
import org.distorted.library.type.Data1D;
27
import org.distorted.library.type.Data3D;
28
import org.distorted.library.type.Data4D;
29
import org.distorted.library.type.Dynamic1D;
30
import org.distorted.library.type.Dynamic3D;
31
import org.distorted.library.type.Dynamic4D;
32
import org.distorted.library.type.DynamicQuat;
33
import org.distorted.library.type.Static1D;
34
import org.distorted.library.type.Static3D;
35
import org.distorted.library.type.Static4D;
36

  
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

  
39
class EffectQueueMatrix extends EffectQueue
40
  {   
41
  private static final int NUM_UNIFORMS = 7;
42
  private static final int NUM_CACHE    = 0;
43
  private static final int INDEX = EffectTypes.MATRIX.ordinal();
44

  
45
  private static float[] mMVPMatrix = new float[16];
46
  private static float[] mTmpMatrix = new float[16];
47
  private static float[] mViewMatrix= new float[16];
48

  
49
  private static int mObjDH;      // This is a handle to half a Object dimensions
50
  private static int mMVPMatrixH; // the transformation matrix
51
  private static int mMVMatrixH;  // the modelview matrix.
52
  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54
   
55
  EffectQueueMatrix(long id)
56
    { 
57
    super(id,NUM_UNIFORMS,NUM_CACHE,INDEX );
58
    }
59

  
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

  
62
  private static void multiplyByQuat(float[] matrix, float X, float Y, float Z, float W)
63
    {
64
    float xx= X * X;
65
    float xy= X * Y;
66
    float xz= X * Z;
67
    float xw= X * W;
68
    float yy= Y * Y;
69
    float yz= Y * Z;
70
    float yw= Y * W;
71
    float zz= Z * Z;
72
    float zw= Z * W;
73

  
74
    mTmpMatrix[0]  = 1 - 2 * ( yy + zz );
75
    mTmpMatrix[1]  =     2 * ( xy - zw );
76
    mTmpMatrix[2]  =     2 * ( xz + yw );
77
    mTmpMatrix[4]  =     2 * ( xy + zw );
78
    mTmpMatrix[5]  = 1 - 2 * ( xx + zz );
79
    mTmpMatrix[6]  =     2 * ( yz - xw );
80
    mTmpMatrix[8]  =     2 * ( xz - yw );
81
    mTmpMatrix[9]  =     2 * ( yz + xw );
82
    mTmpMatrix[10] = 1 - 2 * ( xx + yy );
83
    mTmpMatrix[3]  = mTmpMatrix[7] = mTmpMatrix[11] = mTmpMatrix[12] = mTmpMatrix[13] = mTmpMatrix[14] = 0;
84
    mTmpMatrix[15] = 1;
85
    
86
    Matrix.multiplyMM(mMVPMatrix, 0, matrix, 0, mTmpMatrix, 0);  
87

  
88
    matrix[ 0] = mMVPMatrix[ 0];
89
    matrix[ 1] = mMVPMatrix[ 1];
90
    matrix[ 2] = mMVPMatrix[ 2];
91
    matrix[ 3] = mMVPMatrix[ 3];
92
    matrix[ 4] = mMVPMatrix[ 4];
93
    matrix[ 5] = mMVPMatrix[ 5];
94
    matrix[ 6] = mMVPMatrix[ 6];
95
    matrix[ 7] = mMVPMatrix[ 7];
96
    matrix[ 8] = mMVPMatrix[ 8];
97
    matrix[ 9] = mMVPMatrix[ 9];
98
    matrix[10] = mMVPMatrix[10];
99
    matrix[11] = mMVPMatrix[11];
100
    matrix[12] = mMVPMatrix[12];
101
    matrix[13] = mMVPMatrix[13];
102
    matrix[14] = mMVPMatrix[14];
103
    matrix[15] = mMVPMatrix[15];
104
    }
105

  
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

  
108
  private void magnify(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
109
    {
110
    float scale, nx, ny;
111
    float[] result= new float[4];
112
    float[] point = new float[4];
113
    float[] matrix= new float[16];
114
    float minx = Integer.MAX_VALUE;
115
    float maxx = Integer.MIN_VALUE;
116
    float miny = Integer.MAX_VALUE;
117
    float maxy = Integer.MIN_VALUE;
118

  
119
    point[3] = 1.0f;
120

  
121
    Matrix.multiplyMM(matrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
122

  
123
    point[0] = +halfX; point[1] = +halfY; point[2] = +halfZ;
124
    Matrix.multiplyMV(result,0,matrix,0,point,0);
125
    nx = result[0]/result[3];
126
    ny = result[1]/result[3];
127
    if( nx<minx ) minx = nx;
128
    if( nx>maxx ) maxx = nx;
129
    if( ny<miny ) miny = ny;
130
    if( ny>maxy ) maxy = ny;
131

  
132
    point[0] = +halfX; point[1] = +halfY; point[2] = -halfZ;
133
    Matrix.multiplyMV(result,0,matrix,0,point,0);
134
    nx = result[0]/result[3];
135
    ny = result[1]/result[3];
136
    if( nx<minx ) minx = nx;
137
    if( nx>maxx ) maxx = nx;
138
    if( ny<miny ) miny = ny;
139
    if( ny>maxy ) maxy = ny;
140

  
141
    point[0] = +halfX; point[1] = -halfY; point[2] = +halfZ;
142
    Matrix.multiplyMV(result,0,matrix,0,point,0);
143
    nx = result[0]/result[3];
144
    ny = result[1]/result[3];
145
    if( nx<minx ) minx = nx;
146
    if( nx>maxx ) maxx = nx;
147
    if( ny<miny ) miny = ny;
148
    if( ny>maxy ) maxy = ny;
149

  
150
    point[0] = +halfX; point[1] = -halfY; point[2] = -halfZ;
151
    Matrix.multiplyMV(result,0,matrix,0,point,0);
152
    nx = result[0]/result[3];
153
    ny = result[1]/result[3];
154
    if( nx<minx ) minx = nx;
155
    if( nx>maxx ) maxx = nx;
156
    if( ny<miny ) miny = ny;
157
    if( ny>maxy ) maxy = ny;
158

  
159
    point[0] = -halfX; point[1] = +halfY; point[2] = +halfZ;
160
    Matrix.multiplyMV(result,0,matrix,0,point,0);
161
    nx = result[0]/result[3];
162
    ny = result[1]/result[3];
163
    if( nx<minx ) minx = nx;
164
    if( nx>maxx ) maxx = nx;
165
    if( ny<miny ) miny = ny;
166
    if( ny>maxy ) maxy = ny;
167

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff