GeometricPrimitive.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // GeometricPrimitive.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Collections.Generic;
  12. using Microsoft.Xna.Framework;
  13. using Microsoft.Xna.Framework.Graphics;
  14. #endregion
  15. namespace PerformanceMeasuring
  16. {
  17. /// <summary>
  18. /// Base class for simple geometric primitive models. This provides a vertex
  19. /// buffer, an index buffer, plus methods for drawing the model. Classes for
  20. /// specific types of primitive (CubePrimitive, SpherePrimitive, etc.) are
  21. /// derived from this common base, and use the AddVertex and AddIndex methods
  22. /// to specify their geometry.
  23. ///
  24. /// This class is borrowed from the Primitives3D sample.
  25. /// </summary>
  26. public abstract class GeometricPrimitive : IDisposable
  27. {
  28. #region Fields
  29. // During the process of constructing a primitive model, vertex
  30. // and index data is stored on the CPU in these managed lists.
  31. List<VertexPositionNormal> vertices = new List<VertexPositionNormal>();
  32. List<ushort> indices = new List<ushort>();
  33. // Once all the geometry has been specified, the InitializePrimitive
  34. // method copies the vertex and index data into these buffers, which
  35. // store it on the GPU ready for efficient rendering.
  36. VertexBuffer vertexBuffer;
  37. IndexBuffer indexBuffer;
  38. BasicEffect basicEffect;
  39. #endregion
  40. #region Initialization
  41. /// <summary>
  42. /// Adds a new vertex to the primitive model. This should only be called
  43. /// during the initialization process, before InitializePrimitive.
  44. /// </summary>
  45. protected void AddVertex(Vector3 position, Vector3 normal)
  46. {
  47. vertices.Add(new VertexPositionNormal(position, normal));
  48. }
  49. /// <summary>
  50. /// Adds a new index to the primitive model. This should only be called
  51. /// during the initialization process, before InitializePrimitive.
  52. /// </summary>
  53. protected void AddIndex(int index)
  54. {
  55. if (index > ushort.MaxValue)
  56. throw new ArgumentOutOfRangeException("index");
  57. indices.Add((ushort)index);
  58. }
  59. /// <summary>
  60. /// Queries the index of the current vertex. This starts at
  61. /// zero, and increments every time AddVertex is called.
  62. /// </summary>
  63. protected int CurrentVertex
  64. {
  65. get { return vertices.Count; }
  66. }
  67. /// <summary>
  68. /// Once all the geometry has been specified by calling AddVertex and AddIndex,
  69. /// this method copies the vertex and index data into GPU format buffers, ready
  70. /// for efficient rendering.
  71. protected void InitializePrimitive(GraphicsDevice graphicsDevice)
  72. {
  73. // Create a vertex declaration, describing the format of our vertex data.
  74. // Create a vertex buffer, and copy our vertex data into it.
  75. vertexBuffer = new VertexBuffer(graphicsDevice,
  76. typeof(VertexPositionNormal),
  77. vertices.Count, BufferUsage.None);
  78. vertexBuffer.SetData(vertices.ToArray());
  79. // Create an index buffer, and copy our index data into it.
  80. indexBuffer = new IndexBuffer(graphicsDevice, typeof(ushort),
  81. indices.Count, BufferUsage.None);
  82. indexBuffer.SetData(indices.ToArray());
  83. // Create a BasicEffect, which will be used to render the primitive.
  84. basicEffect = new BasicEffect(graphicsDevice);
  85. basicEffect.EnableDefaultLighting();
  86. basicEffect.PreferPerPixelLighting = false;
  87. }
  88. /// <summary>
  89. /// Finalizer.
  90. /// </summary>
  91. ~GeometricPrimitive()
  92. {
  93. Dispose(false);
  94. }
  95. /// <summary>
  96. /// Frees resources used by this object.
  97. /// </summary>
  98. public void Dispose()
  99. {
  100. Dispose(true);
  101. GC.SuppressFinalize(this);
  102. }
  103. /// <summary>
  104. /// Frees resources used by this object.
  105. /// </summary>
  106. protected virtual void Dispose(bool disposing)
  107. {
  108. if (disposing)
  109. {
  110. if (vertexBuffer != null)
  111. vertexBuffer.Dispose();
  112. if (indexBuffer != null)
  113. indexBuffer.Dispose();
  114. if (basicEffect != null)
  115. basicEffect.Dispose();
  116. }
  117. }
  118. #endregion
  119. #region Draw
  120. /// <summary>
  121. /// Draws the primitive model, using the specified effect. Unlike the other
  122. /// Draw overload where you just specify the world/view/projection matrices
  123. /// and color, this method does not set any renderstates, so you must make
  124. /// sure all states are set to sensible values before you call it.
  125. /// </summary>
  126. public void Draw(Effect effect)
  127. {
  128. GraphicsDevice graphicsDevice = effect.GraphicsDevice;
  129. // Set our vertex declaration, vertex buffer, and index buffer.
  130. graphicsDevice.SetVertexBuffer(vertexBuffer);
  131. graphicsDevice.Indices = indexBuffer;
  132. foreach (EffectPass effectPass in effect.CurrentTechnique.Passes)
  133. {
  134. effectPass.Apply();
  135. int primitiveCount = indices.Count / 3;
  136. graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
  137. vertices.Count, 0, primitiveCount);
  138. }
  139. }
  140. /// <summary>
  141. /// Draws the primitive model, using a BasicEffect shader with default
  142. /// lighting. Unlike the other Draw overload where you specify a custom
  143. /// effect, this method sets important renderstates to sensible values
  144. /// for 3D model rendering, so you do not need to set these states before
  145. /// you call it.
  146. /// </summary>
  147. public void Draw(Matrix world, Matrix view, Matrix projection, Color color)
  148. {
  149. // Set BasicEffect parameters.
  150. basicEffect.World = world;
  151. basicEffect.View = view;
  152. basicEffect.Projection = projection;
  153. basicEffect.DiffuseColor = color.ToVector3();
  154. basicEffect.Alpha = color.A / 255.0f;
  155. GraphicsDevice device = basicEffect.GraphicsDevice;
  156. device.DepthStencilState = DepthStencilState.Default;
  157. if (color.A < 255)
  158. {
  159. // Set renderstates for alpha blended rendering.
  160. device.BlendState = BlendState.AlphaBlend;
  161. }
  162. else
  163. {
  164. // Set renderstates for opaque rendering.
  165. device.BlendState = BlendState.Opaque;
  166. }
  167. // Draw the model, using BasicEffect.
  168. Draw(basicEffect);
  169. }
  170. #endregion
  171. }
  172. }