From c43df10c2aebbc290b22230558e143def5e05f50 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 5 Jan 2023 13:41:48 -0800 Subject: [PATCH] vertex binding API improvements --- MoonWorks.csproj | 3 +- src/Graphics/IVertexType.cs | 2 +- src/Graphics/RefreshStructs.cs | 15 --------- src/Graphics/State/VertexInputState.cs | 37 +++++++++++++++++--- src/Graphics/Utility/Conversions.cs | 28 +++++++++++++++- src/Graphics/VertexBindingAndAttributes.cs | 39 ++++++++++++++++++++++ 6 files changed, 102 insertions(+), 22 deletions(-) create mode 100644 src/Graphics/VertexBindingAndAttributes.cs diff --git a/MoonWorks.csproj b/MoonWorks.csproj index 70339402..ccbd6509 100644 --- a/MoonWorks.csproj +++ b/MoonWorks.csproj @@ -1,9 +1,10 @@ - net6.0;net7.0 + net7.0 x64 true + 11 diff --git a/src/Graphics/IVertexType.cs b/src/Graphics/IVertexType.cs index fe5d6b68..cd055f2d 100644 --- a/src/Graphics/IVertexType.cs +++ b/src/Graphics/IVertexType.cs @@ -2,6 +2,6 @@ namespace MoonWorks.Graphics { public interface IVertexType { - VertexAttribute[] Attributes(uint binding = 0); + static abstract VertexElementFormat[] Formats { get; } } } diff --git a/src/Graphics/RefreshStructs.cs b/src/Graphics/RefreshStructs.cs index 0f018289..9d8502cf 100644 --- a/src/Graphics/RefreshStructs.cs +++ b/src/Graphics/RefreshStructs.cs @@ -145,21 +145,6 @@ namespace MoonWorks.Graphics public uint Binding; public VertexElementFormat Format; public uint Offset; - - public static VertexAttribute Create( - uint binding, - uint location, - VertexElementFormat format, - uint offset - ) { - return new VertexAttribute - { - Location = location, - Binding = binding, - Format = format, - Offset = offset - }; - } } [StructLayout(LayoutKind.Sequential)] diff --git a/src/Graphics/State/VertexInputState.cs b/src/Graphics/State/VertexInputState.cs index 6e35a601..466b1745 100644 --- a/src/Graphics/State/VertexInputState.cs +++ b/src/Graphics/State/VertexInputState.cs @@ -30,12 +30,41 @@ VertexAttributes = vertexAttributes; } + public VertexInputState( + VertexBindingAndAttributes bindingAndAttributes + ) { + VertexBindings = new VertexBinding[] { bindingAndAttributes.VertexBinding }; + VertexAttributes = bindingAndAttributes.VertexAttributes; + } + + public VertexInputState( + VertexBindingAndAttributes[] bindingAndAttributesArray + ) { + VertexBindings = new VertexBinding[bindingAndAttributesArray.Length]; + var attributesLength = 0; + + for (var i = 0; i < bindingAndAttributesArray.Length; i += 1) + { + VertexBindings[i] = bindingAndAttributesArray[i].VertexBinding; + attributesLength += bindingAndAttributesArray[i].VertexAttributes.Length; + } + + VertexAttributes = new VertexAttribute[attributesLength]; + + var attributeIndex = 0; + for (var i = 0; i < bindingAndAttributesArray.Length; i += 1) + { + for (var j = 0; j < bindingAndAttributesArray[i].VertexAttributes.Length; j += 1) + { + VertexAttributes[attributeIndex] = bindingAndAttributesArray[i].VertexAttributes[j]; + attributeIndex += 1; + } + } + } + public static VertexInputState CreateSingleBinding() where T : unmanaged, IVertexType { - return new VertexInputState( - VertexBinding.Create(), - default(T).Attributes() - ); + return new VertexInputState(VertexBindingAndAttributes.Create(0)); } } } diff --git a/src/Graphics/Utility/Conversions.cs b/src/Graphics/Utility/Conversions.cs index 5d05be93..1e1a9247 100644 --- a/src/Graphics/Utility/Conversions.cs +++ b/src/Graphics/Utility/Conversions.cs @@ -1,7 +1,28 @@ -namespace MoonWorks +using System.Collections.Generic; +using System.Runtime.InteropServices; +using MoonWorks.Graphics; + +namespace MoonWorks { public static class Conversions { + private readonly static Dictionary Sizes = new Dictionary + { + { VertexElementFormat.Byte4, (uint) Marshal.SizeOf() }, + { VertexElementFormat.Color, (uint) Marshal.SizeOf() }, + { VertexElementFormat.Float, (uint) Marshal.SizeOf() }, + { VertexElementFormat.HalfVector2, (uint) Marshal.SizeOf() }, + { VertexElementFormat.HalfVector4, (uint) Marshal.SizeOf() }, + { VertexElementFormat.NormalizedShort2, (uint) Marshal.SizeOf() }, + { VertexElementFormat.NormalizedShort4, (uint) Marshal.SizeOf() }, + { VertexElementFormat.Short2, (uint) Marshal.SizeOf() }, + { VertexElementFormat.Short4, (uint) Marshal.SizeOf() }, + { VertexElementFormat.UInt, (uint) Marshal.SizeOf() }, + { VertexElementFormat.Vector2, (uint) Marshal.SizeOf() }, + { VertexElementFormat.Vector3, (uint) Marshal.SizeOf() }, + { VertexElementFormat.Vector4, (uint) Marshal.SizeOf() } + }; + public static byte BoolToByte(bool b) { return (byte) (b ? 1 : 0); @@ -11,5 +32,10 @@ { return b != 0; } + + public static uint VertexElementFormatSize(VertexElementFormat format) + { + return Sizes[format]; + } } } diff --git a/src/Graphics/VertexBindingAndAttributes.cs b/src/Graphics/VertexBindingAndAttributes.cs new file mode 100644 index 00000000..2651827f --- /dev/null +++ b/src/Graphics/VertexBindingAndAttributes.cs @@ -0,0 +1,39 @@ +namespace MoonWorks.Graphics +{ + // This is a convenience structure for pairing a vertex binding with its associated attributes. + public struct VertexBindingAndAttributes + { + public VertexBinding VertexBinding { get; } + public VertexAttribute[] VertexAttributes { get; } + + public VertexBindingAndAttributes(VertexBinding binding, VertexAttribute[] attributes) + { + VertexBinding = binding; + VertexAttributes = attributes; + } + + public static VertexBindingAndAttributes Create(uint bindingIndex) where T : unmanaged, IVertexType + { + VertexBinding binding = VertexBinding.Create(bindingIndex); + VertexAttribute[] attributes = new VertexAttribute[T.Formats.Length]; + uint offset = 0; + + for (uint i = 0; i < T.Formats.Length; i += 1) + { + var format = T.Formats[i]; + + attributes[i] = new VertexAttribute + { + Binding = bindingIndex, + Location = i, + Format = format, + Offset = offset + }; + + offset += Conversions.VertexElementFormatSize(format); + } + + return new VertexBindingAndAttributes(binding, attributes); + } + } +}