Exemplo n.º 1
0
 internal GpuParticleProcessorData(ParticleSystemTypeData typeData, bool useColourValues, bool usesUserValues, bool storeLifeData, TargetPlatform targetPlatform) : this(
         GpuParticleShaderBuilder.BuildGpuLogicPixelShader(typeData.ParticleLogicData.Once, GpuParticleShaderBuilder.LogicType.Once, usesUserValues, useColourValues, storeLifeData, targetPlatform, typeData.GpuBufferPosition),
         GpuParticleShaderBuilder.BuildGpuLogicPixelShader(typeData.ParticleLogicData.Once, GpuParticleShaderBuilder.LogicType.OnceClone, usesUserValues, useColourValues, storeLifeData, targetPlatform, typeData.GpuBufferPosition),
         GpuParticleShaderBuilder.BuildGpuLogicPixelShader(typeData.ParticleLogicData.Frame, GpuParticleShaderBuilder.LogicType.Frame, usesUserValues, useColourValues, storeLifeData, targetPlatform, typeData.GpuBufferPosition),
         GpuParticleShaderBuilder.BuildGpuLogicPixelShader(typeData.ParticleLogicData.Frame, GpuParticleShaderBuilder.LogicType.FrameMove, usesUserValues, useColourValues, storeLifeData, targetPlatform, typeData.GpuBufferPosition))
 {
 }
