Project

General

Profile

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

library / src / main / java / org / distorted / library / main / DistortedEffects.java @ 6bb59aad

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.main;
21

    
22
import android.content.res.Resources;
23
import android.opengl.GLES30;
24

    
25
import org.distorted.library.R;
26
import org.distorted.library.effect.Effect;
27
import org.distorted.library.message.EffectListener;
28
import org.distorted.library.program.DistortedProgram;
29
import org.distorted.library.program.FragmentCompilationException;
30
import org.distorted.library.program.FragmentUniformsException;
31
import org.distorted.library.program.LinkingException;
32
import org.distorted.library.program.VertexCompilationException;
33
import org.distorted.library.program.VertexUniformsException;
34

    
35
import java.io.InputStream;
36
import java.nio.ByteBuffer;
37
import java.nio.ByteOrder;
38
import java.nio.FloatBuffer;
39
import java.util.ArrayList;
40

    
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42
/**
43
 * Class containing Matrix,Vertex and Fragment effect queues. Postprocessing queue is held in a separate
44
 * class.
45
 * <p>
46
 * The queues hold actual effects to be applied to a given (DistortedTexture,MeshObject) combo.
47
 */
48
public class DistortedEffects
49
  {
50
  /// MAIN PROGRAM ///
51
  private static DistortedProgram mMainProgram;
52
  private static int mMainTextureH;
53
  private static ArrayList<Effect> mEnabledEffects = new ArrayList<>();
54

    
55
  /// BLIT PROGRAM ///
56
  private static DistortedProgram mBlitProgram;
57
  private static int mBlitTextureH;
58
  private static int mBlitDepthH;
59
  private static final FloatBuffer mQuadPositions;
60

    
61
  static
62
    {
63
    float[] positionData= { -0.5f, -0.5f,  -0.5f, 0.5f,  0.5f,-0.5f,  0.5f, 0.5f };
64
    mQuadPositions = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder()).asFloatBuffer();
65
    mQuadPositions.put(positionData).position(0);
66
    }
67

    
68
  /// BLIT DEPTH PROGRAM ///
69
  private static DistortedProgram mBlitDepthProgram;
70
  private static int mBlitDepthTextureH;
71
  private static int mBlitDepthDepthTextureH;
72
  private static int mBlitDepthDepthH;
73

    
74
  /// NORMAL PROGRAM /////
75
  private static DistortedProgram mNormalProgram;
76
  private static int mNormalMVPMatrixH;
77
  /// END PROGRAMS //////
78

    
79
  private static long mNextID =0;
80
  private long mID;
81

    
82
  private EffectQueueMatrix mM;
83
  private EffectQueueFragment mF;
84
  private EffectQueueVertex mV;
85

    
86
  private boolean matrixCloned, vertexCloned, fragmentCloned;
87

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

    
90
  static void createProgram(Resources resources)
91
  throws FragmentCompilationException,VertexCompilationException,VertexUniformsException,FragmentUniformsException,LinkingException
