Skip to content

Commit

Permalink
VertexInputDescriptor can generate VertexInputBindingDescriptors per …
Browse files Browse the repository at this point in the history
…VertexType
  • Loading branch information
deccer committed Jul 30, 2023
1 parent 6765f26 commit c21efac
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 40 deletions.
6 changes: 6 additions & 0 deletions src/EngineKit/Graphics/GraphicsPipelineBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ public IGraphicsPipelineBuilder WithVertexInput(VertexInputDescriptor vertexInpu
return this;
}

public IGraphicsPipelineBuilder WithVertexAttributesForVertexType(VertexType vertexType)
{
_graphicsPipelineDescriptor.VertexInput = VertexInputDescriptor.ForVertexType(vertexType);
return this;
}

public IGraphicsPipelineBuilder WithShadersFromFiles(
string vertexShaderFilePath,
string fragmentShaderFilePath)
Expand Down
2 changes: 2 additions & 0 deletions src/EngineKit/Graphics/IGraphicsPipelineBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ IGraphicsPipelineBuilder WithShadersFromStrings(
string fragmentShaderSource);

IGraphicsPipelineBuilder WithVertexInput(VertexInputDescriptor vertexInputDescriptor);

IGraphicsPipelineBuilder WithVertexAttributesForVertexType(VertexType vertexType);

