#region CPL License /* Nuclex Framework Copyright (C) 2002-2009 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion #if UNITTEST using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using NUnit.Framework; namespace Nuclex.Graphics { /// Unit tests for the vertex element attribute [TestFixture] internal class VertexDeclarationHelperTest { #region struct TestVertex /// /// A vertex used to unit-test the format auto-detection of /// the vertex declaration helper /// private struct TestVertex { /// A vertex element of type Vector2 [VertexElement(VertexElementUsage.TextureCoordinate)] public Vector2 TestVector2; /// A vertex element of type Vector3 [VertexElement(VertexElementUsage.Position)] public Vector3 TestVector3; /// A vertex element of type Vector4 [VertexElement(VertexElementUsage.Normal)] public Vector4 TestVector4; /// A vertex element of type Color [VertexElement(VertexElementUsage.Color)] public Color TestColor; /// A vertex element of type float [VertexElement(VertexElementUsage.BlendWeight)] public float TestSingle; /// A vertex element of type int [VertexElement(VertexElementUsage.Sample)] public int TestInt; /// A vertex element of type short [VertexElement(VertexElementUsage.Sample, UsageIndex = 1)] public short TestShort; /// A vertex element of type short [VertexElement(VertexElementUsage.BlendWeight, VertexElementFormat.Vector4)] public Matrix TestExplicitMatrix; } #endregion // struct TestVertex #region struct UnknownTypeVertex /// /// A vertex containing a data type not recognized by the format auto-detection of /// the vertex declaration helper /// private struct UnknownTypeVertex { /// A vertex element of type DateTime [VertexElement(VertexElementUsage.Sample, UsageIndex = 1)] public DateTime TestTimestamp; } #endregion // struct UnknownTypeVertex #region struct EmptyVertex /// An empty vertex type used to unit-test error behavior private struct EmptyVertex { } #endregion // struct EmptyVertex #region struct UnattributedFieldVertex /// /// A vertex type containing a field without a vertex element attribute /// private struct UnattributedFieldVertex { /// A vertex element of type Vector3 public Vector3 TestVector3; /// A vertex element of type Color public Color TestColor; } #endregion // struct UnattributedFieldVertex #region struct SecondStreamVertex /// /// A vertex containing an additional data element to be used as second vertex stream /// private struct SecondStreamVertex { /// A vertex element of type DateTime [VertexElement(VertexElementUsage.BlendWeight, UsageIndex = 1)] public float BlendWeight; } #endregion // struct SecondStreamVertex #region struct GapVertex /// /// A vertex in which not all elements are used by the shader /// private struct GapVertex { /// Position of the vertex [VertexElement(VertexElementUsage.Position)] public Vector3 Position; /// Velocity the vertex is moving at public Vector3 Velocity; /// Size of the vertex when rendered as a point sprite [VertexElement(VertexElementUsage.PointSize)] public float Size; } #endregion // struct GapVertex /// /// Verifies that the stride of a vertex structure can be determined /// [Test] public void TestStrideDetermination() { Assert.AreEqual(114, VertexDeclarationHelper.GetStride()); Assert.AreEqual(4, VertexDeclarationHelper.GetStride()); } /// /// Tests whether the vertex declaration helper fails is provieed with two /// null references instead of two vertex element lists /// [Test] public void TestThrowOnCombineNull() { Assert.Throws( delegate() { VertexDeclarationHelper.Combine(null, null); } ); } /// /// Tests whether the vertex declaration helper is able to combine two vertex element /// lists into a single one /// [Test] public void TestCombine() { VertexElement[] firstElements = VertexDeclarationHelper.BuildElementList(); VertexElement[] secondElements = VertexDeclarationHelper.BuildElementList< SecondStreamVertex >(); VertexElement[] combinedElements = VertexDeclarationHelper.Combine(firstElements, secondElements); Assert.AreEqual(firstElements.Length + secondElements.Length, combinedElements.Length); CollectionAssert.IsSubsetOf(firstElements, combinedElements); CollectionAssert.IsSubsetOf(secondElements, combinedElements); } /// /// Tests whether the vertex declaration helper fails on empty vertices /// [Test] public void TestThrowOnEmptyVertex() { Assert.Throws( delegate() { VertexElement[] elements = VertexDeclarationHelper.BuildElementList(); } ); } /// /// Tests whether the vertex declaration helper fails when format auto-detection /// is used on unknown data types /// [Test] public void TestThrowOnUnknownTypeVertex() { Assert.Throws( delegate() { VertexElement[] elements = VertexDeclarationHelper.BuildElementList< UnknownTypeVertex >(); } ); } /// /// Tests whether the vertex declaration helper fails when no field of /// a Vertex has have the vertex element attribute assigned to it /// [Test] public void TestThrowOnUnattributedFieldVertex() { Assert.Throws( delegate() { VertexElement[] elements = VertexDeclarationHelper.BuildElementList< UnattributedFieldVertex >(); } ); } /// Tests the format auto-detection of vertex elements [Test] public void TestFormatAutoDetection() { VertexElement[] elements = VertexDeclarationHelper.BuildElementList(); Assert.AreEqual(8, elements.Length); Assert.AreEqual(VertexElementFormat.Vector2, elements[0].VertexElementFormat); Assert.AreEqual(VertexElementFormat.Vector3, elements[1].VertexElementFormat); Assert.AreEqual(VertexElementFormat.Vector4, elements[2].VertexElementFormat); Assert.AreEqual(VertexElementFormat.Color, elements[3].VertexElementFormat); Assert.AreEqual(VertexElementFormat.Single, elements[4].VertexElementFormat); Assert.AreEqual(VertexElementFormat.Short4, elements[5].VertexElementFormat); Assert.AreEqual(VertexElementFormat.Short2, elements[6].VertexElementFormat); Assert.AreEqual(VertexElementFormat.Vector4, elements[7].VertexElementFormat); Assert.AreEqual(1, elements[6].UsageIndex); } /// /// Tests whether a vertex containing a field in its middle that isn't seen by /// the vertex shader is processed correctly /// [Test] public void TestGapVertexElements() { VertexElement[] elements = VertexDeclarationHelper.BuildElementList(); Assert.AreEqual(2, elements.Length); Assert.Greater(elements[1].Offset, elements[0].Offset); } /// /// Only serves to satisfy the compiler. Otherwise, warning CS0414 would occur /// since the fields of the private vertex structures are never assigned to /// protected void EliminateCompilerWarnings() { TestVertex testVertex; testVertex.TestVector2 = Vector2.Zero; testVertex.TestVector3 = Vector3.Zero; testVertex.TestVector4 = Vector4.Zero; testVertex.TestColor = Color.White; testVertex.TestSingle = 0.0f; testVertex.TestInt = 0; testVertex.TestShort = 0; testVertex.TestExplicitMatrix = Matrix.Identity; UnknownTypeVertex unknownTypeVertex; unknownTypeVertex.TestTimestamp = DateTime.MinValue; UnattributedFieldVertex unattributedFieldVertex; unattributedFieldVertex.TestVector3 = Vector3.Zero; unattributedFieldVertex.TestColor = Color.White; SecondStreamVertex secondStreamVertex; secondStreamVertex.BlendWeight = 0.0f; GapVertex gapVertex; gapVertex.Position = Vector3.Zero; gapVertex.Velocity = Vector3.Zero; gapVertex.Size = 0.0f; } } } // namespace Nuclex.Graphics #endif // UNITTEST