Project

General

Profile

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

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

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

    
93
      if( mInter[1][i]!=null ) mInter[1][i].interpolateMain(mBuf, 4*i, mCurrentDuration[i]);
94

    
95
      mCurrentDuration[i] += step;
96
      }
97
   
98
    mTime = currTime;  
99
    }
100

    
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

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

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

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

    
154
        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.
155
        mUniforms[NUM_UNIFORMS*i+5] = MVmatrix[1]*tx + MVmatrix[5]*ty + MVmatrix[13]; //
156
        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
157
        mUniforms[NUM_UNIFORMS*i+7] = h*mBuf[4*i+3];                                  //
158

    
159
        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
160
          {
161
          mUniforms[NUM_UNIFORMS*i+1] = 2.0f*mObjHalfX/mUniforms[NUM_UNIFORMS*i];
162
          mUniforms[NUM_UNIFORMS*i+2] = 2.0f*mObjHalfY/mUniforms[NUM_UNIFORMS*i];
163
          }
164
        }
165
      }
166
    }
167
  
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169
// macroblock, alpha, brightness, contrast, saturation
170

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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