123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- #region File Description
- //-----------------------------------------------------------------------------
- // GeometricPrimitive.cs
- //
- // Microsoft XNA Community Game Platform
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #endregion
- #region Using Statements
- using System;
- using System.Collections.Generic;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- #endregion
- namespace PerformanceMeasuring
- {
- /// <summary>
- /// Base class for simple geometric primitive models. This provides a vertex
- /// buffer, an index buffer, plus methods for drawing the model. Classes for
- /// specific types of primitive (CubePrimitive, SpherePrimitive, etc.) are
- /// derived from this common base, and use the AddVertex and AddIndex methods
- /// to specify their geometry.
- ///
- /// This class is borrowed from the Primitives3D sample.
- /// </summary>
- public abstract class GeometricPrimitive : IDisposable
- {
- #region Fields
- // During the process of constructing a primitive model, vertex
- // and index data is stored on the CPU in these managed lists.
- List<VertexPositionNormal> vertices = new List<VertexPositionNormal>();
- List<ushort> indices = new List<ushort>();
- // Once all the geometry has been specified, the InitializePrimitive
- // method copies the vertex and index data into these buffers, which
- // store it on the GPU ready for efficient rendering.
- VertexBuffer vertexBuffer;
- IndexBuffer indexBuffer;
- BasicEffect basicEffect;
- #endregion
- #region Initialization
- /// <summary>
- /// Adds a new vertex to the primitive model. This should only be called
- /// during the initialization process, before InitializePrimitive.
- /// </summary>
- protected void AddVertex(Vector3 position, Vector3 normal)
- {
- vertices.Add(new VertexPositionNormal(position, normal));
- }
- /// <summary>
- /// Adds a new index to the primitive model. This should only be called
- /// during the initialization process, before InitializePrimitive.
- /// </summary>
- protected void AddIndex(int index)
- {
- if (index > ushort.MaxValue)
- throw new ArgumentOutOfRangeException("index");
- indices.Add((ushort)index);
- }
- /// <summary>
- /// Queries the index of the current vertex. This starts at
- /// zero, and increments every time AddVertex is called.
- /// </summary>
- protected int CurrentVertex
- {
- get { return vertices.Count; }
- }
- /// <summary>
- /// Once all the geometry has been specified by calling AddVertex and AddIndex,
- /// this method copies the vertex and index data into GPU format buffers, ready
- /// for efficient rendering.
- protected void InitializePrimitive(GraphicsDevice graphicsDevice)
- {
- // Create a vertex declaration, describing the format of our vertex data.
- // Create a vertex buffer, and copy our vertex data into it.
- vertexBuffer = new VertexBuffer(graphicsDevice,
- typeof(VertexPositionNormal),
- vertices.Count, BufferUsage.None);
- vertexBuffer.SetData(vertices.ToArray());
- // Create an index buffer, and copy our index data into it.
- indexBuffer = new IndexBuffer(graphicsDevice, typeof(ushort),
- indices.Count, BufferUsage.None);
- indexBuffer.SetData(indices.ToArray());
- // Create a BasicEffect, which will be used to render the primitive.
- basicEffect = new BasicEffect(graphicsDevice);
- basicEffect.EnableDefaultLighting();
- basicEffect.PreferPerPixelLighting = false;
- }
- /// <summary>
- /// Finalizer.
- /// </summary>
- ~GeometricPrimitive()
- {
- Dispose(false);
- }
- /// <summary>
- /// Frees resources used by this object.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- /// <summary>
- /// Frees resources used by this object.
- /// </summary>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (vertexBuffer != null)
- vertexBuffer.Dispose();
- if (indexBuffer != null)
- indexBuffer.Dispose();
- if (basicEffect != null)
- basicEffect.Dispose();
- }
- }
- #endregion
- #region Draw
- /// <summary>
- /// Draws the primitive model, using the specified effect. Unlike the other
- /// Draw overload where you just specify the world/view/projection matrices
- /// and color, this method does not set any renderstates, so you must make
- /// sure all states are set to sensible values before you call it.
- /// </summary>
- public void Draw(Effect effect)
- {
- GraphicsDevice graphicsDevice = effect.GraphicsDevice;
- // Set our vertex declaration, vertex buffer, and index buffer.
- graphicsDevice.SetVertexBuffer(vertexBuffer);
- graphicsDevice.Indices = indexBuffer;
- foreach (EffectPass effectPass in effect.CurrentTechnique.Passes)
- {
- effectPass.Apply();
- int primitiveCount = indices.Count / 3;
- graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
- vertices.Count, 0, primitiveCount);
- }
- }
- /// <summary>
- /// Draws the primitive model, using a BasicEffect shader with default
- /// lighting. Unlike the other Draw overload where you specify a custom
- /// effect, this method sets important renderstates to sensible values
- /// for 3D model rendering, so you do not need to set these states before
- /// you call it.
- /// </summary>
- public void Draw(Matrix world, Matrix view, Matrix projection, Color color)
- {
- // Set BasicEffect parameters.
- basicEffect.World = world;
- basicEffect.View = view;
- basicEffect.Projection = projection;
- basicEffect.DiffuseColor = color.ToVector3();
- basicEffect.Alpha = color.A / 255.0f;
- GraphicsDevice device = basicEffect.GraphicsDevice;
- device.DepthStencilState = DepthStencilState.Default;
- if (color.A < 255)
- {
- // Set renderstates for alpha blended rendering.
- device.BlendState = BlendState.AlphaBlend;
- }
- else
- {
- // Set renderstates for opaque rendering.
- device.BlendState = BlendState.Opaque;
- }
- // Draw the model, using BasicEffect.
- Draw(basicEffect);
- }
- #endregion
- }
- }
|