Project

General

Profile

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

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

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.Data1D;
26
import org.distorted.library.type.Data4D;
27
import org.distorted.library.type.Dynamic1D;
28
import org.distorted.library.type.Dynamic4D;
29
import org.distorted.library.type.Static1D;
30
import org.distorted.library.type.Static3D;
31
import org.distorted.library.type.Static4D;
32

    
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

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

    
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

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

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

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

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

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  synchronized void sendZero() 
134
    {
135
    GLES20.glUniform1i( mNumEffectsH, 0);
136
    }
137
    
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139
// Do various post-processing on already computed effects.
140
// 1) move all Points and scale all Region radii by a ModelView matrix
141
// 2) in case of macroblock, pre-compute some values so that we don't have to do it in the fragment shader.
142
  
143
  void postprocess(float[] MVmatrix)
144
    {
145
    if( mNumEffects>0 )
146
      {
147
      float tx,ty;   
148
      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
149
      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.
150
   
151
      for(int i=0; i<mNumEffects; i++)
152
        {   
153
        tx = mBuf[4*i  ]-mObjHalfX; // we have to invert y and move everything by (half of bmp width, half of bmp height)
154
        ty =-mBuf[4*i+1]+mObjHalfY; //
155

    
156
        mUniforms[NUM_UNIFORMS*i+4] = 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.
157
        mUniforms[NUM_UNIFORMS*i+5] = MVmatrix[1]*tx + MVmatrix[5]*ty + MVmatrix[13]; //
158
        mUniforms[NUM_UNIFORMS*i+6] = w*mBuf[4*i+2];                                  // in fragment shader rx and ry radii are the last two values of the second vec4
159
        mUniforms[NUM_UNIFORMS*i+7] = h*mBuf[4*i+3];                                  //
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
// macroblock, alpha, brightness, contrast, saturation
172

    
173
  synchronized long add(EffectNames eln, Data1D data)
174
    {
175
    if( mMax[INDEX]>mNumEffects )
176
      {
177
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects); 
178

    
179
      if( data instanceof Dynamic1D)
180
        mInter[0][mNumEffects] = (Dynamic1D)data;
181
      else if( data instanceof Static1D )
182
        {
183
        mInter[0][mNumEffects] = null;
184
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)data).getX();
185
        }
186
      else return -1;
187

    
188
      mInter[1][mNumEffects] = null;
189
      mBuf[4*mNumEffects+2] = 1000*mObjHalfX;
190
      mBuf[4*mNumEffects+3] = 1000*mObjHalfY;
191

    
192
      return addBase(eln); 
193
      }
194
      
195
    return -1;
196
    }
197
  
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199
// macroblock, alpha, brightness, contrast, saturation
200

    
201
  synchronized long add(EffectNames eln, Data1D data, Data4D region)
202
    {
203
    if( mMax[INDEX]>mNumEffects )
204
      {
205
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
206

    
207
      if( data instanceof Dynamic1D)
208
        mInter[0][mNumEffects] = (Dynamic1D)data;
209
      else if( data instanceof Static1D )
210
        {
211
        mInter[0][mNumEffects] = null;
212
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)data).getX();
213
        }
214
      else return -1;
215

    
216
      if( region instanceof Dynamic4D)
217
        mInter[1][mNumEffects] = (Dynamic4D)region;
218
      else if( region instanceof Static4D )
219
        {
220
        mInter[1][mNumEffects]  = null;
221
        mBuf[4*mNumEffects  ] = ((Static4D)region).getX();
222
        mBuf[4*mNumEffects+1] = ((Static4D)region).getY();
223
        mBuf[4*mNumEffects+2] = ((Static4D)region).getZ();
224
        mBuf[4*mNumEffects+3] = ((Static4D)region).getW();
225
        }
226
      else return -1;
227

    
228
      return addBase(eln);
229
      }
230
      
231
    return -1;
232
    }
233
  
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235
// chroma
236

    
237
  synchronized long add(EffectNames eln, Data1D level, Static3D color, Data4D region)
238
    {
239
    if( mMax[INDEX]>mNumEffects )
240
      {
241
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
242

    
243
      if( level instanceof Dynamic1D)
244
        mInter[0][mNumEffects] = (Dynamic1D)level;
245
      else if( level instanceof Static1D )
246
        {
247
        mInter[0][mNumEffects] = null;
248
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)level).getX();
249
        }
