Project

General

Profile

Download (13.4 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / EffectQueueFragment.java @ e458a4ba

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.GLES20;
23

    
24
import org.distorted.library.message.EffectMessage;
25
import org.distorted.library.type.Float2D;
26
import org.distorted.library.type.Float3D;
27
import org.distorted.library.type.Float4D;
28
import org.distorted.library.type.Interpolator;
29
import org.distorted.library.type.Interpolator1D;
30
import org.distorted.library.type.Interpolator2D;
31

    
32
///////////////////////////////////////////////////////////////////////////////////////////////////
33

    
34
class EffectQueueFragment extends EffectQueue
35
  {
36
  private static final int NUM_UNIFORMS = 9;
37
  private static final int INDEX = EffectTypes.FRAGMENT.ordinal();
38
  private float[] mBuf;
39
  private static int mNumEffectsH;
40
  private static int mTypeH;
41
  private static int mUniformsH;
42
  
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44
   
45
  public EffectQueueFragment(DistortedObject obj)
46
    { 
47
    super(obj,NUM_UNIFORMS,INDEX);
48
   
49
    if( mMax[INDEX]>0 )
50
      {
51
      mBuf= new float[4*mMax[INDEX]];
52
      }
53
    }
54

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

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

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

    
102
///////////////////////////////////////////////////////////////////////////////////////////////////
103

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

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

    
132
  synchronized void sendZero() 
133
    {
134
    GLES20.glUniform1i( mNumEffectsH, 0);
135
    }
136
    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
// Do various post-processing on already computed effects.
139
// 1) move all Points and scale all Region radii by a ModelView matrix
140
// 2) in case of macroblock, pre-compute some values so that we don't have to do it in the fragment shader.
141
  
142
  void postprocess(float[] MVmatrix)
143
    {
144
    if( mNumEffects>0 )
145
      {
146
      float tx,ty;   
147
      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
148
      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.
149
   
150
      for(int i=0; i<mNumEffects; i++)
151
        {   
152
        tx = mBuf[4*i  ]-mObjHalfX; // we have to invert y and move everything by (half of bmp width, half of bmp height)
153
        ty =-mBuf[4*i+1]+mObjHalfY; //
154
      
155
        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
156
        mUniforms[NUM_UNIFORMS*i+5] = h*mBuf[4*i+3];                                  // 
157
     // mUniforms[NUM_UNIFORMS*i+6] =                                                 // this value is not used in Fragment Shader   
158
        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.
159
        mUniforms[NUM_UNIFORMS*i+8] = MVmatrix[1]*tx + MVmatrix[5]*ty + MVmatrix[13]; //  
160
        
161
        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
162
          {
163
          mUniforms[NUM_UNIFORMS*i+1] = 2.0f*mObjHalfX/mUniforms[NUM_UNIFORMS*i];
164
          mUniforms[NUM_UNIFORMS*i+2] = 2.0f*mObjHalfY/mUniforms[NUM_UNIFORMS*i];
165
          }
166
        }
167
      }
168
    }
169
  
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171
       
172
  synchronized long add(EffectNames eln, Interpolator inter, Float4D region, Interpolator2D point)
173
    {
174
    if( mMax[INDEX]>mNumEffects )
175
      {
176
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects); 
177
      mInterI[mNumEffects] = inter;
178
      mInterP[mNumEffects] = point;
179

    
180
      if( region==null )
181
        {
182
        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
183
        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
184
        }
185
      else
186
        {
187
        float z = region.getZ();
188
        float w = region.getW();
189

    
190
        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
191
        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
192
        }
193

    
194
      return addBase(eln); 
195
      }
196
      
197
    return -1;
198
    }
199
  
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

    
202
  synchronized long add(EffectNames eln, Interpolator inter, Float4D region, Float2D point)
203
    {
204
    if( mMax[INDEX]>mNumEffects )
205
      {
206
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);    
207
      mInterI[mNumEffects] = inter;
208
      mInterP[mNumEffects] = null;
209
      mBuf[4*mNumEffects  ] = point.getX();
210
      mBuf[4*mNumEffects+1] = point.getY();
211

    
212
      if( region==null )
213
        {
214
        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
215
        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
216
        }
217
      else
218
        {
219
        float z = region.getZ();
220
        float w = region.getW();
221

    
222
        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
223
        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
224
        }
225

    
226
      return addBase(eln);
227
      }
228
      
229
    return -1;
230
    }
