#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 } }