Project

General

Profile

« Previous | Next » 

Revision 9ae0853e

Added by Leszek Koltunski 2 months ago

transition the 'effectqueue' package.

View differences:

src/main/java/org/distorted/library/effectqueue/EffectQueue.kt
18 18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19 19
///////////////////////////////////////////////////////////////////////////////////////////////////
20 20

  
21
package org.distorted.library.effectqueue;
22

  
23
import org.distorted.library.effect.Effect;
24
import org.distorted.library.effect.EffectName;
25
import org.distorted.library.effect.EffectType;
26
import org.distorted.library.main.DistortedLibrary;
27
import org.distorted.library.main.InternalMaster;
28
import org.distorted.library.main.InternalStackFrameList;
29
import org.distorted.library.uniformblock.UniformBlockFloatUniforms;
30
import org.distorted.library.uniformblock.UniformBlockIntUniforms;
31

  
32
import java.util.ArrayList;
33
import java.util.HashMap;
21
package org.distorted.library.effectqueue
22

  
23
import org.distorted.library.effect.Effect
24
import org.distorted.library.effect.EffectName
25
import org.distorted.library.effect.EffectType
26
import org.distorted.library.main.DistortedLibrary
27
import org.distorted.library.main.InternalMaster
28
import org.distorted.library.main.InternalMaster.Slave
29
import org.distorted.library.main.InternalStackFrameList
30
import org.distorted.library.uniformblock.UniformBlockFloatUniforms
31
import org.distorted.library.uniformblock.UniformBlockIntUniforms
32
import kotlin.math.max
34 33

  
35 34
///////////////////////////////////////////////////////////////////////////////////////////////////
36
/**
37
 * Not part of public API, do not document
38
 *
39
 * @y.exclude
40
 */
