Esempio n. 1
0
        /// <summary>
        /// <para>Creates a vertex buffer that will map an array of float or vector primitives to a specified Vertex Usage and index</para>
        /// </summary>
        /// <param name="data"></param>
        /// <param name="elementUsage"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static Vertices <VertexType> CreateSingleElementVertices(VertexType[] data, VertexElementUsage elementUsage, int index)
        {
            if (typeof(float) != typeof(VertexType) &&
                typeof(Vector2) != typeof(VertexType) &&
                typeof(Vector3) != typeof(VertexType) &&
                typeof(Vector4) != typeof(VertexType) &&
                typeof(Microsoft.Xna.Framework.Graphics.PackedVector.HalfVector2) != typeof(VertexType) &&
                typeof(Microsoft.Xna.Framework.Graphics.PackedVector.HalfVector4) != typeof(VertexType))
            {
                throw new ArgumentException("Only float and vector types are supported for single element vertex buffers");
            }

            if (data == null)
            {
                throw new ArgumentNullException();
            }
            if (index >= 16 || index < 0)
            {
                throw new ArgumentException("index");
            }

            VertexElementFormat format = VertexDeclarationBuilder.DetermineFormat(typeof(VertexType));

            VertexElement[] elements = new VertexElement[] { new VertexElement(0, 0, format, VertexElementMethod.Default, elementUsage, (byte)index) };

            int stride = VertexElementAttribute.CalculateVertexStride(elements);

            return(new Vertices <VertexType>(data, elements, stride));
        }
Esempio n. 2
0
        /// <summary>
        /// Computes the stride for a vertex format
        /// </summary>
        /// <param name="elements"></param>
        /// <returns></returns>
        public static int CalculateVertexStride(VertexElement[] elements)
        {
            int stride = 0;

            for (int i = 0; i < elements.Length; i++)
            {
                stride = Math.Max(stride, elements[i].Offset + VertexElementAttribute.SizeOfFormatType(elements[i].VertexElementFormat));
            }
            return(stride);
        }
Esempio n. 3
0
        /// <summary>
        /// [NOT VALIDATED] Use with caution. No validation is performed by this method. Creates a vertex buffer from a raw data array, using a user specified <see cref="VertexElement"/> array.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="elements"></param>
        /// <returns></returns>
        /// <remarks>This method is only here to get around some limitations of the XNA content pipeline</remarks>
        public static Vertices <VertexType> CreateRawDataVertices(VertexType[] data, VertexElement[] elements)
        {
            if (typeof(byte) != typeof(VertexType))
            {
                throw new ArgumentException("Only byte[] raw vertices are supported at this time");
            }
            if (data == null || elements == null)
            {
                throw new ArgumentNullException();
            }
            if (elements.Length == 0)
            {
                throw new ArgumentException();
            }

            int stride = VertexElementAttribute.CalculateVertexStride(elements);

            return(new Vertices <VertexType>(data, elements, stride));
        }
Esempio n. 4
0
        public VertexElement[] GetDeclaration(Type type)
        {
            lock (declarationMapping)
            {
                VertexElement[] mapping;
                if (declarationMapping.TryGetValue(type, out mapping))
                {
                    return(mapping);
                }

                if (type == typeof(Vector3))                //special case
                {
                    mapping = new VertexElement[] { new VertexElement(0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0) }
                }
                ;
                if (type == typeof(Vector4))
                {
                    mapping = new VertexElement[] { new VertexElement(0, 0, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.Position, 0) }
                }
                ;

                if (mapping == null)
                {
                    List <VertexElement> elements = new List <VertexElement>();
                    int offset = 0;

                    if (type.IsValueType == false)
                    {
                        throw new ArgumentException("Type " + type.Name + " is a not a ValueType (struct)");
                    }

                    foreach (FieldInfo f in type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance))
                    {
                        if (!f.ReflectedType.IsValueType)
                        {
                            throw new ArgumentException("Field " + type.Name + "." + f.Name + " is a not a ValueType (struct)");
                        }

                        int size = Marshal.SizeOf(f.FieldType);

                        bool attribSet = false;

                        foreach (object o in f.GetCustomAttributes(true))
                        {
                            if (o is VertexElementAttribute)
                            {
                                VertexElementAttribute att    = (VertexElementAttribute)o;
                                VertexElementFormat    format = att.VertexElementFormat;
                                if (format == VertexElementFormat.Unused)
                                {
                                    format = DetermineFormat(f);
                                }
                                else
                                {
                                    int formatSize;
                                    if (!formatMappingSize.TryGetValue(format, out formatSize))
                                    {
                                        throw new ArgumentException(string.Format("Invlaid VertexElementFormat ({0}) specified in VertexElementAttribute for {1}.{2}", format, type.FullName, f.Name));
                                    }
                                    if (formatSize != Marshal.SizeOf(f.FieldType))
                                    {
                                        throw new ArgumentException(string.Format("VertexElementFormat size mismatch in {4}.{5}, {0} requires a size of {1}, specified type {2} has size {3}", format, formatSize, f.FieldType.FullName, Marshal.SizeOf(f.FieldType), type.FullName, f.Name));
                                    }
                                }

                                elements.Add(new VertexElement(0, (short)offset, format, VertexElementMethod.Default, att.VertexElementUsage, (byte)att.UsageIndex));
                                attribSet = true;
                                break;
                            }
                        }

                        if (!attribSet)
                        {
                            VertexElementFormat format = DetermineFormat(f);
                            int index;
                            VertexElementUsage usage = DetermineUsage(elements, f, out index);

                            elements.Add(new VertexElement(0, (short)offset, format, VertexElementMethod.Default, usage, (byte)index));
                        }

                        offset += size;
                    }

                    mapping = elements.ToArray();
                }
                declarationMapping.Add(type, mapping);

                return(mapping);
            }
        }