#region File Description
//-----------------------------------------------------------------------------
// RetroProjectiles.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.Diagnostics;
#endregion
namespace Spacewar
{
///
/// A collection to batch render the bullets for retro mode
///
public class RetroProjectiles : Projectiles
{
private Effect effect;
private EffectParameter worldViewProjectionParam;
private VertexBuffer buffer;
private const int maxTriangleCount = 200;
private const int maxProjectileCount = maxTriangleCount * 3;
VertexPositionColor[] data;
public RetroProjectiles(Game game)
: base(game)
{
Create();
}
///
/// Creates a group of projectiles
///
/// Which player shot the bullet
/// Start position of projectile
/// Initial velocity of projectile
/// Direction projectile is facing
/// Game time that this projectile was shot
/// The particles to add to for effects
public override void Add(PlayerIndex player, Vector3 position, Vector3 velocity, float angle, TimeSpan time, Particles particles)
{
Add(new Projectile(GameInstance, player, position, velocity, angle, time, null));
}
///
/// Renders all bullets in a single batch
///
public override void Render()
{
if (Count > 0)
{
base.Render();
//RETRO
//All bullets are rendered in a single draw call.
//Build a new vertex buffer with all the bullets
IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService));
GraphicsDevice device = graphicsService.GraphicsDevice;
// Don't exceed the maximum number of vertices in our default Vertex Buffer!
int totalCount = (Count > maxTriangleCount) ? maxTriangleCount : Count;
int position = 0;
foreach (Projectile bullet in this)
{
if (position < maxProjectileCount)
{
Vector3 bulletPosition = bullet.Position;
data[position++].Position = bulletPosition;
data[position++].Position = bulletPosition + new Vector3(-1, 0, 0);
data[position++].Position = bulletPosition + new Vector3(0, 1, 0);
bulletPosition.X += .5f;
data[position++].Position = bulletPosition;
data[position++].Position = bulletPosition + new Vector3(-1, 0, 0);
data[position++].Position = bulletPosition + new Vector3(0, 1, 0);
}
}
device.RasterizerState = RasterizerState.CullNone;
worldViewProjectionParam.SetValue(SpacewarGame.Camera.View * SpacewarGame.Camera.Projection);
effect.Techniques[0].Passes[0].Apply();
device.DrawUserPrimitives(PrimitiveType.TriangleList, data, 0, totalCount * 2);
//We DO NOT call the base class here since we have handled all the children
}
}
public void Create()
{
//Load the correct shader and set up the parameters
if (effect == null || effect.IsDisposed)
{
OnCreateDevice();
}
}
public override void OnCreateDevice()
{
IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)GameInstance.Services.GetService(typeof(IGraphicsDeviceService));
effect = SpacewarGame.ContentManager.Load(SpacewarGame.Settings.MediaPath + @"shaders\simple");
worldViewProjectionParam = effect.Parameters["worldViewProjection"];
buffer = new VertexBuffer(graphicsService.GraphicsDevice, typeof(VertexPositionColor), maxProjectileCount * 4, BufferUsage.WriteOnly);
data = new VertexPositionColor[maxProjectileCount * 4];
// initialize the Projectile Pool
for (int position = 0; position < maxProjectileCount * 4; position++)
{
data[position] = new VertexPositionColor(new Vector3(0.0f, 0.0f, 0.0f), Color.White);
}
}
}
}