Revision 9ae0853e
Added by Leszek Koltunski 6 months ago
| 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(); | |
Also available in: Unified diff
transition the 'effectqueue' package.