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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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