diff options
| author | s-ol <s+removethis@s-ol.nu> | 2026-04-10 17:08:15 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2026-04-10 22:22:45 +0000 |
| commit | 5d3f9aef90bed7713ce07614fdd154d50223ba61 (patch) | |
| tree | c6cfdc75e645773de14bf4cad8bbb89f60f267d6 | |
| parent | more TSV logging (diff) | |
| download | glsl-view-5d3f9aef90bed7713ce07614fdd154d50223ba61.tar.gz glsl-view-5d3f9aef90bed7713ce07614fdd154d50223ba61.zip | |
support arrays of uniforms, remove finished sources
| -rw-r--r-- | src/control.zig | 128 | ||||
| -rw-r--r-- | src/ffmpeg.zig | 16 | ||||
| -rw-r--r-- | src/gl.zig | 660 | ||||
| -rw-r--r-- | src/source.zig | 9 | ||||
| -rw-r--r-- | src/tsv.zig | 7 |
5 files changed, 415 insertions, 405 deletions
diff --git a/src/control.zig b/src/control.zig index 9810645..e52129e 100644 --- a/src/control.zig +++ b/src/control.zig @@ -22,49 +22,9 @@ fn verify_args_all(expected: u8, got: []const u8) !void { } } -fn set_one( - comptime T: type, - dest: *(if (T == bool) c.GLuint else T), - argv: []const [*c]c.lo_arg, - types: []const u8, -) !void { - if (types.len != 1) - return error.sizeMismatch; - - switch (T) { - f32 => { - try verify_args_all('f', types); - dest.* = argv[0].*.f; - }, - f64 => { - try verify_args_all('d', types); - dest.* = argv[0].*.d; - }, - i32 => { - try verify_args_all('d', types); - dest.* = argv[0].*.i; - }, - u32 => { - try verify_args_all('d', types); - const val = argv[0].*.i; - if (val < 0) - return error.signDisallowed; - dest.* = @as(u32, @intCast(val)); - }, - bool => { - dest.* = switch (types[0]) { - 'T' => c.GL_TRUE, - 'F' => c.GL_FALSE, - else => return error.typeMismatch, - }; - }, - else => return error.invalidType, - } -} - fn set_array( comptime T: type, - dest: [](if (T == bool) c.GLuint else T), + dest: []T, argv: []const [*c]c.lo_arg, types: []const u8, ) !void { @@ -197,6 +157,26 @@ pub const ControlServer = struct { } pub fn update(self: *ControlServer) void { + var names: [256][]const u8 = undefined; + var i: usize = 0; + + var tit = self.sources.iterator(); + while (tit.next()) |entry| { + const remove = entry.value_ptr.*.update(); + + if (remove) { + std.debug.print("delete source {s}\n", .{entry.key_ptr.*}); + entry.value_ptr.*.deinit(self.allocator); + names[i] = entry.key_ptr.*; + i += 1; + } + } + + for (names[0..i]) |name| { + _ = self.sources.remove(name); + self.allocator.free(name); + } + while (c.lo_server_recv_noblock(self.server, 0) > 0) {} } @@ -242,20 +222,25 @@ pub const ControlServer = struct { fn set_texture( self: *ControlServer, - dest: *?*gl.Texture, + dest: []?*gl.Texture, texture_type: gl.Texture.Type, types: []const u8, argv: []const [*c]c.lo_arg, ) !void { - if (types.len != 1 or types[0] != 's') return error.invalidType; + try verify_args_all('s', types); - const nameZ: [*:0]const u8 = @ptrCast(&argv[0].*.s); - const name = std.mem.span(nameZ); + if (types.len != dest.len) + return error.sizeMismatch; - const source = self.sources.get(name) orelse return error.texNotFound; - if (source.texture.type != texture_type) return error.wrongTextureType; + for (argv, dest) |arg, *tex| { + const nameZ: [*:0]const u8 = @ptrCast(&arg.*.s); + const name = std.mem.span(nameZ); - dest.* = &source.texture; + const source = self.sources.get(name) orelse return error.texNotFound; + if (source.texture.type != texture_type) return error.wrongTextureType; + + tex.* = &source.texture; + } } fn handle_uniform(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool { @@ -270,7 +255,7 @@ pub const ControlServer = struct { break :blk try self.cache.get(nameZ) orelse return false; }; - var value = (uniform.value orelse unreachable).getPointer(); + var value = uniform.value; while (parts.next()) |component| { const i = switch (component[0]) { 'x', 'r', 's' => 0, @@ -286,6 +271,7 @@ pub const ControlServer = struct { return error.invalidIndex; } } + value = value.flatten(); if (std.mem.eql(u8, types, "s")) { const param_stringZ: [*:0]const u8 = @ptrCast(&argv[0].*.s); @@ -304,44 +290,12 @@ pub const ControlServer = struct { } try switch (value) { - .FLOAT => |val| set_one(f32, val, argv, types), - .DOUBLE => |val| set_one(f64, val, argv, types), - .INT => |val| set_one(i32, val, argv, types), - .UNSIGNED_INT => |val| set_one(u32, val, argv, types), - .BOOL => |val| set_one(bool, val, argv, types), - .FLOAT_VEC2 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_VEC3 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_VEC4 => |val| set_array(f32, val.*[0..], argv, types), - .DOUBLE_VEC2 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_VEC3 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_VEC4 => |val| set_array(f64, val.*[0..], argv, types), - .INT_VEC2 => |val| set_array(i32, val.*[0..], argv, types), - .INT_VEC3 => |val| set_array(i32, val.*[0..], argv, types), - .INT_VEC4 => |val| set_array(i32, val.*[0..], argv, types), - .UNSIGNED_INT_VEC2 => |val| set_array(u32, val.*[0..], argv, types), - .UNSIGNED_INT_VEC3 => |val| set_array(u32, val.*[0..], argv, types), - .UNSIGNED_INT_VEC4 => |val| set_array(u32, val.*[0..], argv, types), - .BOOL_VEC2 => |val| set_array(bool, val.*[0..], argv, types), - .BOOL_VEC3 => |val| set_array(bool, val.*[0..], argv, types), - .BOOL_VEC4 => |val| set_array(bool, val.*[0..], argv, types), - .FLOAT_MAT2 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_MAT3 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_MAT4 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_MAT2x3 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_MAT2x4 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_MAT3x2 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_MAT3x4 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_MAT4x2 => |val| set_array(f32, val.*[0..], argv, types), - .FLOAT_MAT4x3 => |val| set_array(f32, val.*[0..], argv, types), - .DOUBLE_MAT2 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_MAT3 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_MAT4 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_MAT2x3 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_MAT2x4 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_MAT3x2 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_MAT3x4 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_MAT4x2 => |val| set_array(f64, val.*[0..], argv, types), - .DOUBLE_MAT4x3 => |val| set_array(f64, val.*[0..], argv, types), + inline .FLOAT, + .DOUBLE, + .INT, + .UNSIGNED_INT, + .BOOL, + => |val| set_array(@TypeOf(val[0]), val, argv, types), .SAMPLER_2D, .SAMPLER_2D_SHADOW, diff --git a/src/ffmpeg.zig b/src/ffmpeg.zig index 37b8d69..af742b2 100644 --- a/src/ffmpeg.zig +++ b/src/ffmpeg.zig @@ -425,6 +425,7 @@ pub const StreamSource = struct { self.* = .{ .source = .{ .texture = texture, + .update_fn = update_source, .deinit_fn = deinit, .register_fn = register_methods, .unregister_fn = unregister_methods, @@ -448,6 +449,12 @@ pub const StreamSource = struct { return &self.source; } + fn update_source(source: *src.Source) !bool { + const self: *StreamSource = @fieldParentPtr("source", source); + if (self.thread.has_quit) return true; + return false; + } + fn register_methods(source: *src.Source, name: []const u8, control: *ctrl.ControlServer) void { const self: *StreamSource = @fieldParentPtr("source", source); self.flags.register(name, control); @@ -462,11 +469,12 @@ pub const StreamSource = struct { if (!std.mem.eql(u8, param, "offset")) return error.unknownSourceParam; const frame = @rem(self.frame + self.depth - 1, self.depth); + if (value.arrayLength() != 1) return error.uniformNotSupported; try switch (value) { - .FLOAT => |val| val.* = @as(f32, @floatFromInt(frame)) / @as(f32, @floatFromInt(self.depth)), - .DOUBLE => |val| val.* = @as(f64, @floatFromInt(frame)) / @as(f64, @floatFromInt(self.depth)), - .INT => |val| val.* = frame, - .UNSIGNED_INT => |val| val.* = @intCast(frame), + .FLOAT => |val| val[0] = @as(f32, @floatFromInt(frame)) / @as(f32, @floatFromInt(self.depth)), + .DOUBLE => |val| val[0] = @as(f64, @floatFromInt(frame)) / @as(f64, @floatFromInt(self.depth)), + .INT => |val| val[0] = frame, + .UNSIGNED_INT => |val| val[0] = @intCast(frame), else => error.uniformNotSupported, }; } @@ -255,215 +255,214 @@ const UniformType = enum(c.GLint) { UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = c.GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, UNSIGNED_INT_SAMPLER_BUFFER = c.GL_UNSIGNED_INT_SAMPLER_BUFFER, UNSIGNED_INT_SAMPLER_2D_RECT = c.GL_UNSIGNED_INT_SAMPLER_2D_RECT, -}; -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: ?*Texture, - SAMPLER_2D: ?*Texture, - SAMPLER_3D: ?*Texture, - SAMPLER_CUBE: ?*Texture, - SAMPLER_1D_SHADOW: ?*Texture, - SAMPLER_2D_SHADOW: ?*Texture, - SAMPLER_1D_ARRAY: ?*Texture, - SAMPLER_2D_ARRAY: ?*Texture, - SAMPLER_1D_ARRAY_SHADOW: ?*Texture, - SAMPLER_2D_ARRAY_SHADOW: ?*Texture, - SAMPLER_2D_MULTISAMPLE: ?*Texture, - SAMPLER_2D_MULTISAMPLE_ARRAY: ?*Texture, - SAMPLER_CUBE_SHADOW: ?*Texture, - SAMPLER_BUFFER: ?*Texture, - SAMPLER_2D_RECT: ?*Texture, - SAMPLER_2D_RECT_SHADOW: ?*Texture, - INT_SAMPLER_1D: ?*Texture, - INT_SAMPLER_2D: ?*Texture, - INT_SAMPLER_3D: ?*Texture, - INT_SAMPLER_CUBE: ?*Texture, - INT_SAMPLER_1D_ARRAY: ?*Texture, - INT_SAMPLER_2D_ARRAY: ?*Texture, - INT_SAMPLER_2D_MULTISAMPLE: ?*Texture, - INT_SAMPLER_2D_MULTISAMPLE_ARRAY: ?*Texture, - INT_SAMPLER_BUFFER: ?*Texture, - INT_SAMPLER_2D_RECT: ?*Texture, - UNSIGNED_INT_SAMPLER_1D: ?*Texture, - UNSIGNED_INT_SAMPLER_2D: ?*Texture, - UNSIGNED_INT_SAMPLER_3D: ?*Texture, - UNSIGNED_INT_SAMPLER_CUBE: ?*Texture, - UNSIGNED_INT_SAMPLER_1D_ARRAY: ?*Texture, - UNSIGNED_INT_SAMPLER_2D_ARRAY: ?*Texture, - UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: ?*Texture, - UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: ?*Texture, - UNSIGNED_INT_SAMPLER_BUFFER: ?*Texture, - UNSIGNED_INT_SAMPLER_2D_RECT: ?*Texture, - - // pub fn deinit(self: *const UniformValue) void { - // switch (self.*) { - // .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| { - // // if (value) |texture| texture.destroy(); - // _ = value; - // }, - // else => {}, - // } - // } - - pub fn getPointer(self: *UniformValue) UniformPointer { - return switch (self.*) { - inline else => |*value, tag| @unionInit(UniformPointer, @tagName(tag), value), + pub fn nestedType(self: UniformType) ?UniformType { + return switch (self) { + .FLOAT_VEC2, .FLOAT_VEC3, .FLOAT_VEC4 => .FLOAT, + .DOUBLE_VEC2, .DOUBLE_VEC3, .DOUBLE_VEC4 => .DOUBLE, + .INT_VEC2, .INT_VEC3, .INT_VEC4 => .INT, + .UNSIGNED_INT_VEC2, .UNSIGNED_INT_VEC3, .UNSIGNED_INT_VEC4 => .UNSIGNED_INT, + .BOOL_VEC2, .BOOL_VEC3, .BOOL_VEC4 => .BOOL, + .FLOAT_MAT2, .FLOAT_MAT3x2, .FLOAT_MAT4x2 => .FLOAT_VEC2, + .FLOAT_MAT2x3, .FLOAT_MAT3, .FLOAT_MAT4x3 => .FLOAT_VEC3, + .FLOAT_MAT2x4, .FLOAT_MAT3x4, .FLOAT_MAT4 => .FLOAT_VEC4, + .DOUBLE_MAT2, .DOUBLE_MAT3x2, .DOUBLE_MAT4x2 => .DOUBLE_VEC2, + .DOUBLE_MAT2x3, .DOUBLE_MAT3, .DOUBLE_MAT4x3 => .DOUBLE_VEC3, + .DOUBLE_MAT2x4, .DOUBLE_MAT3x4, .DOUBLE_MAT4 => .DOUBLE_VEC4, + else => null, + }; + } + + pub fn asType(self: UniformType) type { + return switch (self) { + .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, + .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, + => ?*Texture, }; } }; pub const UniformPointer = 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: *?*Texture, - SAMPLER_2D: *?*Texture, - SAMPLER_3D: *?*Texture, - SAMPLER_CUBE: *?*Texture, - SAMPLER_1D_SHADOW: *?*Texture, - SAMPLER_2D_SHADOW: *?*Texture, - SAMPLER_1D_ARRAY: *?*Texture, - SAMPLER_2D_ARRAY: *?*Texture, - SAMPLER_1D_ARRAY_SHADOW: *?*Texture, - SAMPLER_2D_ARRAY_SHADOW: *?*Texture, - SAMPLER_2D_MULTISAMPLE: *?*Texture, - SAMPLER_2D_MULTISAMPLE_ARRAY: *?*Texture, - SAMPLER_CUBE_SHADOW: *?*Texture, - SAMPLER_BUFFER: *?*Texture, - SAMPLER_2D_RECT: *?*Texture, - SAMPLER_2D_RECT_SHADOW: *?*Texture, - INT_SAMPLER_1D: *?*Texture, - INT_SAMPLER_2D: *?*Texture, - INT_SAMPLER_3D: *?*Texture, - INT_SAMPLER_CUBE: *?*Texture, - INT_SAMPLER_1D_ARRAY: *?*Texture, - INT_SAMPLER_2D_ARRAY: *?*Texture, - INT_SAMPLER_2D_MULTISAMPLE: *?*Texture, - INT_SAMPLER_2D_MULTISAMPLE_ARRAY: *?*Texture, - INT_SAMPLER_BUFFER: *?*Texture, - INT_SAMPLER_2D_RECT: *?*Texture, - UNSIGNED_INT_SAMPLER_1D: *?*Texture, - UNSIGNED_INT_SAMPLER_2D: *?*Texture, - UNSIGNED_INT_SAMPLER_3D: *?*Texture, - UNSIGNED_INT_SAMPLER_CUBE: *?*Texture, - UNSIGNED_INT_SAMPLER_1D_ARRAY: *?*Texture, - UNSIGNED_INT_SAMPLER_2D_ARRAY: *?*Texture, - UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: *?*Texture, - UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: *?*Texture, - UNSIGNED_INT_SAMPLER_BUFFER: *?*Texture, - UNSIGNED_INT_SAMPLER_2D_RECT: *?*Texture, - - pub fn index(self: *const UniformPointer, i: u8) !UniformPointer { - const length: u8 = switch (self.*) { + 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: []?*Texture, + SAMPLER_2D: []?*Texture, + SAMPLER_3D: []?*Texture, + SAMPLER_CUBE: []?*Texture, + SAMPLER_1D_SHADOW: []?*Texture, + SAMPLER_2D_SHADOW: []?*Texture, + SAMPLER_1D_ARRAY: []?*Texture, + SAMPLER_2D_ARRAY: []?*Texture, + SAMPLER_1D_ARRAY_SHADOW: []?*Texture, + SAMPLER_2D_ARRAY_SHADOW: []?*Texture, + SAMPLER_2D_MULTISAMPLE: []?*Texture, + SAMPLER_2D_MULTISAMPLE_ARRAY: []?*Texture, + SAMPLER_CUBE_SHADOW: []?*Texture, + SAMPLER_BUFFER: []?*Texture, + SAMPLER_2D_RECT: []?*Texture, + SAMPLER_2D_RECT_SHADOW: []?*Texture, + INT_SAMPLER_1D: []?*Texture, + INT_SAMPLER_2D: []?*Texture, + INT_SAMPLER_3D: []?*Texture, + INT_SAMPLER_CUBE: []?*Texture, + INT_SAMPLER_1D_ARRAY: []?*Texture, + INT_SAMPLER_2D_ARRAY: []?*Texture, + INT_SAMPLER_2D_MULTISAMPLE: []?*Texture, + INT_SAMPLER_2D_MULTISAMPLE_ARRAY: []?*Texture, + INT_SAMPLER_BUFFER: []?*Texture, + INT_SAMPLER_2D_RECT: []?*Texture, + UNSIGNED_INT_SAMPLER_1D: []?*Texture, + UNSIGNED_INT_SAMPLER_2D: []?*Texture, + UNSIGNED_INT_SAMPLER_3D: []?*Texture, + UNSIGNED_INT_SAMPLER_CUBE: []?*Texture, + UNSIGNED_INT_SAMPLER_1D_ARRAY: []?*Texture, + UNSIGNED_INT_SAMPLER_2D_ARRAY: []?*Texture, + UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: []?*Texture, + UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: []?*Texture, + UNSIGNED_INT_SAMPLER_BUFFER: []?*Texture, + UNSIGNED_INT_SAMPLER_2D_RECT: []?*Texture, + + pub fn arrayLength(self: *const UniformPointer) usize { + return switch (self.*) { + inline else => |e| e.len, + }; + } + + pub fn flatten(self: *const UniformPointer) UniformPointer { + switch (self.*) { + inline else => |value, tag| { + if (comptime tag.nestedType()) |inner| { + const Inner = inner.asType(); + const inside: [*]Inner = @ptrCast(&value[0][0]); + const len = value.len * value[0].len; + return @unionInit(UniformPointer, @tagName(inner), inside[0..len]); + } else { + return self.*; + } + }, + } + } + + pub fn index(self: *const UniformPointer, i: usize) !UniformPointer { + const array_len = self.arrayLength(); + + if (array_len > 1) { + if (i >= array_len) return error.invalidIndex; + + return switch (self.*) { + inline else => |value, tag| @unionInit(UniformPointer, @tagName(tag), value[i .. i + 1]), + }; + } + + const length: usize = 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, @@ -486,7 +485,7 @@ pub const UniformPointer = union(UniformType) { }; pub const CachedUniform = struct { - value: ?*UniformValue, + value: UniformPointer, location: c.GLint, pub fn init( @@ -502,26 +501,28 @@ pub 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 _u_type: c.GLint = undefined; + var u_size: c.GLint = undefined; + c.glGetActiveUniformsiv(shader.program_id, 1, &index, c.GL_UNIFORM_TYPE, &_u_type); + c.glGetActiveUniformsiv(shader.program_id, 1, &index, c.GL_UNIFORM_SIZE, &u_size); - switch (@as(UniformType, @enumFromInt(_utype))) { - inline else => |utype| { + switch (@as(UniformType, @enumFromInt(_u_type))) { + inline else => |u_type| { const location = try shader.uniformLocation(nameZ); - const value = try allocator.create(UniformValue); - errdefer allocator.destroy(value); + const buffer = try allocator.alloc(u_type.asType(), @intCast(u_size)); + errdefer allocator.free(buffer); - value.* = @unionInit(UniformValue, @tagName(utype), undefined); - return .{ .value = value, .location = location }; + const value = @unionInit(UniformPointer, @tagName(u_type), buffer); + var self = CachedUniform{ .value = value, .location = location }; + self.getShaderValue(shader); + return self; }, } } pub fn deinit(self: *CachedUniform, allocator: std.mem.Allocator) void { - if (self.value) |value| { - // value.deinit(); - allocator.destroy(value); - self.value = null; + switch (self.value) { + inline else => |buffer| allocator.free(buffer), } } @@ -530,57 +531,71 @@ pub const CachedUniform = struct { dest: *CachedUniform, allocator: std.mem.Allocator, ) bool { - if (@as(UniformType, self.value.?.*) != dest.value.?.*) return false; + if (@as(UniformType, self.value) != dest.value or + self.value.arrayLength() != dest.value.arrayLength()) + { + self.deinit(allocator); + return false; + } - dest.deinit(allocator); - dest.value = self.value; - self.value = null; + std.mem.swap(UniformPointer, &self.value, &dest.value); + self.deinit(allocator); return true; } + fn flatPointer(comptime Inner: type, value: anytype) [*]Inner { + switch (@typeInfo(@TypeOf(value))) { + .pointer => |pointer| { + if (pointer.child == Inner) return @ptrCast(value); + return flatPointer(Inner, &value[0]); + }, + inline else => @compileError("type not found in flatPointer"), + } + } + pub fn setShaderValue(self: *const CachedUniform, shader: ShaderProgram) void { const program = shader.program_id; 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), + switch (self.value) { + .FLOAT => |value| c.glProgramUniform1fv(program, location, @intCast(value.len), value.ptr), + .FLOAT_VEC2 => |value| c.glProgramUniform2fv(program, location, @intCast(value.len), flatPointer(f32, value)), + .FLOAT_VEC3 => |value| c.glProgramUniform3fv(program, location, @intCast(value.len), flatPointer(f32, value)), + .FLOAT_VEC4 => |value| c.glProgramUniform4fv(program, location, @intCast(value.len), flatPointer(f32, value)), + .DOUBLE => |value| c.glProgramUniform1dv(program, location, @intCast(value.len), value.ptr), + .DOUBLE_VEC2 => |value| c.glProgramUniform1dv(program, location, @intCast(value.len), flatPointer(f64, value)), + .DOUBLE_VEC3 => |value| c.glProgramUniform2dv(program, location, @intCast(value.len), flatPointer(f64, value)), + .DOUBLE_VEC4 => |value| c.glProgramUniform3dv(program, location, @intCast(value.len), flatPointer(f64, value)), + .INT => |value| c.glProgramUniform1iv(program, location, @intCast(value.len), value.ptr), + .INT_VEC2 => |value| c.glProgramUniform2iv(program, location, @intCast(value.len), flatPointer(c_int, value)), + .INT_VEC3 => |value| c.glProgramUniform3iv(program, location, @intCast(value.len), flatPointer(c_int, value)), + .INT_VEC4 => |value| c.glProgramUniform4iv(program, location, @intCast(value.len), flatPointer(c_int, value)), + .UNSIGNED_INT => |value| c.glProgramUniform1uiv(program, location, @intCast(value.len), value.ptr), + .UNSIGNED_INT_VEC2 => |value| c.glProgramUniform2uiv(program, location, @intCast(value.len), flatPointer(c_uint, value)), + .UNSIGNED_INT_VEC3 => |value| c.glProgramUniform3uiv(program, location, @intCast(value.len), flatPointer(c_uint, value)), + .UNSIGNED_INT_VEC4 => |value| c.glProgramUniform4uiv(program, location, @intCast(value.len), flatPointer(c_uint, value)), + .BOOL => |value| c.glProgramUniform1uiv(program, location, @intCast(value.len), value.ptr), + .BOOL_VEC2 => |value| c.glProgramUniform2uiv(program, location, @intCast(value.len), flatPointer(c_uint, value)), + .BOOL_VEC3 => |value| c.glProgramUniform3uiv(program, location, @intCast(value.len), flatPointer(c_uint, value)), + .BOOL_VEC4 => |value| c.glProgramUniform4uiv(program, location, @intCast(value.len), flatPointer(c_uint, value)), + .FLOAT_MAT2 => |value| c.glProgramUniformMatrix2fv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f32, value)), + .FLOAT_MAT3 => |value| c.glProgramUniformMatrix3fv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f32, value)), + .FLOAT_MAT4 => |value| c.glProgramUniformMatrix4fv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f32, value)), + .FLOAT_MAT2x3 => |value| c.glProgramUniformMatrix2x3fv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f32, value)), + .FLOAT_MAT2x4 => |value| c.glProgramUniformMatrix2x4fv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f32, value)), + .FLOAT_MAT3x2 => |value| c.glProgramUniformMatrix3x2fv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f32, value)), + .FLOAT_MAT3x4 => |value| c.glProgramUniformMatrix3x4fv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f32, value)), + .FLOAT_MAT4x2 => |value| c.glProgramUniformMatrix4x2fv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f32, value)), + .FLOAT_MAT4x3 => |value| c.glProgramUniformMatrix4x3fv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f32, value)), + .DOUBLE_MAT2 => |value| c.glProgramUniformMatrix2dv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f64, value)), + .DOUBLE_MAT3 => |value| c.glProgramUniformMatrix3dv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f64, value)), + .DOUBLE_MAT4 => |value| c.glProgramUniformMatrix4dv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f64, value)), + .DOUBLE_MAT2x3 => |value| c.glProgramUniformMatrix2x3dv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f64, value)), + .DOUBLE_MAT2x4 => |value| c.glProgramUniformMatrix2x4dv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f64, value)), + .DOUBLE_MAT3x2 => |value| c.glProgramUniformMatrix3x2dv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f64, value)), + .DOUBLE_MAT3x4 => |value| c.glProgramUniformMatrix3x4dv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f64, value)), + .DOUBLE_MAT4x2 => |value| c.glProgramUniformMatrix4x2dv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f64, value)), + .DOUBLE_MAT4x3 => |value| c.glProgramUniformMatrix4x3dv(program, location, @intCast(value.len), c.GL_FALSE, flatPointer(f64, value)), .SAMPLER_1D, .SAMPLER_2D, .SAMPLER_3D, @@ -617,10 +632,12 @@ pub const CachedUniform = struct { .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .UNSIGNED_INT_SAMPLER_BUFFER, .UNSIGNED_INT_SAMPLER_2D_RECT, - => |value| { - if (value) |texture| { - const index = texture.bind(); - c.glProgramUniform1i(program, location, @intCast(index)); + => |values| { + for (values) |value| { + if (value) |texture| { + const index = texture.bind(); + c.glProgramUniform1i(program, location, @intCast(index)); + } } }, } @@ -630,45 +647,49 @@ pub const CachedUniform = struct { const program = shader.program_id; 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), + switch (self.value) { + inline .FLOAT, + .FLOAT_VEC2, + .FLOAT_VEC3, + .FLOAT_VEC4, + .FLOAT_MAT2, + .FLOAT_MAT3, + .FLOAT_MAT4, + .FLOAT_MAT2x3, + .FLOAT_MAT2x4, + .FLOAT_MAT3x2, + .FLOAT_MAT3x4, + .FLOAT_MAT4x2, + .FLOAT_MAT4x3, + => |value| c.glGetUniformfv(program, location, flatPointer(f32, value)), + inline .DOUBLE, + .DOUBLE_VEC2, + .DOUBLE_VEC3, + .DOUBLE_VEC4, + .DOUBLE_MAT2, + .DOUBLE_MAT3, + .DOUBLE_MAT4, + .DOUBLE_MAT2x3, + .DOUBLE_MAT2x4, + .DOUBLE_MAT3x2, + .DOUBLE_MAT3x4, + .DOUBLE_MAT4x2, + .DOUBLE_MAT4x3, + => |value| c.glGetUniformdv(program, location, flatPointer(f64, value)), + inline .INT, + .INT_VEC2, + .INT_VEC3, + .INT_VEC4, + => |value| c.glGetUniformiv(program, location, flatPointer(c_int, value)), + inline .UNSIGNED_INT, + .UNSIGNED_INT_VEC2, + .UNSIGNED_INT_VEC3, + .UNSIGNED_INT_VEC4, + .BOOL, + .BOOL_VEC2, + .BOOL_VEC3, + .BOOL_VEC4, + => |value| c.glGetUniformuiv(program, location, flatPointer(c_uint, value)), .SAMPLER_1D, .SAMPLER_2D, .SAMPLER_3D, @@ -705,7 +726,11 @@ pub const CachedUniform = struct { .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .UNSIGNED_INT_SAMPLER_BUFFER, .UNSIGNED_INT_SAMPLER_2D_RECT, - => |*value| value.* = null, + => |values| { + for (values) |*value| { + value.* = null; + } + }, } } }; @@ -877,6 +902,7 @@ pub const Thread = struct { thread: std.Thread, window: *c.GLFWwindow, quit: bool, + has_quit: bool, pub fn init( allocator: std.mem.Allocator, @@ -891,6 +917,7 @@ pub const Thread = struct { .thread = undefined, .window = undefined, .quit = false, + .has_quit = false, }; thread.thread = try std.Thread.spawn( @@ -914,6 +941,7 @@ pub const Thread = struct { @call(.auto, f, args) catch |err| { std.debug.print("Error in thread: {}\n", .{err}); }; + self.has_quit = true; } }; @@ -921,8 +949,11 @@ pub const Thread = struct { } pub fn deinit(self: *Thread, allocator: std.mem.Allocator) void { - self.quit = true; - self.thread.join(); + if (!self.has_quit) { + self.quit = true; + self.thread.join(); + self.has_quit = true; + } c.glfwDestroyWindow(self.window); allocator.destroy(self); @@ -960,7 +991,6 @@ pub const UniformCache = struct { var uniform = CachedUniform.init(self.allocator, self.shader.*, name) catch return null; errdefer uniform.deinit(self.allocator); - uniform.getShaderValue(self.shader.*); try self.uniforms.put(cloned_name, uniform); } @@ -973,14 +1003,6 @@ pub const UniformCache = struct { pub fn refresh(self: *UniformCache) !void { var old_uniforms = self.uniforms.move(); - defer { - var it = old_uniforms.iterator(); - while (it.next()) |entry| { - self.allocator.free(entry.key_ptr.*); - entry.value_ptr.deinit(self.allocator); - } - old_uniforms.deinit(); - } { var it = old_uniforms.iterator(); @@ -989,9 +1011,19 @@ pub const UniformCache = struct { if (old_entry.value_ptr.tryMove(uniform, self.allocator)) { uniform.setShaderValue(self.shader.*); } + } else { + old_entry.value_ptr.deinit(self.allocator); } } } + + { + var it = old_uniforms.iterator(); + while (it.next()) |entry| { + self.allocator.free(entry.key_ptr.*); + } + old_uniforms.deinit(); + } } }; diff --git a/src/source.zig b/src/source.zig index 917e08a..6a3781c 100644 --- a/src/source.zig +++ b/src/source.zig @@ -6,6 +6,7 @@ const util = @import("util.zig"); pub const Source = struct { texture: gl.Texture, + update_fn: ?*const fn (self: *Source) anyerror!bool = null, deinit_fn: *const fn (self: *Source, allocator: std.mem.Allocator) void, register_fn: ?*const fn (self: *Source, name: []const u8, control: *ctrl.ControlServer) void = null, unregister_fn: ?*const fn (self: *Source, name: []const u8, control: *ctrl.ControlServer) void = null, @@ -27,6 +28,14 @@ pub const Source = struct { } } + pub fn update(self: *Source) bool { + if (self.update_fn) |update_fn| { + return update_fn(self) catch return true; + } + + return false; + } + pub fn updateUniform(self: *Source, param: []const u8, value: gl.UniformPointer) anyerror!void { if (self.update_uniform_fn) |update_uniform_fn| { try update_uniform_fn(self, param, value); diff --git a/src/tsv.zig b/src/tsv.zig index a199b90..fb5db96 100644 --- a/src/tsv.zig +++ b/src/tsv.zig @@ -47,6 +47,7 @@ pub const TSVSource = struct { self.* = .{ .source = .{ .texture = gl.Texture.create(texture_type), + .update_fn = update_source, .deinit_fn = deinit, }, .stream = .{}, @@ -61,6 +62,12 @@ pub const TSVSource = struct { return &self.source; } + fn update_source(source: *src.Source) !bool { + const self: *TSVSource = @fieldParentPtr("source", source); + if (self.thread.has_quit) return true; + return false; + } + fn deinit(source: *const src.Source, allocator: std.mem.Allocator) void { const self: *const TSVSource = @fieldParentPtr("source", source); |