92
    {
93
    // MAIN PROGRAM ////////////////////////////////////
94
    final InputStream mainVertStream = resources.openRawResource(R.raw.main_vertex_shader);
95
    final InputStream mainFragStream = resources.openRawResource(R.raw.main_fragment_shader);
96

    
97
    String mainVertHeader= Distorted.GLSL_VERSION;
98
    String mainFragHeader= Distorted.GLSL_VERSION;
99

    
100
    boolean foundF = false;
101
    boolean foundV = false;
102
    int type, effects = mEnabledEffects.size();
103
    Effect effect;
104

    
105
    for(int i=0; i<effects; i++)
106
      {
107
      effect = mEnabledEffects.remove(0);
108
      type   = effect.getType();
109

    
110
      if( type == Effect.VERTEX )
111
        {
112
        mainVertHeader += ("#define "+effect.getString()+" "+effect.getName()+"\n");
113
        foundV = true;
114
        }
115
      else if( type == Effect.FRAGMENT )
116
        {
117
        mainFragHeader += ("#define "+effect.getString()+" "+effect.getName()+"\n");
118
        foundF = true;
119
        }
120
      }
121

    
122
    mainVertHeader += ("#define NUM_VERTEX "   + ( foundV ? getMaxVertex()   : 0 ) + "\n");
123
    mainFragHeader += ("#define NUM_FRAGMENT " + ( foundF ? getMaxFragment() : 0 ) + "\n");
124

    
125
    //android.util.Log.e("Effects", "vertHeader= "+mainVertHeader);
126
    //android.util.Log.e("Effects", "fragHeader= "+mainFragHeader);
127

    
128
    String[] feedback = { "v_Position", "v_endPosition" };
129

    
130
    mMainProgram = new DistortedProgram(mainVertStream,mainFragStream, mainVertHeader, mainFragHeader, Distorted.GLSL, feedback);
131

    
132
    int mainProgramH = mMainProgram.getProgramHandle();
133
    EffectQueueFragment.getUniforms(mainProgramH);
134
    EffectQueueVertex.getUniforms(mainProgramH);
135
    EffectQueueMatrix.getUniforms(mainProgramH);
136
    mMainTextureH= GLES30.glGetUniformLocation( mainProgramH, "u_Texture");
137

    
138
    // BLIT PROGRAM ////////////////////////////////////
139
    final InputStream blitVertStream = resources.openRawResource(R.raw.blit_vertex_shader);
140
    final InputStream blitFragStream = resources.openRawResource(R.raw.blit_fragment_shader);
141

    
142
    String blitVertHeader= (Distorted.GLSL_VERSION + "#define NUM_VERTEX 0\n"  );
143
    String blitFragHeader= (Distorted.GLSL_VERSION + "#define NUM_FRAGMENT 0\n");
144

    
145
    try
146
      {
147
      mBlitProgram = new DistortedProgram(blitVertStream,blitFragStream,blitVertHeader,blitFragHeader, Distorted.GLSL);
148
      }
149
    catch(Exception e)
150
      {
151
      android.util.Log.e("EFFECTS", "exception trying to compile BLIT program: "+e.getMessage());
152
      throw new RuntimeException(e.getMessage());
153
      }
154

    
155
    int blitProgramH = mBlitProgram.getProgramHandle();
156
    mBlitTextureH  = GLES30.glGetUniformLocation( blitProgramH, "u_Texture");
157
    mBlitDepthH    = GLES30.glGetUniformLocation( blitProgramH, "u_Depth");
158

    
159
    // BLIT DEPTH PROGRAM ////////////////////////////////////
160
    final InputStream blitDepthVertStream = resources.openRawResource(R.raw.blit_depth_vertex_shader);
161
    final InputStream blitDepthFragStream = resources.openRawResource(R.raw.blit_depth_fragment_shader);
162

    
163
    try
164
      {
165
      mBlitDepthProgram = new DistortedProgram(blitDepthVertStream,blitDepthFragStream,blitVertHeader,blitFragHeader, Distorted.GLSL);
166
      }
167
    catch(Exception e)
168
      {
169
      android.util.Log.e("EFFECTS", "exception trying to compile BLIT DEPTH program: "+e.getMessage());
170
      throw new RuntimeException(e.getMessage());
171
      }
172

    
173
    int blitDepthProgramH   = mBlitDepthProgram.getProgramHandle();
174
    mBlitDepthTextureH      = GLES30.glGetUniformLocation( blitDepthProgramH, "u_Texture");
175
    mBlitDepthDepthTextureH = GLES30.glGetUniformLocation( blitDepthProgramH, "u_DepthTexture");
176
    mBlitDepthDepthH        = GLES30.glGetUniformLocation( blitDepthProgramH, "u_Depth");
177

    
178
    // NORMAL PROGRAM //////////////////////////////////////
179
    final InputStream normalVertexStream   = resources.openRawResource(R.raw.normal_vertex_shader);
180
    final InputStream normalFragmentStream = resources.openRawResource(R.raw.normal_fragment_shader);
181

    
182
    try
183
      {
184
      mNormalProgram = new DistortedProgram(normalVertexStream,normalFragmentStream, Distorted.GLSL_VERSION, Distorted.GLSL_VERSION, Distorted.GLSL);
185
      }
186
    catch(Exception e)
187
      {
188
      android.util.Log.e("EFFECTS", "exception trying to compile NORMAL program: "+e.getMessage());
189
      throw new RuntimeException(e.getMessage());
190
      }
191

    
192
    int normalProgramH = mNormalProgram.getProgramHandle();
193
    mNormalMVPMatrixH  = GLES30.glGetUniformLocation( normalProgramH, "u_MVPMatrix");
194
    }
