Exemple #1
0
        private static int ComputeAttributeStride(IEnumerable <VertexAttribute> attributes)
        {
            var stride = 0;

            foreach (var attr in attributes)
            {
                stride += VertexAttribute.GetSizeInBytes(attr.Type, attr.Size);
            }

            return(stride);
        }
        internal static VertexAttribute[] GenerateAttributes(Type type)
        {
            // Get all fields w/ attribute defs
            var fields = type.GetFields()
                         .Where(x => x.GetCustomAttribute <VertexAttributeAttribute>() != null)
                         .ToArray();

            // Must have at least one attribute defined
            if (fields.Length == 0)
            {
                throw new InvalidOperationException("Must have at least one field with a vertex attribute defined.");
            }

            // Console.WriteLine($"Attribute Layout: {type}");

            // Create attribute list (one attributed per field)
            var attributes = new List <VertexAttribute>();

            // For each field
            for (var f = 0; f < fields.Length; f++)
            {
                var attribute = fields[f].GetCustomAttribute <VertexAttributeAttribute>();
                var field     = fields[f];

                // Number of attributes needed to describe this data, most attributes will be one.
                var attributeCount = GetAttributeCount(field.FieldType);

                // Get offset and usable size
                var nextOffset = f != (fields.Length - 1) ? OffsetOf(fields[f + 1]) : Marshal.SizeOf(type);
                var currOffset = OffsetOf(field);
                var size       = nextOffset - currOffset;

                // Gather respective field type
                var attr  = GetAttributeType(field.FieldType);
                var step  = GetSizeInBytes(attr, 1) * attributeCount;
                var count = size / step;
                var waste = size % step;
                if (waste != 0)
                {
                    throw new Exception($"Vertex attribute defined in struct has unattributed space after '{attr}'.");
                }

                // Store extracted attribute data
                for (var o = 0u; o < attributeCount; o++)
                {
                    var _attribute = new VertexAttribute(attribute.Attribute, count, attr, attribute.Normalize, o);
                    // Console.WriteLine($"  {attribute.Attribute} ({_attribute.Index}): {count} x {attr}");
                    attributes.Add(_attribute);
                }
            }

            return(attributes.ToArray());