opengl: simplify vertex attribute setting

This commit is contained in:
Mitchell Hashimoto
2022-04-05 08:25:36 -07:00
parent 684fb64705
commit 6ba0a13a9b
2 changed files with 52 additions and 8 deletions

View File

@ -168,12 +168,9 @@ pub fn render(
var binding = try vbo.bind(.ArrayBuffer);
defer binding.unbind();
try binding.setData(vertices.items, .DynamicDraw);
try binding.enableVertexAttribArray(0);
try binding.vertexAttribPointer(0, 3, gl.c.GL_FLOAT, false, 9 * @sizeOf(f32), null);
try binding.enableVertexAttribArray(1);
try binding.vertexAttribPointer(1, 2, gl.c.GL_FLOAT, false, 9 * @sizeOf(f32), @intToPtr(*const anyopaque, 3 * @sizeOf(f32)));
try binding.enableVertexAttribArray(2);
try binding.vertexAttribPointer(2, 4, gl.c.GL_FLOAT, false, 9 * @sizeOf(f32), @intToPtr(*const anyopaque, 5 * @sizeOf(f32)));
try binding.attribute(0, 3, [9]f32, 0);
try binding.attribute(1, 2, [9]f32, 3);
try binding.attribute(2, 4, [9]f32, 5);
try gl.drawArrays(gl.c.GL_TRIANGLES, 0, @intCast(c_int, vertices.items.len * 6));
try gl.VertexArray.unbind();

View File

@ -101,11 +101,58 @@ pub const Binding = struct {
};
}
pub inline fn enableVertexAttribArray(_: Binding, idx: c.GLuint) !void {
pub inline fn enableAttribArray(_: Binding, idx: c.GLuint) !void {
c.glEnableVertexAttribArray(idx);
}
pub inline fn vertexAttribPointer(
/// Shorthand for vertexAttribPointer that is specialized towards the
/// common use case of specifying an array of homogeneous types that
/// don't need normalization. This also enables the attribute at idx.
pub fn attribute(
b: Binding,
idx: c.GLuint,
size: c.GLint,
comptime T: type,
offset: usize,
) !void {
const info: struct {
// Type of the each component in the array.
typ: c.GLenum,
// The byte offset between each full set of attributes.
stride: c.GLsizei,
// The size of each component used in calculating the offset.
offset: usize,
} = switch (@typeInfo(T)) {
.Array => |ary| .{
.typ = switch (ary.child) {
f32 => c.GL_FLOAT,
else => @compileError("unsupported array child type"),
},
.offset = @sizeOf(ary.child),
.stride = @sizeOf(T),
},
else => @compileError("unsupported type"),
};
const offsetPtr = if (offset > 0)
@intToPtr(*const anyopaque, offset * info.offset)
else
null;
try b.attributeAdvanced(
idx,
size,
info.typ,
false,
info.stride,
offsetPtr,
);
try b.enableAttribArray(idx);
}
pub inline fn attributeAdvanced(
_: Binding,
idx: c.GLuint,
size: c.GLint,