Revision 241d3e5f
Added by Leszek Koltunski 6 months ago
| src/main/java/org/distorted/library/effectqueue/EffectQueue.java | ||
|---|---|---|
| 1 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 2 | // Copyright 2016 Leszek Koltunski leszek@koltunski.pl // | |
| 3 | // // | |
| 4 | // This file is part of Distorted. // | |
| 5 | // // | |
| 6 | // This library is free software; you can redistribute it and/or // | |
| 7 | // modify it under the terms of the GNU Lesser General Public // | |
| 8 | // License as published by the Free Software Foundation; either // | |
| 9 | // version 2.1 of the License, or (at your option) any later version. // | |
| 10 | // // | |
| 11 | // This library 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 GNU // | |
| 14 | // Lesser General Public License for more details. // | |
| 15 | // // | |
| 16 | // You should have received a copy of the GNU Lesser General Public // | |
| 17 | // License along with this library; if not, write to the Free Software // | |
| 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // | |
| 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 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; | |
| 34 |  | |
| 35 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 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 | |
| 65 |     {
 | |
| 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 | } | |
| 79 | } | |
| 80 |  | |
| 81 | private final ArrayList<Job> mJobs; | |
| 82 |  | |
| 83 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 84 |  | |
| 85 | EffectQueue(int numFloatUniforms, int numIntUniforms, boolean useUBO, int index) | |
| 86 |     {
 | |
| 87 | mCreated = false; | |
| 88 | mID = 0; | |
| 89 | mNumEffects = 0; | |
| 90 | mNumEffectsToBe = 0; | |
| 91 | mIndex = index; | |
| 92 |  | |
| 93 | mJobs = new ArrayList<>(); | |
| 94 |  | |
| 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. | |
| 101 |  | |
| 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(); | |
| 115 |  | |
| 116 | for(int i=0; i<numJobs; i++) | |
| 117 |         {
 | |
| 118 | Job job = source.mJobs.get(i); | |
| 119 | mJobs.add(job); | |
| 120 | } | |
| 121 |  | |
| 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; | |
| 131 |  | |
| 132 | mJobs = new ArrayList<>(); | |
| 133 |  | |
| 134 | int max = InternalStackFrameList.getMax(mIndex); | |
| 135 |  | |
| 136 | if( max>0 ) | |
| 137 |         {
 | |
| 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 | } | |
| 146 | } | |
| 147 | } | |
| 148 | } | |
| 149 |  | |
| 150 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 151 |  | |
| 152 | public static void allocateQueues(EffectQueue[] queues, EffectQueue[] from, int flags) | |
| 153 |     {
 | |
| 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 | } | |
| 159 |  | |
| 160 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 161 |  | |
| 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); | |
| 168 | } | |
| 169 |  | |
| 170 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 171 |  | |
| 172 | public static void send(EffectQueue[] queues, int programH, float distance, float mipmap, | |
| 173 | float[] projection, float inflate, int variant ) | |
| 174 |     {
 | |
| 175 | ((EffectQueueMatrix )queues[0]).send(distance, mipmap, projection, variant); | |
| 176 | ((EffectQueueVertex )queues[1]).send(inflate, programH, variant); | |
| 177 | ((EffectQueueFragment)queues[2]).send(variant); | |
| 178 | } | |
| 179 |  | |
| 180 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 181 | // variant: 0 --> MAIN 1 --> OIT 2 --> prePOST 3 --> FULL | |
| 182 |  | |
| 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 | } | |
| 189 |  | |
| 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) | |
| 194 |  | |
| 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; | |
| 207 | } | |
| 208 | else | |
| 209 |         {
 | |
| 210 | mID = InternalStackFrameList.getNextQueueID(); | |
| 211 | map.put(list,mID); | |
| 212 | } | |
| 213 | } | |
| 214 | else | |
| 215 |       {
 | |
| 216 | mID = 0; | |
| 217 | } | |
| 218 | } | |
| 219 |  | |
| 220 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 221 |  | |
| 222 | public long getID() | |
| 223 |     {
 | |
| 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); | |
| 239 | } | |
| 240 |  | |
| 241 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 242 | // this assumes 0<=effect | |
| 243 |  | |
| 244 | private void removeNow(int pos) | |
| 245 |     {
 | |
| 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 | } | |
| 254 | } | |
| 255 |  | |
| 256 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 257 |  | |
| 258 | private void addNow(int pos, Effect effect) | |
| 259 |     {
 | |
| 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 | } | |
| 268 | } | |
| 269 |  | |
| 270 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 271 |  | |
| 272 | public synchronized int removeByName(EffectName name) | |
| 273 |     {
 | |
| 274 | int ret = 0; | |
| 275 |  | |
| 276 | for(int i=0; i<mNumEffects; i++) | |
| 277 |       {
 | |
| 278 | if( mEffects[i].getName() == name ) | |
| 279 |         {
 | |
| 280 | mJobs.add(new Job(DETACH,0,0,true,mEffects[i])); | |
| 281 | ret++; | |
| 282 | } | |
| 283 | } | |
| 284 |  | |
| 285 | if( ret>0 ) | |
| 286 |       {
 | |
| 287 | InternalMaster.newSlave(this); | |
| 288 | mNumEffectsToBe-=ret; | |
| 289 | } | |
| 290 |  | |
| 291 | return ret; | |
| 292 | } | |
| 293 |  | |
| 294 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 295 |  | |
| 296 | public synchronized int removeById(long id) | |
| 297 |     {
 | |
| 298 | for(int i=0; i<mNumEffects; i++) | |
| 299 |       {
 | |
| 300 | if( mEffects[i].getID() == id ) | |
| 301 |         {
 | |
| 302 | mJobs.add(new Job(DETACH,0,0,true,mEffects[i])); | |
| 303 | InternalMaster.newSlave(this); | |
| 304 | mNumEffectsToBe--; | |
| 305 | return 1; | |
| 306 | } | |
| 307 | } | |
| 308 |  | |
| 309 | return 0; | |
| 310 | } | |
| 311 |  | |
| 312 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 313 |  | |
| 314 | public synchronized int removeEffect(Effect effect) | |
| 315 |     {
 | |
| 316 | for(int i=0; i<mNumEffects; i++) | |
| 317 |       {
 | |
| 318 | if( mEffects[i]==effect ) | |
| 319 |         {
 | |
| 320 | mJobs.add(new Job(DETACH,0,0,true,mEffects[i])); | |
| 321 | InternalMaster.newSlave(this); | |
| 322 | mNumEffectsToBe--; | |
| 323 | return 1; | |
| 324 | } | |
| 325 | } | |
| 326 |  | |
| 327 | return 0; | |
| 328 | } | |
| 329 |  | |
| 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; | |
| 355 | } | |
| 356 |  | |
| 357 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 358 |  | |
| 359 | public boolean add(Effect effect, int position) | |
| 360 |     {
 | |
| 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; | |
| 370 | } | |
| 371 |  | |
| 372 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 373 |  | |
| 374 | public boolean exists(long id) | |
| 375 |     {
 | |
| 376 | for(int i=0; i<mNumEffects; i++) | |
| 377 |       {
 | |
| 378 | if( mEffects[i].getID() == id ) return true; | |
| 379 | } | |
| 380 |  | |
| 381 | return false; | |
| 382 | } | |
| 383 |  | |
| 384 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 385 |  | |
| 386 | public int getNumEffects() | |
| 387 |     {
 | |
| 388 | return mNumEffects; | |
| 389 | } | |
| 390 |  | |
| 391 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 392 |  | |
| 393 | public int getNumEffectsToBe() | |
| 394 |     {
 | |
| 395 | return mNumEffectsToBe; | |
| 396 | } | |
| 397 |  | |
| 398 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 399 |  | |
| 400 | public Effect getEffect(int position) | |
| 401 |     {
 | |
| 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 | } | |
| 412 |  | |
| 413 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 414 |  | |
| 415 | public void setAssociation(long effectID) | |
| 416 |     {
 | |
| 417 | for(int j=0; j<mNumEffects; j++) | |
| 418 |       {
 | |
| 419 | if (mEffects[j].getID() == effectID) | |
| 420 |         {
 | |
| 421 | mUBI.addAssociations(j,mEffects[j]); | |
| 422 | } | |
| 423 | } | |
| 424 | } | |
| 425 |  | |
| 426 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 427 |  | |
| 428 | public void markForDeletion() | |
| 429 |     {
 | |
| 430 | mUBI.markForDeletion(); | |
| 431 | mUBF.markForDeletion(); | |
| 432 | } | |
| 433 |  | |
| 434 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 435 |  | |
| 436 | public String retEffects() | |
| 437 |     {
 | |
| 438 | String dbg=""; | |
| 439 |  | |
| 440 | for(int i=0; i<mNumEffects; i++) | |
| 441 |       {
 | |
| 442 | dbg += (i+": "+mEffects[i].getString()+" "); | |
| 443 | } | |
| 444 |  | |
| 445 | return dbg; | |
| 446 | } | |
| 447 |  | |
| 448 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 449 |  | |
| 450 | public void doWork() | |
| 451 |     {
 | |
| 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); | |
| 459 |  | |
| 460 | switch(job.type) | |
| 461 |         {
 | |
| 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; | |
| 521 | } | |
| 522 | } | |
| 523 |  | |
| 524 | if( changed && mIndex==EffectType.POSTPROCESS.ordinal() ) regenerateID(); | |
| 525 | } | |
| 526 | } | |
| src/main/java/org/distorted/library/effectqueue/EffectQueue.kt | ||
|---|---|---|
| 1 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 2 | // Copyright 2016 Leszek Koltunski leszek@koltunski.pl // | |
| 3 | // // | |
| 4 | // This file is part of Distorted. // | |
| 5 | // // | |
| 6 | // This library is free software; you can redistribute it and/or // | |
| 7 | // modify it under the terms of the GNU Lesser General Public // | |
| 8 | // License as published by the Free Software Foundation; either // | |
| 9 | // version 2.1 of the License, or (at your option) any later version. // | |
| 10 | // // | |
| 11 | // This library 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 GNU // | |
| 14 | // Lesser General Public License for more details. // | |
| 15 | // // | |
| 16 | // You should have received a copy of the GNU Lesser General Public // | |
| 17 | // License along with this library; if not, write to the Free Software // | |
| 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // | |
| 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 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; | |
| 34 |  | |
| 35 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 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 | |
| 65 |     {
 | |
| 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 | } | |
| 79 | } | |
| 80 |  | |
| 81 | private final ArrayList<Job> mJobs; | |
| 82 |  | |
| 83 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 84 |  | |
| 85 | EffectQueue(int numFloatUniforms, int numIntUniforms, boolean useUBO, int index) | |
| 86 |     {
 | |
| 87 | mCreated = false; | |
| 88 | mID = 0; | |
| 89 | mNumEffects = 0; | |
| 90 | mNumEffectsToBe = 0; | |
| 91 | mIndex = index; | |
| 92 |  | |
| 93 | mJobs = new ArrayList<>(); | |
| 94 |  | |
| 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. | |
| 101 |  | |
| 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(); | |
| 115 |  | |
| 116 | for(int i=0; i<numJobs; i++) | |
| 117 |         {
 | |
| 118 | Job job = source.mJobs.get(i); | |
| 119 | mJobs.add(job); | |
| 120 | } | |
| 121 |  | |
| 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; | |
| 131 |  | |
| 132 | mJobs = new ArrayList<>(); | |
| 133 |  | |
| 134 | int max = InternalStackFrameList.getMax(mIndex); | |
| 135 |  | |
| 136 | if( max>0 ) | |
| 137 |         {
 | |
| 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 | } | |
| 146 | } | |
| 147 | } | |
| 148 | } | |
| 149 |  | |
| 150 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 151 |  | |
| 152 | public static void allocateQueues(EffectQueue[] queues, EffectQueue[] from, int flags) | |
| 153 |     {
 | |
| 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 | } | |
| 159 |  | |
| 160 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 161 |  | |
| 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); | |
| 168 | } | |
| 169 |  | |
| 170 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 171 |  | |
| 172 | public static void send(EffectQueue[] queues, int programH, float distance, float mipmap, | |
| 173 | float[] projection, float inflate, int variant ) | |
| 174 |     {
 | |
| 175 | ((EffectQueueMatrix )queues[0]).send(distance, mipmap, projection, variant); | |
| 176 | ((EffectQueueVertex )queues[1]).send(inflate, programH, variant); | |
| 177 | ((EffectQueueFragment)queues[2]).send(variant); | |
| 178 | } | |
| 179 |  | |
| 180 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 181 | // variant: 0 --> MAIN 1 --> OIT 2 --> prePOST 3 --> FULL | |
| 182 |  | |
| 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 | } | |
| 189 |  | |
| 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) | |
| 194 |  | |
| 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; | |
| 207 | } | |
| 208 | else | |
| 209 |         {
 | |
| 210 | mID = InternalStackFrameList.getNextQueueID(); | |
| 211 | map.put(list,mID); | |
| 212 | } | |
| 213 | } | |
| 214 | else | |
| 215 |       {
 | |
| 216 | mID = 0; | |
| 217 | } | |
| 218 | } | |
| 219 |  | |
| 220 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 221 |  | |
| 222 | public long getID() | |
| 223 |     {
 | |
| 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); | |
| 239 | } | |
| 240 |  | |
| 241 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 242 | // this assumes 0<=effect | |
| 243 |  | |
| 244 | private void removeNow(int pos) | |
| 245 |     {
 | |
| 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 | } | |
| 254 | } | |
| 255 |  | |
| 256 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 257 |  | |
| 258 | private void addNow(int pos, Effect effect) | |
| 259 |     {
 | |
| 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 | } | |
| 268 | } | |
| 269 |  | |
| 270 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 271 |  | |
| 272 | public synchronized int removeByName(EffectName name) | |
| 273 |     {
 | |
| 274 | int ret = 0; | |
| 275 |  | |
| 276 | for(int i=0; i<mNumEffects; i++) | |
| 277 |       {
 | |
| 278 | if( mEffects[i].getName() == name ) | |
| 279 |         {
 | |
| 280 | mJobs.add(new Job(DETACH,0,0,true,mEffects[i])); | |
| 281 | ret++; | |
| 282 | } | |
| 283 | } | |
| 284 |  | |
| 285 | if( ret>0 ) | |
| 286 |       {
 | |
| 287 | InternalMaster.newSlave(this); | |
| 288 | mNumEffectsToBe-=ret; | |
| 289 | } | |
| 290 |  | |
| 291 | return ret; | |
| 292 | } | |
| 293 |  | |
| 294 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 295 |  | |
| 296 | public synchronized int removeById(long id) | |
| 297 |     {
 | |
| 298 | for(int i=0; i<mNumEffects; i++) | |
| 299 |       {
 | |
| 300 | if( mEffects[i].getID() == id ) | |
| 301 |         {
 | |
| 302 | mJobs.add(new Job(DETACH,0,0,true,mEffects[i])); | |
| 303 | InternalMaster.newSlave(this); | |
| 304 | mNumEffectsToBe--; | |
| 305 | return 1; | |
| 306 | } | |
| 307 | } | |
| 308 |  | |
| 309 | return 0; | |
| 310 | } | |
| 311 |  | |
| 312 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 313 |  | |
| 314 | public synchronized int removeEffect(Effect effect) | |
| 315 |     {
 | |
| 316 | for(int i=0; i<mNumEffects; i++) | |
| 317 |       {
 | |
| 318 | if( mEffects[i]==effect ) | |
| 319 |         {
 | |
| 320 | mJobs.add(new Job(DETACH,0,0,true,mEffects[i])); | |
| 321 | InternalMaster.newSlave(this); | |
| 322 | mNumEffectsToBe--; | |
| 323 | return 1; | |
| 324 | } | |
| 325 | } | |
| 326 |  | |
| 327 | return 0; | |
| 328 | } | |
| 329 |  | |
| 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; | |
| 355 | } | |
| 356 |  | |
| 357 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 358 |  | |
| 359 | public boolean add(Effect effect, int position) | |
| 360 |     {
 | |
| 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; | |
| 370 | } | |
| 371 |  | |
| 372 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 373 |  | |
| 374 | public boolean exists(long id) | |
| 375 |     {
 | |
| 376 | for(int i=0; i<mNumEffects; i++) | |
| 377 |       {
 | |
| 378 | if( mEffects[i].getID() == id ) return true; | |
| 379 | } | |
| 380 |  | |
| 381 | return false; | |
| 382 | } | |
| 383 |  | |
| 384 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 385 |  | |
| 386 | public int getNumEffects() | |
| 387 |     {
 | |
| 388 | return mNumEffects; | |
| 389 | } | |
| 390 |  | |
| 391 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 392 |  | |
| 393 | public int getNumEffectsToBe() | |
| 394 |     {
 | |
| 395 | return mNumEffectsToBe; | |
| 396 | } | |
| 397 |  | |
| 398 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 399 |  | |
| 400 | public Effect getEffect(int position) | |
| 401 |     {
 | |
| 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 | } | |
| 412 |  | |
| 413 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 414 |  | |
| 415 | public void setAssociation(long effectID) | |
| 416 |     {
 | |
| 417 | for(int j=0; j<mNumEffects; j++) | |
| 418 |       {
 | |
| 419 | if (mEffects[j].getID() == effectID) | |
| 420 |         {
 | |
| 421 | mUBI.addAssociations(j,mEffects[j]); | |
| 422 | } | |
| 423 | } | |
| 424 | } | |
| 425 |  | |
| 426 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 427 |  | |
| 428 | public void markForDeletion() | |
| 429 |     {
 | |
| 430 | mUBI.markForDeletion(); | |
| 431 | mUBF.markForDeletion(); | |
| 432 | } | |
| 433 |  | |
| 434 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 435 |  | |
| 436 | public String retEffects() | |
| 437 |     {
 | |
| 438 | String dbg=""; | |
| 439 |  | |
| 440 | for(int i=0; i<mNumEffects; i++) | |
| 441 |       {
 | |
| 442 | dbg += (i+": "+mEffects[i].getString()+" "); | |
| 443 | } | |
| 444 |  | |
| 445 | return dbg; | |
| 446 | } | |
| 447 |  | |
| 448 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 449 |  | |
| 450 | public void doWork() | |
| 451 |     {
 | |
| 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); | |
| 459 |  | |
| 460 | switch(job.type) | |
| 461 |         {
 | |
| 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; | |
| 521 | } | |
| 522 | } | |
| 523 |  | |
| 524 | if( changed && mIndex==EffectType.POSTPROCESS.ordinal() ) regenerateID(); | |
| 525 | } | |
| 526 | } | |
| src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.java | ||
|---|---|---|
| 1 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 2 | // Copyright 2016 Leszek Koltunski leszek@koltunski.pl // | |
| 3 | // // | |
| 4 | // This file is part of Distorted. // | |
| 5 | // // | |
| 6 | // This library is free software; you can redistribute it and/or // | |
| 7 | // modify it under the terms of the GNU Lesser General Public // | |
| 8 | // License as published by the Free Software Foundation; either // | |
| 9 | // version 2.1 of the License, or (at your option) any later version. // | |
| 10 | // // | |
| 11 | // This library 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 GNU // | |
| 14 | // Lesser General Public License for more details. // | |
| 15 | // // | |
| 16 | // You should have received a copy of the GNU Lesser General Public // | |
| 17 | // License along with this library; if not, write to the Free Software // | |
| 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // | |
| 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 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.FragmentEffect; | |
| 27 | import org.distorted.library.message.EffectMessageSender; | |
| 28 |  | |
| 29 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 30 |  | |
| 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]; | |
| 41 |  | |
| 42 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 43 |  | |
| 44 | EffectQueueFragment() | |
| 45 |     { 
 | |
| 46 | super(NUM_FLOAT_UNIFORMS, NUM_INT_UNIFORMS, USE_UBO, INDEX); | |
| 47 | } | |
| 48 |  | |
| 49 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 50 |  | |
| 51 | EffectQueueFragment(EffectQueueFragment source) | |
| 52 |     {
 | |
| 53 | super(source); | |
| 54 | } | |
| 55 |  | |
| 56 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 57 |  | |
| 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"); | |
| 63 | } | |
| 64 |  | |
| 65 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 66 |  | |
| 67 | void compute(long currTime, long step) | |
| 68 |     {
 | |
| 69 | if( mNumEffects>0 ) | |
| 70 |       {
 | |
| 71 | float[] array = mUBF.getBackingArray(); | |
| 72 |  | |
| 73 | for(int i=0; i<mNumEffects; i++) | |
| 74 |         {
 | |
| 75 | if( mEffects[i].compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step) ) | |
| 76 |           {
 | |
| 77 | EffectMessageSender.newMessage(mEffects[i]); | |
| 78 | } | |
| 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 | } | |
| 98 | } | |
| src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.kt | ||
|---|---|---|
| 1 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 2 | // Copyright 2016 Leszek Koltunski leszek@koltunski.pl // | |
| 3 | // // | |
| 4 | // This file is part of Distorted. // | |
| 5 | // // | |
| 6 | // This library is free software; you can redistribute it and/or // | |
| 7 | // modify it under the terms of the GNU Lesser General Public // | |
| 8 | // License as published by the Free Software Foundation; either // | |
| 9 | // version 2.1 of the License, or (at your option) any later version. // | |
| 10 | // // | |
| 11 | // This library 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 GNU // | |
| 14 | // Lesser General Public License for more details. // | |
| 15 | // // | |
| 16 | // You should have received a copy of the GNU Lesser General Public // | |
| 17 | // License along with this library; if not, write to the Free Software // | |
| 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // | |
| 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 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.FragmentEffect; | |
| 27 | import org.distorted.library.message.EffectMessageSender; | |
| 28 |  | |
| 29 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 30 |  | |
| 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]; | |
| 41 |  | |
| 42 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 43 |  | |
| 44 | EffectQueueFragment() | |
| 45 |     { 
 | |
| 46 | super(NUM_FLOAT_UNIFORMS, NUM_INT_UNIFORMS, USE_UBO, INDEX); | |
| 47 | } | |
| 48 |  | |
| 49 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 50 |  | |
| 51 | EffectQueueFragment(EffectQueueFragment source) | |
| 52 |     {
 | |
| 53 | super(source); | |
| 54 | } | |
| 55 |  | |
| 56 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 57 |  | |
| 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"); | |
| 63 | } | |
| 64 |  | |
| 65 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 66 |  | |
| 67 | void compute(long currTime, long step) | |
| 68 |     {
 | |
| 69 | if( mNumEffects>0 ) | |
| 70 |       {
 | |
| 71 | float[] array = mUBF.getBackingArray(); | |
| 72 |  | |
| 73 | for(int i=0; i<mNumEffects; i++) | |
| 74 |         {
 | |
| 75 | if( mEffects[i].compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step) ) | |
| 76 |           {
 | |
| 77 | EffectMessageSender.newMessage(mEffects[i]); | |
| 78 | } | |
| 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 | } | |
| 98 | } | |
| src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java | ||
|---|---|---|
| 1 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 2 | // Copyright 2016 Leszek Koltunski leszek@koltunski.pl // | |
| 3 | // // | |
| 4 | // This file is part of Distorted. // | |
| 5 | // // | |
| 6 | // This library is free software; you can redistribute it and/or // | |
| 7 | // modify it under the terms of the GNU Lesser General Public // | |
| 8 | // License as published by the Free Software Foundation; either // | |
| 9 | // version 2.1 of the License, or (at your option) any later version. // | |
| 10 | // // | |
| 11 | // This library 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 GNU // | |
| 14 | // Lesser General Public License for more details. // | |
| 15 | // // | |
| 16 | // You should have received a copy of the GNU Lesser General Public // | |
| 17 | // License along with this library; if not, write to the Free Software // | |
| 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // | |
| 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 20 |  | |
| 21 | package org.distorted.library.effectqueue; | |
| 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; | |
| 29 |  | |
| 30 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 31 |  | |
| 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) | |
| 57 |     {
 | |
| 58 | super(source); | |
| 59 | } | |
| 60 |  | |
| 61 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 62 |  | |
| 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 | } | |
| 69 |  | |
| 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++) | |
| 79 |         {
 | |
| 80 | if( mEffects[i].compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step) ) | |
| 81 |           {
 | |
| 82 | EffectMessageSender.newMessage(mEffects[i]); | |
| 83 | } | |
| 84 | } | |
| 85 | } | |
| 86 | } | |
| 87 |  | |
| 88 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 89 |  | |
| 90 | void send(float distance, float mipmap, float[] projection, int variant) | |
| 91 |     {
 | |
| 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 | } | |
| 117 |  | |
| 118 | // combined Model-View-Projection matrix | |
| 119 | MatrixHelper.multiply(mMVPMatrix, projection, mModelViewMatrixP); | |
| 120 |  | |
| 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); | |
| 124 | } | |
| 125 | } | |
| src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.kt | ||
|---|---|---|
| 1 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 2 | // Copyright 2016 Leszek Koltunski leszek@koltunski.pl // | |
| 3 | // // | |
| 4 | // This file is part of Distorted. // | |
| 5 | // // | |
| 6 | // This library is free software; you can redistribute it and/or // | |
| 7 | // modify it under the terms of the GNU Lesser General Public // | |
| 8 | // License as published by the Free Software Foundation; either // | |
| 9 | // version 2.1 of the License, or (at your option) any later version. // | |
| 10 | // // | |
| 11 | // This library 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 GNU // | |
| 14 | // Lesser General Public License for more details. // | |
| 15 | // // | |
| 16 | // You should have received a copy of the GNU Lesser General Public // | |
| 17 | // License along with this library; if not, write to the Free Software // | |
| 18 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // | |
| 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 20 |  | |
| 21 | package org.distorted.library.effectqueue; | |
| 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; | |
| 29 |  | |
| 30 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 31 |  | |
| 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) | |
| 57 |     {
 | |
| 58 | super(source); | |
| 59 | } | |
| 60 |  | |
| 61 | /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 62 |  | |
| 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 | } | |
| 69 |  | |
| 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++) | |
| 79 |         {
 | |
| 80 | if( mEffects[i].compute(array, NUM_FLOAT_UNIFORMS*i, currTime, step) ) | |
| 81 |           {
 | |
| 82 | EffectMessageSender.newMessage(mEffects[i]); | |
| 83 | } | |
| 84 | } | |
| 85 | } | |
| 86 | } | |
Also available in: Unified diff
Rename .java to .kt