public void Dispose() { DisposeMember(ref vs); DisposeMember(ref ps); positionSize = null; velocityRotation = null; colourValues = null; userValues = null; randTexture = null; lifeTexture = null; vreg = null; psConstants = null; vsMoveConstants = null; constantCache = null; }
public void Dispose() { fx.Dispose(); positionSize = null; velocityRotation = null; colourValues = null; userValues = null; randTexture = null; lifeTexture = null; vreg = null; psConstants = null; vsMoveConstants = null; constantCache = null; }
//setup the shaders that copy or add particles public int SetMoveShaderEnabled(DrawState state, GpuParticleProcessor target, GpuParticleProcessor moveSource, Vector4[] constants, ParticleSpawnValues[] initialData, int count, int startIndex) { if (constants != null) { if (constantCache == null) { constantCache = state.Application.UserValues[ConstantCacheName] as ConstantCache; if (constantCache == null) { constantCache = new ConstantCache(); state.Application.UserValues[ConstantCacheName] = constantCache; } } Vector4[] buffer = null; int copyCount = 0; int regCount = count; if (initialData != null) regCount = Math.Min(240, count * 5); //adding requires potentially lots of space if (count > 128) { copyCount = Math.Min(240, regCount); buffer = constantCache.buffer240; } else if (regCount > 64) { copyCount = Math.Min(128, regCount); buffer = constantCache.buffer128; } else if (regCount > 32) { copyCount = Math.Min(64, regCount); buffer = constantCache.buffer64; } else if (regCount > 16) { copyCount = Math.Min(32, regCount); buffer = constantCache.buffer32; } else { copyCount = Math.Min(16, regCount); buffer = constantCache.buffer16; } if (initialData != null) this.enabledAddVS = true; else this.enabledMoveVS = true; this.vsMoveConstants = buffer; //write from the 7th index on int index = ConstantCacheOffset; if (initialData != null) { //initial data gets rather complex. //the initial particle data is huge (64bytes), but often there is loads of duplicates. // //the constants array also doesn't use the 'y' value. //So, the starting info will be put in a dictionary, to remove duplicates. //Then, the y value will be used to write indices to read from. //at this point, the copyCount value is useless. spawnIndices.Clear(); int space = buffer.Length - index; int written = 0; float indexF = 0; int endIndex = count + startIndex; //copy as many entries as possible copyCount = 0; float offset = 0; for (int i = startIndex; i < endIndex; i++) { float dataIndex; if (written == space) break; if (!spawnIndices.TryGetValue(initialData[i], out dataIndex)) { //have to write data if (written + 5 > space) break; Vector4 value = constants[i]; value.Y = indexF; buffer[index++] = value; spawnIndices.Add(initialData[i], indexF); written += 5; indexF += 4;//value takes 4 registers } else { //this is a duplicate Vector4 value = constants[i]; value.Y = dataIndex; buffer[index++] = value; written ++; } copyCount++; offset++; } //thats as much as can be written //fill in the details... //offset the indices with the starting point to read from for (int i = 0; i < copyCount; i++) buffer[ConstantCacheOffset + i].Y += offset; indexF = 0; foreach (ParticleSpawnValues value in spawnIndices.Keys) { //this should be in logical order if (indexF != spawnIndices[value]) throw new InvalidOperationException(); indexF += 4; buffer[index++] = value.PositionSize; buffer[index++] = value.VelocityRotation; buffer[index++] = value.Colour; buffer[index++] = value.UserValues; } } else { for (int i = 0; i < copyCount; i++) buffer[index++] = constants[startIndex++]; } //write target size into index 4 XY //write destination size into index 5 XY moveSource = moveSource ?? target; buffer[4] = new Vector4(target.ResolutionX, target.ResolutionY, 1.0f / target.ResolutionX, 1.0f / target.ResolutionY); buffer[5] = new Vector4(moveSource.ResolutionX, moveSource.ResolutionY, 1.0f / moveSource.ResolutionX, 1.0f / moveSource.ResolutionY); return copyCount; } else { this.vsMoveConstants = null; this.enabledMoveVS = false; this.enabledAddVS = false; return 0; } }
//setup the shaders that copy or add particles public int SetMoveShaderEnabled(DrawState state, GpuParticleProcessor target, GpuParticleProcessor moveSource, Vector4[] constants, ParticleSpawnValues[] initialData, int count, int startIndex) { if (constants != null) { if (constantCache == null) { constantCache = state.UserValues[ConstantCacheName] as ConstantCache; if (constantCache == null) { constantCache = new ConstantCache(); state.UserValues[ConstantCacheName] = constantCache; } } Vector4[] buffer = null; int copyCount = 0; int regCount = count; if (initialData != null) { regCount = Math.Min(240, count * 5); //adding requires potentially lots of space } if (count > 128) { copyCount = Math.Min(240, regCount); buffer = constantCache.buffer240; } else if (regCount > 64) { copyCount = Math.Min(128, regCount); buffer = constantCache.buffer128; } else if (regCount > 32) { copyCount = Math.Min(64, regCount); buffer = constantCache.buffer64; } else if (regCount > 16) { copyCount = Math.Min(32, regCount); buffer = constantCache.buffer32; } else { copyCount = Math.Min(16, regCount); buffer = constantCache.buffer16; } if (initialData != null) { this.enabledAddVS = true; } else { this.enabledMoveVS = true; } this.vsMoveConstants = buffer; //write from the 7th index on int index = ConstantCacheOffset; if (initialData != null) { //initial data gets rather complex. //the initial particle data is huge (64bytes), but often there is loads of duplicates. // //the constants array also doesn't use the 'y' value. //So, the starting info will be put in a dictionary, to remove duplicates. //Then, the y value will be used to write indices to read from. //at this point, the copyCount value is useless. spawnIndices.Clear(); int space = buffer.Length - index; int written = 0; float indexF = 0; int endIndex = count + startIndex; //copy as many entries as possible copyCount = 0; float offset = 0; for (int i = startIndex; i < endIndex; i++) { float dataIndex; if (written == space) { break; } if (!spawnIndices.TryGetValue(initialData[i], out dataIndex)) { //have to write data if (written + 5 > space) { break; } Vector4 value = constants[i]; value.Y = indexF; buffer[index++] = value; spawnIndices.Add(initialData[i], indexF); written += 5; indexF += 4; //value takes 4 registers } else { //this is a duplicate Vector4 value = constants[i]; value.Y = dataIndex; buffer[index++] = value; written++; } copyCount++; offset++; } //thats as much as can be written //fill in the details... //offset the indices with the starting point to read from for (int i = 0; i < copyCount; i++) { buffer[ConstantCacheOffset + i].Y += offset; } indexF = 0; foreach (ParticleSpawnValues value in spawnIndices.Keys) { //this should be in logical order if (indexF != spawnIndices[value]) { throw new InvalidOperationException(); } indexF += 4; buffer[index++] = value.PositionSize; buffer[index++] = value.VelocityRotation; buffer[index++] = value.Colour; buffer[index++] = value.UserValues; } } else { for (int i = 0; i < copyCount; i++) { buffer[index++] = constants[startIndex++]; } } //write target size into index 4 XY //write destination size into index 5 XY moveSource = moveSource ?? target; buffer[4] = new Vector4(target.ResolutionX, target.ResolutionY, 1.0f / target.ResolutionX, 1.0f / target.ResolutionY); buffer[5] = new Vector4(moveSource.ResolutionX, moveSource.ResolutionY, 1.0f / moveSource.ResolutionX, 1.0f / moveSource.ResolutionY); return(copyCount); } else { this.vsMoveConstants = null; this.enabledMoveVS = false; this.enabledAddVS = false; return(0); } }