195

    
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197

    
198
  private void initializeEffectLists(DistortedEffects d, int flags)
199
    {
200
    if( (flags & Distorted.CLONE_MATRIX) != 0 )
201
      {
202
      mM = d.mM;
203
      matrixCloned = true;
204
      }
205
    else
206
      {
207
      mM = new EffectQueueMatrix(mID);
208
      matrixCloned = false;
209
      }
210
    
211
    if( (flags & Distorted.CLONE_VERTEX) != 0 )
212
      {
213
      mV = d.mV;
214
      vertexCloned = true;
215
      }
216
    else
217
      {
218
      mV = new EffectQueueVertex(mID);
219
      vertexCloned = false;
220
      }
221
    
222
    if( (flags & Distorted.CLONE_FRAGMENT) != 0 )
223
      {
224
      mF = d.mF;
225
      fragmentCloned = true;
226
      }
227
    else
228
      {
229
      mF = new EffectQueueFragment(mID);
230
      fragmentCloned = false;
231
      }
232
    }
233

    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

    
236
  private void displayNormals(MeshObject mesh)
237
    {
238
    GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mAttTFO[0]);
239
    GLES30.glBeginTransformFeedback( GLES30.GL_POINTS);
240
    DistortedRenderState.switchOffDrawing();
241
    GLES30.glDrawArrays( GLES30.GL_POINTS, 0, mesh.numVertices);
242
    DistortedRenderState.restoreDrawing();
243
    GLES30.glEndTransformFeedback();
244
    GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
245

    
246
    mNormalProgram.useProgram();
247
    GLES30.glUniformMatrix4fv(mNormalMVPMatrixH, 1, false, mM.getMVP() , 0);
248
    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mAttTFO[0]);
249
    GLES30.glVertexAttribPointer(mNormalProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, 0);
250
    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
251
    GLES30.glLineWidth(8.0f);
252
    GLES30.glDrawArrays(GLES30.GL_LINES, 0, 2*mesh.numVertices);
253
    }
254

    
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256

    
257
  void drawPriv(float halfW, float halfH, MeshObject mesh, DistortedOutputSurface surface, long currTime, float marginInPixels)
258
    {
259
    mM.compute(currTime);
260
    mV.compute(currTime);
261
    mF.compute(currTime);
262

    
263
    float halfZ = halfW*mesh.zFactor;
264

    
265
    GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
266

    
267
    mMainProgram.useProgram();
268
    GLES30.glUniform1i(mMainTextureH, 0);
269

    
270
    if( Distorted.GLSL >= 300 )
271
      {
272
      GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mAttVBO[0]);
273
      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET0);
274
      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET1);
275
      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET2);
276
      GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
277
      }
278
    else
279
      {
280
      mesh.mVertAttribs.position(0);
281
      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
282
      mesh.mVertAttribs.position(MeshObject.POS_DATA_SIZE);
283
      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
284
      mesh.mVertAttribs.position(MeshObject.POS_DATA_SIZE+MeshObject.NOR_DATA_SIZE);
285
      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
286
      }
287

    
288
    mM.send(surface,halfW,halfH,halfZ,marginInPixels);
289
    mV.send(halfW,halfH,halfZ);
290
    mF.send(halfW,halfH);
291

    
292
    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.numVertices);
293

    
294
    if( mesh.mShowNormals ) displayNormals(mesh);
295
    }
296

    
297
///////////////////////////////////////////////////////////////////////////////////////////////////
298
   
