using System; using Chernobyl.Collections.Generic.Event; using Chernobyl.Dependency; using Chernobyl.Graphics.Drawing; using Chernobyl.Graphics.Polygon.Buffers; using Chernobyl.Mathematics.Geometry; using Chernobyl.Mathematics.Movement; using Microsoft.Xna.Framework.Graphics; namespace Chernobyl.Graphics.Xna.Controllers { /// /// The XNA implementation of an . /// public class XnaRender : DrawableTransform, IRender { /// /// Constructor. /// /// The services class whose services will be /// injected into the render objects /// The primitive type of the render object. /// The used by the created /// object to control drawing. /// The used by the created /// to control transformations. /// The used by the created /// to control shape related functionality. public XnaRender(IEventCollection services, Chernobyl.Graphics.Drawing.PrimitiveType primitiveType, IDrawable drawable, ITransform decoratedTransform, IShape shape) { _drawableImplementer = drawable; _drawableImplementer.DecoratoringDrawable = this; _decoratedTransform = decoratedTransform; _shapeImplementer = shape; PrimitiveType = primitiveType; DrawMethod = NoOpDraw; services.Inject(this); } /// /// Calls draw on the children objects. Overload to add you own implementation. /// public override uint Draw() { DrawMethod(); return base.Draw(); } /// /// The method that draws the mesh /// public Action DrawMethod { get; set; } /// /// Draws a mesh with indices specified. /// public void DrawWithIndices() { SceneWorldMatrix.Value = WorldMatrix; VertexBuffer vertexBuffer = Mesh.XnaVertexBuffer; GraphicsDevice.DrawIndexedPrimitives(XnaPrimitiveType, 0, 0, (int)Mesh.Count, 0, Utility.GetPrimitiveCount(XnaPrimitiveType, Mesh.Count)); } /// /// Draws a mesh without indices specified. /// public void DrawWithoutIndices() { SceneWorldMatrix.Value = WorldMatrix; VertexBuffer vertexBuffer = Mesh.XnaVertexBuffer; GraphicsDevice.DrawPrimitives(XnaPrimitiveType, 0, Utility.GetPrimitiveCount(XnaPrimitiveType, Mesh.Count)); } /// /// A no-op (no operation) draw method that does nothing. This /// is the default DrawMethod used by this draw. /// public void NoOpDraw() {} /// /// The mesh element buffer used to draw the data. /// public IXnaMesh Mesh { get { return _mesh; } set { _mesh = value; RevaluateDrawMethod(); } } /// /// The index buffer used to draw the data. /// public IBuffer IndexBuffer { get { return _indexBuffer; } set { _indexBuffer = value; RevaluateDrawMethod(); } } /// /// The primitive type being drawn. /// public Chernobyl.Graphics.Drawing.PrimitiveType PrimitiveType { get { return Utility.ToChernobylPrimitiveType(XnaPrimitiveType); } set { XnaPrimitiveType = Utility.ToXnaPrimitiveType(value); } } /// /// The graphics devices used by this draw. /// [Inject] public GraphicsDevice GraphicsDevice { get { return _graphicsDevice; } set { _graphicsDevice = value; RevaluateDrawMethod(); } } /// /// The world matrix used to set our transformation on. /// [Inject] public IWorldMatrixParameter SceneWorldMatrix { get { return _sceneWorldMatrix; } set { _sceneWorldMatrix = value; RevaluateDrawMethod(); } } /// /// The largest width of the object in the object's X axis. /// public float Width { get { return _shapeImplementer.Width; } } /// /// The largest height of the object in the object's Y axis. /// public float Height { get { return _shapeImplementer.Height; } } /// /// The largest depth of the object in the object's Z axis. /// public float Depth { get { return _shapeImplementer.Depth; } } /// /// True if this is convex, false if it is concave /// or has 0 (such as a point). A /// is convex if for every pair of points within /// the object, every point on the straight line segment that joins them /// is also within the object. A concave is the /// opposite of this. /// public bool IsConvex { get { return _shapeImplementer.IsConvex; } } /// /// The amount of space taken up by an object on a flat plane in /// square metres (m^2). /// public float Area { get { return _shapeImplementer.Area; } } /// /// The amount of 3D space this object consumes in cubic metres (m^3). /// If this object is 2D, then the value of this property is zero. /// public float Volume { get { return _shapeImplementer.Volume; } } /// /// The length of the path that surrounds a shape specified in metres (m). /// In the case of a closed curve such as a circle, this value represents /// the circumference of the object. /// public float Perimeter { get { return _shapeImplementer.Perimeter; } } /// /// The minimum number of coordinates needed to specify each point /// within this object. For example: a point has 0 dimensions, a /// line has 1 dimension, a circle or rectangle has 2 dimensions, a /// cube or sphere has 3 dimensions, and a moving cube or sphere has 4. /// public uint Dimensions { get { return _shapeImplementer.Dimensions; } } /// /// The drawable that implements the drawing of this object. /// protected override IDrawable DrawableImplementer { get { return _drawableImplementer; } } /// /// The transform that provides this transforms capabilities. /// protected override ITransform DecoratedTransform { get { return _decoratedTransform; } } /// /// The that implements the width and height /// capabilities of this type. /// protected IShape GeometryImplementer { get { return _shapeImplementer; } } /// /// Checks the draw method to ensure that is the correct draw method /// given whether the IndexBuffer and Mesh exist. /// void RevaluateDrawMethod() { if (Mesh != null && GraphicsDevice != null && SceneWorldMatrix != null) { if (IndexBuffer != null) DrawMethod = DrawWithIndices; else DrawMethod = DrawWithoutIndices; } else DrawMethod = NoOpDraw; } /// /// The XNA primitive type. /// Microsoft.Xna.Framework.Graphics.PrimitiveType XnaPrimitiveType { get; set; } /// /// The backing field to . /// IXnaMesh _mesh; /// /// The backing field to . /// IBuffer _indexBuffer; /// /// The backing field to /// GraphicsDevice _graphicsDevice; /// /// The backing field to . /// IWorldMatrixParameter _sceneWorldMatrix; /// /// The backing field to . /// IDrawable _drawableImplementer; /// /// The backing field to . /// ITransform _decoratedTransform; /// /// The backing field to . /// IShape _shapeImplementer; } }