41
public abstract class EffectQueue implements InternalMaster.Slave
42
  {
43
  public static final int MAIN_VARIANTS = 4; // Number of Main program variants (ATM 4: MAIN, MAIN OIT, PREPROCESS, FULL)
44

  
45
  static final int VERT_INT_UBO_BINDING = 5;
46
  static final int VERT_FLO_UBO_BINDING = 6;
47

  
48
  private static final int CREATE = 0;
49
  private static final int ATTACH = 1;
50
  private static final int DETACH = 2;
51
  private static final int DETALL = 3;
52

  
53
  int mNumEffects;              // 'ToBe' will be more than mNumEffects if doWork() hasn't
54
  private int mNumEffectsToBe;  // added them yet (or less if it hasn't removed some yet)
55
  Effect[] mEffects;
56

  
57
  UniformBlockFloatUniforms mUBF;
58
  UniformBlockIntUniforms mUBI;
59

  
60
  private long mID;
61
  private final int mIndex;
62
  private boolean mCreated;
63

  
64
  private static class Job
35
/** Not part of public API, do not document
36
*
37
* @y.exclude
38
*/
39
abstract class EffectQueue : Slave
40
{
41
    ///////////////////////////////////////////////////////////////////////////////////////////////
42
    var numEffects: Int = 0     // 'ToBe' will be more than mNumEffects if doWork() hasn't
43
    var numEffectsToBe: Int = 0 // added them yet (or less if it hasn't removed some yet)
44
        private set
45
    var mEffects: Array<Effect?>
46
    var mUBF: UniformBlockFloatUniforms? = null
47
    var mUBI: UniformBlockIntUniforms? = null
48
    var iD: Long = 0
49
        private set
50
    private val mIndex: Int
51
    private var mCreated = false
52

  
53
    private class Job(var type: Int, var num1: Int, var num2: Int, var bool: Boolean, e: Effect?)
65 54
    {
66
    int type;
67
    int num1, num2;
68
    boolean bool;
69
    Effect effect;
70

  
71
    Job(int t, int m1, int m2, boolean n, Effect e)
72
      {
73
      type  = t;
74
      num1  = m1;
75
      num2  = m2;
76
      bool  = n;
77
      effect= e;
78
      }
55
        var effect: Effect = e!!
79 56
    }
80 57

  
81
  private final ArrayList<Job> mJobs;
58
    private val mJobs: ArrayList<Job>
82 59

  
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84
   
85
  EffectQueue(int numFloatUniforms, int numIntUniforms, boolean useUBO, int index)
60
    companion object
86 61
    {
87
    mCreated        = false;
88
    mID             = 0;
89
    mNumEffects     = 0;
90
    mNumEffectsToBe = 0;
91
    mIndex          = index;
92

  
93
    mJobs = new ArrayList<>();
62
        const val MAIN_VARIANTS: Int = 4 // Number of Main program variants (ATM 4: MAIN, MAIN OIT, PREPROCESS, FULL)
63
        const val VERT_INT_UBO_BINDING: Int = 5
64
        const val VERT_FLO_UBO_BINDING: Int = 6
94 65

  
95
    mJobs.add(new Job(CREATE,numFloatUniforms,numIntUniforms,useUBO,null)); // create the stuff that depends on max number
96
    InternalMaster.newSlave(this);                                          // of uniforms later, on first render.
97
    }
98

  
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100
// this is not thread safe! The 'source' might change while we're copying it.
66
        private const val CREATE = 0
67
        private const val ATTACH = 1
68
        private const val DETACH = 2
69
        private const val DETALL = 3
101 70

  
102
  EffectQueue(EffectQueue source)
103
    {
104
    if( !source.mCreated )
105
      {
106
      mCreated        = false;
107
      mID             = 0;
108
      mNumEffects     = 0;
109
      mNumEffectsToBe = 0;
110
      mIndex          = source.mIndex;
111

  
112
      mJobs = new ArrayList<>();
113

  
114
      int numJobs = source.mJobs.size();
71
        ///////////////////////////////////////////////////////////////////////////////////////////
72
        fun allocateQueues(queues: Array<EffectQueue?>, from: Array<EffectQueue?>, flags: Int)
73
        {
74
            queues[0] = if ((flags and DistortedLibrary.CLONE_MATRIX     ) != 0) from[0] else EffectQueueMatrix()
75
            queues[1] = if ((flags and DistortedLibrary.CLONE_VERTEX     ) != 0) from[1] else EffectQueueVertex()
76
            queues[2] = if ((flags and DistortedLibrary.CLONE_FRAGMENT   ) != 0) from[2] else EffectQueueFragment()
77
            queues[3] = if ((flags and DistortedLibrary.CLONE_POSTPROCESS) != 0) from[3] else EffectQueuePostprocess()
78
        }
115 79

  
116
      for(int i=0; i<numJobs; i++)
80
        ///////////////////////////////////////////////////////////////////////////////////////////
81
        fun compute(queues: Array<EffectQueue>, currTime: Long, step: Long)
117 82
        {
118
        Job job = source.mJobs.get(i);
119
        mJobs.add(job);
83
            (queues[0] as EffectQueueMatrix     ).compute(currTime, step)
84
            (queues[1] as EffectQueueVertex     ).compute(currTime, step)
85
            (queues[2] as EffectQueueFragment   ).compute(currTime, step)
86
            (queues[3] as EffectQueuePostprocess).compute(currTime, step)
120 87
        }
121 88

  
122
      InternalMaster.newSlave(this);
123
      }
124
    else
125
      {
126
      mCreated        = true;
127
      mID             = source.mID;
128
      mNumEffects     = source.mNumEffects;
129
      mNumEffectsToBe = source.mNumEffectsToBe;
130
      mIndex          = source.mIndex;
89
        ///////////////////////////////////////////////////////////////////////////////////////////
90
        fun send(queues: Array<EffectQueue>, programH: Int, distance: Float, mipmap: Float,
91
                 projection: FloatArray, inflate: Float, variant: Int)
92
        {
93
            (queues[0] as EffectQueueMatrix  ).send(distance, mipmap, projection, variant)
94
            (queues[1] as EffectQueueVertex  ).send(inflate, programH, variant)
95
            (queues[2] as EffectQueueFragment).send(variant)
96
        }
131 97

  
132
      mJobs = new ArrayList<>();
98
        ///////////////////////////////////////////////////////////////////////////////////////////
99
        // variant: 0 --> MAIN  1 --> OIT  2 --> prePOST  3 --> FULL
100
        @JvmStatic
101
        fun getUniforms(programH: Int, variant: Int)
102
        {
103
            EffectQueueFragment.uniforms(programH, variant)
104
            EffectQueueVertex  .uniforms(programH, variant)
105
            EffectQueueMatrix  .uniforms(programH, variant)
106
        }
133 107

  
134
      int max = InternalStackFrameList.getMax(mIndex);
108
        ///////////////////////////////////////////////////////////////////////////////////////////
109
        @JvmStatic
110
        fun setMax(index: Int, m: Int): Boolean
111
        {
112
            return InternalStackFrameList.setMax(index, max(m,0) )
113
        }
135 114

  
136
      if( max>0 )
115
        ///////////////////////////////////////////////////////////////////////////////////////////
116
        @JvmStatic
117
        fun getMax(index: Int): Int
137 118
        {
138
        mEffects= new Effect[max];
139
        mUBI  = new UniformBlockIntUniforms(source.mUBI);
140
        mUBF  = new UniformBlockFloatUniforms(source.mUBF);
141

  
142
        if( mNumEffects>=0 )
143
          {
144
          System.arraycopy(source.mEffects, 0, mEffects, 0, mNumEffects);
145
          }
119
            return InternalStackFrameList.getMax(index)
146 120
        }
147
      }
148 121
    }
149 122

  
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151

  
152
  public static void allocateQueues(EffectQueue[] queues, EffectQueue[] from, int flags)
123
    ///////////////////////////////////////////////////////////////////////////////////////////////
124
    internal constructor(numFloatUniforms: Int, numIntUniforms: Int, useUBO: Boolean, index: Int)
153 125
    {
154
    queues[0] = (flags & DistortedLibrary.CLONE_MATRIX     ) != 0 ? from[0] : new EffectQueueMatrix();
155
    queues[1] = (flags & DistortedLibrary.CLONE_VERTEX     ) != 0 ? from[1] : new EffectQueueVertex();
156
    queues[2] = (flags & DistortedLibrary.CLONE_FRAGMENT   ) != 0 ? from[2] : new EffectQueueFragment();
157
    queues[3] = (flags & DistortedLibrary.CLONE_POSTPROCESS) != 0 ? from[3] : new EffectQueuePostprocess();
158
    }
126
        mCreated       = false
127
        iD             = 0
128
        numEffects     = 0
129
        numEffectsToBe = 0
130
        mIndex         = index
159 131

  
160
///////////////////////////////////////////////////////////////////////////////////////////////////
132
        mJobs = ArrayList()
161 133

  
162
  public static void compute(EffectQueue[] queues, long currTime, long step)
163
    {
164
    ((EffectQueueMatrix     )queues[0]).compute(currTime,step);
165
    ((EffectQueueVertex     )queues[1]).compute(currTime,step);
166
    ((EffectQueueFragment   )queues[2]).compute(currTime,step);
167
    ((EffectQueuePostprocess)queues[3]).compute(currTime,step);
134
        mJobs.add( Job(CREATE,numFloatUniforms,numIntUniforms,useUBO,null) ) // create the stuff that depends on max number
135
        InternalMaster.newSlave(this)                                        // of uniforms later, on first render.
168 136
    }
169 137

  
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

  
172
  public static void send(EffectQueue[] queues, int programH, float distance, float mipmap,
173
                          float[] projection, float inflate, int variant )
138
    ///////////////////////////////////////////////////////////////////////////////////////////////
139
    // this is not thread safe! The 'source' might change while we're copying it.
140
    internal constructor(source: EffectQueue)
174 141
    {
175
    ((EffectQueueMatrix  )queues[0]).send(distance, mipmap, projection, variant);
176
    ((EffectQueueVertex  )queues[1]).send(inflate, programH, variant);
177
    ((EffectQueueFragment)queues[2]).send(variant);
178
    }
142
        if (!source.mCreated)
143
        {
144
            mCreated       = false
145
            iD             = 0
146
            numEffects     = 0
147
            numEffectsToBe = 0
148
            mIndex         = source.mIndex
179 149

  
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181
// variant: 0 --> MAIN  1 --> OIT  2 --> prePOST  3 --> FULL
150
            mJobs = ArrayList()
182 151

  
183
  public static void getUniforms(int programH, int variant)
184
    {
185
    EffectQueueFragment.uniforms(programH,variant);
186
    EffectQueueVertex  .uniforms(programH,variant);
187
    EffectQueueMatrix  .uniforms(programH,variant);
188
    }
152
            val numJobs = source.mJobs.size
189 153

  
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191
// Every effect queue has an ID, which should be the same iff two queues hold the same effects.
192
// (this is a speedup: then both queues can be applied once, which seriously speeds up stuff -
193
// especially important in case of postprocessing)
154
            for (i in 0..<numJobs)
155
            {
156
                val job = source.mJobs[i]
157
                mJobs.add(job)
158
            }
194 159

  
195
  private void regenerateID()
196
    {
197
    if( mNumEffects>0 )
198
      {
199
      HashMap<ArrayList<Long>,Long> map = InternalStackFrameList.getMap();
200
      ArrayList<Long> list = new ArrayList<>();
201
      for (int i=0; i<mNumEffects; i++) list.add(mEffects[i].getID());
202
      Long id = map.get(list);
203

  
204
      if( id!=null )
205
        {
206
        mID = id;
160
            InternalMaster.newSlave(this)
207 161
        }
208
      else
162
        else
209 163
        {
210
        mID = InternalStackFrameList.getNextQueueID();
211
        map.put(list,mID);
164
            mCreated       = true
165
            iD             = source.iD
166
            numEffects     = source.numEffects
167
            numEffectsToBe = source.numEffectsToBe
168
            mIndex         = source.mIndex
169

  
170
            mJobs = ArrayList()
171

  
172
            val max = InternalStackFrameList.getMax(mIndex)
173

  
174
            if (max > 0)
175
            {
176
                mEffects = arrayOfNulls(max)
177
                mUBI = UniformBlockIntUniforms(source.mUBI!!)
178
                mUBF = UniformBlockFloatUniforms(source.mUBF!!)
179
                if (numEffects>=0) System.arraycopy(source.mEffects, 0, mEffects, 0, numEffects)
180
            }
212 181
        }
213
      }
214
    else
215
      {
216
      mID = 0;
217
      }
218 182
    }
219 183

  
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221

  
222
  public long getID()
184
    ///////////////////////////////////////////////////////////////////////////////////////////////
185
    // Every effect queue has an ID, which should be the same iff two queues hold the same effects.
186
    // (this is a speedup: then both queues can be applied once, which seriously speeds up stuff -
187
    // especially important in case of postprocessing)
188
    private fun regenerateID()
223 189
    {
224
    return mID;
225
    }
226

  
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

  
229
  public static boolean setMax(int index, int m)
230
    {
231
    return InternalStackFrameList.setMax(index, Math.max(m,0));
232
    }
233

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

  
236
  public static int getMax(int index)
237
    {
238
    return InternalStackFrameList.getMax(index);
190
        if (numEffects > 0)
191
        {
192
            val map = InternalStackFrameList.getMap()
193
            val list = ArrayList<Long>()
194
            for (i in 0..<numEffects) list.add(mEffects[i]!!.id)
195
            val id = map[list]
196

  
197
            if (id != null)
198
            {
199
                iD = id
200
            }
201
            else
202
            {
203
                iD = InternalStackFrameList.getNextQueueID()
204
                map[list] = iD
205
            }
206
        }
207
        else
208
        {
209
            iD = 0
210
        }
239 211
    }
240 212

  
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242
// this assumes 0<=effect
243

  
244
  private void removeNow(int pos)
213
    ///////////////////////////////////////////////////////////////////////////////////////////////
214
    private fun removeNow(pos: Int)
245 215
    {
246
    if( mNumEffects>pos )
247
      {
248
      mNumEffects--;
249
      mEffects[pos].remQueue(this);
250
      System.arraycopy(mEffects, pos+1, mEffects, pos, mNumEffects-pos);
251
      mUBI.remove(pos, mNumEffects);
252
      mEffects[mNumEffects] = null;
253
      }
216
        if (pos in 0..<numEffects)
217
        {
218
            numEffects--
219
            mEffects[pos]!!.remQueue(this)
220
            System.arraycopy(mEffects, pos + 1, mEffects, pos, numEffects - pos)
221
            mUBI!!.remove(pos, numEffects)
222
            mEffects[numEffects] = null
223
        }
254 224
    }
255 225

  
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

  
258
  private void addNow(int pos, Effect effect)
226
    ///////////////////////////////////////////////////////////////////////////////////////////////
227
    private fun addNow(pos: Int, effect: Effect)
259 228
    {
260
    mEffects[pos] = effect;
261
    mUBI.addOrdinal(pos, effect.getName().ordinal() );
262
    effect.addQueue(this);
263

  
264
    if( mIndex==EffectType.VERTEX.ordinal() )
265
      {
266
      mUBI.addAssociations(pos,effect);
267
      }
229
        mEffects[pos] = effect
230
        mUBI!!.addOrdinal(pos, effect.name.ordinal)
231
        effect.addQueue(this)
232
        if (mIndex==EffectType.VERTEX.ordinal) mUBI!!.addAssociations(pos, effect)
268 233
    }
269 234

  
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

  
272
  public synchronized int removeByName(EffectName name)
235
    ///////////////////////////////////////////////////////////////////////////////////////////////
236
    @Synchronized
237
    fun removeByName(name: EffectName): Int
273 238
    {
274
    int ret = 0;
239
        var ret = 0
275 240

  
276
    for(int i=0; i<mNumEffects; i++)
277
      {
278
      if( mEffects[i].getName() == name )
241
        for (i in 0..<numEffects)
279 242
        {
280
        mJobs.add(new Job(DETACH,0,0,true,mEffects[i]));
281
        ret++;
243
            if (mEffects[i]!!.name == name)
244
            {
245
                mJobs.add( Job(DETACH,0,0,true,mEffects[i]) )
246
                ret++
247
            }
282 248
        }
283
      }
284 249

  
285
    if( ret>0 )
286
      {
287
      InternalMaster.newSlave(this);
288
      mNumEffectsToBe-=ret;
289
      }
250
        if (ret > 0)
251
        {
252
            InternalMaster.newSlave(this)
253
            numEffectsToBe -= ret
254
        }
290 255

  
291
    return ret;
256
        return ret
292 257
    }
293 258

  
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295

  
296
  public synchronized int removeById(long id)
259
    ///////////////////////////////////////////////////////////////////////////////////////////////
260
    @Synchronized
261
    fun removeById(id: Long): Int
297 262
    {
298
    for(int i=0; i<mNumEffects; i++)
299
      {
300
      if( mEffects[i].getID() == id )
263
        for (i in 0..<numEffects)
301 264
        {
302
        mJobs.add(new Job(DETACH,0,0,true,mEffects[i]));
303
        InternalMaster.newSlave(this);
304
        mNumEffectsToBe--;
305
        return 1;
265
            if (mEffects[i]!!.id == id)
266
            {
267
                mJobs.add( Job(DETACH,0,0,true,mEffects[i]) )
268
                InternalMaster.newSlave(this)
269
                numEffectsToBe--
270
                return 1
271
            }
306 272
        }
307
      }
308 273

  
309
    return 0;
274
        return 0
310 275
    }
311 276

  
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

  
314
  public synchronized int removeEffect(Effect effect)
277
    ///////////////////////////////////////////////////////////////////////////////////////////////
278
    @Synchronized
279
    fun removeEffect(effect: Effect): Int
315 280
    {
316
    for(int i=0; i<mNumEffects; i++)
317
      {
318
      if( mEffects[i]==effect )
281
        for (i in 0..<numEffects)
319 282
        {
320
        mJobs.add(new Job(DETACH,0,0,true,mEffects[i]));
321
        InternalMaster.newSlave(this);
322
        mNumEffectsToBe--;
323
        return 1;
283
            if (mEffects[i] === effect) {
284
                mJobs.add(
285
                    Job(
286
                        DETACH, 0, 0, true,
287
                        mEffects[i]
288
                    )
289
                )
290
                InternalMaster.newSlave(this)
291
                numEffectsToBe--
292
                return 1
293
            }
324 294
        }
325
      }
326
   
327
    return 0;
328
    }
329 295

  
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331
// we do want to notify Listeners if they called 'abortAll' themselves but don't want to notify
332
// them if it is the library itself which is releasing resources.
333

  
334
  public synchronized int removeAll(boolean notify)
335
    {
336
    mJobs.add(new Job(DETALL,0,0,notify,null));
337
    InternalMaster.newSlave(this);
338
    mNumEffectsToBe = 0;
339
    return mNumEffects;
340
    }
341

  
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
  
344
  public boolean add(Effect effect)
345
    {
346
    if( InternalStackFrameList.getMax(mIndex)>mNumEffectsToBe || !mCreated )
347
      {
348
      mJobs.add(new Job(ATTACH,-1,0,false,effect));
349
      InternalMaster.newSlave(this);
350
      mNumEffectsToBe++;
351
      return true;
352
      }
353

  
354
    return false;
296
        return 0
355 297
    }
356 298

  
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358

  
359
  public boolean add(Effect effect, int position)
299
    ///////////////////////////////////////////////////////////////////////////////////////////////
300
    // we do want to notify Listeners if they called 'abortAll' themselves but don't want to notify
301
    // them if it is the library itself which is releasing resources.
302
    @Synchronized
303
    fun removeAll(notify: Boolean): Int
360 304
    {
361
    if( InternalStackFrameList.getMax(mIndex)>mNumEffectsToBe || !mCreated )
362
      {
363
      mJobs.add(new Job(ATTACH,position,0,false,effect));
364
      InternalMaster.newSlave(this);
365
      mNumEffectsToBe++;
366
      return true;
367
      }
368

  
369
    return false;
305
        mJobs.add( Job(DETALL,0,0,notify,null) )
306
        InternalMaster.newSlave(this)
307
        numEffectsToBe = 0
308
        return numEffects
370 309
    }
371 310

  
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

  
374
  public boolean exists(long id)
311
    ///////////////////////////////////////////////////////////////////////////////////////////////
312
    fun add(effect: Effect?): Boolean
375 313
    {
376
    for(int i=0; i<mNumEffects; i++)
377
      {
378
      if( mEffects[i].getID() == id ) return true;
379
      }
314
        if (InternalStackFrameList.getMax(mIndex) > numEffectsToBe || !mCreated)
315
        {
316
            mJobs.add( Job(ATTACH,-1,0,false,effect) )
317
            InternalMaster.newSlave(this)
318
            numEffectsToBe++
319
            return true
320
        }
380 321

  
381
    return false;
322
        return false
382 323
    }
383 324

  
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

  
386
  public int getNumEffects()
325
    ///////////////////////////////////////////////////////////////////////////////////////////////
326
    fun add(effect: Effect?, position: Int): Boolean
387 327
    {
388
    return mNumEffects;
389
    }
390

  
391
///////////////////////////////////////////////////////////////////////////////////////////////////
328
        if (InternalStackFrameList.getMax(mIndex) > numEffectsToBe || !mCreated)
329
        {
330
            mJobs.add( Job(ATTACH,position,0,false,effect) )
331
            InternalMaster.newSlave(this)
332
            numEffectsToBe++
333
            return true
334
        }
392 335

  
393
  public int getNumEffectsToBe()
394
    {
395
    return mNumEffectsToBe;
336
        return false
396 337
    }
397 338

  
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399

  
400
  public Effect getEffect(int position)
339
    ///////////////////////////////////////////////////////////////////////////////////////////////
340
    fun exists(id: Long): Boolean
401 341
    {
402
    if( position>=0 && position< mNumEffects )
403
      {
404
      return mEffects[position];
405
      }
406
    else
407
      {
408
      DistortedLibrary.logMessage("EffectQueue: getEffect: out of range "+position);
409
      return null;
410
      }
411
    }
342
        for (i in 0..<numEffects)
343
            if (mEffects[i]!!.id==id) return true
412 344

  
413
///////////////////////////////////////////////////////////////////////////////////////////////////
345
        return false
346
    }
414 347

  
415
  public void setAssociation(long effectID)
348
    ///////////////////////////////////////////////////////////////////////////////////////////////
349
    fun getEffect(position: Int): Effect?
416 350
    {
417
    for(int j=0; j<mNumEffects; j++)
418
      {
419
      if (mEffects[j].getID() == effectID)
351
        if (position in 0..<numEffects)
352
        {
353
            return mEffects[position]
354
        }
355
        else
420 356
        {
421
        mUBI.addAssociations(j,mEffects[j]);
357
            DistortedLibrary.logMessage("EffectQueue: getEffect: out of range $position")
358
            return null
422 359
        }
423
      }
424 360
    }
425 361

  
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

  
428
  public void markForDeletion()
362
    ///////////////////////////////////////////////////////////////////////////////////////////////
363
    fun setAssociation(effectID: Long)
429 364
    {
430
    mUBI.markForDeletion();
431
    mUBF.markForDeletion();
365
        for (j in 0..<numEffects)
366
            if (mEffects[j]!!.id == effectID)
367
                mUBI!!.addAssociations(j, mEffects[j]!!)
432 368
    }
433 369

  
434
///////////////////////////////////////////////////////////////////////////////////////////////////
370
    ///////////////////////////////////////////////////////////////////////////////////////////////
371
    fun markForDeletion()
372
    {
373
        mUBI!!.markForDeletion()
374
        mUBF!!.markForDeletion()
375
    }
435 376

  
436
  public String retEffects()
377
    ///////////////////////////////////////////////////////////////////////////////////////////////
378
    fun retEffects(): String
437 379
    {
438
    String dbg="";
380
        var dbg = ""
439 381

  
440
    for(int i=0; i<mNumEffects; i++)
441
      {
442
      dbg += (i+": "+mEffects[i].getString()+" ");
443
      }
382
        for (i in 0..<numEffects)
383
            dbg += (i.toString() + ": " + mEffects[i]!!.string + " ")
444 384

  
445
    return dbg;
385
        return dbg
446 386
    }
447 387

  
448
///////////////////////////////////////////////////////////////////////////////////////////////////
449

  
450
  public void doWork()
388
    ///////////////////////////////////////////////////////////////////////////////////////////////
389
    override fun doWork()
451 390
    {
452
    boolean changed = false;
453
    int num = mJobs.size();
454
    Job job;
455

  
456
    for(int i=0; i<num; i++)
457
      {
458
      job = mJobs.remove(0);
391
        var changed = false
392
        val num = mJobs.size
393
        var job: Job
459 394

  
460
      switch(job.type)
395
        for (i in 0..<num)
461 396
        {
462
        case CREATE: int max = InternalStackFrameList.getMax(mIndex);
463
                     if( max>0 )
464
                       {
465
                       mEffects= new Effect[max];
466
                       mUBF    = new UniformBlockFloatUniforms(job.num1, max, job.bool);
467
                       mUBI    = new UniformBlockIntUniforms  (job.num2, max, job.bool);
468
                       }
469
                     mCreated = true;
470

  
471
                     break;
472
        case ATTACH: if( InternalStackFrameList.getMax(mIndex)>mNumEffects ) // it is possible that we have first
473
                       {                                                     // added effects and then lowered mMax
474
                       int position = job.num1;
475

  
476
                       if( position<0 )
477
                         {
478
                         addNow(mNumEffects,job.effect);
479
                         mNumEffects++;
480
                         changed = true;
481
                         }
482
                       else if( position<=mNumEffects )
483
                         {
484
                         System.arraycopy(mEffects, position, mEffects, position+1, mNumEffects-position);
485
                         mUBI.makeHole(position, mNumEffects);
486
                         addNow(position,job.effect);
487
                         mNumEffects++;
488
                         changed = true;
489
                         }
490
                       }
491
                     else
492
                       {
493
                       DistortedLibrary.logMessage("EffectQueue: failed to add effect "+job.effect.getName());
494
                       }
495
                     break;
496
        case DETACH: for(int j=0; j<mNumEffects; j++)
497
                       {
498
                       if (mEffects[j] == job.effect)
499
                         {
500
                         removeNow(j);
501
                         changed = true;
502
                         break;
503
                         }
504
                       }
505
                     break;
506
        case DETALL: for(int j=0; j<mNumEffects; j++ )
507
                       {
508
                       changed = true;
509
                       mEffects[j] = null;
510
                       }
511

  
512
                     // TODO: notify listeners?
513
                     /* if( job.bool )
514
                          {
515
                          // ...
516
                          }
517
                      */
518

  
519
                     mNumEffects= 0;
520
                     break;
397
            job = mJobs.removeAt(0)
398

  
399
            when (job.type)
400
            {
401
                CREATE ->
402
                        {
403
                            val max = InternalStackFrameList.getMax(mIndex)
404
                            if (max > 0)
405
                            {
406
                                mEffects = arrayOfNulls(max)
407
                                mUBF = UniformBlockFloatUniforms(job.num1, max, job.bool)
408
                                mUBI = UniformBlockIntUniforms(job.num2, max, job.bool)
409
                            }
410
                            mCreated = true
411
                        }
412
                ATTACH ->
413
                        if (InternalStackFrameList.getMax(mIndex)>numEffects)  // it is possible that we have first
414
                        {                                                      // added effects and then lowered mMax
415
                            val position = job.num1
416

  
417
                            if (position < 0)
418
                            {
419
                                addNow(numEffects, job.effect)
420
                                numEffects++
421
                                changed = true
422
                            }
423
                            else if (position <= numEffects)
424
                            {
425
                                System.arraycopy(mEffects, position, mEffects, position+1, numEffects - position)
426
                                mUBI!!.makeHole(position, numEffects)
427
                                addNow(position, job.effect)
428
                                numEffects++
429
                                changed = true
430
                            }
431
                        }
432
                        else
433
                        {
434
                            DistortedLibrary.logMessage("EffectQueue: failed to add effect " + job.effect.name)
435
                        }
436

  
437
                DETACH ->
438
                        {
439
                            var j = 0
440

  
441
                            while (j < numEffects)
442
                            {
443
                                if (mEffects[j] === job.effect)
444
                                {
445
                                    removeNow(j)
446
                                    changed = true
447
                                    break
448
                                }
449
                                j++
450
                            }
451
                        }
452

  
453
                DETALL ->
454
                        {
455
                            var j = 0
456
                            while (j < numEffects)
457
                            {
458
                                changed = true
459
                                mEffects[j] = null
460
                                j++
461
                            }
462

  
463
                            // TODO: notify listeners?
464
                            /* if( job.bool )
465
                                {
466
                                // ...
467
                                }
468
                            */
469
                            numEffects = 0
470
                        }
471
            }
521 472
        }
522
      }
523 473

  
524
    if( changed && mIndex==EffectType.POSTPROCESS.ordinal() ) regenerateID();
474
        if (changed && mIndex == EffectType.POSTPROCESS.ordinal) regenerateID()
525 475
    }
526
  }
476

  
477
}
src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.kt
18 18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19 19
///////////////////////////////////////////////////////////////////////////////////////////////////
20 20

  
21
package org.distorted.library.effectqueue;
21
package org.distorted.library.effectqueue
22 22

  
23
import android.opengl.GLES30;
24

  
25
import org.distorted.library.effect.EffectType;
26
import org.distorted.library.effect.FragmentEffect;
27
import org.distorted.library.message.EffectMessageSender;
23
import android.opengl.GLES30
24
import org.distorted.library.effect.EffectType
25
import org.distorted.library.effect.FragmentEffect
26
import org.distorted.library.message.EffectMessageSender.Companion.newMessage
28 27

  
29 28
///////////////////////////////////////////////////////////////////////////////////////////////////
29
internal class EffectQueueFragment : EffectQueue
30
{
31
    companion object
32
    {
33
        private const val NUM_FLOAT_UNIFORMS = FragmentEffect.NUM_FLOAT_UNIFORMS
34
        private const val NUM_INT_UNIFORMS = FragmentEffect.NUM_INT_UNIFORMS
35
        private const val USE_UBO = false
36
        private val INDEX = EffectType.FRAGMENT.ordinal
30 37

  
31
class EffectQueueFragment extends EffectQueue
32
  {
33
  private static final int NUM_FLOAT_UNIFORMS = FragmentEffect.NUM_FLOAT_UNIFORMS;
34
  private static final int NUM_INT_UNIFORMS   = FragmentEffect.NUM_INT_UNIFORMS;
35
  private static final boolean USE_UBO        = false;
36
  private static final int INDEX = EffectType.FRAGMENT.ordinal();
37

  
38
  private final static int[] mNumEffectsH  = new int[MAIN_VARIANTS];
39
  private final static int[] mIntUniformsH = new int[MAIN_VARIANTS];
40
  private final static int[] mFloUniformsH = new int[MAIN_VARIANTS];
38
        private val mNumEffectsH  = IntArray(MAIN_VARIANTS)
39
        private val mIntUniformsH = IntArray(MAIN_VARIANTS)
40
        private val mFloUniformsH = IntArray(MAIN_VARIANTS)
41 41

  
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43
   
44
  EffectQueueFragment()
45
    { 
46
    super(NUM_FLOAT_UNIFORMS, NUM_INT_UNIFORMS, USE_UBO, INDEX);
42
        ///////////////////////////////////////////////////////////////////////////////////////////
43
        fun uniforms(mProgramH: Int, variant: Int)
44
        {
45
            mNumEffectsH[variant]  = GLES30.glGetUniformLocation(mProgramH, "fNumEffects")
46
            mIntUniformsH[variant] = GLES30.glGetUniformLocation(mProgramH, "fProperties")
47
            mFloUniformsH[variant] = GLES30.glGetUniformLocation(mProgramH, "fUniforms")
48
        }
47 49
    }
50
    ///////////////////////////////////////////////////////////////////////////////////////////////
48 51

  
49
///////////////////////////////////////////////////////////////////////////////////////////////////
52
    constructor() : super(NUM_FLOAT_UNIFORMS,NUM_INT_UNIFORMS,USE_UBO,INDEX)
53
    constructor(source: EffectQueueFragment) : super(source)
50 54

  
51
  EffectQueueFragment(EffectQueueFragment source)
55
    ///////////////////////////////////////////////////////////////////////////////////////////////
56
    fun compute(currTime: Long, step: Long)
52 57
    {
53
    super(source);
54
    }
55

  
56
///////////////////////////////////////////////////////////////////////////////////////////////////
58
        if (numEffects > 0)
59
        {
60
            val array = mUBF!!.backingArray
57 61

  
58
  static void uniforms(int mProgramH, int variant)
59
    {
60
    mNumEffectsH[variant]   = GLES30.glGetUniformLocation  ( mProgramH, "fNumEffects");
61
    mIntUniformsH[variant]  = GLES30.glGetUniformLocation  ( mProgramH, "fProperties");
62
    mFloUniformsH[variant]  = GLES30.glGetUniformLocation  ( mProgramH, "fUniforms");
62
            for (i in 0..<numEffects)
63
                if (mEffects[i]!!.compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step))
64
                    newMessage(mEffects[i]!!)
65
        }
63 66
    }
64 67

  
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66
  
67
  void compute(long currTime, long step)
68
    ///////////////////////////////////////////////////////////////////////////////////////////////
69
    fun send(variant: Int)
68 70
    {
69
    if( mNumEffects>0 )
70
      {
71
      float[] array = mUBF.getBackingArray();
71
        GLES30.glUniform1i(mNumEffectsH[variant],numEffects)
72 72

  
73
      for(int i=0; i<mNumEffects; i++)
73
        if (numEffects>0)
74 74
        {
75
        if( mEffects[i].compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step) )
76
          {
77
          EffectMessageSender.newMessage(mEffects[i]);
78
          }
75
            val arrayI = mUBI!!.backingArray
76
            val arrayF = mUBF!!.backingArray
77
            GLES30.glUniform4iv(mIntUniformsH[variant],numEffects,arrayI,0)
78
            GLES30.glUniform4fv(mFloUniformsH[variant],(NUM_FLOAT_UNIFORMS/4)*numEffects,arrayF,0)
79 79
        }
80
      }
81
    }
82

  
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84
  
85
  void send(int variant)
86
    {
87
    GLES30.glUniform1i( mNumEffectsH[variant], mNumEffects);
88

  
89
    if( mNumEffects>0 )
90
      {
91
      int[]   arrayI = mUBI.getBackingArray();
92
      float[] arrayF = mUBF.getBackingArray();
93

  
94
      GLES30.glUniform4iv( mIntUniformsH[variant],                       mNumEffects, arrayI, 0);
95
      GLES30.glUniform4fv( mFloUniformsH[variant],(NUM_FLOAT_UNIFORMS/4)*mNumEffects, arrayF, 0);
96
      }  
97 80
    }
98
  }
81
}
src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.kt
18 18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19 19
///////////////////////////////////////////////////////////////////////////////////////////////////
20 20

  
21
package org.distorted.library.effectqueue;
21
package org.distorted.library.effectqueue
22 22

  
23
import android.opengl.GLES30;
24

  
25
import org.distorted.library.helpers.MatrixHelper;
26
import org.distorted.library.effect.EffectType;
27
import org.distorted.library.effect.MatrixEffect;
28
import org.distorted.library.message.EffectMessageSender;
23
import android.opengl.GLES30
24
import org.distorted.library.effect.EffectType
25
import org.distorted.library.effect.MatrixEffect
26
import org.distorted.library.helpers.MatrixHelper.multiply
27
import org.distorted.library.message.EffectMessageSender.Companion.newMessage
29 28

  
30 29
///////////////////////////////////////////////////////////////////////////////////////////////////
31 30

  
32
class EffectQueueMatrix extends EffectQueue
33
  {
34
  private static final int NUM_FLOAT_UNIFORMS = MatrixEffect.NUM_FLOAT_UNIFORMS;
35
  private static final int NUM_INT_UNIFORMS   = MatrixEffect.NUM_INT_UNIFORMS;
36
  private static final boolean USE_UBO        = false;
37
  private static final int INDEX = EffectType.MATRIX.ordinal();
38

  
39
  private static final float[] mMVPMatrix       = new float[16];
40
  private static final float[] mModelViewMatrixP= new float[16];
41
  private static final float[] mModelViewMatrixV= new float[16];
42

  
43
  private static final int[] mMVPMatrixH = new int[MAIN_VARIANTS];
44
  private static final int[] mMVMatrixPH = new int[MAIN_VARIANTS];
45
  private static final int[] mMVMatrixVH = new int[MAIN_VARIANTS];
46

  
47
///////////////////////////////////////////////////////////////////////////////////////////////////
48
   
49
  EffectQueueMatrix()
50
    { 
51
    super(NUM_FLOAT_UNIFORMS, NUM_INT_UNIFORMS, USE_UBO, INDEX);
52
    }
53

  
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

  
56
  EffectQueueMatrix(EffectQueueMatrix source)
31
internal class EffectQueueMatrix : EffectQueue
32
{
33
    companion object
57 34
    {
58
    super(source);
59
    }
35
        private const val NUM_FLOAT_UNIFORMS = MatrixEffect.NUM_FLOAT_UNIFORMS
36
        private const val NUM_INT_UNIFORMS   = MatrixEffect.NUM_INT_UNIFORMS
37
        private const val USE_UBO = false
38
        private val INDEX = EffectType.MATRIX.ordinal
60 39

  
61
///////////////////////////////////////////////////////////////////////////////////////////////////
40
        private val mMVPMatrix        = FloatArray(16)
41
        private val mModelViewMatrixP = FloatArray(16)
42
        private val mModelViewMatrixV = FloatArray(16)
62 43

  
63
  static void uniforms(int mProgramH, int variant)
64
    {
65
    mMVPMatrixH[variant]= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix");
66
    mMVMatrixPH[variant]= GLES30.glGetUniformLocation(mProgramH, "u_MVMatrixP");
67
    mMVMatrixVH[variant]= GLES30.glGetUniformLocation(mProgramH, "u_MVMatrixV");
68
    }
44
        private val mMVPMatrixH = IntArray(MAIN_VARIANTS)
45
        private val mMVMatrixPH = IntArray(MAIN_VARIANTS)
46
        private val mMVMatrixVH = IntArray(MAIN_VARIANTS)
69 47

  
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

  
72
  void compute(long currTime, long step)
73
    {
74
    if( mNumEffects>0 )
75
      {
76
      float[] array = mUBF.getBackingArray();
77

  
78
      for(int i=0; i<mNumEffects; i++)
48
        ///////////////////////////////////////////////////////////////////////////////////////////
49
        fun uniforms(mProgramH: Int, variant: Int)
79 50
        {
80
        if( mEffects[i].compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step) )
81
          {
82
          EffectMessageSender.newMessage(mEffects[i]);
83
          }
51
            mMVPMatrixH[variant] = GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix")
52
            mMVMatrixPH[variant] = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrixP")
53
            mMVMatrixVH[variant] = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrixV")
84 54
        }
85
      }
86
    }  
55
    }
