/* * EntityBillboardSprite.cs * Authors: * 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.Content; using Microsoft.Xna.Framework.Graphics; using Util; namespace tAC_Engine.Graphics.Entities { /// /// Defines a sprite that will always face in the direction of the camera /// public class EntityBillboardSprite : DrawableGameScreenComponent { #region Fields // Size of the particle for when reserving space in vertex buffer private readonly int SIZE_IN_BYTES; // A vertex buffer holding our particles. This contains the same data as // the particles array, but copied across to where the GPU can access it. private DynamicVertexBuffer mVertexBuffer; // Vertex declaration describes the format of our ParticleVertex structure. private VertexDeclaration mVertexDeclaration; /// /// Reference to the current content manager /// protected ContentManager Content; /// /// Effect file used for rendering the billboard sprite /// protected Effect mBillBoardShader; // Information for how the sprite should be drawn SpriteData mSpriteData; // The texture that represents the billboard sprite Texture2D mTexture; /// /// The name of the texture file to be used /// protected String m_TextureName; // The current view matrix in which to render with Matrix mView; // The current projection matrix in which to render with Matrix mProjection; #endregion #region Properties /// /// Gets/Sets the sprite data /// public SpriteData Particle { get { return mSpriteData; } set { mSpriteData = value; Game.GraphicsDevice.Vertices[0].SetSource(null, 0, 0); SpriteData[] tempArray = new SpriteData[1]; tempArray[0] = mSpriteData; mVertexBuffer.SetData(tempArray, 0, 1); } } /// /// Gets the texture to be used for rendering /// public Texture2D Texture { get { return mTexture; } } /// /// Gets/Sets the name of the texture file to be used /// public String TextureName { get { return m_TextureName; } set { m_TextureName = value; } } /// /// Gets/Sets the current view matrix /// public Matrix View { get { return mView; } set { mView = value; } } /// /// Gets/Sets the current projection matrix /// public Matrix Projection { get { return mProjection; } set { mProjection = value; } } #endregion #region Creation /// /// Constructor for the billboard spite /// /// Reference to the current content manager /// Path name for the texture file /// Information of the sprite for how it should be rendered public EntityBillboardSprite(ContentManager pContent, String pTexturePathName, SpriteData pSpriteData) { Content = pContent; m_TextureName = pTexturePathName; mSpriteData = pSpriteData; SIZE_IN_BYTES = System.Runtime.InteropServices.Marshal.SizeOf(typeof(SpriteData)); mVertexDeclaration = new VertexDeclaration(Game.GraphicsDevice, SpriteData.VertexElements); mVertexBuffer = new DynamicVertexBuffer(Game.GraphicsDevice, SIZE_IN_BYTES, BufferUsage.WriteOnly | BufferUsage.Points); } #endregion #region Management /// /// Loads in necessary information for content dependent objects /// protected override void LoadContent() { base.LoadContent(); mTexture = Content.Load(m_TextureName); mBillBoardShader = Content.Load(AssemblyLocator.GetLocation(typeof(EntityBillboardSprite).Assembly.FullName) + @"\Content\ParticleEffect"); Game.GraphicsDevice.Vertices[0].SetSource(null, 0, 0); SpriteData[] tempArray = new SpriteData[1]; tempArray[0] = mSpriteData; mVertexBuffer.SetData(tempArray, 0, 1); } #endregion #region Render /// /// Renders the billboard sprite /// /// Time that has passed in game public override void Draw(GameTime gameTime) { // Set point sprite values Game.GraphicsDevice.RenderState.PointSpriteEnable = true; Game.GraphicsDevice.RenderState.PointSizeMax = 256; Game.GraphicsDevice.RenderState.DepthBufferEnable = true; Game.GraphicsDevice.RenderState.DepthBufferWriteEnable = false; mBillBoardShader.Parameters["View"].SetValue(mView); mBillBoardShader.Parameters["Projection"].SetValue(mProjection); mBillBoardShader.Parameters["Texture"].SetValue(mTexture); mBillBoardShader.CommitChanges(); Game.GraphicsDevice.Vertices[0].SetSource(mVertexBuffer, 0, SIZE_IN_BYTES); Game.GraphicsDevice.VertexDeclaration = mVertexDeclaration; mBillBoardShader.Begin(); foreach (EffectPass pass in mBillBoardShader.CurrentTechnique.Passes) { pass.Begin(); Game.GraphicsDevice.DrawPrimitives(PrimitiveType.PointList, 0, 1); pass.End(); } mBillBoardShader.End(); base.Draw(gameTime); } #endregion } /// /// Defines the data size and information needed for rendering the billboard sprite /// public struct SpriteData { /// /// Vector used for the size of the particle via two-dimensions /// public Vector2 size; /// /// Current position of the particle /// public Vector3 position; /// /// Vector used for the color of the particle via RGBA /// public Vector4 color; /// /// Describe the layout of this structure /// public static readonly VertexElement[] VertexElements = { // Size data new VertexElement(0, 0, VertexElementFormat.Vector2, VertexElementMethod.Default, VertexElementUsage.PointSize, 0), // Position data new VertexElement(0, 8, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0), // Color data new VertexElement(0, 20, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.Color, 0) }; } }