GeometricPrimitive.cs 7.0 KB

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