Advertisement
Guest User

XNA RenderObject with 2 types of Cubes

a guest
May 31st, 2013
431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.05 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. using Microsoft.Xna.Framework.Graphics;
  6. using Microsoft.Xna.Framework;
  7.  
  8. namespace CubeRender
  9. {
  10.  
  11.     public enum RenderObjectType
  12.     {
  13.         VertexIndex,
  14.         Vertex
  15.     }
  16.  
  17.     public abstract class RenderObject : IDisposable
  18.     {
  19.         private List<IVertexType> vertices = new List<IVertexType>();
  20.         public List<IVertexType> Vertices { get { return vertices; } }
  21.  
  22.         private List<ushort> indices = new List<ushort>();
  23.         public List<ushort> Indices { get { return indices; } }
  24.  
  25.         private VertexBuffer vertexBuffer;
  26.         public VertexBuffer VertexBuffer { get { return vertexBuffer; } protected set { vertexBuffer = value; } }
  27.  
  28.         private IndexBuffer indexBuffer;
  29.         public IndexBuffer IndexBuffer { get { return indexBuffer; } protected set { indexBuffer = value; } }
  30.  
  31.         private PrimitiveType primitiveType;
  32.         public PrimitiveType PrimitiveType { get { return primitiveType; } set { primitiveType = value; } }
  33.  
  34.         private RenderObjectType type;
  35.         public RenderObjectType Type { get { return type; } protected set { type = value; } }
  36.  
  37.         public int VerticeCount { get { return vertices.Count; } }
  38.  
  39.         private int? primitiveCount = null;
  40.         public virtual int PrimitiveCount { get { if (primitiveCount == null) { return vertices.Count / 3; } else { return primitiveCount.Value; } } protected set { primitiveCount = value; } }
  41.  
  42.         public VertexDeclaration VertexDeclaration { get { return vertexBuffer.VertexDeclaration; } }
  43.  
  44.         private Vector3 rotation = Vector3.Zero;
  45.         public Vector3 Rotation { get { return rotation; } set { if (rotation != value) { rotation = value; UpdateWorld(); } } }
  46.  
  47.         private Vector3 position = Vector3.Zero;
  48.         public Vector3 Position { get { return position; } set { if (position != value) { position = value; UpdateWorld(); } } }
  49.  
  50.         private float scale = 1f;
  51.         public float Scale { get { return scale; } set { if (scale != value) { scale = value; UpdateWorld(); } } }
  52.  
  53.         private Matrix? world;
  54.         public Matrix World
  55.         {
  56.             get
  57.             {
  58.                 if (world == null)
  59.                 {
  60.                     UpdateWorld();
  61.                 }
  62.  
  63.                 return world.Value;
  64.             }
  65.         }
  66.  
  67.         protected BoundingBox? boundingBox = null;
  68.         public abstract BoundingBox BoundingBox { get; }
  69.  
  70.         private void UpdateWorld()
  71.         {
  72.             world =
  73.                 Matrix.CreateScale(Scale) *
  74.                 Matrix.CreateRotationX(Rotation.X) *
  75.                 Matrix.CreateRotationY(Rotation.Y) *
  76.                 Matrix.CreateRotationZ(Rotation.Z) *
  77.                 Matrix.CreateTranslation(Position);
  78.  
  79.             boundingBox = null;
  80.         }
  81.  
  82.         protected virtual void Initialize<T>(GraphicsDevice graphicsDevice, RenderObjectType type, PrimitiveType primitiveType) where T : struct, IVertexType
  83.         {
  84.             Type = type;
  85.             PrimitiveType = primitiveType;
  86.  
  87.             vertexBuffer = new VertexBuffer(graphicsDevice, typeof(T), vertices.Count, BufferUsage.None);
  88.             vertexBuffer.SetData<T>(vertices.Select(m => (T)m).ToArray());
  89.  
  90.             if (Type == RenderObjectType.VertexIndex)
  91.             {
  92.                 indexBuffer = new IndexBuffer(graphicsDevice, typeof(ushort), indices.Count, BufferUsage.None);
  93.                 indexBuffer.SetData(indices.ToArray());
  94.             }
  95.         }
  96.  
  97.         protected void AddVertex<T>(T vertex) where T : struct, IVertexType
  98.         {
  99.             vertices.Add(vertex);
  100.         }
  101.  
  102.         protected void AddIndex(int index)
  103.         {
  104.             if (index > ushort.MaxValue)
  105.                 throw new ArgumentOutOfRangeException("index");
  106.  
  107.             indices.Add((ushort)index);
  108.         }
  109.  
  110.         ~RenderObject()
  111.         {
  112.             Dispose(false);
  113.         }
  114.  
  115.         public void Dispose()
  116.         {
  117.             Dispose(true);
  118.             GC.SuppressFinalize(this);
  119.         }
  120.  
  121.         protected virtual void Dispose(bool disposing)
  122.         {
  123.             if (disposing)
  124.             {
  125.                 if (vertexBuffer != null)
  126.                     vertexBuffer.Dispose();
  127.  
  128.                 if (indexBuffer != null)
  129.                     indexBuffer.Dispose();
  130.             }
  131.         }
  132.  
  133.         public virtual void Draw(GraphicsDevice graphicsDevice, BasicEffect effect)
  134.         {
  135.             if (effect == null || effect.IsDisposed)
  136.                 return;
  137.  
  138.             effect.World = this.World;
  139.  
  140.             foreach (EffectPass pass in effect.CurrentTechnique.Passes)
  141.                 pass.Apply();
  142.  
  143.             if (this.Type == RenderObjectType.VertexIndex)
  144.             {
  145.                 graphicsDevice.Indices = this.IndexBuffer;
  146.                 graphicsDevice.SetVertexBuffer(this.VertexBuffer);
  147.                 graphicsDevice.DrawIndexedPrimitives(this.PrimitiveType, 0, 0, this.VerticeCount, 0, this.PrimitiveCount);
  148.             }
  149.             else if (this.Type == RenderObjectType.Vertex)
  150.             {
  151.                 graphicsDevice.Indices = null;
  152.                 graphicsDevice.SetVertexBuffer(this.VertexBuffer);
  153.                 graphicsDevice.DrawIndexedPrimitives(this.PrimitiveType, 0, 0, this.VerticeCount, 0, this.PrimitiveCount);
  154.             }
  155.         }
  156.     }
  157.  
  158.     public abstract class PrimitiveColor : RenderObject
  159.     {
  160.         public override BoundingBox BoundingBox
  161.         {
  162.             get
  163.             {
  164.                 if (this.boundingBox == null)
  165.                 {
  166.                     boundingBox = BoundingBox.CreateFromPoints(this.Vertices.Select(m => Vector3.Transform(((VertexPositionColor)m).Position, this.World)));
  167.                 }
  168.  
  169.                 return this.boundingBox.Value;
  170.             }
  171.         }
  172.     }
  173.  
  174.     public class Cube2 : PrimitiveColor
  175.     {
  176.         public Cube2(GraphicsDevice graphicsDevice) : this(graphicsDevice, Color.White, 1f, 1f, 1f)
  177.         {
  178.         }
  179.  
  180.         public Cube2(GraphicsDevice graphicsDevice, Color color, float width = 1f, float height = 1f, float depth = 1f)
  181.         {
  182.             Vector3 size = new Vector3(width, height, depth);
  183.  
  184.             // A cube has six faces, each one pointing in a different direction.
  185.             Vector3[] normals =
  186.             {
  187.                 new Vector3(0, 0, 1),
  188.                 new Vector3(0, 0, -1),
  189.                 new Vector3(1, 0, 0),
  190.                 new Vector3(-1, 0, 0),
  191.                 new Vector3(0, 1, 0),
  192.                 new Vector3(0, -1, 0),
  193.             };
  194.  
  195.             // Create each face in turn.
  196.             foreach (Vector3 normal in normals)
  197.             {
  198.                 // Get two vectors perpendicular to the face normal and to each other.
  199.                 Vector3 side1 = new Vector3(normal.Y, normal.Z, normal.X);
  200.                 Vector3 side2 = Vector3.Cross(normal, side1);
  201.  
  202.                 // Six indices (two triangles) per face.
  203.                 AddIndex(VerticeCount + 0);
  204.                 AddIndex(VerticeCount + 1);
  205.                 AddIndex(VerticeCount + 2);
  206.  
  207.                 AddIndex(VerticeCount + 0);
  208.                 AddIndex(VerticeCount + 2);
  209.                 AddIndex(VerticeCount + 3);
  210.  
  211.                 // Four vertices per face.
  212.                 AddVertex(new VertexPositionColor((normal - side1 - side2) * size / 2, color));
  213.                 AddVertex(new VertexPositionColor((normal - side1 + side2) * size / 2, color));
  214.                 AddVertex(new VertexPositionColor((normal + side1 + side2) * size / 2, color));
  215.                 AddVertex(new VertexPositionColor((normal + side1 - side2) * size / 2, color));
  216.             }
  217.  
  218.             PrimitiveCount = VerticeCount;
  219.  
  220.             Initialize<VertexPositionColor>(graphicsDevice, RenderObjectType.VertexIndex, PrimitiveType.TriangleList);
  221.         }
  222.  
  223.     }
  224.  
  225.     public class Cube : PrimitiveColor
  226.     {
  227.         public Cube(GraphicsDevice graphicsDevice)
  228.         {
  229.             AddVertex<VertexPositionColor>(new VertexPositionColor(new Vector3(-1, -1, -1), Color.Black));
  230.             AddVertex<VertexPositionColor>(new VertexPositionColor(new Vector3(-1, -1, 1), Color.Red));
  231.             AddVertex<VertexPositionColor>(new VertexPositionColor(new Vector3(1, -1, 1), Color.Yellow));
  232.             AddVertex<VertexPositionColor>(new VertexPositionColor(new Vector3(1, -1, -1), Color.Green));
  233.             AddVertex<VertexPositionColor>(new VertexPositionColor(new Vector3(-1, 1, -1), Color.Blue));
  234.             AddVertex<VertexPositionColor>(new VertexPositionColor(new Vector3(-1, 1, 1), Color.Magenta));
  235.             AddVertex<VertexPositionColor>(new VertexPositionColor(new Vector3(1, 1, 1), Color.White));
  236.             AddVertex<VertexPositionColor>(new VertexPositionColor(new Vector3(1, 1, -1), Color.Cyan));
  237.  
  238.             //bottom face
  239.             AddIndex(0);
  240.             AddIndex(2);
  241.             AddIndex(3);
  242.             AddIndex(0);
  243.             AddIndex(1);
  244.             AddIndex(2);
  245.  
  246.             // top face
  247.             AddIndex(4);
  248.             AddIndex(6);
  249.             AddIndex(5);
  250.             AddIndex(4);
  251.             AddIndex(7);
  252.             AddIndex(6);
  253.  
  254.             // front face
  255.             AddIndex(5);
  256.             AddIndex(2);
  257.             AddIndex(1);
  258.             AddIndex(5);
  259.             AddIndex(6);
  260.             AddIndex(2);
  261.  
  262.             // back face
  263.             AddIndex(0);
  264.             AddIndex(7);
  265.             AddIndex(4);
  266.             AddIndex(0);
  267.             AddIndex(3);
  268.             AddIndex(7);
  269.  
  270.             // left face
  271.             AddIndex(0);
  272.             AddIndex(4);
  273.             AddIndex(1);
  274.             AddIndex(1);
  275.             AddIndex(4);
  276.             AddIndex(5);
  277.  
  278.             //right face
  279.             AddIndex(2);
  280.             AddIndex(6);
  281.             AddIndex(3);
  282.             AddIndex(3);
  283.             AddIndex(6);
  284.             AddIndex(7);
  285.  
  286.             PrimitiveCount = VerticeCount*2;
  287.  
  288.             Initialize<VertexPositionColor>(graphicsDevice, RenderObjectType.VertexIndex, PrimitiveType.TriangleList);
  289.         }
  290.     }
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement