public void TestStreamProperty() { VertexElementAttribute attribute = getVertexElementAttribute <TestVertex>( "Stream123" ); Assert.AreEqual(123, attribute.Stream); Assert.AreEqual(VertexElementUsage.TessellateFactor, attribute.Usage); Assert.AreEqual(false, attribute.FormatProvided); Assert.AreEqual(0, attribute.UsageIndex); }
public void TestUsageConstructor() { VertexElementAttribute attribute = getVertexElementAttribute <TestVertex>( "UsageOnly" ); Assert.AreEqual(0, attribute.Stream); Assert.AreEqual(VertexElementUsage.Position, attribute.Usage); Assert.AreEqual(false, attribute.FormatProvided); Assert.AreEqual(0, attribute.UsageIndex); }
public void TestUsageIndexProperty() { VertexElementAttribute attribute = getVertexElementAttribute <TestVertex>( "SecondUsage" ); Assert.AreEqual(0, attribute.Stream); Assert.AreEqual(VertexElementUsage.TextureCoordinate, attribute.Usage); Assert.AreEqual(false, attribute.FormatProvided); Assert.AreEqual(1, attribute.UsageIndex); }
/// <summary>Builds a vertex element from an attributed field in a structure</summary> /// <param name="fieldInfo"> /// Reflected data on the field for which a vertex element will be built /// </param> /// <param name="attribute">Vertex eelement attribute assigned to the field</param> /// <param name="element"> /// Output parameter the newly built vertex element is stored in /// </param> private static void buildVertexElement( FieldInfo fieldInfo, VertexElementAttribute attribute, ref VertexElement element ) { #if !XNA_4 element.VertexElementMethod = attribute.Method; #endif element.VertexElementUsage = attribute.Usage; element.UsageIndex = attribute.UsageIndex; // Was an explicit data type provided for this field? if (attribute.FormatProvided == true) { element.VertexElementFormat = attribute.Format; } else // Nope, try to auto-detect the data type { if (fieldInfo.FieldType == typeof(Vector2)) { element.VertexElementFormat = VertexElementFormat.Vector2; } else if (fieldInfo.FieldType == typeof(Vector3)) { element.VertexElementFormat = VertexElementFormat.Vector3; } else if (fieldInfo.FieldType == typeof(Vector4)) { element.VertexElementFormat = VertexElementFormat.Vector4; } else if (fieldInfo.FieldType == typeof(Color)) { element.VertexElementFormat = VertexElementFormat.Color; } else if (fieldInfo.FieldType == typeof(float)) { element.VertexElementFormat = VertexElementFormat.Single; } else if (fieldInfo.FieldType == typeof(int)) { element.VertexElementFormat = VertexElementFormat.Short4; } else if (fieldInfo.FieldType == typeof(short)) { element.VertexElementFormat = VertexElementFormat.Short2; } else // No success in auto-detection, give up { throw new InvalidOperationException( "Unrecognized field type, please specify vertex format explicitly" ); } } }
public void TestMethodProperty() { VertexElementAttribute attribute = getVertexElementAttribute <TestVertex>( "LookupMethod" ); Assert.AreEqual(0, attribute.Stream); Assert.AreEqual(VertexElementUsage.TextureCoordinate, attribute.Usage); Assert.AreEqual(false, attribute.FormatProvided); Assert.AreEqual(VertexElementMethod.LookUp, attribute.Method); Assert.AreEqual(0, attribute.UsageIndex); }
public void TestUsageAndFormatConstructor() { VertexElementAttribute attribute = getVertexElementAttribute <TestVertex>( "UsageAndFormat" ); Assert.AreEqual(0, attribute.Stream); Assert.AreEqual(VertexElementUsage.Color, attribute.Usage); Assert.AreEqual(true, attribute.FormatProvided); Assert.AreEqual(VertexElementFormat.Byte4, attribute.Format); Assert.AreEqual(0, attribute.UsageIndex); }
/// <summary> /// Builds a vertex element list that can be used to construct a vertex declaration /// from a vertex structure that has the vertex element attributes applied to it /// </summary> /// <typeparam name="VertexType"> /// Vertex structure with vertex element attributes applied to it /// </typeparam> /// <param name="stream"> /// Index of the vertex buffer that will contain this element /// </param> /// <returns> /// A vertex element list that can be used to create a new vertex declaration matching /// the provided vertex structure /// </returns> /// <remarks> /// Data for vertices can come from multiple vertex buffers. For example, you can store /// the positions of your vertices in one vertex buffer and then store the texture /// coordinates in an entirely different vertex buffer, only to combine them at rendering /// time by using the two vertex buffers as two simultaneous vertex data streams. /// </remarks> public static VertexElement[] BuildElementList <VertexType>(short stream) where VertexType : struct { #endif FieldInfo[] fields = getFields <VertexType>(); int fieldOffset = 0; int elementCount = 0; // Set up an array for the vertex elements and fill it with the data we // gather directly from the vertex structure VertexElement[] elements = new VertexElement[fields.Length]; for (int index = 0; index < fields.Length; ++index) { // Find out whether this field is used by the vertex shader. If so, add // it to the elements list so it ends up in the vertex shader. VertexElementAttribute attribute = getVertexElementAttribute(fields[index]); if (attribute != null) { buildVertexElement(fields[index], attribute, ref elements[elementCount]); #if !(XBOX360 || WINDOWS_PHONE) fieldOffset = Marshal.OffsetOf(typeof(VertexType), fields[index].Name).ToInt32(); #endif elements[elementCount].Offset = (short)fieldOffset; #if !XNA_4 elements[elementCount].Stream = stream; #endif ++elementCount; } #if XBOX360 fieldOffset += Marshal.SizeOf(fields[index].FieldType); #endif } // If there isn't a single vertex element, this type would be completely useless // as a vertex. Probably the user forgot to add the VertexElementAttribute. if (elementCount == 0) { throw new InvalidOperationException( "No fields had the VertexElementAttribute assigned to them." ); } Array.Resize(ref elements, elementCount); return(elements); }