Exemplo n.º 1
0
        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;
			}
		}
Exemplo n.º 4
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);
            }
        }