299
  static void blitPriv(DistortedOutputSurface surface)
300
    {
301
    mBlitProgram.useProgram();
302

    
303
    GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
304
    GLES30.glUniform1i(mBlitTextureH, 0);
305
    GLES30.glUniform1f( mBlitDepthH , 1.0f-surface.mNear);
306
    GLES30.glVertexAttribPointer(mBlitProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions);
307
    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
308
    }
309

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

    
312
  static void blitDepthPriv(DistortedOutputSurface surface)
313
    {
314
    mBlitDepthProgram.useProgram();
315

    
316
    GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
317
    GLES30.glUniform1i(mBlitDepthTextureH, 0);
318
    GLES30.glUniform1i(mBlitDepthDepthTextureH, 1);
319
    GLES30.glUniform1f( mBlitDepthDepthH , 1.0f-surface.mNear);
320
    GLES30.glVertexAttribPointer(mBlitDepthProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions);
321
    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325
   
326
  private void releasePriv()
327
    {
328
    if( !matrixCloned   ) mM.abortAll(false);
329
    if( !vertexCloned   ) mV.abortAll(false);
330
    if( !fragmentCloned ) mF.abortAll(false);
331

    
332
    mM = null;
333
    mV = null;
334
    mF = null;
335
    }
336

    
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338

    
339
  static void onDestroy()
340
    {
341
    mNextID = 0;
342
    }
343

    
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345
// PUBLIC API
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347
/**
348
 * Create empty effect queue.
349
 */
350
  public DistortedEffects()
351
    {
352
    mID = ++mNextID;
353
    initializeEffectLists(this,0);
354
    }
355

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357
/**
358
 * Copy constructor.
359
 * <p>
360
 * Whatever we do not clone gets created just like in the default constructor.
361
 *
362
 * @param dc    Source object to create our object from
363
 * @param flags A bitmask of values specifying what to copy.
364
 *              For example, CLONE_VERTEX | CLONE_MATRIX.
365
 */
366
  public DistortedEffects(DistortedEffects dc, int flags)
367
    {
368
    mID = ++mNextID;
369
    initializeEffectLists(dc,flags);
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373
/**
374
 * Releases all resources. After this call, the queue should not be used anymore.
375
 */
376
  @SuppressWarnings("unused")
377
  public synchronized void delete()
378
    {
379
    releasePriv();
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383
/**
384
 * Returns unique ID of this instance.
385
 *
386
 * @return ID of the object.
387
 */
388
  public long getID()
389
      {
390
      return mID;
391
      }
392

    
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394
/**
395
 * Adds the calling class to the list of Listeners that get notified each time some event happens 
396
 * to one of the Effects in those queues. Nothing will happen if 'el' is already in the list.
397
 * 
398
 * @param el A class implementing the EffectListener interface that wants to get notifications.
399
 */
400
  @SuppressWarnings("unused")
401
  public void registerForMessages(EffectListener el)
402
    {
403
    mV.registerForMessages(el);
404
    mF.registerForMessages(el);
405
    mM.registerForMessages(el);
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409
/**
410
 * Removes the calling class from the list of Listeners.
411
 * 
412
 * @param el A class implementing the EffectListener interface that no longer wants to get notifications.
413
 */
414
  @SuppressWarnings("unused")
415
  public void deregisterForMessages(EffectListener el)
416
    {
417
    mV.deregisterForMessages(el);
418
    mF.deregisterForMessages(el);
419
    mM.deregisterForMessages(el);
420
    }
421

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423
/**
424
 * Aborts all Effects.
425
 * @return Number of effects aborted.
426
 */
427
  public int abortAllEffects()
428
    {
429
    return mM.abortAll(true) + mV.abortAll(true) + mF.abortAll(true);
430
    }
431

    
432
///////////////////////////////////////////////////////////////////////////////////////////////////
433
/**
434
 * Aborts all Effects of a given type, for example all MATRIX Effects.
435
 * 
436
 * @param type one of the constants defined in {@link Effect}
437
 * @return Number of effects aborted.
438
 */
439
  public int abortByType(int type)
440
    {
441
    switch(type)
442
      {
443
      case Effect.MATRIX     : return mM.abortAll(true);
444
      case Effect.VERTEX     : return mV.abortAll(true);
445
      case Effect.FRAGMENT   : return mF.abortAll(true);
446
  //  case Effect.POSTPROCESS: return mP.abortAll(true);
447
      default                : return 0;
448
      }
449
    }
450
    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452
/**
453
 * Aborts a single Effect.
454
 * 
455
 * @param effect the Effect we want to abort.
456
 * @return number of Effects aborted. Always either 0 or 1.
457
 */
458
  public int abortEffect(Effect effect)
459
    {
460
    switch(effect.getType())
461
      {
462
      case Effect.MATRIX     : return mM.removeEffect(effect);
463
      case Effect.VERTEX     : return mV.removeEffect(effect);
464
      case Effect.FRAGMENT   : return mF.removeEffect(effect);
465
  //  case Effect.POSTPROCESS: return mP.removeEffect(effect);
466
      default                : return 0;
467
      }
468
    }
469

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471
/**
472
 * Abort all Effects of a given name, for example all rotations.
473
 * 
474
 * @param name one of the constants defined in
475
 *             {@link org.distorted.library.effect.MatrixEffect},
476
 *             {@link org.distorted.library.effect.VertexEffect},
477
 *             {@link org.distorted.library.effect.FragmentEffect} or
478
 *             {@link org.distorted.library.effect.PostprocessEffect}
479
 * @return number of Effects aborted.
480
 */
481
  public int abortByName(int name)
482
    {
483
    switch(Effect.getType(name))
484
      {
485
      case Effect.MATRIX     : return mM.removeByName(name);
486
      case Effect.VERTEX     : return mV.removeByName(name);
487
      case Effect.FRAGMENT   : return mF.removeByName(name);
488
  //  case Effect.POSTPROCESS: return mP.removeByName(name);
489
      default                : return 0;
490
      }
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494
/**
495
 * Enables a given Effect.
496
 * <p>
497
 * By default, all effects are disabled. One has to explicitly enable each effect one intends to use.
498
 * This needs to be called BEFORE shaders get compiled, i.e. before the call to Distorted.onCreate().
499
 * The point: by enabling only the effects we need, we can optimize the shaders.
500
 *
501
 * @param name one of the constants defined in
502
 *             {@link org.distorted.library.effect.MatrixEffect},
503
 *             {@link org.distorted.library.effect.VertexEffect},
504
 *             {@link org.distorted.library.effect.FragmentEffect} or
505
 *             {@link org.distorted.library.effect.PostprocessEffect}
506
 */
507
  public static void enableEffect(int name)
508
    {
509
    mEffectEnabled[name] = true;
510
    }
511

    
512
///////////////////////////////////////////////////////////////////////////////////////////////////
513
/**
514
 * Returns the maximum number of Matrix effects.
515
 *
516
 * @return The maximum number of Matrix effects
517
 */
518
  @SuppressWarnings("unused")
519
  public static int getMaxMatrix()
520
    {
521
    return EffectQueue.getMax(Effect.MATRIX);
522
    }
523

    
524
///////////////////////////////////////////////////////////////////////////////////////////////////
525
/**
526
 * Returns the maximum number of Vertex effects.
527
 *
528
 * @return The maximum number of Vertex effects
529
 */
530
  @SuppressWarnings("unused")
531
  public static int getMaxVertex()
532
    {
533
    return EffectQueue.getMax(Effect.VERTEX);
534
    }
535

    
536
///////////////////////////////////////////////////////////////////////////////////////////////////
537
/**
538
 * Returns the maximum number of Fragment effects.
539
 *
540
 * @return The maximum number of Fragment effects
541
 */
542
  @SuppressWarnings("unused")
543
  public static int getMaxFragment()
544
    {
545
    return EffectQueue.getMax(Effect.FRAGMENT);
546
    }
547

    
548
///////////////////////////////////////////////////////////////////////////////////////////////////
549
/**
550
 * Sets the maximum number of Matrix effects that can be stored in a single EffectQueue at one time.
551
 * This can fail if:
552
 * <ul>
553
 * <li>the value of 'max' is outside permitted range (0 &le; max &le; Byte.MAX_VALUE)
554
 * <li>We try to increase the value of 'max' when it is too late to do so already. It needs to be called
555
 *     before the Vertex Shader gets compiled, i.e. before the call to {@link Distorted#onCreate}. After this
556
 *     time only decreasing the value of 'max' is permitted.
557
 * <li>Furthermore, this needs to be called before any instances of the DistortedEffects class get created.
558
 * </ul>
559
 *
560
 * @param max new maximum number of simultaneous Matrix Effects. Has to be a non-negative number not greater
561
 *            than Byte.MAX_VALUE
562
 * @return <code>true</code> if operation was successful, <code>false</code> otherwise.
563
 */
564
  @SuppressWarnings("unused")
565
  public static boolean setMaxMatrix(int max)
566
    {
567
    return EffectQueue.setMax(Effect.MATRIX,max);
568
    }
569

    
570
///////////////////////////////////////////////////////////////////////////////////////////////////
571
/**
572
 * Sets the maximum number of Vertex effects that can be stored in a single EffectQueue at one time.
573
 * This can fail if:
574
 * <ul>
575
 * <li>the value of 'max' is outside permitted range (0 &le; max &le; Byte.MAX_VALUE)
576
 * <li>We try to increase the value of 'max' when it is too late to do so already. It needs to be called
577
 *     before the Vertex Shader gets compiled, i.e. before the call to {@link Distorted#onCreate}. After this
578
 *     time only decreasing the value of 'max' is permitted.
579
* <li>Furthermore, this needs to be called before any instances of the DistortedEffects class get created.
580
 * </ul>
581
 *
582
 * @param max new maximum number of simultaneous Vertex Effects. Has to be a non-negative number not greater
583
 *            than Byte.MAX_VALUE
584
 * @return <code>true</code> if operation was successful, <code>false</code> otherwise.
585
 */
586
  @SuppressWarnings("unused")
587
  public static boolean setMaxVertex(int max)
588
    {
589
    return EffectQueue.setMax(Effect.VERTEX,max);
590
    }
591

    
592
///////////////////////////////////////////////////////////////////////////////////////////////////
593
/**
594
 * Sets the maximum number of Fragment effects that can be stored in a single EffectQueue at one time.
595
 * This can fail if:
596
 * <ul>
597
 * <li>the value of 'max' is outside permitted range (0 &le; max &le; Byte.MAX_VALUE)
598
 * <li>We try to increase the value of 'max' when it is too late to do so already. It needs to be called
599
 *     before the Fragment Shader gets compiled, i.e. before the call to {@link Distorted#onCreate}. After this
600
 *     time only decreasing the value of 'max' is permitted.
601
 * <li>Furthermore, this needs to be called before any instances of the DistortedEffects class get created.
602
 * </ul>
603
 *
604
 * @param max new maximum number of simultaneous Fragment Effects. Has to be a non-negative number not greater
605
 *            than Byte.MAX_VALUE
606
 * @return <code>true</code> if operation was successful, <code>false</code> otherwise.
607
 */
608
  @SuppressWarnings("unused")
609
  public static boolean setMaxFragment(int max)
610
    {
611
    return EffectQueue.setMax(Effect.FRAGMENT,max);
612
    }
613

    
614
///////////////////////////////////////////////////////////////////////////////////////////////////
615
/**
616
 * Add a new Effect to our queue.
617
 *
618
 * @param effect The Effect to add.
619
 */
620
  public void apply(Effect effect)
621
    {
622
    switch(effect.getType())
623
      {
624
      case Effect.VERTEX      : mV.add(effect); break;
625
      case Effect.FRAGMENT    : mF.add(effect); break;
626
      case Effect.MATRIX      : mM.add(effect); break;
627
   // case Effect.POSTPROCESS : mP.add(effect); break;
628
      }
629
    }
630
  }
(2-2/24)