예제 #1
0
 //this method is called back from the particle system
 void Content.IParticleSystemDrawer.DrawGpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint count, Texture2D positionSize, Texture2D velocityRotation, Texture2D colour, Texture2D userValues)
 {
     if ((drawMask & (1u << particleType.TypeIndex)) != 0)
     {
         this.DrawGpuParticles(state, particleType, count, alphaBlendState ?? particleType.BlendMode, positionSize, velocityRotation, colour, userValues, particleType.GpuBufferPosition);
     }
 }
예제 #2
0
 void Content.IParticleSystemDrawer.DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint count, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colour, Vector4[] userValues)
 {
     if ((drawMask & (1u << particleType.TypeIndex)) != 0)
     {
         this.DrawCpuParticles(state, particleType, count, alphaBlendState ?? particleType.BlendMode, positionSize, velocityRotation, colour, userValues);
     }
 }
예제 #3
0
        /// <summary>
        /// draws the particles on a GPU system
        /// </summary>
        protected override void DrawGpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Texture2D positionTex, Texture2D velocityRotation, Texture2D colourTex, Texture2D userValues, bool usesUserValuesPositionBuffer)
        {
            //this is very similar to the billboard drawer (see it for reference)
            Vector2 targetSize = state.DrawTarget.Size;

            state.PushRenderState();
            state.RenderState.AlphaBlend = blendMode;
            state.RenderState.DepthColourCull.DepthWriteEnabled = false;

            Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state);

            //get the shared vertice
            BillboardParticles2DElement.GenerateBillboardVertices(state, ref vertices, ref indices);

            int count = (int)particleCount;

            DrawVelocityParticles_GpuTex       shaderNoColour = null;
            DrawVelocityParticlesColour_GpuTex shaderColour   = null;
            //user variants
            DrawVelocityParticles_GpuTex_UserOffset       shaderNoColour_UO = null;
            DrawVelocityParticlesColour_GpuTex_UserOffset shaderColour_UO   = null;

            float resolutionXF = (float)positionTex.Width;
            float resolutionYF = (float)positionTex.Height;

            Vector2 invTextureSize;

            Vector2 velScale = new Vector2(velocityScale, 0);

            if (this.useRotationToScaleVelocityEffect)
            {
                velScale = new Vector2(0, velocityScale);
            }
            invTextureSize = new Vector2(1.0f / resolutionXF, 1.0f / resolutionYF);


            IShader shader;

            if (!usesUserValuesPositionBuffer)
            {
                if (colourTex != null)
                {
                    shader = shaderColour = state.GetShader <DrawVelocityParticlesColour_GpuTex>();

                    shaderColour.PositionTexture = positionTex;
                    shaderColour.ColourTexture   = colourTex;
                    shaderColour.VelocityTexture = velocityRotation;
                    shaderColour.DisplayTexture  = displayTexture;

                    shaderColour.SetVelocityScale(ref velScale);
                }
                else
                {
                    shader = shaderNoColour = state.GetShader <DrawVelocityParticles_GpuTex>();

                    shaderNoColour.PositionTexture = positionTex;
                    shaderNoColour.VelocityTexture = velocityRotation;
                    shaderNoColour.DisplayTexture  = displayTexture;

                    shaderNoColour.SetVelocityScale(ref velScale);
                }
            }
            else
            {
                if (colourTex != null)
                {
                    shader = shaderColour_UO = state.GetShader <DrawVelocityParticlesColour_GpuTex_UserOffset>();

                    shaderColour_UO.PositionTexture = positionTex;
                    shaderColour_UO.ColourTexture   = colourTex;
                    shaderColour_UO.VelocityTexture = velocityRotation;
                    shaderColour_UO.UserTexture     = userValues;
                    shaderColour_UO.DisplayTexture  = displayTexture;

                    shaderColour_UO.SetVelocityScale(ref velScale);
                }
                else
                {
                    shader = shaderNoColour_UO = state.GetShader <DrawVelocityParticles_GpuTex_UserOffset>();

                    shaderNoColour_UO.PositionTexture = positionTex;
                    shaderNoColour_UO.VelocityTexture = velocityRotation;
                    shaderNoColour_UO.UserTexture     = userValues;
                    shaderNoColour_UO.DisplayTexture  = displayTexture;

                    shaderNoColour_UO.SetVelocityScale(ref velScale);
                }
            }


            int drawn = 0;

            while (count > 0)
            {
                int drawCount = Math.Min(count, vertices.Count / 4);

                if (!usesUserValuesPositionBuffer)
                {
                    if (colourTex != null)
                    {
                        shaderColour.TextureSizeOffset = new Vector3(invTextureSize, (float)drawn);
                    }
                    else
                    {
                        shaderNoColour.TextureSizeOffset = new Vector3(invTextureSize, (float)drawn);
                    }
                }
                else
                {
                    if (colourTex != null)
                    {
                        shaderColour_UO.TextureSizeOffset = new Vector3(invTextureSize, (float)drawn);
                    }
                    else
                    {
                        shaderNoColour_UO.TextureSizeOffset = new Vector3(invTextureSize, (float)drawn);
                    }
                }

                //bind
                shader.Bind(state);

                vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0);

                count -= drawCount;
                drawn += drawCount;
            }


            state.PopRenderState();
        }
