/// <summary>
        /// Renders a collection of particles
        /// </summary>
        public void RenderParticles( IRenderContext context, IParticleSystem particleSystem )
        {
            ISerialParticleBuffer sBuffer = ( ISerialParticleBuffer )particleSystem.Buffer;
            SerialParticleFieldIterator posIter = new SerialParticleFieldIterator( sBuffer, ParticleBase.Position );

            for ( int particleIndex = 0; particleIndex < sBuffer.NumActiveParticles; ++particleIndex )
            {
                posIter.MoveNext( );
                Graphics.Draw.Billboard( s_ParticleBrush, posIter.Point3Value, ParticleSize, ParticleSize );
            }
        }
 /// <summary>
 /// Kills particles
 /// </summary>
 public void KillParticles( IParticleSystem particles )
 {
     SerialParticleFieldIterator iter = new SerialParticleFieldIterator( ( ISerialParticleBuffer )particles.Buffer, ParticleBase.Age );
     for ( int i = 0; i < particles.Buffer.NumActiveParticles; ++i )
     {
         iter.MoveNext( );
         ++iter.IntValue;
         if ( iter.IntValue > m_DeathAge )
         {
             particles.Buffer.MarkParticleForRemoval( i );
         }
     }
     particles.Buffer.RemoveMarkedParticles( );
 }
        /// <summary>
        /// Updates all particles
        /// </summary>
        public void Update( IParticleSystem ps, float updateTime )
        {
            ISerialParticleBuffer sBuffer = ( ISerialParticleBuffer )ps.Buffer;
            SerialParticleFieldIterator posIter = new SerialParticleFieldIterator( sBuffer, ParticleBase.Position );
            SerialParticleFieldIterator velIter = new SerialParticleFieldIterator( sBuffer, ParticleBase.Velocity );

            Vector3 g = Vector3.YAxis * -Gravity * updateTime;

            float fr = 1.0f - Friction;
            for ( int particleIndex = 0; particleIndex < sBuffer.NumActiveParticles; ++particleIndex )
            {
                posIter.MoveNext( );
                velIter.MoveNext( );

                posIter.Point3Value += velIter.Vector3Value;
                posIter.Point3Value += g;
                velIter.Vector3Value *= fr;
            }
        }
        /// <summary>
        /// Renders a particle system
        /// </summary>
        public unsafe void RenderParticles( IRenderContext context, IParticleSystem particleSystem )
        {
            ISerialParticleBuffer sBuffer = ( ISerialParticleBuffer )particleSystem.Buffer;
            if ( m_MaxParticles != sBuffer.MaximumNumberOfParticles )
            {
                BuildBuffers( sBuffer.MaximumNumberOfParticles );
            }
            using ( IVertexBufferLock vbLock = m_Vb.Lock( 0, sBuffer.NumActiveParticles * 4, false, true ) )
            {
                Vertex* curVertex = ( Vertex* )vbLock.Bytes;
                SerialParticleFieldIterator posIter = new SerialParticleFieldIterator( sBuffer, ParticleBase.Position );

                ICamera3 camera = ( ICamera3 )Graphics.Renderer.Camera;
                Vector3 xAxis = camera.Frame.XAxis * ParticleSize / 2;
                Vector3 yAxis = camera.Frame.YAxis * ParticleSize / 2;

                const float maxU = 1.0f;
                const float maxV = 1.0f;

                for ( int particleIndex = 0; particleIndex < sBuffer.NumActiveParticles; ++particleIndex )
                {
                    posIter.MoveNext( );
                    curVertex++->Setup( posIter.Point3Value - xAxis - yAxis, 0, 0 );
                    curVertex++->Setup( posIter.Point3Value + xAxis - yAxis, maxU, 0 );
                    curVertex++->Setup( posIter.Point3Value + xAxis + yAxis, maxU, maxV );
                    curVertex++->Setup( posIter.Point3Value - xAxis + yAxis, 0, maxV );
                }
            }

            m_RenderState.Begin( );
            if ( m_Texture.Texture != null )
            {
                Graphics.Renderer.PushTextures( );
                m_Texture.Begin( );
            }
            m_Vb.Begin( );
            m_Ib.Draw( PrimitiveType.TriList, 0, sBuffer.NumActiveParticles * 2 );
            m_Vb.End( );
            if ( m_Texture.Texture != null )
            {
                m_Texture.End( );
                Graphics.Renderer.PopTextures( );
            }
            m_RenderState.End( );
        }