Esempio n. 1
0
 public ProcessorAddList(IParticleProcessor processor)
 {
     this.processor = processor as GpuParticleProcessor;
 }
Esempio n. 2
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);
            }
        }