Engine – EntityRenderer.cs

 

#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ParadigmEngine.TileEngine;
using ParadigmEngine.ParticleSystem;
#endregion

namespace ParadigmEngine
{
    /// <summary>
    /// Handles the drawing of world entities as well as particles
    /// </summary>
    public class EntityRenderer
    {
        #region Fields
        /// <summary>
        /// List containing all of the entities that will be rendered
        /// </summary>
        private static List<DrawableWorldEntity> entityList;

        #endregion

        #region Public Methods
        /// <summary>
        /// Initialize the entity renderer
        /// </summary>
        public static void Initialize()
        {
            entityList = new List<DrawableWorldEntity>();
        }

        /// <summary>
        /// Adds a list of entities to be rendered
        /// </summary>
        public static void AddEntities(List<DrawableWorldEntity> entities)
        {
            entityList.AddRange(entities);

            if (entityList.Count > 1)
            {
                // sort the entity list by Y coord to ensure proper occlusion
                entityList.Sort(delegate(DrawableWorldEntity entity1, DrawableWorldEntity entity2)
                {
                    return entity1.SpawnedFrom.Y.CompareTo(entity2.SpawnedFrom.Y);
                });
            }
        }

        /// <summary>
        /// Clears the entity list
        /// </summary>
        public static void ClearEntities()
        {
            entityList.Clear();
        }

        /// <summary>
        /// Draws all entities in the list
        /// </summary>
        public static void Draw(GameTime gameTime, SpriteBatch spriteBatch, Texture2D particleTexture, Matrix transformMatrix, bool usingEditor)
        {
            // blend mode
            BlendMode currentBlendMode = BlendMode.AlphaBlend;

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None, transformMatrix);
            for (int i = 0; i < entityList.Count; i++)
            {
               // if the entity is a world object
               if (entityList[i].EntityType == DrawableEntityType.Object)
               {
                   // make sure we are in alpha blending mode
                   if (currentBlendMode == BlendMode.Additive)
                   {
                       currentBlendMode = BlendMode.AlphaBlend;

                       spriteBatch.End();
                       spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None, transformMatrix);
                   }

                   // if we are in the editor, pass an extra parameter to include the option for transparency
                   if (usingEditor)
                   {
                       entityList[i].Draw(gameTime, spriteBatch, false);
                   }
                   else // otherwise draw as normal
                   {
                       entityList[i].Draw(gameTime, spriteBatch);
                   }
               }
               else // if the entity is a particle
               {
                   Particle particle = entityList[i] as Particle;

                   if (!particle.Additive && !particle.refract)
                   {
                       particle.Draw(spriteBatch, particleTexture);
                   }

                   if (particle.Additive && !particle.refract)
                   {
                       // if we need to switch the blend mode, end the current spritebatch call and change to the new blend
                       if (currentBlendMode == BlendMode.AlphaBlend)
                       {
                           currentBlendMode = BlendMode.Additive;

                           spriteBatch.End();
                           spriteBatch.Begin(SpriteBlendMode.Additive, SpriteSortMode.Immediate, SaveStateMode.None, transformMatrix);
                       }

                       particle.Draw(spriteBatch, particleTexture);

                       // check the next entity in the list.  if it is a particle with the same blend mode, we do not need to switch blending mode
                       // if it has a different blend mode, or is not a particle, we will switch the blend mode now
                       if (i !=  entityList.Count - 1)
                       {
                           Particle nextParticle = entityList[i + 1] as Particle;

                           if (nextParticle != null)
                           {
                               if (!nextParticle.Additive)
                               {
                                   currentBlendMode = BlendMode.AlphaBlend;

                                   spriteBatch.End();
                                   spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None, transformMatrix);
                               }
                           }
                       }
                   }
               }
            }
            spriteBatch.End();
        }
        #endregion
    }
}