Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
GeometricPrimitive.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 //
4 // Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 // THE SOFTWARE.
23 
24 using System;
25 using SiliconStudio.Core;
26 
27 namespace SiliconStudio.Paradox.Graphics
28 {
29  /// <summary>
30  /// A geometric primitive used to draw a simple model built from a set of vertices and indices.
31  /// </summary>
32  public class GeometricPrimitive<T> : ComponentBase where T : struct, IVertex
33  {
34  /// <summary>
35  /// The index buffer used by this geometric primitive.
36  /// </summary>
37  public readonly Buffer IndexBuffer;
38 
39  /// <summary>
40  /// The vertex buffer used by this geometric primitive.
41  /// </summary>
42  public readonly Buffer VertexBuffer;
43 
44  /// <summary>
45  /// The default graphics device.
46  /// </summary>
47  protected readonly GraphicsDevice GraphicsDevice;
48 
49  /// <summary>
50  /// The input layout used by this geometric primitive (shared for all geometric primitive).
51  /// </summary>
52  private readonly VertexArrayObject vertexArrayObject;
53 
54  /// <summary>
55  /// True if the index buffer is a 32 bit index buffer.
56  /// </summary>
57  public readonly bool IsIndex32Bits;
58 
59  /// <summary>
60  /// Initializes a new instance of the <see cref="GeometricPrimitive{T}"/> class.
61  /// </summary>
62  /// <param name="graphicsDevice">The graphics device.</param>
63  /// <param name="geometryMesh">The geometry mesh.</param>
64  /// <exception cref="System.InvalidOperationException">Cannot generate more than 65535 indices on feature level HW <= 9.3</exception>
65  public GeometricPrimitive(GraphicsDevice graphicsDevice, GeometricMeshData<T> geometryMesh)
66  {
67  GraphicsDevice = graphicsDevice;
68 
69  var vertices = geometryMesh.Vertices;
70  var indices = geometryMesh.Indices;
71 
72  if (geometryMesh.IsLeftHanded)
73  ReverseWinding(vertices, indices);
74 
75  if (indices.Length < 0xFFFF)
76  {
77  var indicesShort = new ushort[indices.Length];
78  for (int i = 0; i < indicesShort.Length; i++)
79  {
80  indicesShort[i] = (ushort)indices[i];
81  }
82  IndexBuffer = Buffer.Index.New(graphicsDevice, indicesShort).RecreateWith(indicesShort).DisposeBy(this);
83  }
84  else
85  {
86  if (graphicsDevice.Features.Profile <= GraphicsProfile.Level_9_3)
87  {
88  throw new InvalidOperationException("Cannot generate more than 65535 indices on feature level HW <= 9.3");
89  }
90 
91  IndexBuffer = Buffer.Index.New(graphicsDevice, indices).RecreateWith(indices).DisposeBy(this);
92  IsIndex32Bits = true;
93  }
94 
95  // For now it will keep buffers for recreation.
96  // TODO: A better alternative would be to store recreation parameters so that we can reuse procedural code.
97  VertexBuffer = Buffer.Vertex.New(graphicsDevice, vertices).RecreateWith(vertices).DisposeBy(this);
98 
99  vertexArrayObject = VertexArrayObject.New(graphicsDevice, new IndexBufferBinding(IndexBuffer, IsIndex32Bits, indices.Length), new VertexBufferBinding(VertexBuffer, new T().GetLayout(), vertices.Length)).DisposeBy(this);
100  }
101 
102  /// <summary>
103  /// Draws this <see cref="GeometricPrimitive" />.
104  /// </summary>
105  public void Draw()
106  {
107  Draw(GraphicsDevice);
108  }
109 
110  /// <summary>
111  /// Draws this <see cref="GeometricPrimitive" />.
112  /// </summary>
113  /// <param name="graphicsDevice">The graphics device.</param>
114  public void Draw(GraphicsDevice graphicsDevice)
115  {
116  // Setup the Vertex Buffer
117  graphicsDevice.SetVertexArrayObject(vertexArrayObject);
118 
119  // Finally Draw this mesh
120  graphicsDevice.DrawIndexed(PrimitiveType.TriangleList, IndexBuffer.ElementCount);
121  }
122 
123  /// <summary>
124  /// Helper for flipping winding of geometric primitives for LH vs. RH coordinates
125  /// </summary>
126  /// <typeparam name="TIndex">The type of the T index.</typeparam>
127  /// <param name="vertices">The vertices.</param>
128  /// <param name="indices">The indices.</param>
129  private void ReverseWinding<TIndex>(T[] vertices, TIndex[] indices)
130  {
131  for (int i = 0; i < indices.Length; i += 3)
132  {
133  Utilities.Swap(ref indices[i], ref indices[i + 2]);
134  }
135 
136  for (int i = 0; i < vertices.Length; i++)
137  {
138  vertices[i].FlipWinding();
139  }
140  }
141  }
142 
143  /// <summary>
144  /// A geometric primitive. Use <see cref="Cube"/>, <see cref="Cylinder"/>, <see cref="GeoSphere"/>, <see cref="Plane"/>, <see cref="Sphere"/>, <see cref="Teapot"/>, <see cref="Torus"/>. See <see cref="Draw+vertices"/> to learn how to use it.
145  /// </summary>
146  public partial class GeometricPrimitive : GeometricPrimitive<VertexPositionNormalTexture>
147  {
148  public GeometricPrimitive(GraphicsDevice graphicsDevice, GeometricMeshData<VertexPositionNormalTexture> geometryMesh) : base(graphicsDevice, geometryMesh)
149  {
150  }
151  }
152 }
readonly GraphicsDevice GraphicsDevice
The default graphics device.
void Draw(GraphicsDevice graphicsDevice)
Draws this GeometricPrimitive.
A geometric primitive. Use Cube, Cylinder, GeoSphere, Plane, Sphere, Teapot, Torus. See Draw+vertices to learn how to use it.
readonly bool IsIndex32Bits
True if the index buffer is a 32 bit index buffer.
Base class for a framework component.
All-in-One Buffer class linked SharpDX.Direct3D11.Buffer.
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
readonly Buffer VertexBuffer
The vertex buffer used by this geometric primitive.
GeometricPrimitive(GraphicsDevice graphicsDevice, GeometricMeshData< T > geometryMesh)
Initializes a new instance of the GeometricPrimitive{T} class.
GraphicsDeviceFeatures Features
Gets the features supported by this graphics device.
bool IsLeftHanded
Gets or sets a value indicating whether this instance is left handed.
readonly Buffer IndexBuffer
The index buffer used by this geometric primitive.
GraphicsProfile
Identifies the set of supported devices for the demo based on device capabilities.
The base interface for all the vertex data structure.
Definition: IVertex.cs:9
GeometricPrimitive(GraphicsDevice graphicsDevice, GeometricMeshData< VertexPositionNormalTexture > geometryMesh)
Binding structure that specifies a vertex buffer and other per-vertex parameters (such as offset and ...
GraphicsProfile Profile
Features level of the current device.