예제 #4
0
        //draws on CPU particle systems
        /// <summary>
        /// draws the particles from a CPU system
        /// </summary>
        protected override void DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colourData, Vector4[] userValues)
        {
            //this is very similar to the billboard drawer (see it for reference)
            Vector2 targetSize = state.DrawTarget.Size;

            state.PushRenderState();
            state.RenderState.AlphaBlend = blendMode;
            state.RenderState.DepthColourCull.DepthWriteEnabled = false;

            Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state);

            BillboardParticles2DElement.GenerateBillboardVertices(state, ref this.vertices, ref this.indices);


            int count = (int)particleCount;



            DrawVelocityParticles_BillboardCpu       shaderNoColour = null;
            DrawVelocityParticlesColour_BillboardCpu shaderColour   = null;


            if (colourData != null)
            {
                shaderColour = state.GetShader <DrawVelocityParticlesColour_BillboardCpu>();
            }
            else
            {
                shaderNoColour = state.GetShader <DrawVelocityParticles_BillboardCpu>();
            }

            Vector2 velScale = new Vector2(velocityScale, 0);

            if (this.useRotationToScaleVelocityEffect)
            {
                velScale = new Vector2(0, velocityScale);
            }

            int drawn = 0;

            while (count > 0)
            {
                int drawCount;

                drawCount = Math.Min(count, 80);

                if (colourData != null)
                {
                    shaderColour.PositionData.SetArray(positionSize, drawn);
                    shaderColour.VelocityData.SetArray(velocityRotation, drawn);
                    shaderColour.ColourData.SetArray(colourData, drawn);

                    shaderColour.DisplayTexture = displayTexture;
                    shaderColour.SetVelocityScale(ref velScale);

                    shaderColour.Bind(state);
                }
                else
                {
                    shaderNoColour.PositionData.SetArray(positionSize, drawn);
                    shaderNoColour.VelocityData.SetArray(velocityRotation, drawn);

                    shaderNoColour.DisplayTexture = displayTexture;
                    shaderNoColour.SetVelocityScale(ref velScale);

                    shaderNoColour.Bind(state);
                }

                vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0);

                count -= drawCount;
                drawn += drawCount;
            }


            state.PopRenderState();
        }
예제 #5
0
 /// <summary>
 /// This method is only present on Windows builds
 /// </summary>
 /// <param name="blendMode"></param><param name="colour"></param><param name="count"></param><param name="particleType"></param>
 /// <param name="positionSize"></param><param name="state"></param><param name="userValues"></param><param name="velocityRotation"></param>
 protected abstract void DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint count, AlphaBlendState blendMode, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colour, Vector4[] userValues);
예제 #6
0
 /// <summary>
 /// <para>Method to override to draw 3D particles</para>
 /// <para>Note: When 'usesUserValuesPositionBuffer' is true, the values 'user1, user2 and user3' (yzw in the UserTexture) store a position offset for the particle</para></summary>
 /// <param name="state"></param><param name="particleType"></param><param name="count"></param><param name="blendMode"></param>
 /// <param name="positionSize"></param><param name="velocityRotation"></param><param name="colour"></param><param name="userValues"></param><param name="usesUserValuesPositionBuffer"></param>
 protected abstract void DrawGpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint count, AlphaBlendState blendMode, Texture2D positionSize, Texture2D velocityRotation, Texture2D colour, Texture2D userValues, bool usesUserValuesPositionBuffer);
예제 #7
0
        /// <summary>
        /// implements the method to draw gpu particles
        /// </summary>
        protected override void DrawGpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Texture2D positionTex, Texture2D velocityRotation, Texture2D colourTex, Texture2D userValues, bool usesUserValuesPositionBuffer)
        {
            Vector2 targetSize = state.DrawTarget.Size;

            state.PushRenderState();
            state.RenderState.AlphaBlend = blendMode;
            state.RenderState.DepthColourCull.DepthWriteEnabled = false;

            //get the display texture, or a white texture if none exists
            Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state);

            //get / create the shared vertices and indices for drawing billboard particles
            BillboardParticles2DElement.GenerateBillboardVertices(state, ref vertices, ref indices);

            int count = (int)particleCount;

            //instances of the two possible shaders
            DrawVelocityBillboardParticles_GpuTex3D       shaderNoColour = null;
            DrawVelocityBillboardParticlesColour_GpuTex3D shaderColour   = null;
            //user variantes
            DrawVelocityBillboardParticles_GpuTex3D_UserOffset       shaderNoColour_UO = null;
            DrawVelocityBillboardParticlesColour_GpuTex3D_UserOffset shaderColour_UO   = null;

            float resolutionXF = (float)positionTex.Width;
            float resolutionYF = (float)positionTex.Height;

            Vector2 invTextureSize = new Vector2(1.0f / resolutionXF, 1.0f / resolutionYF);

            Matrix cameraMatrix;

            state.Camera.GetCameraMatrix(out cameraMatrix);

            Vector3 worldSpaceYAxis = new Vector3(cameraMatrix.M21, cameraMatrix.M22, cameraMatrix.M23);


            Vector2 velScale = new Vector2(velocityScale, 0);

            if (this.useRotationToScaleVelocityEffect)
            {
                velScale = new Vector2(0, velocityScale);
            }

            IShader shader;

            if (!usesUserValuesPositionBuffer)
            {
                if (colourTex != null)                 // does this particle system use colours?
                {
                    //get the shader
                    shaderColour = state.GetShader <DrawVelocityBillboardParticlesColour_GpuTex3D>();

                    //set the samplers
                    shaderColour.PositionTexture = positionTex;
                    shaderColour.ColourTexture   = colourTex;
                    shaderColour.VelocityTexture = velocityRotation;
                    shaderColour.DisplayTexture  = displayTexture;

                    shaderColour.SetWorldSpaceYAxis(ref worldSpaceYAxis);
                    shaderColour.SetVelocityScale(ref velScale);
                    shader = shaderColour;
                }
                else
                {
                    shaderNoColour = state.GetShader <DrawVelocityBillboardParticles_GpuTex3D>();

                    shaderNoColour.PositionTexture = positionTex;
                    shaderNoColour.VelocityTexture = velocityRotation;
                    shaderNoColour.DisplayTexture  = displayTexture;

                    shaderNoColour.SetWorldSpaceYAxis(ref worldSpaceYAxis);
                    shaderNoColour.SetVelocityScale(ref velScale);
                    shader = shaderNoColour;
                }
            }
            else
            {
                if (colourTex != null)                 // does this particle system use colours?
                {
                    //get the shader
                    shaderColour_UO = state.GetShader <DrawVelocityBillboardParticlesColour_GpuTex3D_UserOffset>();

                    //set the samplers
                    shaderColour_UO.PositionTexture = positionTex;
                    shaderColour_UO.ColourTexture   = colourTex;
                    shaderColour_UO.VelocityTexture = velocityRotation;
                    shaderColour_UO.UserTexture     = userValues;
                    shaderColour_UO.DisplayTexture  = displayTexture;

                    shaderColour_UO.SetWorldSpaceYAxis(ref worldSpaceYAxis);
                    shaderColour_UO.SetVelocityScale(ref velScale);
                    shader = shaderColour_UO;
                }
                else
                {
                    shaderNoColour_UO = state.GetShader <DrawVelocityBillboardParticles_GpuTex3D_UserOffset>();

                    shaderNoColour_UO.PositionTexture = positionTex;
                    shaderNoColour_UO.VelocityTexture = velocityRotation;
                    shaderNoColour_UO.UserTexture     = userValues;
                    shaderNoColour_UO.DisplayTexture  = displayTexture;

                    shaderNoColour_UO.SetWorldSpaceYAxis(ref worldSpaceYAxis);
                    shaderNoColour_UO.SetVelocityScale(ref velScale);
                    shader = shaderNoColour_UO;
                }
            }


            int drawn = 0;

            while (count > 0)
            {
                //draw upto vertices.Count / 4 (4 vertices per quad)
                int drawCount = Math.Min(count, vertices.Count / 4);

                //set the inverse texture size, and the start offset value, then bind the shader
                if (!usesUserValuesPositionBuffer)
                {
                    if (colourTex != null)
                    {
                        shaderColour.InvTextureSizeOffset = new Vector3(invTextureSize, (float)drawn);
                    }
                    else
                    {
                        shaderNoColour.InvTextureSizeOffset = new Vector3(invTextureSize, (float)drawn);
                    }
                }
                else
                {
                    if (colourTex != null)
                    {
                        shaderColour_UO.InvTextureSizeOffset = new Vector3(invTextureSize, (float)drawn);
                    }
                    else
                    {
                        shaderNoColour_UO.InvTextureSizeOffset = new Vector3(invTextureSize, (float)drawn);
                    }
                }

                //bind
                shader.Bind(state);

                //draw!
                vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0);

                count -= drawCount;
                drawn += drawCount;
            }

            //and done.
            state.PopRenderState();
        }
