Skip to content

Instantly share code, notes, and snippets.

@schroffl
Last active January 20, 2019 23:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schroffl/2e1b3339d2b609a96a0ea1e92eb6a602 to your computer and use it in GitHub Desktop.
Save schroffl/2e1b3339d2b609a96a0ea1e92eb6a602 to your computer and use it in GitHub Desktop.

I just yanked out a few lines from my code and put it into a simplified context, but I hope it's still possible to understand. The code is working if I take out the @compileError and replace it with unreachable, but having a type-checked function for interfacing with shaders was one of my goals when I started this project.

const math = @import("math.zig");
const c = @import("c.zig");
const Uniforms = struct {
uProjection: math.Mat3,
uScale: math.Vec2
};
const Program = struct {
uniform_locations: [2]c.GLint,
pub fn setUniform(self: Self, name: []const u8, value: var) void {
const ValueT = @typeOf(value);
const fields = @typeInfo(Uniforms).Struct.fields;
inline for (fields) |field, i| {
const name_match = std.mem.eql(u8, field.name, name);
const type_match = field.field_type == ValueT;
const location = self.uniform_locations[i];
if (name_match) {
if (!type_match) {
// This gets called on every iteration, not only when the names match.
@compileError("Types don't match");
}
switch (field.field_type) {
f32 => c.glUniform1f(location, value),
math.Mat3 => {
const matrix_ptr = @ptrCast([*]const math.float, @alignCast(4, &value.data[0]));
c.glUniformMatrix3fv(location, 1, c.GL_FALSE, matrix_ptr);
},
math.Vec2 => c.glUniform2f(location, value.x, value.y),
else => unreachable
}
// This return is neccessary, because otherwise the compiler complains:
// `control flow attempts to use compile-time variable at runtime
return;
}
}
}
}
pub fn main() void {
const p = Program {
.uniform_locations= []c.GLint {0, 1}
};
const mat = math.Mat3.projection(20, 20);
const scale = math.vec2(1, 1);
p.setUniform("uProjection", mat);
p.setUniform("uScale", scale);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment