Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        /// <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);
        }