231
  
232
///////////////////////////////////////////////////////////////////////////////////////////////////
233
       
234
  synchronized long add(EffectNames eln, Interpolator1D inter, Float3D c, Float4D region, Interpolator2D point)
235
    {
236
    if( mMax[INDEX]>mNumEffects )
237
      {
238
      mInterI[mNumEffects] = inter;
239
      mInterP[mNumEffects] = point;
240

    
241
      if( region==null )
242
        {
243
        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
244
        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
245
        }
246
      else
247
        {
248
        float z = region.getZ();
249
        float w = region.getW();
250

    
251
        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
252
        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
253
        }
254

    
255
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.getX();
256
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.getY();
257
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.getZ();
258
     
259
      return addBase(eln); 
260
      }
261
      
262
    return -1;
263
    }
264
  
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

    
267
  synchronized long add(EffectNames eln, Interpolator1D inter, Float3D c, Float4D region, Float2D point)
268
    {
269
    if( mMax[INDEX]>mNumEffects )
270
      {
271
      mInterI[mNumEffects] = inter;
272
      mInterP[mNumEffects] = null;
273
      mBuf[4*mNumEffects  ] = point.getX();
274
      mBuf[4*mNumEffects+1] = point.getY();
275

    
276
      if( region==null )
277
        {
278
        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
279
        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
280
        }
281
      else
282
        {
283
        float z = region.getZ();
284
        float w = region.getW();
285

    
286
        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
287
        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
288
        }
289

    
290
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.getX();
291
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.getY();
292
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.getZ();
293
   
294
      return addBase(eln);
295
      }
296
       
297
    return -1;
298
    }
299
  
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301
       
302
  synchronized long add(EffectNames eln, float t, Float3D c, Float4D region, Interpolator2D point)
303
    {
304
    if( mMax[INDEX]>mNumEffects )
305
      {
306
      mInterI[mNumEffects] = null;
307
      mInterP[mNumEffects] = point;
308

    
309
      if( region==null )
310
        {
311
        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
312
        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
313
        }
314
      else
315
        {
316
        float z = region.getZ();
317
        float w = region.getW();
318

    
319
        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
320
        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
321
        }
322

    
323
      mUniforms[NUM_UNIFORMS*mNumEffects+0] = t;
324
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.getX();
325
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.getY();
326
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.getZ();
327
     
328
      return addBase(eln); 
329
      }
330
      
331
    return -1;
332
    }
333
  
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

    
336
  synchronized long add(EffectNames eln, float t, Float3D c, Float4D region, Float2D point)
337
    {
338
    if( mMax[INDEX]>mNumEffects )
339
      {
340
      mInterI[mNumEffects] = null;
341
      mInterP[mNumEffects] = null;
342
      mBuf[4*mNumEffects  ] = point.getX();
343
      mBuf[4*mNumEffects+1] = point.getY();
344

    
345
      if( region==null )
346
        {
347
        mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
348
        mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
349
        }
350
      else
351
        {
352
        float z = region.getZ();
353
        float w = region.getW();
354

    
355
        mBuf[4*mNumEffects+2] = z<=0.0f ? 1000*mObjHalfX : z;
356
        mBuf[4*mNumEffects+3] = w<=0.0f ? 1000*mObjHalfY : w;
357
        }
358

    
359
      mUniforms[NUM_UNIFORMS*mNumEffects+0] = t;
360
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = c.getX();
361
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = c.getY();
362
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = c.getZ();
363
   
364
      return addBase(eln);
365
      }
366
      
367
    return -1;
368
    }
369
    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371
// end of FragmentEffect   
372
  }
(14-14/18)