87 56

  
88
///////////////////////////////////////////////////////////////////////////////////////////////////
57
    constructor() : super(NUM_FLOAT_UNIFORMS,NUM_INT_UNIFORMS,USE_UBO,INDEX)
58
    constructor(source: EffectQueueMatrix) : super(source)
89 59

  
90
  void send(float distance, float mipmap, float[] projection, int variant)
60
    ///////////////////////////////////////////////////////////////////////////////////////////////
61
    fun compute(currTime: Long, step: Long)
91 62
    {
92
    // i.e. setIdentity(); translate(0,0,-distance); scale(mipmap,mipmap,mipmap)
93
    mModelViewMatrixV[ 0] = mModelViewMatrixP[ 0] = mipmap;
94
    mModelViewMatrixV[ 1] = mModelViewMatrixP[ 1] = 0;
95
    mModelViewMatrixV[ 2] = mModelViewMatrixP[ 2] = 0;
96
    mModelViewMatrixV[ 3] = mModelViewMatrixP[ 3] = 0;
97
    mModelViewMatrixV[ 4] = mModelViewMatrixP[ 4] = 0;
98
    mModelViewMatrixV[ 5] = mModelViewMatrixP[ 5] = mipmap;
99
    mModelViewMatrixV[ 6] = mModelViewMatrixP[ 6] = 0;
100
    mModelViewMatrixV[ 7] = mModelViewMatrixP[ 7] = 0;
101
    mModelViewMatrixV[ 8] = mModelViewMatrixP[ 8] = 0;
102
    mModelViewMatrixV[ 9] = mModelViewMatrixP[ 9] = 0;
103
    mModelViewMatrixV[10] = mModelViewMatrixP[10] = mipmap;
104
    mModelViewMatrixV[11] = mModelViewMatrixP[11] = 0;
105
    mModelViewMatrixV[12] = mModelViewMatrixP[12] = 0;
106
    mModelViewMatrixV[13] = mModelViewMatrixP[13] = 0;
107
    mModelViewMatrixV[14] = mModelViewMatrixP[14] = -distance;
108
    mModelViewMatrixV[15] = mModelViewMatrixP[15] = 1;
109

  
110
    float[] array = mUBF.getBackingArray();
111

  
112
    // the 'Model' part of the MV matrix
113
    for(int i=mNumEffects-1; i>=0; i--)
114
      {
115
      ((MatrixEffect)mEffects[i]).apply(mModelViewMatrixP,mModelViewMatrixV,array,i);
116
      }
63
        if (numEffects>0)
64
        {
65
            val array = mUBF!!.backingArray
117 66

  
118
    // combined Model-View-Projection matrix
119
    MatrixHelper.multiply(mMVPMatrix, projection, mModelViewMatrixP);
67
            for (i in 0..<numEffects)
68
                if (mEffects[i]!!.compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step))
69
                    newMessage(mEffects[i]!!)
70
        }
