diff options
| author | s-ol <s+removethis@s-ol.nu> | 2023-10-29 22:47:27 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2023-10-29 22:47:27 +0000 |
| commit | 536c820d9ccdda07d02934b82d26e21adbd39d9d (patch) | |
| tree | ffc00b4de676184dcfe3cc377c0ee26d80e5efb0 | |
| parent | specifying config.yaml path as CLI arg (diff) | |
| download | glsl-view-536c820d9ccdda07d02934b82d26e21adbd39d9d.tar.gz glsl-view-536c820d9ccdda07d02934b82d26e21adbd39d9d.zip | |
allow indexing uniforms, fix bug
| -rw-r--r-- | src/control.zig | 158 | ||||
| -rw-r--r-- | src/gl.zig | 396 |
2 files changed, 322 insertions, 232 deletions
diff --git a/src/control.zig b/src/control.zig index d7ce531..344badc 100644 --- a/src/control.zig +++ b/src/control.zig @@ -12,6 +12,40 @@ fn verify_args(expected: u8, got: []const u8) !void { } } +fn set_one( + comptime T: type, + dest: *T, + argc: c_int, + argv: [*c][*c]c.lo_arg, + types: []const u8, +) !void { + if (argc != 1) + return error.sizeMismatch; + + switch (T) { + f32 => { + try verify_args('f', types); + dest.* = argv[0].*.f; + }, + f64 => { + try verify_args('d', types); + dest.* = argv[0].*.d; + }, + i32 => { + try verify_args('d', types); + dest.* = argv[0].*.i; + }, + u32 => { + try verify_args('d', types); + const val = argv[0].*.i; + if (val < 0) + return error.signDisallowed; + dest.* = @as(u32, @intCast(val)); + }, + else => return error.invalidType, + } +} + fn set_array( comptime T: type, dest: []T, @@ -111,56 +145,80 @@ pub const ControlServer = struct { fn set_uniform( self: *ControlServer, - uniform_name: []const u8, + path: []const u8, argv: [*c][*c]c.lo_arg, argc: c_int, types: []const u8, ) !void { - var buffer: [256]u8 = undefined; - std.mem.copy(u8, buffer[0..], uniform_name); - buffer[uniform_name.len] = 0; - const name = buffer[0 .. uniform_name.len + 1]; - const uniform = (try self.cache.get(name)) orelse return error.notFound; - - try switch (uniform.value) { - .FLOAT => |*val| set_array(f32, @as([*]f32, @ptrCast(val))[0..1], argc, argv, types), - .DOUBLE => |*val| set_array(f64, @as([*]f64, @ptrCast(val))[0..1], argc, argv, types), - .INT => |*val| set_array(i32, @as([*]i32, @ptrCast(val))[0..1], argc, argv, types), - .UNSIGNED_INT => |*val| set_array(u32, @as([*]u32, @ptrCast(val))[0..1], argc, argv, types), - .BOOL => |*val| set_array(u32, @as([*]u32, @ptrCast(val))[0..1], argc, argv, types), - .FLOAT_VEC2 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_VEC3 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_VEC4 => |*val| set_array(f32, val[0..], argc, argv, types), - .DOUBLE_VEC2 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_VEC3 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_VEC4 => |*val| set_array(f64, val[0..], argc, argv, types), - .INT_VEC2 => |*val| set_array(i32, val[0..], argc, argv, types), - .INT_VEC3 => |*val| set_array(i32, val[0..], argc, argv, types), - .INT_VEC4 => |*val| set_array(i32, val[0..], argc, argv, types), - .UNSIGNED_INT_VEC2 => |*val| set_array(u32, val[0..], argc, argv, types), - .UNSIGNED_INT_VEC3 => |*val| set_array(u32, val[0..], argc, argv, types), - .UNSIGNED_INT_VEC4 => |*val| set_array(u32, val[0..], argc, argv, types), - .BOOL_VEC2 => |*val| set_array(u32, val[0..], argc, argv, types), - .BOOL_VEC3 => |*val| set_array(u32, val[0..], argc, argv, types), - .BOOL_VEC4 => |*val| set_array(u32, val[0..], argc, argv, types), - .FLOAT_MAT2 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_MAT3 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_MAT4 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_MAT2x3 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_MAT2x4 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_MAT3x2 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_MAT3x4 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_MAT4x2 => |*val| set_array(f32, val[0..], argc, argv, types), - .FLOAT_MAT4x3 => |*val| set_array(f32, val[0..], argc, argv, types), - .DOUBLE_MAT2 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_MAT3 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_MAT4 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_MAT2x3 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_MAT2x4 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_MAT3x2 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_MAT3x4 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_MAT4x2 => |*val| set_array(f64, val[0..], argc, argv, types), - .DOUBLE_MAT4x3 => |*val| set_array(f64, val[0..], argc, argv, types), + var parts = std.mem.tokenizeScalar(u8, path, '/'); + var uniform: *gl.CachedUniform = undefined; + + if (parts.next()) |uniform_name| { + var nameZ = try self.allocator.dupeZ(u8, uniform_name); + defer self.allocator.free(nameZ); + + const res = try self.cache.get(nameZ); + uniform = res orelse return error.notFound; + } else { + return error.invalidMessage; + } + + var value = uniform.value; + while (parts.next()) |component| { + const i = switch (component[0]) { + 'x', 'r', 's' => 0, + 'y', 'g', 't' => 1, + 'z', 'b', 'p' => 2, + 'w', 'a', 'q' => 3, + else => std.fmt.parseUnsigned(u8, component, 10) catch null, + }; + + if (i) |ii| { + value = try value.index(ii); + } else { + return error.invalidIndex; + } + } + + try switch (value) { + .FLOAT => |val| set_one(f32, val, argc, argv, types), + .DOUBLE => |val| set_one(f64, val, argc, argv, types), + .INT => |val| set_one(i32, val, argc, argv, types), + .UNSIGNED_INT => |val| set_one(u32, val, argc, argv, types), + .BOOL => |val| set_one(u32, val, argc, argv, types), + .FLOAT_VEC2 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_VEC3 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_VEC4 => |val| set_array(f32, val.*[0..], argc, argv, types), + .DOUBLE_VEC2 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_VEC3 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_VEC4 => |val| set_array(f64, val.*[0..], argc, argv, types), + .INT_VEC2 => |val| set_array(i32, val.*[0..], argc, argv, types), + .INT_VEC3 => |val| set_array(i32, val.*[0..], argc, argv, types), + .INT_VEC4 => |val| set_array(i32, val.*[0..], argc, argv, types), + .UNSIGNED_INT_VEC2 => |val| set_array(u32, val.*[0..], argc, argv, types), + .UNSIGNED_INT_VEC3 => |val| set_array(u32, val.*[0..], argc, argv, types), + .UNSIGNED_INT_VEC4 => |val| set_array(u32, val.*[0..], argc, argv, types), + .BOOL_VEC2 => |val| set_array(u32, val.*[0..], argc, argv, types), + .BOOL_VEC3 => |val| set_array(u32, val.*[0..], argc, argv, types), + .BOOL_VEC4 => |val| set_array(u32, val.*[0..], argc, argv, types), + .FLOAT_MAT2 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_MAT3 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_MAT4 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_MAT2x3 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_MAT2x4 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_MAT3x2 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_MAT3x4 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_MAT4x2 => |val| set_array(f32, val.*[0..], argc, argv, types), + .FLOAT_MAT4x3 => |val| set_array(f32, val.*[0..], argc, argv, types), + .DOUBLE_MAT2 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_MAT3 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_MAT4 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_MAT2x3 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_MAT2x4 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_MAT3x2 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_MAT3x4 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_MAT4x2 => |val| set_array(f64, val.*[0..], argc, argv, types), + .DOUBLE_MAT4x3 => |val| set_array(f64, val.*[0..], argc, argv, types), else => error.uniformNotSupported, }; @@ -181,13 +239,9 @@ pub const ControlServer = struct { const path = _path[0..c.strlen(_path)]; const types = _types[0..@as(u32, @intCast(argc))]; - if (!std.mem.startsWith(u8, path, "/")) { - std.debug.print("invalid OSC message {s} ({s})\n", .{ path, types }); - return 1; - } - - self.set_uniform(path[1..], argv, argc, types) catch |err| { + self.set_uniform(path, argv, argc, types) catch |err| { std.debug.print("{} while processing {s}\n", .{ err, path }); + return 1; }; return 0; } @@ -81,92 +81,116 @@ const UniformType = enum(c.GLint) { }; const UniformValue = union(UniformType) { - FLOAT: f32, - FLOAT_VEC2: [2]f32, - FLOAT_VEC3: [3]f32, - FLOAT_VEC4: [4]f32, - DOUBLE: f64, - DOUBLE_VEC2: [2]f64, - DOUBLE_VEC3: [3]f64, - DOUBLE_VEC4: [4]f64, - INT: c_int, // i32 but bug - INT_VEC2: [2]c_int, - INT_VEC3: [3]c_int, - INT_VEC4: [4]c_int, - UNSIGNED_INT: c_uint, - UNSIGNED_INT_VEC2: [2]c_uint, - UNSIGNED_INT_VEC3: [3]c_uint, - UNSIGNED_INT_VEC4: [4]c_uint, - BOOL: c_uint, - BOOL_VEC2: [2]c_uint, - BOOL_VEC3: [3]c_uint, - BOOL_VEC4: [4]c_uint, - FLOAT_MAT2: [2 * 2]f32, - FLOAT_MAT3: [3 * 3]f32, - FLOAT_MAT4: [4 * 4]f32, - FLOAT_MAT2x3: [2 * 3]f32, - FLOAT_MAT2x4: [2 * 4]f32, - FLOAT_MAT3x2: [3 * 2]f32, - FLOAT_MAT3x4: [3 * 4]f32, - FLOAT_MAT4x2: [4 * 2]f32, - FLOAT_MAT4x3: [4 * 3]f32, - DOUBLE_MAT2: [2 * 2]f64, - DOUBLE_MAT3: [3 * 3]f64, - DOUBLE_MAT4: [4 * 4]f64, - DOUBLE_MAT2x3: [2 * 3]f64, - DOUBLE_MAT2x4: [2 * 4]f64, - DOUBLE_MAT3x2: [3 * 2]f64, - DOUBLE_MAT3x4: [3 * 4]f64, - DOUBLE_MAT4x2: [4 * 2]f64, - DOUBLE_MAT4x3: [4 * 3]f64, - SAMPLER_1D: c_int, - SAMPLER_2D: c_int, - SAMPLER_3D: c_int, - SAMPLER_CUBE: c_int, - SAMPLER_1D_SHADOW: c_int, - SAMPLER_2D_SHADOW: c_int, - SAMPLER_1D_ARRAY: c_int, - SAMPLER_2D_ARRAY: c_int, - SAMPLER_1D_ARRAY_SHADOW: c_int, - SAMPLER_2D_ARRAY_SHADOW: c_int, - SAMPLER_2D_MULTISAMPLE: c_int, - SAMPLER_2D_MULTISAMPLE_ARRAY: c_int, - SAMPLER_CUBE_SHADOW: c_int, - SAMPLER_BUFFER: c_int, - SAMPLER_2D_RECT: c_int, - SAMPLER_2D_RECT_SHADOW: c_int, - INT_SAMPLER_1D: c_int, - INT_SAMPLER_2D: c_int, - INT_SAMPLER_3D: c_int, - INT_SAMPLER_CUBE: c_int, - INT_SAMPLER_1D_ARRAY: c_int, - INT_SAMPLER_2D_ARRAY: c_int, - INT_SAMPLER_2D_MULTISAMPLE: c_int, - INT_SAMPLER_2D_MULTISAMPLE_ARRAY: c_int, - INT_SAMPLER_BUFFER: c_int, - INT_SAMPLER_2D_RECT: c_int, - UNSIGNED_INT_SAMPLER_1D: c_int, - UNSIGNED_INT_SAMPLER_2D: c_int, - UNSIGNED_INT_SAMPLER_3D: c_int, - UNSIGNED_INT_SAMPLER_CUBE: c_int, - UNSIGNED_INT_SAMPLER_1D_ARRAY: c_int, - UNSIGNED_INT_SAMPLER_2D_ARRAY: c_int, - UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: c_int, - UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: c_int, - UNSIGNED_INT_SAMPLER_BUFFER: c_int, - UNSIGNED_INT_SAMPLER_2D_RECT: c_int, - - pub fn init(utype: UniformType) UniformValue { - inline for (@typeInfo(UniformType).Enum.fields) |field| { - if (@as(UniformType, @enumFromInt(field.value)) == utype) - return @unionInit(UniformValue, field.name, undefined); + FLOAT: *f32, + FLOAT_VEC2: *[2]f32, + FLOAT_VEC3: *[3]f32, + FLOAT_VEC4: *[4]f32, + DOUBLE: *f64, + DOUBLE_VEC2: *[2]f64, + DOUBLE_VEC3: *[3]f64, + DOUBLE_VEC4: *[4]f64, + INT: *c_int, // i32 but bug + INT_VEC2: *[2]c_int, + INT_VEC3: *[3]c_int, + INT_VEC4: *[4]c_int, + UNSIGNED_INT: *c_uint, + UNSIGNED_INT_VEC2: *[2]c_uint, + UNSIGNED_INT_VEC3: *[3]c_uint, + UNSIGNED_INT_VEC4: *[4]c_uint, + BOOL: *c_uint, + BOOL_VEC2: *[2]c_uint, + BOOL_VEC3: *[3]c_uint, + BOOL_VEC4: *[4]c_uint, + FLOAT_MAT2: *[2 * 2]f32, + FLOAT_MAT3: *[3 * 3]f32, + FLOAT_MAT4: *[4 * 4]f32, + FLOAT_MAT2x3: *[2 * 3]f32, + FLOAT_MAT2x4: *[2 * 4]f32, + FLOAT_MAT3x2: *[3 * 2]f32, + FLOAT_MAT3x4: *[3 * 4]f32, + FLOAT_MAT4x2: *[4 * 2]f32, + FLOAT_MAT4x3: *[4 * 3]f32, + DOUBLE_MAT2: *[2 * 2]f64, + DOUBLE_MAT3: *[3 * 3]f64, + DOUBLE_MAT4: *[4 * 4]f64, + DOUBLE_MAT2x3: *[2 * 3]f64, + DOUBLE_MAT2x4: *[2 * 4]f64, + DOUBLE_MAT3x2: *[3 * 2]f64, + DOUBLE_MAT3x4: *[3 * 4]f64, + DOUBLE_MAT4x2: *[4 * 2]f64, + DOUBLE_MAT4x3: *[4 * 3]f64, + SAMPLER_1D: *c_int, + SAMPLER_2D: *c_int, + SAMPLER_3D: *c_int, + SAMPLER_CUBE: *c_int, + SAMPLER_1D_SHADOW: *c_int, + SAMPLER_2D_SHADOW: *c_int, + SAMPLER_1D_ARRAY: *c_int, + SAMPLER_2D_ARRAY: *c_int, + SAMPLER_1D_ARRAY_SHADOW: *c_int, + SAMPLER_2D_ARRAY_SHADOW: *c_int, + SAMPLER_2D_MULTISAMPLE: *c_int, + SAMPLER_2D_MULTISAMPLE_ARRAY: *c_int, + SAMPLER_CUBE_SHADOW: *c_int, + SAMPLER_BUFFER: *c_int, + SAMPLER_2D_RECT: *c_int, + SAMPLER_2D_RECT_SHADOW: *c_int, + INT_SAMPLER_1D: *c_int, + INT_SAMPLER_2D: *c_int, + INT_SAMPLER_3D: *c_int, + INT_SAMPLER_CUBE: *c_int, + INT_SAMPLER_1D_ARRAY: *c_int, + INT_SAMPLER_2D_ARRAY: *c_int, + INT_SAMPLER_2D_MULTISAMPLE: *c_int, + INT_SAMPLER_2D_MULTISAMPLE_ARRAY: *c_int, + INT_SAMPLER_BUFFER: *c_int, + INT_SAMPLER_2D_RECT: *c_int, + UNSIGNED_INT_SAMPLER_1D: *c_int, + UNSIGNED_INT_SAMPLER_2D: *c_int, + UNSIGNED_INT_SAMPLER_3D: *c_int, + UNSIGNED_INT_SAMPLER_CUBE: *c_int, + UNSIGNED_INT_SAMPLER_1D_ARRAY: *c_int, + UNSIGNED_INT_SAMPLER_2D_ARRAY: *c_int, + UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: *c_int, + UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: *c_int, + UNSIGNED_INT_SAMPLER_BUFFER: *c_int, + UNSIGNED_INT_SAMPLER_2D_RECT: *c_int, + + pub fn init(allocator: std.mem.Allocator, comptime utype: UniformType) !UniformValue { + const data = try allocator.create(std.meta.Child(std.meta.TagPayload(UniformValue, utype))); + return @unionInit(UniformValue, @tagName(utype), data); + } + + pub fn deinit(self: *const UniformValue, allocator: std.mem.Allocator) void { + switch (self.*) { + inline else => |value| allocator.destroy(value), } + } + + pub fn index(self: *const UniformValue, i: u8) !UniformValue { + const length: u8 = switch (self.*) { + .FLOAT_VEC2, .DOUBLE_VEC2, .INT_VEC2, .BOOL_VEC2, .UNSIGNED_INT_VEC2 => 2, + .FLOAT_VEC3, .DOUBLE_VEC3, .INT_VEC3, .UNSIGNED_INT_VEC3 => 3, + .BOOL_VEC3, .FLOAT_VEC4, .DOUBLE_VEC4, .INT_VEC4, .UNSIGNED_INT_VEC4, .BOOL_VEC4 => 4, + else => return error.notIndexable, + }; - unreachable; + if (i >= length) { + return error.invalidIndex; + } + + return switch (self.*) { + .FLOAT_VEC2, .FLOAT_VEC3, .FLOAT_VEC4 => |v| .{ .FLOAT = &v[i] }, + .DOUBLE_VEC2, .DOUBLE_VEC3, .DOUBLE_VEC4 => |v| .{ .DOUBLE = &v[i] }, + .INT_VEC2, .INT_VEC3, .INT_VEC4 => |v| .{ .INT = &v[i] }, + .UNSIGNED_INT_VEC2, .UNSIGNED_INT_VEC3, .UNSIGNED_INT_VEC4 => |v| .{ .UNSIGNED_INT = &v[i] }, + .BOOL_VEC2, .BOOL_VEC3, .BOOL_VEC4 => |v| .{ .BOOL = &v[i] }, + else => unreachable, + }; } }; -const CachedUniform = struct { +pub const CachedUniform = struct { value: UniformValue, location: c.GLint, @@ -177,16 +201,22 @@ const CachedUniform = struct { if (index == c.GL_INVALID_INDEX) return error.invalidUniform; - var utype: c.GLint = undefined; - c.glGetActiveUniformsiv(shader.program_id, 1, &index, c.GL_UNIFORM_TYPE, &utype); + var _utype: c.GLint = undefined; + c.glGetActiveUniformsiv(shader.program_id, 1, &index, c.GL_UNIFORM_TYPE, &_utype); - var self = CachedUniform{ - .value = UniformValue.init(@as(UniformType, @enumFromInt(utype))), - .location = try shader.uniformLocation(name), - }; + switch (@as(UniformType, @enumFromInt(_utype))) { + inline else => |utype| { + const location = try shader.uniformLocation(name); + const value = try UniformValue.init(allocator, utype); + errdefer value.deinit(allocator); - self.getShaderValue(shader); - return self; + return .{ .value = value, .location = location }; + }, + } + } + + pub fn deinit(self: *const CachedUniform, allocator: std.mem.Allocator) void { + self.value.deinit(allocator); } // zig fmt: off @@ -195,45 +225,45 @@ const CachedUniform = struct { const location = self.location; switch (self.value) { - .FLOAT => |*value| c.glProgramUniform1fv(program, location, 1, value), - .FLOAT_VEC2 => |*value| c.glProgramUniform2fv(program, location, 1, value), - .FLOAT_VEC3 => |*value| c.glProgramUniform3fv(program, location, 1, value), - .FLOAT_VEC4 => |*value| c.glProgramUniform4fv(program, location, 1, value), - .DOUBLE => |*value| c.glProgramUniform1dv(program, location, 1, value), - .DOUBLE_VEC2 => |*value| c.glProgramUniform1dv(program, location, 1, value), - .DOUBLE_VEC3 => |*value| c.glProgramUniform2dv(program, location, 1, value), - .DOUBLE_VEC4 => |*value| c.glProgramUniform3dv(program, location, 1, value), - .INT => |*value| c.glProgramUniform1iv(program, location, 1, value), - .INT_VEC2 => |*value| c.glProgramUniform2iv(program, location, 1, value), - .INT_VEC3 => |*value| c.glProgramUniform3iv(program, location, 1, value), - .INT_VEC4 => |*value| c.glProgramUniform4iv(program, location, 1, value), - .UNSIGNED_INT => |*value| c.glProgramUniform1uiv(program, location, 1, value), - .UNSIGNED_INT_VEC2 => |*value| c.glProgramUniform2uiv(program, location, 1, value), - .UNSIGNED_INT_VEC3 => |*value| c.glProgramUniform3uiv(program, location, 1, value), - .UNSIGNED_INT_VEC4 => |*value| c.glProgramUniform4uiv(program, location, 1, value), - .BOOL => |*value| c.glProgramUniform1uiv(program, location, 1, value), - .BOOL_VEC2 => |*value| c.glProgramUniform2uiv(program, location, 1, value), - .BOOL_VEC3 => |*value| c.glProgramUniform3uiv(program, location, 1, value), - .BOOL_VEC4 => |*value| c.glProgramUniform4uiv(program, location, 1, value), - .FLOAT_MAT2 => |*value| c.glProgramUniformMatrix2fv(program, location, 1, c.GL_FALSE, value), - .FLOAT_MAT3 => |*value| c.glProgramUniformMatrix3fv(program, location, 1, c.GL_FALSE, value), - .FLOAT_MAT4 => |*value| c.glProgramUniformMatrix4fv(program, location, 1, c.GL_FALSE, value), - .FLOAT_MAT2x3 => |*value| c.glProgramUniformMatrix2x3fv(program, location, 1, c.GL_FALSE, value), - .FLOAT_MAT2x4 => |*value| c.glProgramUniformMatrix2x4fv(program, location, 1, c.GL_FALSE, value), - .FLOAT_MAT3x2 => |*value| c.glProgramUniformMatrix3x2fv(program, location, 1, c.GL_FALSE, value), - .FLOAT_MAT3x4 => |*value| c.glProgramUniformMatrix3x4fv(program, location, 1, c.GL_FALSE, value), - .FLOAT_MAT4x2 => |*value| c.glProgramUniformMatrix4x2fv(program, location, 1, c.GL_FALSE, value), - .FLOAT_MAT4x3 => |*value| c.glProgramUniformMatrix4x3fv(program, location, 1, c.GL_FALSE, value), - .DOUBLE_MAT2 => |*value| c.glProgramUniformMatrix2dv(program, location, 1, c.GL_FALSE, value), - .DOUBLE_MAT3 => |*value| c.glProgramUniformMatrix3dv(program, location, 1, c.GL_FALSE, value), - .DOUBLE_MAT4 => |*value| c.glProgramUniformMatrix4dv(program, location, 1, c.GL_FALSE, value), - .DOUBLE_MAT2x3 => |*value| c.glProgramUniformMatrix2x3dv(program, location, 1, c.GL_FALSE, value), - .DOUBLE_MAT2x4 => |*value| c.glProgramUniformMatrix2x4dv(program, location, 1, c.GL_FALSE, value), - .DOUBLE_MAT3x2 => |*value| c.glProgramUniformMatrix3x2dv(program, location, 1, c.GL_FALSE, value), - .DOUBLE_MAT3x4 => |*value| c.glProgramUniformMatrix3x4dv(program, location, 1, c.GL_FALSE, value), - .DOUBLE_MAT4x2 => |*value| c.glProgramUniformMatrix4x2dv(program, location, 1, c.GL_FALSE, value), - .DOUBLE_MAT4x3 => |*value| c.glProgramUniformMatrix4x3dv(program, location, 1, c.GL_FALSE, value), - .SAMPLER_1D, .SAMPLER_2D, .SAMPLER_3D, .SAMPLER_CUBE, .SAMPLER_1D_SHADOW, .SAMPLER_2D_SHADOW, .SAMPLER_1D_ARRAY, .SAMPLER_2D_ARRAY, .SAMPLER_1D_ARRAY_SHADOW, .SAMPLER_2D_ARRAY_SHADOW, .SAMPLER_2D_MULTISAMPLE, .SAMPLER_2D_MULTISAMPLE_ARRAY, .SAMPLER_CUBE_SHADOW, .SAMPLER_BUFFER, .SAMPLER_2D_RECT, .SAMPLER_2D_RECT_SHADOW, .INT_SAMPLER_1D, .INT_SAMPLER_2D, .INT_SAMPLER_3D, .INT_SAMPLER_CUBE, .INT_SAMPLER_1D_ARRAY, .INT_SAMPLER_2D_ARRAY, .INT_SAMPLER_2D_MULTISAMPLE, .INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .INT_SAMPLER_BUFFER, .INT_SAMPLER_2D_RECT, .UNSIGNED_INT_SAMPLER_1D, .UNSIGNED_INT_SAMPLER_2D, .UNSIGNED_INT_SAMPLER_3D, .UNSIGNED_INT_SAMPLER_CUBE, .UNSIGNED_INT_SAMPLER_1D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .UNSIGNED_INT_SAMPLER_BUFFER, .UNSIGNED_INT_SAMPLER_2D_RECT => |value| c.glProgramUniform1i(program, location, value), + .FLOAT => |value| c.glProgramUniform1fv(program, location, 1, value), + .FLOAT_VEC2 => |value| c.glProgramUniform2fv(program, location, 1, value), + .FLOAT_VEC3 => |value| c.glProgramUniform3fv(program, location, 1, value), + .FLOAT_VEC4 => |value| c.glProgramUniform4fv(program, location, 1, value), + .DOUBLE => |value| c.glProgramUniform1dv(program, location, 1, value), + .DOUBLE_VEC2 => |value| c.glProgramUniform1dv(program, location, 1, value), + .DOUBLE_VEC3 => |value| c.glProgramUniform2dv(program, location, 1, value), + .DOUBLE_VEC4 => |value| c.glProgramUniform3dv(program, location, 1, value), + .INT => |value| c.glProgramUniform1iv(program, location, 1, value), + .INT_VEC2 => |value| c.glProgramUniform2iv(program, location, 1, value), + .INT_VEC3 => |value| c.glProgramUniform3iv(program, location, 1, value), + .INT_VEC4 => |value| c.glProgramUniform4iv(program, location, 1, value), + .UNSIGNED_INT => |value| c.glProgramUniform1uiv(program, location, 1, value), + .UNSIGNED_INT_VEC2 => |value| c.glProgramUniform2uiv(program, location, 1, value), + .UNSIGNED_INT_VEC3 => |value| c.glProgramUniform3uiv(program, location, 1, value), + .UNSIGNED_INT_VEC4 => |value| c.glProgramUniform4uiv(program, location, 1, value), + .BOOL => |value| c.glProgramUniform1uiv(program, location, 1, value), + .BOOL_VEC2 => |value| c.glProgramUniform2uiv(program, location, 1, value), + .BOOL_VEC3 => |value| c.glProgramUniform3uiv(program, location, 1, value), + .BOOL_VEC4 => |value| c.glProgramUniform4uiv(program, location, 1, value), + .FLOAT_MAT2 => |value| c.glProgramUniformMatrix2fv(program, location, 1, c.GL_FALSE, value), + .FLOAT_MAT3 => |value| c.glProgramUniformMatrix3fv(program, location, 1, c.GL_FALSE, value), + .FLOAT_MAT4 => |value| c.glProgramUniformMatrix4fv(program, location, 1, c.GL_FALSE, value), + .FLOAT_MAT2x3 => |value| c.glProgramUniformMatrix2x3fv(program, location, 1, c.GL_FALSE, value), + .FLOAT_MAT2x4 => |value| c.glProgramUniformMatrix2x4fv(program, location, 1, c.GL_FALSE, value), + .FLOAT_MAT3x2 => |value| c.glProgramUniformMatrix3x2fv(program, location, 1, c.GL_FALSE, value), + .FLOAT_MAT3x4 => |value| c.glProgramUniformMatrix3x4fv(program, location, 1, c.GL_FALSE, value), + .FLOAT_MAT4x2 => |value| c.glProgramUniformMatrix4x2fv(program, location, 1, c.GL_FALSE, value), + .FLOAT_MAT4x3 => |value| c.glProgramUniformMatrix4x3fv(program, location, 1, c.GL_FALSE, value), + .DOUBLE_MAT2 => |value| c.glProgramUniformMatrix2dv(program, location, 1, c.GL_FALSE, value), + .DOUBLE_MAT3 => |value| c.glProgramUniformMatrix3dv(program, location, 1, c.GL_FALSE, value), + .DOUBLE_MAT4 => |value| c.glProgramUniformMatrix4dv(program, location, 1, c.GL_FALSE, value), + .DOUBLE_MAT2x3 => |value| c.glProgramUniformMatrix2x3dv(program, location, 1, c.GL_FALSE, value), + .DOUBLE_MAT2x4 => |value| c.glProgramUniformMatrix2x4dv(program, location, 1, c.GL_FALSE, value), + .DOUBLE_MAT3x2 => |value| c.glProgramUniformMatrix3x2dv(program, location, 1, c.GL_FALSE, value), + .DOUBLE_MAT3x4 => |value| c.glProgramUniformMatrix3x4dv(program, location, 1, c.GL_FALSE, value), + .DOUBLE_MAT4x2 => |value| c.glProgramUniformMatrix4x2dv(program, location, 1, c.GL_FALSE, value), + .DOUBLE_MAT4x3 => |value| c.glProgramUniformMatrix4x3dv(program, location, 1, c.GL_FALSE, value), + .SAMPLER_1D, .SAMPLER_2D, .SAMPLER_3D, .SAMPLER_CUBE, .SAMPLER_1D_SHADOW, .SAMPLER_2D_SHADOW, .SAMPLER_1D_ARRAY, .SAMPLER_2D_ARRAY, .SAMPLER_1D_ARRAY_SHADOW, .SAMPLER_2D_ARRAY_SHADOW, .SAMPLER_2D_MULTISAMPLE, .SAMPLER_2D_MULTISAMPLE_ARRAY, .SAMPLER_CUBE_SHADOW, .SAMPLER_BUFFER, .SAMPLER_2D_RECT, .SAMPLER_2D_RECT_SHADOW, .INT_SAMPLER_1D, .INT_SAMPLER_2D, .INT_SAMPLER_3D, .INT_SAMPLER_CUBE, .INT_SAMPLER_1D_ARRAY, .INT_SAMPLER_2D_ARRAY, .INT_SAMPLER_2D_MULTISAMPLE, .INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .INT_SAMPLER_BUFFER, .INT_SAMPLER_2D_RECT, .UNSIGNED_INT_SAMPLER_1D, .UNSIGNED_INT_SAMPLER_2D, .UNSIGNED_INT_SAMPLER_3D, .UNSIGNED_INT_SAMPLER_CUBE, .UNSIGNED_INT_SAMPLER_1D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .UNSIGNED_INT_SAMPLER_BUFFER, .UNSIGNED_INT_SAMPLER_2D_RECT => |value| c.glProgramUniform1i(program, location, value.*), } } @@ -242,45 +272,45 @@ const CachedUniform = struct { const location = self.location; switch (self.value) { - .FLOAT => |*value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value), - .FLOAT_VEC2 => |*value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value), - .FLOAT_VEC3 => |*value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value), - .FLOAT_VEC4 => |*value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value), - .DOUBLE => |*value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value), - .DOUBLE_VEC2 => |*value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value), - .DOUBLE_VEC3 => |*value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value), - .DOUBLE_VEC4 => |*value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value), - .INT => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .INT_VEC2 => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .INT_VEC3 => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .INT_VEC4 => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .UNSIGNED_INT => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .UNSIGNED_INT_VEC2 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .UNSIGNED_INT_VEC3 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .UNSIGNED_INT_VEC4 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .BOOL => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .BOOL_VEC2 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .BOOL_VEC3 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .BOOL_VEC4 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), - .FLOAT_MAT2 => |*value| c.glGetUniformfv(program, location, value), - .FLOAT_MAT3 => |*value| c.glGetUniformfv(program, location, value), - .FLOAT_MAT4 => |*value| c.glGetUniformfv(program, location, value), - .FLOAT_MAT2x3 => |*value| c.glGetUniformfv(program, location, value), - .FLOAT_MAT2x4 => |*value| c.glGetUniformfv(program, location, value), - .FLOAT_MAT3x2 => |*value| c.glGetUniformfv(program, location, value), - .FLOAT_MAT3x4 => |*value| c.glGetUniformfv(program, location, value), - .FLOAT_MAT4x2 => |*value| c.glGetUniformfv(program, location, value), - .FLOAT_MAT4x3 => |*value| c.glGetUniformfv(program, location, value), - .DOUBLE_MAT2 => |*value| c.glGetUniformdv(program, location, value), - .DOUBLE_MAT3 => |*value| c.glGetUniformdv(program, location, value), - .DOUBLE_MAT4 => |*value| c.glGetUniformdv(program, location, value), - .DOUBLE_MAT2x3 => |*value| c.glGetUniformdv(program, location, value), - .DOUBLE_MAT2x4 => |*value| c.glGetUniformdv(program, location, value), - .DOUBLE_MAT3x2 => |*value| c.glGetUniformdv(program, location, value), - .DOUBLE_MAT3x4 => |*value| c.glGetUniformdv(program, location, value), - .DOUBLE_MAT4x2 => |*value| c.glGetUniformdv(program, location, value), - .DOUBLE_MAT4x3 => |*value| c.glGetUniformdv(program, location, value), - .SAMPLER_1D, .SAMPLER_2D, .SAMPLER_3D, .SAMPLER_CUBE, .SAMPLER_1D_SHADOW, .SAMPLER_2D_SHADOW, .SAMPLER_1D_ARRAY, .SAMPLER_2D_ARRAY, .SAMPLER_1D_ARRAY_SHADOW, .SAMPLER_2D_ARRAY_SHADOW, .SAMPLER_2D_MULTISAMPLE, .SAMPLER_2D_MULTISAMPLE_ARRAY, .SAMPLER_CUBE_SHADOW, .SAMPLER_BUFFER, .SAMPLER_2D_RECT, .SAMPLER_2D_RECT_SHADOW, .INT_SAMPLER_1D, .INT_SAMPLER_2D, .INT_SAMPLER_3D, .INT_SAMPLER_CUBE, .INT_SAMPLER_1D_ARRAY, .INT_SAMPLER_2D_ARRAY, .INT_SAMPLER_2D_MULTISAMPLE, .INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .INT_SAMPLER_BUFFER, .INT_SAMPLER_2D_RECT, .UNSIGNED_INT_SAMPLER_1D, .UNSIGNED_INT_SAMPLER_2D, .UNSIGNED_INT_SAMPLER_3D, .UNSIGNED_INT_SAMPLER_CUBE, .UNSIGNED_INT_SAMPLER_1D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .UNSIGNED_INT_SAMPLER_BUFFER, .UNSIGNED_INT_SAMPLER_2D_RECT => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .FLOAT => |value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value), + .FLOAT_VEC2 => |value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value), + .FLOAT_VEC3 => |value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value), + .FLOAT_VEC4 => |value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value), + .DOUBLE => |value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value), + .DOUBLE_VEC2 => |value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value), + .DOUBLE_VEC3 => |value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value), + .DOUBLE_VEC4 => |value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value), + .INT => |value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .INT_VEC2 => |value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .INT_VEC3 => |value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .INT_VEC4 => |value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .UNSIGNED_INT => |value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .UNSIGNED_INT_VEC2 => |value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .UNSIGNED_INT_VEC3 => |value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .UNSIGNED_INT_VEC4 => |value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .BOOL => |value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .BOOL_VEC2 => |value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .BOOL_VEC3 => |value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .BOOL_VEC4 => |value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value), + .FLOAT_MAT2 => |value| c.glGetUniformfv(program, location, value), + .FLOAT_MAT3 => |value| c.glGetUniformfv(program, location, value), + .FLOAT_MAT4 => |value| c.glGetUniformfv(program, location, value), + .FLOAT_MAT2x3 => |value| c.glGetUniformfv(program, location, value), + .FLOAT_MAT2x4 => |value| c.glGetUniformfv(program, location, value), + .FLOAT_MAT3x2 => |value| c.glGetUniformfv(program, location, value), + .FLOAT_MAT3x4 => |value| c.glGetUniformfv(program, location, value), + .FLOAT_MAT4x2 => |value| c.glGetUniformfv(program, location, value), + .FLOAT_MAT4x3 => |value| c.glGetUniformfv(program, location, value), + .DOUBLE_MAT2 => |value| c.glGetUniformdv(program, location, value), + .DOUBLE_MAT3 => |value| c.glGetUniformdv(program, location, value), + .DOUBLE_MAT4 => |value| c.glGetUniformdv(program, location, value), + .DOUBLE_MAT2x3 => |value| c.glGetUniformdv(program, location, value), + .DOUBLE_MAT2x4 => |value| c.glGetUniformdv(program, location, value), + .DOUBLE_MAT3x2 => |value| c.glGetUniformdv(program, location, value), + .DOUBLE_MAT3x4 => |value| c.glGetUniformdv(program, location, value), + .DOUBLE_MAT4x2 => |value| c.glGetUniformdv(program, location, value), + .DOUBLE_MAT4x3 => |value| c.glGetUniformdv(program, location, value), + .SAMPLER_1D, .SAMPLER_2D, .SAMPLER_3D, .SAMPLER_CUBE, .SAMPLER_1D_SHADOW, .SAMPLER_2D_SHADOW, .SAMPLER_1D_ARRAY, .SAMPLER_2D_ARRAY, .SAMPLER_1D_ARRAY_SHADOW, .SAMPLER_2D_ARRAY_SHADOW, .SAMPLER_2D_MULTISAMPLE, .SAMPLER_2D_MULTISAMPLE_ARRAY, .SAMPLER_CUBE_SHADOW, .SAMPLER_BUFFER, .SAMPLER_2D_RECT, .SAMPLER_2D_RECT_SHADOW, .INT_SAMPLER_1D, .INT_SAMPLER_2D, .INT_SAMPLER_3D, .INT_SAMPLER_CUBE, .INT_SAMPLER_1D_ARRAY, .INT_SAMPLER_2D_ARRAY, .INT_SAMPLER_2D_MULTISAMPLE, .INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .INT_SAMPLER_BUFFER, .INT_SAMPLER_2D_RECT, .UNSIGNED_INT_SAMPLER_1D, .UNSIGNED_INT_SAMPLER_2D, .UNSIGNED_INT_SAMPLER_3D, .UNSIGNED_INT_SAMPLER_CUBE, .UNSIGNED_INT_SAMPLER_1D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .UNSIGNED_INT_SAMPLER_BUFFER, .UNSIGNED_INT_SAMPLER_2D_RECT => |value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value), } } // zig fmt: on @@ -359,6 +389,7 @@ pub const UniformCache = struct { pub fn deinit(self: *UniformCache) void { var it = self.uniforms.iterator(); while (it.next()) |entry| { + entry.value_ptr.deinit(self.allocator); self.allocator.free(entry.key_ptr.*); } @@ -408,21 +439,26 @@ pub const UniformCache = struct { } } - // name has to be zero-terminated! - pub fn get(self: *UniformCache, name: []const u8) !?*CachedUniform { - const cloned_name = try self.allocator.dupe(u8, name); - errdefer self.allocator.free(cloned_name); - - var result = try self.uniforms.getOrPut(cloned_name); - if (!result.found_existing) { - result.value_ptr.* = CachedUniform.init(self.shader.*, name.ptr) catch { - _ = self.uniforms.remove(cloned_name); - self.allocator.free(cloned_name); - return null; - }; + pub fn get(self: *UniformCache, name: [:0]u8) !?*CachedUniform { + var getValue = false; + + if (!self.uniforms.contains(name)) { + const cloned_name = try self.allocator.dupe(u8, name); + errdefer self.allocator.free(cloned_name); + + const uniform = CachedUniform.init(self.allocator, self.shader.*, name.ptr) catch return null; + errdefer uniform.deinit(self.allocator); + + try self.uniforms.put(cloned_name, uniform); + getValue = true; + } + + if (self.uniforms.getPtr(name)) |ptr| { + ptr.getShaderValue(self.shader.*); + return ptr; } - return result.value_ptr; + return null; } }; |