IGraphicsPipelineBuilder WithTopology(
PrimitiveTopology primitiveTopology,
Expand Down
11 changes: 6 additions & 5 deletions src/EngineKit/Graphics/MeshLoaders/SharpGltfMeshLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ private void ProcessNode(ICollection<MeshPrimitive> meshPrimitives, Node node, I

var meshPrimitive = new MeshPrimitive(meshName);
meshPrimitive.Transform = node.WorldMatrix.ToMatrix();
meshPrimitive.MaterialName = primitive.Material?.Name ?? (primitive.Material == null ? "M_NotFound" : materials.ElementAt(primitive.Material.LogicalIndex)?.Name) ?? "M_NotFound";
meshPrimitive.MaterialName = primitive.Material?.Name ?? (primitive.Material == null ? Material.MaterialNotFoundName : materials.ElementAt(primitive.Material.LogicalIndex)?.Name) ?? Material.MaterialNotFoundName;
meshPrimitive.BoundingBox = BoundingBox.FromPoints(positions.ToArray());

var vertexType = GetVertexTypeFromVertexAccessorNames(primitive!.VertexAccessors!.Keys.ToList());
Expand Down Expand Up @@ -269,10 +269,11 @@ private void ProcessNode(ICollection<MeshPrimitive> meshPrimitives, Node node, I

for (var i = 0; i < positions.Length; i++)
{
var position = Vector3.TransformPosition(positions[i], meshPrimitive.Transform);
//var position = positions[i];
var normal = Vector3.TransformDirection(normals[i], meshPrimitive.Transform);
//var normal = normals[i];//Vector3.TransformDirection(normals[i], meshPrimitive.Transform);
//var position = Vector3.TransformPosition(positions[i], meshPrimitive.Transform);
ref var position = ref positions[i];
//var normal = Vector3.TransformDirection(normals[i], meshPrimitive.Transform);
ref var normal = ref normals[i];

var realTangentXyz = new Vector3(realTangents[i].X, realTangents[i].Y, realTangents[i].Z);
var realTangent = new Vector4(realTangentXyz, realTangents[i].W);

Expand Down
22 changes: 1 addition & 21 deletions src/EngineKit/Graphics/MeshPrimitive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ public int Stride
VertexType.Unknown => 0,
VertexType.Position => 12,
VertexType.PositionColor => 24,
VertexType.PositionColorNormal => 36,
VertexType.PositionColorNormalUv => 44,
VertexType.PositionColorUv => 32,
VertexType.PositionNormal => 24,
VertexType.PositionNormalUv => 32,
Expand Down Expand Up @@ -118,6 +116,7 @@ public static MeshPrimitive Combine(params MeshPrimitive[] meshPrimitives)
return combinedMeshPrimitive;
}

//public Span<VertexPositionNormalUvTangent> GetVertices()
public VertexPositionNormalUvTangent[] GetVertices()
{
if (!RealTangents.Any())
Expand Down Expand Up @@ -244,25 +243,6 @@ public void AddPositionColor(
VertexType = VertexType.PositionColor;
}

public void AddPositionColorNormal(
Vector3 position,
Vector3 color,
Vector3 normal)
{
AddVertex(position, color, normal, tangent: null);
VertexType = VertexType.PositionColorNormal;
}

public void AddPositionColorNormalUv(
Vector3 position,
Vector3 color,
Vector3 normal,
Vector2 uv)
{
AddVertex(position, color, normal, uv, tangent: null);
VertexType = VertexType.PositionColorNormalUv;
}

public void AddPositionNormal(
Vector3 position,
Vector3 normal)
Expand Down
30 changes: 19 additions & 11 deletions src/EngineKit/Graphics/PooledMesh.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
using EngineKit.Mathematics;

namespace EngineKit.Graphics;

public readonly struct PooledMesh
{
public readonly uint IndexCount;

public readonly uint IndexOffset;

public readonly int VertexCount;

public readonly int VertexOffset;

public readonly string? MaterialName;

public PooledMesh(uint indexCount, uint indexOffset, int vertexCount, int vertexOffset, string? materialName)
public PooledMesh(uint indexCount, uint indexOffset, int vertexCount, int vertexOffset, Vector3 aabbMax, Vector3 aabbMin, string? materialName)
{
AabbMax = aabbMax;
AabbMin = aabbMin;
IndexCount = indexCount;
IndexOffset = indexOffset;
VertexCount = vertexCount;
VertexOffset = vertexOffset;
MaterialName = materialName;
}

public readonly Vector3 AabbMax;

public readonly Vector3 AabbMin;

public readonly uint IndexCount;

public readonly uint IndexOffset;

public readonly int VertexCount;

public readonly int VertexOffset;

public readonly string? MaterialName;
}
143 changes: 143 additions & 0 deletions src/EngineKit/Graphics/VertexInputDescriptor.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,151 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using EngineKit.Mathematics;
using ImGuiNET;
using Num = System.Numerics;

namespace EngineKit.Graphics;

public readonly record struct VertexInputDescriptor(VertexInputBindingDescriptor[] VertexBindingDescriptors, Label Label)
{
private static readonly IDictionary<VertexType, VertexInputDescriptor> _vertexTypeToVertexInputDescriptorMapping;
private static readonly IDictionary<Type, bool> _fieldTypeToNormalizedMapping;
private static readonly IDictionary<Type, int> _fieldTypeToComponentCountMapping;
private static readonly IDictionary<Type, DataType> _fieldTypeToDataTypeMapping;

public readonly VertexInputBindingDescriptor[] VertexBindingDescriptors = VertexBindingDescriptors;

public readonly Label Label = Label;

static VertexInputDescriptor()
{
_fieldTypeToComponentCountMapping = new Dictionary<Type, int>
{
{ typeof(float), 1 },
{ typeof(Vector2), 2 },
{ typeof(Num.Vector2), 2},
{ typeof(Vector3), 3 },
{ typeof(Num.Vector3), 3},
{ typeof(Vector4), 4 },
{ typeof(Num.Vector4), 4},
{ typeof(uint), 4 }
};
_fieldTypeToDataTypeMapping = new Dictionary<Type, DataType>
{
{ typeof(float), DataType.Float },
{ typeof(Vector2), DataType.Float },
{ typeof(Num.Vector2), DataType.Float },
{ typeof(Vector3), DataType.Float },
{ typeof(Num.Vector3), DataType.Float },
{ typeof(Vector4), DataType.Float },
{ typeof(Num.Vector4), DataType.Float },
{ typeof(uint), DataType.UnsignedByte }
};
_fieldTypeToNormalizedMapping = new Dictionary<Type, bool>
{
{ typeof(float), false },
{ typeof(Vector2), false },
{ typeof(Num.Vector2), false },
{ typeof(Vector3), false },
{ typeof(Num.Vector3), false },
{ typeof(Vector4), false },
{ typeof(Num.Vector4), false },
{ typeof(uint), true }
};
_vertexTypeToVertexInputDescriptorMapping = new Dictionary<VertexType, VertexInputDescriptor>
{
{ VertexType.Position, BuildVertexInputDescriptorFor<VertexPosition>() },
{ VertexType.PositionColor, BuildVertexInputDescriptorFor<VertexPositionColor>() },
{ VertexType.PositionColorUv, BuildVertexInputDescriptorFor<VertexPositionColorUv>() },
{ VertexType.PositionNormal, BuildVertexInputDescriptorFor<VertexPositionNormal>() },
{ VertexType.PositionNormalUv, BuildVertexInputDescriptorFor<VertexPositionNormalUv>() },
{ VertexType.PositionNormalUvTangent, BuildVertexInputDescriptorFor<VertexPositionNormalUvTangent>() },
{ VertexType.Default, BuildVertexInputDescriptorFor<VertexPositionNormalUvTangent>() },
{ VertexType.ImGui, BuildVertexInputDescriptorFor<ImDrawVert>() }
};
}

public static VertexInputDescriptor ForVertexType(VertexType vertexType)
{
if (_vertexTypeToVertexInputDescriptorMapping.TryGetValue(vertexType, out var vertexInputDescriptor))
{
return vertexInputDescriptor;
}

throw new ArgumentOutOfRangeException($"VertexType {vertexType} has no vertex input descriptor mapping");
}

private static VertexInputDescriptor BuildVertexInputDescriptorFor<TVertexType>()
{
var vertexType = typeof(TVertexType);
var vertexTypeAttributes = vertexType.GetFields();
var vertexInputBindingDescriptors = vertexTypeAttributes.Select((vertexTypeAttribute, index) =>
{
var binding = 0u;
var location = GetLocationFromFieldName(vertexTypeAttribute.Name);
var dataType = GetDataTypeFromFieldType(vertexTypeAttribute.FieldType);
var componentCount = GetComponentCountFromFieldType(vertexTypeAttribute.FieldType);
var offset = (uint)Marshal.OffsetOf<TVertexType>(vertexTypeAttribute.Name);
var isNormalized = GetNormalizedFromFieldType(vertexTypeAttribute.FieldType);

return new VertexInputBindingDescriptor(location, binding, dataType, componentCount, offset, isNormalized);
});
return new VertexInputDescriptor(vertexInputBindingDescriptors.ToArray(), vertexType.Name);
}

private static uint GetLocationFromFieldName(string fieldName)
{
return fieldName switch
{
"Position" => 0u,
"Color" => 1u,
"Normal" => 2u,
"Uv" => 3u,
"Tangent" => 4u,
_ => GetLocationFromFieldNameForImGui(fieldName)
};
}

private static uint GetLocationFromFieldNameForImGui(string fieldName)
{
return fieldName.ToLower() switch
{
"pos" => 0u,
"uv" => 1u,
"col" => 2u,
_ => throw new ArgumentOutOfRangeException(nameof(fieldName), fieldName, null)
};
}

private static bool GetNormalizedFromFieldType(Type fieldType)
{
if (_fieldTypeToNormalizedMapping.TryGetValue(fieldType, out var isNormalized))
{
return isNormalized;
}

throw new ArgumentOutOfRangeException($"FieldType {fieldType.Name} has no normalized mapping");
}

private static DataType GetDataTypeFromFieldType(Type fieldType)
{
if (_fieldTypeToDataTypeMapping.TryGetValue(fieldType, out var dataType))
{
return dataType;
}

throw new ArgumentOutOfRangeException($"FieldType {fieldType.Name} has no data type mapping");
}

private static int GetComponentCountFromFieldType(Type fieldType)
{
if (_fieldTypeToComponentCountMapping.TryGetValue(fieldType, out var componentCount))
{
return componentCount;
}

throw new ArgumentOutOfRangeException($"FieldType {fieldType.Name} has no component count mapping");
}
}
5 changes: 2 additions & 3 deletions src/EngineKit/Graphics/VertexType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ public enum VertexType
ImGui,
Position,
PositionColor,
PositionColorNormal,
PositionColorNormalUv,
PositionColorUv,
PositionNormal,
PositionNormalUv,
PositionNormalUvTangent,
PositionUv,
}
}

0 comments on commit c21efac

Please sign in to comment.