예제 #8
0
        /// <summary>
        /// implements the method to draw cpu processed particles
        /// </summary>
        protected override void DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colourData, Vector4[] userValues)
        {
            //this is a bit more complex, but mostly the same as the GPU draw method
            Vector2 targetSize = state.DrawTarget.Size;

            state.PushRenderState();
            state.RenderState.AlphaBlend = blendMode;
            state.RenderState.DepthColourCull.DepthWriteEnabled = false;

            Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state);

            BillboardParticles2DElement.GenerateBillboardVertices(state, ref this.vertices, ref this.indices);

            Matrix cameraMatrix;

            state.Camera.GetCameraMatrix(out cameraMatrix);

            Vector3 worldSpaceYAxis = new Vector3(cameraMatrix.M21, cameraMatrix.M22, cameraMatrix.M23);


            Vector2 velScale = new Vector2(velocityScale, 0);

            if (this.useRotationToScaleVelocityEffect)
            {
                velScale = new Vector2(0, velocityScale);
            }



            int count = (int)particleCount;

            DrawVelocityBillboardParticles_BillboardCpu3D       shaderNoColour = null;
            DrawVelocityBillboardParticlesColour_BillboardCpu3D shaderColour   = null;

            if (colourData != null)
            {
                shaderColour = state.GetShader <DrawVelocityBillboardParticlesColour_BillboardCpu3D>();
                shaderColour.SetWorldSpaceYAxis(ref worldSpaceYAxis);
                shaderColour.SetVelocityScale(ref velScale);
            }
            else
            {
                shaderNoColour = state.GetShader <DrawVelocityBillboardParticles_BillboardCpu3D>();
                shaderNoColour.SetWorldSpaceYAxis(ref worldSpaceYAxis);
                shaderNoColour.SetVelocityScale(ref velScale);
            }

            int drawn = 0;

            while (count > 0)
            {
                int drawCount;

                drawCount = Math.Min(count, 75);

                if (colourData != null)
                {
                    shaderColour.PositionData.SetArray(positionSize, drawn);
                    shaderColour.VelocityData.SetArray(velocityRotation, drawn);
                    shaderColour.ColourData.SetArray(colourData, drawn);

                    shaderColour.DisplayTexture = displayTexture;

                    shaderColour.Bind(state);
                }
                else
                {
                    shaderNoColour.PositionData.SetArray(positionSize, drawn);
                    shaderNoColour.VelocityData.SetArray(velocityRotation, drawn);

                    shaderNoColour.DisplayTexture = displayTexture;

                    shaderNoColour.Bind(state);
                }

                vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0);

                count -= drawCount;
                drawn += drawCount;
            }


            state.PopRenderState();
        }
예제 #9
0
        /// <summary>
        /// implements the method to draw cpu particles
        /// </summary>
        protected override void DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colourData, Vector4[] userValues)
        {
            //this is a bit more complex, but mostly the same as the GPU draw method
            Vector2 targetSize = state.DrawTarget.Size;

            state.PushRenderState();
            state.RenderState.AlphaBlend = blendMode;
            state.RenderState.DepthColourCull.DepthWriteEnabled = false;

            Texture2D displayTexture = particleType.Texture ?? Xen.Ex.Material.WhiteTexture.GetTexture(state);

            GenerateBillboardVertices(state, ref this.vertices, ref this.indices);


            int count = (int)particleCount;

            DrawBillboardParticles_BillboardCpu       shaderNoColour = null;
            DrawBillboardParticlesColour_BillboardCpu shaderColour   = null;

            if (positionBuffer == null)
            {
                positionBuffer = GetPositionBuffer(state, positionBuffer);
            }

            if (colourData != null)
            {
                shaderColour = state.GetShader <DrawBillboardParticlesColour_BillboardCpu>();
            }
            else
            {
                shaderNoColour = state.GetShader <DrawBillboardParticles_BillboardCpu>();
            }

            int drawn = 0;

            while (count > 0)
            {
                int drawCount;

                drawCount = Math.Min(count, 120);

                //the only major difference from the GPU drawer is here
                for (int i = 0; i < drawCount; i++)
                {
                    //copy position xy and w (size), and velocity.w (rotation)
                    positionBuffer[i]   = positionSize[drawn + i];
                    positionBuffer[i].Z = velocityRotation[drawn + i].W;
                }

                if (colourData != null)
                {
                    shaderColour.PositionData.SetArray(positionBuffer, 0);
                    shaderColour.ColourData.SetArray(colourData, drawn);

                    shaderColour.DisplayTexture = displayTexture;

                    shaderColour.Bind(state);
                }
                else
                {
                    shaderNoColour.PositionData.SetArray(positionBuffer, 0);

                    shaderNoColour.DisplayTexture = displayTexture;

                    shaderNoColour.Bind(state);
                }

                vertices.Draw(state, indices, PrimitiveType.TriangleList, drawCount * 2, 0, 0);

                count -= drawCount;
                drawn += drawCount;
            }


            state.PopRenderState();
        }
예제 #10
0
        /// <summary>
        /// draws the particles from a CPU system
        /// </summary>
        protected override void DrawCpuParticles(DrawState state, Content.ParticleSystemTypeData particleType, uint particleCount, AlphaBlendState blendMode, Vector4[] positionSize, Vector4[] velocityRotation, Vector4[] colourData, Vector4[] userValues)
        {
            Vector2 targetSize = state.DrawTarget.Size;

            state.PushRenderState();
            state.RenderState.AlphaBlend = blendMode;
            state.RenderState.DepthColourCull.DepthWriteEnabled = false;

            VelocityLineParticles2DElement.GenerateLinesVertices(state, ref this.vertices);


            int count = (int)particleCount;



            DrawVelocityParticles_LinesCpu       shaderNoColour = null;
            DrawVelocityParticlesColour_LinesCpu shaderColour   = null;

            if (colourData != null)
            {
                shaderColour = state.GetShader <DrawVelocityParticlesColour_LinesCpu>();
            }
            else
            {
                shaderNoColour = state.GetShader <DrawVelocityParticles_LinesCpu>();
            }

            Vector2 velScale = new Vector2(velocityScale, 0);

            if (this.useRotationToScaleVelocityEffect)
            {
                velScale = new Vector2(0, velocityScale);
            }

            int drawn = 0;

            while (count > 0)
            {
                int drawCount;

                drawCount = Math.Min(count, 80);

                if (colourData != null)
                {
                    shaderColour.PositionData.SetArray(positionSize, drawn);
                    shaderColour.VelocityData.SetArray(velocityRotation, drawn);
                    shaderColour.ColourData.SetArray(colourData, drawn);

                    shaderColour.SetVelocityScale(ref velScale);

                    shaderColour.Bind(state);
                }
                else
                {
                    shaderNoColour.PositionData.SetArray(positionSize, drawn);
                    shaderNoColour.VelocityData.SetArray(velocityRotation, drawn);

                    shaderNoColour.SetVelocityScale(ref velScale);

                    shaderNoColour.Bind(state);
                }

                vertices.Draw(state, null, PrimitiveType.LineList, drawCount, 0, 0);

                count -= drawCount;
                drawn += drawCount;
            }


            state.PopRenderState();
        }