/*
* 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
}
}