/* * ParticleCPURenderer.cs * Authors: Brian Murphy * Copyright (c) 2007-2008 Cornell University This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using tAC_Engine.Graphics.Cameras; using TACParticleEngine.Emitters; using Util; namespace TACParticleEngine.Particles { /// /// This class handles the rendering process for particle effects using CPU /// public static class ParticleCPURenderer { #region Render /// /// Handles drawing via CPU with sprite batches /// /// The current sprite batch sued for drawing /// The current emitter to draw /// The current active camera /// The The viewport in which the particles are drawn within public static void Render(SpriteBatch spriteBatch, Emitter emitter, Camera activeCamera, Viewport viewport) { if (emitter.ParticlesDone) { return; } Texture2D text = emitter.Texture; if (text == null) { return; } Vector3 mForward = activeCamera.LookAt - activeCamera.Eye; mForward.Normalize(); spriteBatch.Begin(emitter.mBlendEffect); if (emitter.mFirstActiveIndex < emitter.mFirstInactiveIndex) { for (int i = emitter.mFirstActiveIndex; i < emitter.mFirstInactiveIndex; ++i) { VertexParticle part = emitter.mVertexParticles[i]; Vector3 mPos = viewport.Project(part.position, activeCamera.Projection, activeCamera.View, Matrix.Identity); float sizeValue = (float)Math.Sqrt(1d / Vector3.Multiply(Vector3.Subtract(part.position, activeCamera.Eye), mForward).Length()); Vector2 size = part.size; int x = (int)(size.X * sizeValue); int y = (int)(size.Y * sizeValue); spriteBatch.Draw(text, new Rectangle((int)mPos.X - (x >> 1), (int)mPos.Y - (y >> 1), x, y), new Color(part.color)); } } else { for (int i = emitter.mFirstActiveIndex; i < emitter.mVertexParticles.Length; ++i) { VertexParticle part = emitter.mVertexParticles[i]; Vector3 mPos = viewport.Project(part.position, activeCamera.Projection, activeCamera.View, Matrix.Identity); float sizeValue = (float)Math.Sqrt(1d / Vector3.Multiply(Vector3.Subtract(part.position, activeCamera.Eye), mForward).Length()); Vector2 size = part.size; int x = (int)(size.X * sizeValue); int y = (int)(size.Y * sizeValue); spriteBatch.Draw(text, new Rectangle((int)mPos.X - (x >> 1), (int)mPos.Y - (y >> 1), x, y), new Color(part.color)); } for (int i = 0; i < emitter.mFirstInactiveIndex; ++i) { VertexParticle part = emitter.mVertexParticles[i]; Vector3 mPos = viewport.Project(part.position, activeCamera.Projection, activeCamera.View, Matrix.Identity); float sizeValue = (float)Math.Sqrt(1d / Vector3.Multiply(Vector3.Subtract(part.position, activeCamera.Eye), mForward).Length()); Vector2 size = part.size; int x = (int)(size.X * sizeValue); int y = (int)(size.Y * sizeValue); spriteBatch.Draw(text, new Rectangle((int)mPos.X - (x >> 1), (int)mPos.Y - (y >> 1), x, y), new Color(part.color)); } } spriteBatch.End(); } #endregion } }