Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
VertexDeclaration.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 using System;
4 using System.Collections.Generic;
5 using SiliconStudio.Core;
6 using SiliconStudio.Core.Serialization;
7 using SiliconStudio.Core.Serialization.Serializers;
8 
9 namespace SiliconStudio.Paradox.Graphics
10 {
11  /// <summary>
12  /// The layout of a vertex buffer with a set of <see cref="VertexElement" />.
13  /// </summary>
14  [DataContract]
15  [DataSerializer(typeof(Serializer))]
16  public class VertexDeclaration : IEquatable<VertexDeclaration>
17  {
18  private readonly VertexElement[] elements;
19  private readonly int instanceCount;
20  private readonly int vertexStride;
21  private readonly int hashCode;
22 
23  /// <summary>
24  /// Initializes a new instance of the <see cref="VertexDeclaration"/> class.
25  /// </summary>
26  internal VertexDeclaration() { }
27 
28  /// <summary>
29  /// Initializes a new instance of the <see cref="VertexDeclaration"/> class.
30  /// </summary>
31  /// <param name="elements">The elements.</param>
32  public VertexDeclaration(params VertexElement[] elements)
33  : this(elements, 0, 0)
34  {
35  }
36 
37  /// <summary>
38  /// Initializes a new instance of the <see cref="VertexDeclaration"/> class.
39  /// </summary>
40  /// <param name="elements">The elements.</param>
41  /// <param name="instanceCount">The instance count.</param>
42  /// <param name="vertexStride">The vertex stride.</param>
43  /// <exception cref="System.ArgumentNullException">elements</exception>
44  public VertexDeclaration(VertexElement[] elements, int instanceCount = 0, int vertexStride = 0)
45  {
46  if (elements == null) throw new ArgumentNullException("elements");
47 
48  this.elements = elements;
49  this.vertexStride = vertexStride == 0 ? VertexElementValidator.GetVertexStride(elements) : vertexStride;
50  this.instanceCount = instanceCount;
51 
52  // Validate Vertices
53  VertexElementValidator.Validate(VertexStride, elements);
54 
55  hashCode = instanceCount;
56  hashCode = (hashCode * 397) ^ vertexStride;
57  foreach (var vertexElement in elements)
58  {
59  hashCode = (hashCode*397) ^ vertexElement.GetHashCode();
60  }
61  }
62 
63  /// <summary>
64  /// Gets the vertex elements.
65  /// </summary>
66  /// <value>The vertex elements.</value>
67  public VertexElement[] VertexElements
68  {
69  get { return elements; }
70  }
71 
72  /// <summary>
73  /// Gets the instance count.
74  /// </summary>
75  /// <value>The instance count.</value>
76  public int InstanceCount
77  {
78  get
79  {
80  return instanceCount;
81  }
82  }
83 
84  /// <summary>
85  /// Gets the vertex stride.
86  /// </summary>
87  /// <value>The vertex stride.</value>
88  public int VertexStride
89  {
90  get
91  {
92  return vertexStride;
93  }
94  }
95 
96  /// <summary>
97  /// Enumerates <see cref="VertexElement"/> with declared offsets.
98  /// </summary>
99  /// <returns>A set of <see cref="VertexElement"/> with offsets.</returns>
101  {
102  int offset = 0;
103  foreach (var element in VertexElements)
104  {
105  // Get new offset (if specified)
106  var currentElementOffset = element.AlignedByteOffset;
107  if (currentElementOffset != VertexElement.AppendAligned)
108  offset = currentElementOffset;
109 
110  var elementSize = element.Format.SizeInBytes();
111  yield return new VertexElementWithOffset(element, offset, elementSize);
112 
113  // Compute next offset (if automatic)
114  offset += elementSize;
115  }
116  }
117 
118  /// <summary>
119  /// Calculate the size of the vertex declaration.
120  /// </summary>
121  /// <returns>The size in bytes of the vertex declaration</returns>
122  public int CalculateSize()
123  {
124  var size = 0;
125  var offset = 0;
126  foreach (var element in VertexElements)
127  {
128  // Get new offset (if specified)
129  var currentElementOffset = element.AlignedByteOffset;
130  if (currentElementOffset != VertexElement.AppendAligned)
131  offset = currentElementOffset;
132 
133  var elementSize = element.Format.SizeInBytes();
134 
135  // Compute next offset (if automatic)
136  offset += elementSize;
137 
138  size = Math.Max(size, offset); // element are not necessary ordered by increasing offsets
139  }
140 
141  return size;
142  }
143 
144  public bool Equals(VertexDeclaration other)
145  {
146  if (ReferenceEquals(null, other)) return false;
147  if (ReferenceEquals(this, other)) return true;
148  return hashCode == other.hashCode && vertexStride == other.vertexStride && instanceCount == other.instanceCount && Utilities.Compare(elements, other.elements);
149  }
150 
151  public override bool Equals(object obj)
152  {
153  if (ReferenceEquals(null, obj)) return false;
154  if (ReferenceEquals(this, obj)) return true;
155  if (obj.GetType() != this.GetType()) return false;
156  return Equals((VertexDeclaration)obj);
157  }
158 
159  public override int GetHashCode()
160  {
161  return hashCode;
162  }
163 
164  /// <summary>
165  /// Performs an implicit conversion from <see cref="VertexElement"/> to <see cref="VertexDeclaration"/>.
166  /// </summary>
167  /// <param name="element">The element.</param>
168  /// <returns>The result of the conversion.</returns>
169  public static implicit operator VertexDeclaration(VertexElement element)
170  {
171  return new VertexDeclaration(element);
172  }
173 
174  /// <summary>
175  /// Performs an implicit conversion from <see cref="VertexElement[][]"/> to <see cref="VertexDeclaration"/>.
176  /// </summary>
177  /// <param name="elements">The elements.</param>
178  /// <returns>The result of the conversion.</returns>
179  public static implicit operator VertexDeclaration(VertexElement[] elements)
180  {
181  return new VertexDeclaration(elements);
182  }
183 
184  internal class Serializer : DataSerializer<VertexDeclaration>, IDataSerializerGenericInstantiation
185  {
186  public override void PreSerialize(ref object obj, ArchiveMode mode, SerializationStream stream)
187  {
188  // We are creating object at deserialization time
189  if (mode == ArchiveMode.Serialize)
190  {
191  base.PreSerialize(ref obj, mode, stream);
192  }
193  }
194 
195  public override void Serialize(ref VertexDeclaration obj, ArchiveMode mode, SerializationStream stream)
196  {
197  if (mode == ArchiveMode.Deserialize)
198  {
199  var elements = stream.Read<VertexElement[]>();
200  var instanceCount = stream.ReadInt32();
201  var vertexStride = stream.ReadInt32();
202  obj = new VertexDeclaration(elements, instanceCount, vertexStride);
203  }
204  else
205  {
206  stream.Write(obj.elements);
207  stream.Write(obj.instanceCount);
208  stream.Write(obj.vertexStride);
209  }
210  }
211 
212  public void EnumerateGenericInstantiations(SerializerSelector serializerSelector, IList<Type> genericInstantiations)
213  {
214  genericInstantiations.Add(typeof(VertexElement[]));
215  }
216  }
217  }
218 }
The layout of a vertex buffer with a set of VertexElement.
int CalculateSize()
Calculate the size of the vertex declaration.
const int AppendAligned
Returns a value that can be used for the offset parameter of an InputElement to indicate that the ele...
Base class for implementation of SerializationStream.
Serializer context. It holds DataSerializer{T} objects and their factories.
VertexDeclaration(params VertexElement[] elements)
Initializes a new instance of the VertexDeclaration class.
Describes how to serialize and deserialize an object without knowing its type. Used as a common base ...
ArchiveMode
Enumerates the different mode of serialization (either serialization or deserialization).
Definition: ArchiveMode.cs:8
_In_ size_t _In_ size_t size
Definition: DirectXTexP.h:175
VertexDeclaration(VertexElement[] elements, int instanceCount=0, int vertexStride=0)
Initializes a new instance of the VertexDeclaration class.
A description of a single element for the input-assembler stage. This structure is related to Direct3...
IEnumerable< VertexElementWithOffset > EnumerateWithOffsets()
Enumerates VertexElement with declared offsets.