#region Copyright
/*
--------------------------------------------------------------------------------
This source file is part of Xenocide
by Project Xenocide Team
For the latest info on Xenocide, see http://www.projectxenocide.com/
This work is licensed under the Creative Commons
Attribution-NonCommercial-ShareAlike 2.5 License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/2.5/
or send a letter to Creative Commons, 543 Howard Street, 5th Floor,
San Francisco, California, 94105, USA.
--------------------------------------------------------------------------------
*/
/*
* @file LineMesh.cs
* @date Created: 2008/01/04
* @author File creator: David Teviotdale
* @author Credits: none
*/
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
#endregion
namespace ProjectXenocide.UI.Scenes
{
///
/// Handles drawing a mesh that's a set of lines in 3D space
///
public class LineMesh : IDisposable
{
#region IDisposable
///
/// Implement IDisposable
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Implement IDisposable
///
/// false when called from a finalizer
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
DisposeBuffers();
if (null != basicEffectVertexDeclaration)
{
basicEffectVertexDeclaration.Dispose();
basicEffectVertexDeclaration = null;
}
}
}
#endregion IDisposable
///
/// Load/create the graphic resources needed by the grid
///
/// the display
/// Thing that knows how what lines to draw
public void LoadContent(GraphicsDevice device, LineMeshBuilder builder)
{
basicEffectVertexDeclaration = new VertexDeclaration(
device, VertexPositionColor.VertexElements);
BuildMesh(device, builder);
}
///
/// Load the buffers with the set of lines to draw
///
///
/// Thing that knows how what lines to draw
public void BuildMesh(GraphicsDevice device, LineMeshBuilder builder)
{
List verts = new List();
List indexes = new List();
builder.Build(verts, indexes);
DisposeBuffers();
constructVertexBuffer(device, verts);
constructIndexBuffer(device, indexes);
}
///
/// construct a vertex buffer that can be used to draw the grid
///
///
///
private void constructVertexBuffer(GraphicsDevice device, List verts)
{
numVertices = verts.Count;
if (0 < numVertices)
{
vertexBuffer = new VertexBuffer(
device,
VertexPositionColor.SizeInBytes * verts.Count,
BufferUsage.None
);
vertexBuffer.SetData(verts.ToArray());
}
}
///
/// construct the line list that can be used to draw the grid.
///
///
///
private void constructIndexBuffer(GraphicsDevice device, List indexes)
{
numLines = indexes.Count / 2;
if (0 < numLines)
{
indexBuffer = new IndexBuffer(
device,
sizeof(short) * indexes.Count,
BufferUsage.None,
IndexElementSize.SixteenBits
);
indexBuffer.SetData(indexes.ToArray());
}
}
///
/// Set up a BasicEffect for drawing the grid
///
/// effect to use to draw the grid
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods",
Justification = "will throw if BasicEffect is null")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
Justification = "What's going on is more clear if this is NOT a static function")]
public void ConfigureEffect(BasicEffect effect)
{
effect.LightingEnabled = false;
effect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
effect.Alpha = 1.0f;
effect.World = Matrix.Identity;
effect.TextureEnabled = false;
effect.VertexColorEnabled = true;
}
///
/// Draw the grid on the device
///
/// Device to render the grid to
/// effect to use to draw the grid
public void Draw(GraphicsDevice device, Effect effect)
{
Draw(device, effect, numLines);
}
///
/// Draw the first lineCount lines of the mesh on the device
///
/// Device to render the grid to
/// effect to use to draw the grid
/// Number of lines to draw
public void Draw(GraphicsDevice device, Effect effect, int lineCount)
{
if (0 < lineCount)
{
Debug.Assert(lineCount <= numLines);
device.VertexDeclaration = basicEffectVertexDeclaration;
device.Vertices[0].SetSource(
vertexBuffer, 0, VertexPositionColor.SizeInBytes);
device.Indices = indexBuffer;
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawIndexedPrimitives(
PrimitiveType.LineList,
0,
0,
numVertices,
0,
lineCount
);
pass.End();
}
effect.End();
}
}
/// Release the buffers cleanly
private void DisposeBuffers()
{
if (null != vertexBuffer)
{
vertexBuffer.Dispose();
vertexBuffer = null;
}
if (null != indexBuffer)
{
indexBuffer.Dispose();
indexBuffer = null;
}
}
#region Fields
/// Defines the vertex structures we're using
private VertexDeclaration basicEffectVertexDeclaration;
/// Vertices making up the lines
private VertexBuffer vertexBuffer;
/// Order to draw the lines
private IndexBuffer indexBuffer;
/// Number of vertices
private int numVertices;
/// Number of lines
private int numLines;
#endregion Fields
}
}