71
    }
120 72

  
121
    GLES30.glUniformMatrix4fv(mMVMatrixVH[variant], 1, false, mModelViewMatrixV, 0);
122
    GLES30.glUniformMatrix4fv(mMVMatrixPH[variant], 1, false, mModelViewMatrixP, 0);
123
    GLES30.glUniformMatrix4fv(mMVPMatrixH[variant], 1, false, mMVPMatrix       , 0);
73
    ///////////////////////////////////////////////////////////////////////////////////////////////
74
    fun send(distance: Float, mipmap: Float, projection: FloatArray, variant: Int)
75
    {
76
        // i.e. setIdentity(); translate(0,0,-distance); scale(mipmap,mipmap,mipmap)
77
        mModelViewMatrixP[ 0] = mipmap
78
        mModelViewMatrixV[ 0] = mModelViewMatrixP[0]
79
        mModelViewMatrixP[ 1] = 0f
80
        mModelViewMatrixV[ 1] = mModelViewMatrixP[1]
81
        mModelViewMatrixP[ 2] = 0f
82
        mModelViewMatrixV[ 2] = mModelViewMatrixP[2]
83
        mModelViewMatrixP[ 3] = 0f
84
        mModelViewMatrixV[ 3] = mModelViewMatrixP[3]
85
        mModelViewMatrixP[ 4] = 0f
86
        mModelViewMatrixV[ 4] = mModelViewMatrixP[4]
87
        mModelViewMatrixP[ 5] = mipmap
88
        mModelViewMatrixV[ 5] = mModelViewMatrixP[5]
89
        mModelViewMatrixP[ 6] = 0f
90
        mModelViewMatrixV[ 6] = mModelViewMatrixP[6]
91
        mModelViewMatrixP[ 7] = 0f
92
        mModelViewMatrixV[ 7] = mModelViewMatrixP[7]
93
        mModelViewMatrixP[ 8] = 0f
94
        mModelViewMatrixV[ 8] = mModelViewMatrixP[8]
95
        mModelViewMatrixP[ 9] = 0f
96
        mModelViewMatrixV[ 9] = mModelViewMatrixP[9]
97
        mModelViewMatrixP[10] = mipmap
98
        mModelViewMatrixV[10] = mModelViewMatrixP[10]
99
        mModelViewMatrixP[11] = 0f
100
        mModelViewMatrixV[11] = mModelViewMatrixP[11]
101
        mModelViewMatrixP[12] = 0f
102
        mModelViewMatrixV[12] = mModelViewMatrixP[12]
103
        mModelViewMatrixP[13] = 0f
104
        mModelViewMatrixV[13] = mModelViewMatrixP[13]
105
        mModelViewMatrixP[14] = -distance
106
        mModelViewMatrixV[14] = mModelViewMatrixP[14]
107
        mModelViewMatrixP[15] = 1f
108
        mModelViewMatrixV[15] = mModelViewMatrixP[15]
109

  
110
        val array = mUBF!!.backingArray
111

  
112
        // the 'Model' part of the MV matrix
113
        for (i in numEffects-1 downTo 0)
114
            (mEffects[i] as MatrixEffect).apply(mModelViewMatrixP, mModelViewMatrixV, array, i)
115

  
116
        // combined Model-View-Projection matrix
117
        multiply(mMVPMatrix, projection, mModelViewMatrixP)
118

  
119
        GLES30.glUniformMatrix4fv(mMVMatrixVH[variant], 1, false, mModelViewMatrixV, 0)
120
        GLES30.glUniformMatrix4fv(mMVMatrixPH[variant], 1, false, mModelViewMatrixP, 0)
121
        GLES30.glUniformMatrix4fv(mMVPMatrixH[variant], 1, false, mMVPMatrix       , 0)
124 122
    }