250
      else return -1;
251

    
252
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = color.getX();
253
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = color.getY();
254
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = color.getZ();
255

    
256
      if( region instanceof Dynamic4D)
257
        mInter[1][mNumEffects] = (Dynamic4D)region;
258
      else if( region instanceof Static4D )
259
        {
260
        mInter[1][mNumEffects]  = null;
261
        mBuf[4*mNumEffects  ] = ((Static4D)region).getX();
262
        mBuf[4*mNumEffects+1] = ((Static4D)region).getY();
263
        mBuf[4*mNumEffects+2] = ((Static4D)region).getZ();
264
        mBuf[4*mNumEffects+3] = ((Static4D)region).getW();
265
        }
266
      else return -1;
267

    
268
      return addBase(eln); 
269
      }
270
      
271
    return -1;
272
    }
273
  
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275
// chroma
276

    
277
  synchronized long add(EffectNames eln, Data1D level, Static3D color)
278
    {
279
    if( mMax[INDEX]>mNumEffects )
280
      {
281
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
282

    
283
      if( level instanceof Dynamic1D)
284
        mInter[0][mNumEffects] = (Dynamic1D)level;
285
      else if( level instanceof Static1D )
286
        {
287
        mInter[0][mNumEffects] = null;
288
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)level).getX();
289
        }
290
      else return -1;
291

    
292
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = color.getX();
293
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = color.getY();
294
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = color.getZ();
295

    
296
      mInter[1][mNumEffects]  = null;          //
297
      mBuf[4*mNumEffects+2] = 1000*mObjHalfX;  // i.e. null region
298
      mBuf[4*mNumEffects+3] = 1000*mObjHalfY;  //
299

    
300
      return addBase(eln);
301
      }
302
       
303
    return -1;
304
    }
305
  
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307
// chroma
308

    
309
  synchronized long add(EffectNames eln, Data4D chroma, Data4D region)
310
    {
311
    if( mMax[INDEX]>mNumEffects )
312
      {
313
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
314

    
315
      if( chroma instanceof Dynamic4D)
316
        mInter[0][mNumEffects] = (Dynamic4D)chroma;
317
      else if( chroma instanceof Static4D )
318
        {
319
        mInter[0][mNumEffects] = null;
320
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static4D)chroma).getX();
321
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static4D)chroma).getY();
322
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static4D)chroma).getZ();
323
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static4D)chroma).getW();
324
        }
325
      else return -1;
326

    
327
      if( region instanceof Dynamic4D)
328
        mInter[1][mNumEffects] = (Dynamic4D)region;
329
      else if( region instanceof Static4D )
330
        {
331
        mInter[1][mNumEffects]  = null;
332
        mBuf[4*mNumEffects  ] = ((Static4D)region).getX();
333
        mBuf[4*mNumEffects+1] = ((Static4D)region).getY();
334
        mBuf[4*mNumEffects+2] = ((Static4D)region).getZ();
335
        mBuf[4*mNumEffects+3] = ((Static4D)region).getW();
336
        }
337
      else return -1;
338

    
339
      return addBase(eln); 
340
      }
341
      
342
    return -1;
343
    }
344
  
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346
// chroma
347

    
348
  synchronized long add(EffectNames eln, Data4D chroma)
349
    {
350
    if( mMax[INDEX]>mNumEffects )
351
      {
352
      EffectNames.fillWithUnities(eln.ordinal(), mUniforms, NUM_UNIFORMS*mNumEffects);
353

    
354
      if( chroma instanceof Dynamic4D)
355
        mInter[0][mNumEffects] = (Dynamic4D)chroma;
356
      else if( chroma instanceof Static4D )
357
        {
358
        mInter[0][mNumEffects] = null;
359
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static4D)chroma).getX();
360
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static4D)chroma).getY();
361
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static4D)chroma).getZ();
362
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static4D)chroma).getW();
363
        }
364
      else return -1;
365

    
366
      mInter[1][mNumEffects]  = null;          //
367
      mBuf[4*mNumEffects+2] = 1000*mObjHalfX;  // i.e. null region
368
      mBuf[4*mNumEffects+3] = 1000*mObjHalfY;  //
369

    
370
      return addBase(eln);
371
      }
372
      
373
    return -1;
374
    }
375
    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377
// end of FragmentEffect   
378
  }
(14-14/17)