Skip to content

Commit

Permalink
🔢 Allow instanced vertex data
Browse files Browse the repository at this point in the history
  • Loading branch information
paulcscharf committed Aug 5, 2024
1 parent a5979ae commit ad26246
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 14 deletions.
5 changes: 4 additions & 1 deletion Bearded.Graphics/Core/Vertices/VertexAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public readonly struct VertexAttribute(
VertexAttribPointerType type,
int stride,
int offset,
VertexAttributeFormat format)
VertexAttributeFormat format,
int divisor)
{
public void SetAttribute(ShaderProgram program)
{
Expand All @@ -37,6 +38,8 @@ public void SetAttribute(ShaderProgram program)
default:
throw new ArgumentOutOfRangeException();
}

GL.VertexAttribDivisor(index, divisor);
}

public override string ToString() =>
Expand Down
5 changes: 3 additions & 2 deletions Bearded.Graphics/Core/Vertices/VertexAttributeTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ public readonly struct VertexAttributeTemplate(
int size,
int bytes,
VertexAttribPointerType type,
VertexAttributeFormat format)
VertexAttributeFormat format,
int divisor)
{
public int Bytes => bytes;
public VertexAttribute ToAttribute(int offset, int stride) => new(name, size, type, stride, offset, format);
public VertexAttribute ToAttribute(int offset, int stride) => new(name, size, type, stride, offset, format, divisor);
}
29 changes: 18 additions & 11 deletions Bearded.Graphics/Core/Vertices/VertexData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,19 @@ public static void SetAttributes<TCollection>(TCollection attributes, ShaderProg
}

public static ImmutableArray<VertexAttribute> MakeAttributeArray(IEnumerable<VertexAttributeTemplate> attributes)
=> MakeAttributeArray(attributes.ToList());
=> MakeAttributeArray(attributes.ToArray());

public static ImmutableArray<VertexAttribute> MakeAttributeArray(params VertexAttributeTemplate[] attributes)
=> MakeAttributeArray((ICollection<VertexAttributeTemplate>)attributes);
=> MakeAttributeArray((ReadOnlySpan<VertexAttributeTemplate>)attributes);

public static ImmutableArray<VertexAttribute> MakeAttributeArray(ICollection<VertexAttributeTemplate> attributes)
public static ImmutableArray<VertexAttribute> MakeAttributeArray(ReadOnlySpan<VertexAttributeTemplate> attributes)
{
var stride = attributes.Sum(a => a.Bytes);
var array = ImmutableArray.CreateBuilder<VertexAttribute>(attributes.Count);
var stride = 0;
foreach (var template in attributes)
{
stride += template.Bytes;
}
var array = ImmutableArray.CreateBuilder<VertexAttribute>(attributes.Length);
var offset = 0;
foreach (var template in attributes)
{
Expand All @@ -49,28 +53,31 @@ public static ImmutableArray<VertexAttribute> MakeAttributeArray(ICollection<Ver
return array.MoveToImmutable();
}

public static VertexAttributeTemplate MakeAttributeTemplate<T>(string name, Format? format = null)
=> MakeAttributeTemplate(name, typeof(T), format);
public static VertexAttributeTemplate MakeAttributeTemplate<T>(
string name, Format? format = null, bool instanced = false)
=> MakeAttributeTemplate(name, typeof(T), format, instanced);

public static VertexAttributeTemplate MakeAttributeTemplate(string name, Type type, Format? format = null)
public static VertexAttributeTemplate MakeAttributeTemplate(
string name, Type type, Format? format = null, bool instanced = false)
{
if (!defaultsForType.TryGetValue(type, out var info))
throw new ArgumentException($"Unknown type: {type.Name}");

var bytes = size(info.Type);

return MakeAttributeTemplate(name, info.Type, info.Count, info.Count * bytes, format ?? info.DefaultFormat);
return MakeAttributeTemplate(
name, info.Type, info.Count, info.Count * bytes, format ?? info.DefaultFormat, instanced);
}

public static VertexAttributeTemplate MakeAttributeTemplate(
string name, PointerType type, int numberOfType, int sizeInBytes, Format format)
string name, PointerType type, int numberOfType, int sizeInBytes, Format format, bool instanced)
{
if (format == Format.Integer && !isValidIntegerType(type))
throw new ArgumentException("Invalid type for integer vertex attribute. Must be an integer.");
if (format == Format.Double && type != PointerType.Double)
throw new ArgumentException("Invalid type for 64-bit vertex attribute. Must be Double.");

return new VertexAttributeTemplate(name, numberOfType, sizeInBytes, type, format);
return new VertexAttributeTemplate(name, numberOfType, sizeInBytes, type, format, instanced ? 1 : 0);
}

private static bool isValidIntegerType(PointerType type)
Expand Down

0 comments on commit ad26246

Please sign in to comment.