aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2026-04-10 17:08:15 +0000
committers-ol <s+removethis@s-ol.nu>2026-04-10 22:22:45 +0000
commit5d3f9aef90bed7713ce07614fdd154d50223ba61 (patch)
treec6cfdc75e645773de14bf4cad8bbb89f60f267d6
parentmore TSV logging (diff)
downloadglsl-view-5d3f9aef90bed7713ce07614fdd154d50223ba61.tar.gz
glsl-view-5d3f9aef90bed7713ce07614fdd154d50223ba61.zip
support arrays of uniforms, remove finished sources
-rw-r--r--src/control.zig128
-rw-r--r--src/ffmpeg.zig16
-rw-r--r--src/gl.zig660
-rw-r--r--src/source.zig9
-rw-r--r--src/tsv.zig7
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,
};
}
diff --git a/src/gl.zig b/src/gl.zig
index 2c7c865..b5716c1 100644
--- a/src/gl.zig
+++ b/src/gl.zig
@@ -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);