Exemplo n.º 2
0
        void IParticleProcessor.Initalise(ParticleSystemTypeData typeData, IParticleProcessor[] allProcessors, bool useColourValues, uint maxLifeTimeSteps, uint timeStepHz, uint maxExpectedCount)
        {
            CpuParticleProcessorData processor = typeData.RuntimeLogicData.CpuParticleProcessorData;

            this.particleTypeData = typeData;
            this.timeStepHz       = timeStepHz;
            this.processors       = allProcessors;
            this.addIndices       = new uint[8];

            //max expected count is always a power of 2
            this.maxCount  = maxExpectedCount;
            this.countMask = maxExpectedCount - 1;

            bool usesUserValues = typeData.RuntimeLogicData.SystemUsesUserValues;
            bool usesLifeOrAge  = typeData.RuntimeLogicData.SystemUsesLifeOrAgeValues;

            positions = new Vector4[maxExpectedCount];
            velocity  = new Vector4[maxExpectedCount];

            if (useColourValues)
            {
                colours = new Vector4[maxExpectedCount];
            }

            if (usesUserValues)
            {
                userdata = new Vector4[maxExpectedCount];
            }

            if (usesLifeOrAge)
            {
                lifeData = new Vector2[maxExpectedCount];
            }

            System.Reflection.Assembly asm = processor.Assembly;

            Type type = asm.GetType(processor.RuntimeClassName);

            System.Reflection.MethodInfo frameMethod = type.GetMethod(typeData.Name + "_frame", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
            System.Reflection.MethodInfo onceMethod  = type.GetMethod(typeData.Name + "_once", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);

            this.frameMethod = (UpdateParticleDelegate)Delegate.CreateDelegate(typeof(UpdateParticleDelegate), frameMethod);
            this.onceMethod  = (AddParticleDelegate)Delegate.CreateDelegate(typeof(AddParticleDelegate), onceMethod);
        }
		//build it
		public ParticleStore(uint maxTimeSteps, ParticleSystemTypeData type, IParticleProcessor processor, int particleTypeCount, int particleTypeIndex)
		{
			if (type == null)
				throw new ArgumentNullException();
			
			this.typeEmitDependancy = new bool[particleTypeCount + 1];
			this.particleTypeIndex = particleTypeIndex;

			this.particleType = type;
			this.processor = processor;

			this.frameEmitter = type.FrameEmitter;
			this.removeEmitter = type.RemoveEmitter;

			this.timeStepCount = 1;
			while (maxTimeSteps > this.timeStepCount)
				this.timeStepCount *= 2;

			this.timeStepMask = (int)this.timeStepCount - 1;

			this.timeSteps = new SystemTimeStep[timeStepCount];
			this.particles = new Particle[Math.Max(4,type.ExpectedMaxCapacity)];

			this.addActions = new AddAction[8];
			this.copyActions = new CopyAction[8];
		}
Exemplo n.º 4
0
 //all code for the particle types are stored in the same assmebly
 internal void AddParticleType(ParticleSystemTypeData typeData)
 {
     methods.Add(CpuParticleLogicBuilder.BuildCpuLogic(typeData.Name + "_frame", typeData.ParticleLogicData.Frame, false));
     methods.Add(CpuParticleLogicBuilder.BuildCpuLogic(typeData.Name + "_once", typeData.ParticleLogicData.Once, true));
 }
Exemplo n.º 5
0
        void IParticleProcessor.Initalise(ParticleSystemTypeData typeData, IParticleProcessor[] allProcessors, bool useColourValues, uint maxLifeTimeSteps, uint timeStepHz, uint maxExpectedCount)
        {
            this.processorData = typeData.RuntimeLogicData.GpuParticleProcessorData;

            //compute resolution to fit the particle count
            this.resolutionX = 2;
            this.resolutionY = 2;

            while (true)
            {
                int count = resolutionX * resolutionY;
                if (count >= maxExpectedCount)
                {
                    break;
                }
                if (resolutionY >= resolutionX)
                {
                    resolutionX *= 2;
                }
                else
                {
                    resolutionY *= 2;
                }
            }

            resolutionXF = (float)resolutionX;
            resolutionYF = (float)resolutionY;

            this.particleTypeData = typeData;

            this.allProcessors      = allProcessors;
            this.renderPasses       = new GpuParticleRenderPass[4];
            this.shaderRandomValues = new Random();

            this.maxParticleTimeStep = maxLifeTimeSteps;
            this.systemStepDeltaTime = 1.0f / ((float)timeStepHz);

            bool usesUserValues = typeData.RuntimeLogicData.SystemUsesUserValues;
            bool usesLifeOrAge  = typeData.RuntimeLogicData.SystemUsesLifeOrAgeValues;

            this.usesLifeStorage = usesLifeOrAge;

            SurfaceFormat vec4Format = SurfaceFormat.HalfVector4;

            if (!ParticleSystem.gpuVTexHalfVec4supported)
            {
                vec4Format = SurfaceFormat.Vector4;
            }

            this.positionSizeBufferA     = new DrawTargetTexture2D(camera, resolutionX, resolutionY, vec4Format);
            this.velocityRotationBufferA = new DrawTargetTexture2D(camera, resolutionX, resolutionY, vec4Format);

            if (useColourValues)
            {
                this.colourBufferA = new DrawTargetTexture2D(camera, resolutionX, resolutionY, vec4Format);
            }
            if (usesUserValues)
            {
                this.userBufferA = new DrawTargetTexture2D(camera, resolutionX, resolutionY, vec4Format);
            }

#if XBOX360
            //technically doing this can produce bugs when the buffers combine to be greater than 10MiB
            //(approx ~320,000 particles)
            //This can happen as the textures are updated in tiles, and it's possible for a particle
            //to be shifted across a tile and recieve an invalid update. However the majority of the time,
            //this would only cause a particle to be a frame behind or ahead. Worst case is the particle
            //either dissapears or is duplicated.

            //it is considered a worthwhile tradeoff for half the render target memory usage

            this.positionSizeBufferB     = positionSizeBufferA;
            this.velocityRotationBufferB = velocityRotationBufferA;
            this.colourBufferB           = colourBufferA;
            this.userBufferB             = userBufferA;
#else
            this.positionSizeBufferB     = new DrawTargetTexture2D(camera, resolutionX, resolutionY, vec4Format);
            this.velocityRotationBufferB = new DrawTargetTexture2D(camera, resolutionX, resolutionY, vec4Format);

            if (useColourValues)
            {
                this.colourBufferB = new DrawTargetTexture2D(camera, resolutionX, resolutionY, vec4Format);
            }
            if (usesUserValues)
            {
                this.userBufferB = new DrawTargetTexture2D(camera, resolutionX, resolutionY, vec4Format);
            }
#endif

            //setup the render target groups (MRT)
            DrawTargetTexture2D[] targets = new DrawTargetTexture2D[2 + (useColourValues ? 1 : 0) + (usesUserValues ? 1 : 0)];

            targets[0] = positionSizeBufferA;
            targets[1] = velocityRotationBufferA;
            if (useColourValues)
            {
                targets[2] = colourBufferA;
            }
            if (usesUserValues)
            {
                targets[targets.Length - 1] = userBufferA;
            }

            this.mrtGroupA = new DrawTargetTexture2DGroup(camera, targets);

            targets[0] = positionSizeBufferB;
            targets[1] = velocityRotationBufferB;
            if (useColourValues)
            {
                targets[2] = colourBufferB;
            }
            if (usesUserValues)
            {
                targets[targets.Length - 1] = userBufferB;
            }

            this.mrtGroupB = new DrawTargetTexture2DGroup(camera, targets);


            this.mrtGroupA.ClearBuffer.Enabled = false;
            this.mrtGroupB.ClearBuffer.Enabled = false;


            if (usesLifeOrAge)
            {
                SurfaceFormat ageFormat = SurfaceFormat.HalfVector2;

                if (!ParticleSystem.gpuVTexHalfVec2supported)
                {
                    ageFormat = SurfaceFormat.HalfVector4;

                    if (!ParticleSystem.gpuVTexHalfVec4supported)
                    {
                        ageFormat = SurfaceFormat.Vector4;
                    }
                }

#if XBOX360
                lifeStoreBufferA = new DrawTargetTexture2D(camera, resolutionX, resolutionY, ageFormat);
                lifeStoreBufferB = lifeStoreBufferA;
                lifeStoreBufferA.ClearBuffer.Enabled = false;

                lifeStoreBufferA.Add(new TexturedElement(lifeStoreBufferA, Vector2.One, true));
#else
                lifeStoreBufferA = new DrawTargetTexture2D(camera, resolutionX, resolutionY, ageFormat);
                lifeStoreBufferB = new DrawTargetTexture2D(camera, resolutionX, resolutionY, ageFormat);
                lifeStoreBufferA.ClearBuffer.Enabled = false;
                lifeStoreBufferB.ClearBuffer.Enabled = false;

                //setup so that when a store buffer is drawn, it copies in the other buffer.

                lifeStoreBufferA.Add(new TexturedElement(lifeStoreBufferB, Vector2.One, true));
                lifeStoreBufferB.Add(new TexturedElement(lifeStoreBufferA, Vector2.One, true));
#endif
            }


            this.scissorTest = new Xen.Graphics.Modifier.ScissorModifier(0, 0, 1, 1);

            //scissor off the MRT, as it uses a fullsize quad to run the particle logic for every particle
            this.mrtGroupA.AddModifier(scissorTest);
            this.mrtGroupB.AddModifier(scissorTest);

            //this is the pass that runs per-frame logic on the particles
            this.backgroundFillPass = new ShaderElement(this.processorData.FrameShader, new Vector2(1, 1), true);

            this.mrtGroupA.Add(backgroundFillPass);
            this.mrtGroupB.Add(backgroundFillPass);

            this.mrtGroupA.Add(this);
            this.mrtGroupB.Add(this);

            if (usesLifeOrAge)
            {
                this.lifeStoreBufferA.Add(this);
#if !XBOX360
                this.lifeStoreBufferB.Add(this);
#endif
            }
        }
		internal GpuParticleProcessorData(ParticleSystemTypeData typeData, bool useColourValues, bool usesUserValues, bool storeLifeData, ContentTargetPlatform targetPlatform, string pathToShaderSystem) : this(
			GpuParticleShaderBuilder.BuildGpuLogicPixelShader(typeData.ParticleLogicData.Once, GpuParticleShaderBuilder.LogicType.Once, GpuParticleShaderBuilder.VertexShaderType.Once, usesUserValues, useColourValues, storeLifeData, targetPlatform, typeData.GpuBufferPosition, pathToShaderSystem),
			GpuParticleShaderBuilder.BuildGpuLogicPixelShader(typeData.ParticleLogicData.Once, GpuParticleShaderBuilder.LogicType.OnceClone, GpuParticleShaderBuilder.VertexShaderType.Clone, usesUserValues, useColourValues, storeLifeData, targetPlatform, typeData.GpuBufferPosition, pathToShaderSystem),
			GpuParticleShaderBuilder.BuildGpuLogicPixelShader(typeData.ParticleLogicData.Frame, GpuParticleShaderBuilder.LogicType.Frame, GpuParticleShaderBuilder.VertexShaderType.Frame, usesUserValues, useColourValues, storeLifeData, targetPlatform, typeData.GpuBufferPosition, pathToShaderSystem),
			GpuParticleShaderBuilder.BuildGpuLogicPixelShader(typeData.ParticleLogicData.Frame, GpuParticleShaderBuilder.LogicType.FrameMove, GpuParticleShaderBuilder.VertexShaderType.Clone, usesUserValues, useColourValues, storeLifeData, targetPlatform, typeData.GpuBufferPosition, pathToShaderSystem))
		{
		}
		//all code for the particle types are stored in the same assmebly
		internal void AddParticleType(ParticleSystemTypeData typeData)
		{
			methods.Add(CpuParticleLogicBuilder.BuildCpuLogic(typeData.Name+"_frame",typeData.ParticleLogicData.Frame,false));
			methods.Add(CpuParticleLogicBuilder.BuildCpuLogic(typeData.Name+"_once",typeData.ParticleLogicData.Once,true));
		}
		void IParticleProcessor.Initalise(ParticleSystemTypeData typeData, IParticleProcessor[] allProcessors, bool useColourValues, uint maxLifeTimeSteps, uint timeStepHz, uint maxExpectedCount)
		{
			CpuParticleProcessorData processor = typeData.RuntimeLogicData.CpuParticleProcessorData;

			this.particleTypeData = typeData;
			this.timeStepHz = timeStepHz;
			this.processors = allProcessors;
			this.addIndices = new uint[8];

			//max expected count is always a power of 2
			this.maxCount = maxExpectedCount;
			this.countMask = maxExpectedCount - 1;

			bool usesUserValues = typeData.RuntimeLogicData.SystemUsesUserValues;
			bool usesLifeOrAge = typeData.RuntimeLogicData.SystemUsesLifeOrAgeValues;

			positions = new Vector4[maxExpectedCount];
			velocity = new Vector4[maxExpectedCount];

			if (useColourValues)
				colours = new Vector4[maxExpectedCount];

			if (usesUserValues)
				userdata = new Vector4[maxExpectedCount];

			if (usesLifeOrAge)
				lifeData = new Vector2[maxExpectedCount];

			System.Reflection.Assembly asm = processor.Assembly;

			Type type = asm.GetType(processor.RuntimeClassName);

			System.Reflection.MethodInfo frameMethod = type.GetMethod(typeData.Name + "_frame", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);
			System.Reflection.MethodInfo onceMethod = type.GetMethod(typeData.Name + "_once", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public);

			this.frameMethod = (UpdateParticleDelegate)Delegate.CreateDelegate(typeof(UpdateParticleDelegate), frameMethod);
			this.onceMethod = (AddParticleDelegate)Delegate.CreateDelegate(typeof(AddParticleDelegate), onceMethod);
		}