125
  }
123
}
src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.kt
18 18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19 19
///////////////////////////////////////////////////////////////////////////////////////////////////
20 20

  
21
package org.distorted.library.effectqueue;
22

  
23
import android.opengl.GLES30;
24

  
25
import org.distorted.library.effect.EffectType;
26
import org.distorted.library.effect.PostprocessEffect;
27
import org.distorted.library.effect.VertexEffect;
28
import org.distorted.library.main.DistortedEffects;
29
import org.distorted.library.main.DistortedLibrary;
30
import org.distorted.library.main.DistortedFramebuffer;
31
import org.distorted.library.main.DistortedNode;
32
import org.distorted.library.main.InternalOutputSurface;
33
import org.distorted.library.main.InternalRenderState;
34
import org.distorted.library.mesh.MeshBase;
35
import org.distorted.library.message.EffectMessageSender;
36
import org.distorted.library.program.DistortedProgram;
37

  
38
import java.io.InputStream;
39

  
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41
/**
42
 * Not part of public API, do not document
43
 *
44
 * @y.exclude
45
 */
46
public class EffectQueuePostprocess extends EffectQueue
47
  {
48
  private static final int NUM_FLOAT_UNIFORMS = PostprocessEffect.NUM_FLOAT_UNIFORMS;
49
  private static final int NUM_INT_UNIFORMS   = PostprocessEffect.NUM_INT_UNIFORMS;
50
  private static final boolean USE_UBO        = false;
51
  private static final int INDEX = EffectType.POSTPROCESS.ordinal();
52

  
53
  private int mHalo;
54
  private boolean mUseHaloDepth;
55
  private float mR, mG, mB, mA;
56

  
57
  private static DistortedProgram mPreProgram;
58
  private static int mPreColorH;
59
  private static int mPreTextureH;
60
  private static int mPreProgramH;
21
package org.distorted.library.effectqueue
22

  
23
import android.opengl.GLES30
24
import org.distorted.library.effect.EffectType
25
import org.distorted.library.effect.PostprocessEffect
26
import org.distorted.library.effect.VertexEffect
27
import org.distorted.library.main.DistortedFramebuffer
28
import org.distorted.library.main.DistortedLibrary
29
import org.distorted.library.main.DistortedNode
30
import org.distorted.library.main.InternalOutputSurface
31
import org.distorted.library.main.InternalRenderState
32
import org.distorted.library.mesh.MeshBase
33
import org.distorted.library.message.EffectMessageSender.Companion.newMessage
34
import org.distorted.library.program.DistortedProgram
35
import java.io.InputStream
61 36

  
62 37
///////////////////////////////////////////////////////////////////////////////////////////////////
63

  
64
  EffectQueuePostprocess()
65
    { 
66
    super(NUM_FLOAT_UNIFORMS, NUM_INT_UNIFORMS, USE_UBO, INDEX );
38
/** Not part of public API, do not document
39
*
40
* @y.exclude
41
*/
42
class EffectQueuePostprocess : EffectQueue
43
{
44
    private var mHalo = 0
45
    private var mUseHaloDepth = false
46
    private var mR = 0f
47
    private var mG = 0f
48
    private var mB = 0f
49
    private var mA = 0f
50

  
51
    val quality: Int
52
        get() = if (numEffects>0) (mEffects[0] as PostprocessEffect).quality else 0
53

  
54
    val renderDirectly: Boolean
55
        get() = numEffects > 0 && (mEffects[0] as PostprocessEffect).renderDirectly
56

  
57
    companion object
58
    {
59
        private const val NUM_FLOAT_UNIFORMS = PostprocessEffect.NUM_FLOAT_UNIFORMS
60
        private const val NUM_INT_UNIFORMS = PostprocessEffect.NUM_INT_UNIFORMS
61
        private const val USE_UBO = false
62
        private val INDEX = EffectType.POSTPROCESS.ordinal
63

  
64
        private var mPreProgram: DistortedProgram? = null
65
        private var mPreColorH = 0
66
        private var mPreTextureH = 0
67
        private var mPreProgramH = 0
68

  
69
        ///////////////////////////////////////////////////////////////////////////////////////////
70
        @JvmStatic
71
        fun createPrograms(vert: InputStream, frag: InputStream, GLSL: Int)
72
        {
73
            val numV = VertexEffect.getNumEnabled()
74

  
75
            val version = "#version $GLSL es\n"
76
            var mainVertHeader = version + ("#define NUM_VERTEX " + (if (numV>0) DistortedLibrary.getMax(EffectType.VERTEX) else 0) + "\n")
77
            val mainFragHeader = version + "\n"
78

  
79
            mainVertHeader += "#define MAX_COMPON " + MeshBase.getMaxEffComponents() + "\n"
80
            if (MeshBase.getUseCenters()) mainVertHeader += "#define COMP_CENTERS\n"
81
            if (DistortedLibrary.isUBOBuggy()) mainVertHeader += "#define BUGGY_UBOS\n"
82
            mainVertHeader += "#define POSTPROCESS\n"
83

  
84
            val enabledEffectV = VertexEffect.getGLSL()
85

  
86
            try
87
            {
88
                mPreProgram = DistortedProgram(vert, frag, mainVertHeader, mainFragHeader, enabledEffectV, null, GLSL, null)
89
            }
90
            catch (e: Exception)
91
            {
92
                DistortedLibrary.logMessage("EffectQueuePostprocess " + e.javaClass.simpleName + " trying to compile PRE program: " + e.message)
93
                throw RuntimeException(e.message)
94
            }
95

  
96
            mPreProgramH = mPreProgram!!.programHandle
97
            getUniforms(mPreProgramH, 2)
98
            MeshBase.getUniforms(mPreProgramH, 2)
99
            mPreColorH = GLES30.glGetUniformLocation(mPreProgramH, "u_Color")
100
            mPreTextureH = GLES30.glGetUniformLocation(mPreProgramH, "u_Texture")
101
        }
67 102
    }
68 103

  
69
///////////////////////////////////////////////////////////////////////////////////////////////////
104
    ///////////////////////////////////////////////////////////////////////////////////////////////
105
    internal constructor() : super(NUM_FLOAT_UNIFORMS, NUM_INT_UNIFORMS, USE_UBO, INDEX)
70 106

  
71
  EffectQueuePostprocess(EffectQueuePostprocess source)
107
    ///////////////////////////////////////////////////////////////////////////////////////////////
108
    internal constructor(source: EffectQueuePostprocess) : super(source)
72 109
    {
73
    super(source);
74

  
75
    mHalo = source.mHalo;
76
    mUseHaloDepth = source.mUseHaloDepth;
77
    mR = source.mR;
78
    mG = source.mG;
79
    mB = source.mB;
80
    mA = source.mA;
110
        mHalo         = source.mHalo
111
        mUseHaloDepth = source.mUseHaloDepth
112
        mR            = source.mR
113
        mG            = source.mG
114
        mB            = source.mB
115
        mA            = source.mA
81 116
    }
82 117

  
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

  
85
  void compute(long currTime, long step)
118
    ///////////////////////////////////////////////////////////////////////////////////////////////
119
    fun compute(currTime: Long, step: Long)
86 120
    {
87
    mR = mG = mB = mA = 0.0f;
88
    mHalo = 0;
89
    int halo;
90
    float[] array = mUBF.getBackingArray();
91

  
92
    for(int i=0; i<mNumEffects; i++)
93
      {
94
      // first zero out the 'alpha' because BLUR effect will not overwrite this (it is a 1D effect)
95
      // and if previously there was a GLOW effect here then mA would be non-zero and we don't want
96
      // that (see preprocess())
97
      array[NUM_FLOAT_UNIFORMS*i+5]=0.0f;
98

  
99
      PostprocessEffect effect = (PostprocessEffect)mEffects[i];
100

  
101
      if( effect.compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step) )
121
        mA = 0.0f
122
        mB = mA
123
        mG = mB
124
        mR = mG
125
        mHalo = 0
126
        var halo: Int
127
        val array = mUBF!!.backingArray
128

  
129
        for (i in 0..<numEffects)
102 130
        {
103
        EffectMessageSender.newMessage(mEffects[i]);
104
        }
131
            // first zero out the 'alpha' because BLUR effect will not overwrite this (it is a 1D effect)
132
            // and if previously there was a GLOW effect here then mA would be non-zero and we don't want
133
            // that (see preprocess())
134
            array[NUM_FLOAT_UNIFORMS*i+5] = 0.0f
105 135

  
106
      halo = (int)array[NUM_FLOAT_UNIFORMS*i];
107
      if( halo>mHalo ) mHalo = halo;
108

  
109
      // TODO  (now only really works in case of 1 effect!)
110
      mUseHaloDepth = effect.getHaloDepth();
111
      }
112

  
113
    // TODO  (now only really works in case of 1 effect!)
114
    if( mNumEffects>0 )
115
      {
116
      mR = array[2];
117
      mG = array[3];
118
      mB = array[4];
119
      mA = array[5];
120
      }
121
    }
136
            val effect = mEffects[i] as PostprocessEffect
122 137

  
123
///////////////////////////////////////////////////////////////////////////////////////////////////
138
            if (effect.compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step))
139
                newMessage(mEffects[i]!!)
124 140

  
125
  public static void createPrograms(InputStream vert, InputStream frag, int GLSL)
126
    {
127
    int numV = VertexEffect.getNumEnabled();
128

  
129
    String version = "#version "+GLSL+" es\n";
130
    String mainVertHeader= version + ("#define NUM_VERTEX " + ( numV>0 ? DistortedLibrary.getMax(EffectType.VERTEX  ) : 0 ) + "\n");
131
    String mainFragHeader= version + "\n";
132

  
133
    mainVertHeader += "#define MAX_COMPON " + MeshBase.getMaxEffComponents() + "\n";
134
    if( MeshBase.getUseCenters() )      mainVertHeader += "#define COMP_CENTERS\n";
135
    if( DistortedLibrary.isUBOBuggy() ) mainVertHeader += "#define BUGGY_UBOS\n";
136
    mainVertHeader += "#define POSTPROCESS\n";
137

  
138
    String enabledEffectV= VertexEffect.getGLSL();
139

  
140
    try
141
      {
142
      mPreProgram = new DistortedProgram(vert, frag, mainVertHeader, mainFragHeader,
143
                                         enabledEffectV, null, GLSL, null);
144
      }
145
    catch(Exception e)
146
      {
147
      DistortedLibrary.logMessage("EffectQueuePostprocess "+ e.getClass().getSimpleName()+" trying to compile PRE program: "+e.getMessage());
148
      throw new RuntimeException(e.getMessage());
149
      }
150

  
151
    mPreProgramH = mPreProgram.getProgramHandle();
152
    EffectQueue.getUniforms( mPreProgramH,2 );
153
    MeshBase.getUniforms( mPreProgramH,2 );
154
    mPreColorH  = GLES30.glGetUniformLocation( mPreProgramH, "u_Color"  );
155
    mPreTextureH= GLES30.glGetUniformLocation( mPreProgramH, "u_Texture");
156
    }
157

  
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159
// TODO  (now only really works in case of 1 effect!)
141
            halo = array[NUM_FLOAT_UNIFORMS*i].toInt()
142
            if (halo>mHalo) mHalo = halo
160 143

  
161
  public int getQuality()
162
    {
163
    return mNumEffects>0 ? ((PostprocessEffect)mEffects[0]).getQuality() : 0;
164
    }
165

  
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167
// TODO  (now only really works in case of 1 effect!)
144
            // TODO  (now only really works in case of 1 effect!)
145
            mUseHaloDepth = effect.haloDepth
146
        }
168 147

  
169
  public boolean getRenderDirectly()
170
    {
171
    return mNumEffects>0 && ((PostprocessEffect) mEffects[0]).getRenderDirectly();
148
        // TODO  (now only really works in case of 1 effect!)
149
        if (numEffects > 0)
150
        {
151
            mR = array[2]
152
            mG = array[3]
153
            mB = array[4]
154
            mA = array[5]
155
        }
172 156
    }
173 157

  
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

  
176
  public int preprocess(InternalOutputSurface buffer, DistortedNode node, float distance, float mipmap, float[] projection)
158
    ///////////////////////////////////////////////////////////////////////////////////////////////
159
    fun preprocess(buffer: InternalOutputSurface, node: DistortedNode, distance: Float,
160
                   mipmap: Float, projection: FloatArray): Int
177 161
    {
178
    MeshBase mesh = node.getMesh();
179
    DistortedEffects effects = node.getEffects();
180

  
181
    int width   = buffer.getWidth();
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff