#region CPL License /* Nuclex Framework Copyright (C) 2002-2009 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Nuclex.Graphics.Batching; namespace Nuclex.Graphics.SpecialEffects.Particles.HighLevel { #if false /// Renders particles as CPU-calculates billboards /// Data type of the particles /// /// /// This default implementation of a particle renderer assumes that your particle /// structure and your particle vertex are one and the same. This is in no way /// a requirement, but has the advantage that the renderer is not required to /// touch each and every particle to produce a vertex for it. /// /// /// Particles are rendered as point sprites, so your effect should be capable /// of processing vertices as such. /// /// public class BillBoardParticleRenderer : IParticleRenderer where ParticleType : struct { /// Initializes a new point particle renderer /// Effect that will be used to render the particle public BillBoardParticleRenderer(Effect effect) : this(new EffectDrawContext(effect)) { } /// Initializes a new point particle renderer /// /// Draw context controlling the rendering of the particles /// public BillBoardParticleRenderer(DrawContext drawContext) { if(drawContext == null) { throw new ArgumentException("Invalid draw context", "drawContext"); } this.drawContext = drawContext; } /// Renders a series of particles /// Particles that will be rendered /// /// Primitive batch that will receive the vertices generated by the particles /// public void Render( ArraySegment particles, PrimitiveBatch primitiveBatch ) { Vector3 cameraPosition = this.Camera.Translation; Vector3 cameraUp = this.Camera.Up; Vector3 cameraForward = this.Camera.Forward; Matrix billboard; ParticleType tl, tr, bl, br; int end = particles.Offset + particles.Count; for(int index = particles.Offset; index < end; ++index) { tl = particles.Array[index]; tr = tl; bl = tl; br = tl; Vector3 position; this.accessor.GetPosition(ref tl, out position); Matrix.CreateBillboard( ref position, ref cameraPosition, ref cameraUp, cameraForward, out billboard ); Vector3 corner; corner.X = position.X + billboard.M11 + billboard.M21; corner.Y = position.Y + billboard.M12 + billboard.M22; corner.Z = position.Z + billboard.M13 + billboard.M23; this.accessor.SetPosition(ref tl, ref corner); corner.X = position.X - billboard.M11 + billboard.M21; corner.Y = position.Y - billboard.M12 + billboard.M22; corner.Z = position.Z - billboard.M13 + billboard.M23; this.accessor.SetPosition(ref tr, ref corner); corner.X = position.X + billboard.M11 - billboard.M21; corner.Y = position.Y + billboard.M12 - billboard.M22; corner.Z = position.Z + billboard.M13 - billboard.M23; this.accessor.SetPosition(ref bl, ref corner); corner.X = position.X - billboard.M11 - billboard.M21; corner.Y = position.Y - billboard.M12 - billboard.M22; corner.Z = position.Z - billboard.M13 - billboard.M23; this.accessor.SetPosition(ref br, ref corner); } primitiveBatch.Draw( particles.Array, particles.Offset, particles.Count, PrimitiveType.PointList, this.drawContext ); } public Matrix Camera; /// Draw context controlling the rendering of the particles private DrawContext drawContext; private IParticleAccessor accessor; } #endif } // namespace Nuclex.Graphics.SpecialEffects.Particles.HighLevel