diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-01-27 10:46:00 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-01-27 10:46:00 +0000 |
| commit | cf949b0f27f051f1095e281671508caf7f535a83 (patch) | |
| tree | 978355253cc3529d3073b44cf5e73a7a9e659075 /src | |
| parent | break OSC in favor of uniform caching (diff) | |
| download | glsl-view-cf949b0f27f051f1095e281671508caf7f535a83.tar.gz glsl-view-cf949b0f27f051f1095e281671508caf7f535a83.zip | |
reimplement working OSC control
Diffstat (limited to 'src')
| -rw-r--r-- | src/control.zig | 70 | ||||
| -rw-r--r-- | src/gl.zig | 40 | ||||
| -rw-r--r-- | src/main.zig | 10 |
3 files changed, 75 insertions, 45 deletions
diff --git a/src/control.zig b/src/control.zig index cec6f80..b48feab 100644 --- a/src/control.zig +++ b/src/control.zig @@ -7,11 +7,13 @@ const param_prefix = "/param/"; pub const ControlServer = struct { server: c.lo_server, - shader: gl.ShaderProgram, + cache: *gl.UniformCache, - pub fn init(allocator: *std.mem.Allocator, config: cfg.OSCConfig) !*ControlServer { + pub fn init(allocator: *std.mem.Allocator, config: cfg.OSCConfig, cache: *gl.UniformCache) !*ControlServer { var self: *ControlServer = try allocator.create(ControlServer); + self.cache = cache; + switch (config) { .Manual => |conf| { var port = [_]u8{0} ** 6; @@ -40,8 +42,7 @@ pub const ControlServer = struct { return self; } - pub fn update(self: *ControlServer, shader: gl.ShaderProgram) void { - self.shader = shader; + pub fn update(self: *ControlServer) void { while (c.lo_server_recv_noblock(self.server, 0) > 0) {} } @@ -64,31 +65,42 @@ pub const ControlServer = struct { return 1; } - const name_slice = path["/param/".len .. path.len - "/set".len]; - // const uniform = self.shader.uniformLocation(name) catch { - // std.debug.warn("param {s} doesn't exist\n", .{uniform_name}); - // return 0; - // }; - - // if (std.mem.eql(u8, types, "f")) { - // self.shader.setUniform1f(uniform, argv[0].*.f); - // } else if (std.mem.eql(u8, types, "ff")) { - // self.shader.setUniform2f(uniform, argv[0].*.f, argv[1].*.f); - // } else if (std.mem.eql(u8, types, "fff")) { - // self.shader.setUniform3f(uniform, argv[0].*.f, argv[1].*.f, argv[2].*.f); - // } else if (std.mem.eql(u8, types, "ffff")) { - // self.shader.setUniform4f(uniform, argv[0].*.f, argv[1].*.f, argv[2].*.f, argv[3].*.f); - // } else if (std.mem.eql(u8, types, "i")) { - // self.shader.setUniform1i(uniform, argv[0].*.i); - // } else if (std.mem.eql(u8, types, "ii")) { - // self.shader.setUniform2i(uniform, argv[0].*.i, argv[1].*.i); - // } else if (std.mem.eql(u8, types, "iii")) { - // self.shader.setUniform3i(uniform, argv[0].*.i, argv[1].*.i, argv[2].*.i); - // } else if (std.mem.eql(u8, types, "iiii")) { - // self.shader.setUniform4i(uniform, argv[0].*.i, argv[1].*.i, argv[2].*.i, argv[3].*.i); - // } else { - // std.debug.warn("unsupported types: {s}\n", .{types}); - // } + const param_name = path["/param/".len .. path.len - "/set".len]; + var buffer: [256]u8 = undefined; + std.mem.copy(u8, buffer[0..], param_name); + buffer[param_name.len] = 0; + + if (self.cache.get(buffer[0 .. param_name.len + 1]) catch null) |uniform| { + if (std.mem.eql(u8, types, "f")) { + uniform.value.FLOAT = argv[0].*.f; + } else if (std.mem.eql(u8, types, "ff")) { + for (uniform.value.FLOAT_VEC2) |*dest, i| + dest.* = argv[i].*.f; + } else if (std.mem.eql(u8, types, "fff")) { + for (uniform.value.FLOAT_VEC3) |*dest, i| + dest.* = argv[i].*.f; + } else if (std.mem.eql(u8, types, "ffff")) { + for (uniform.value.FLOAT_VEC4) |*dest, i| + dest.* = argv[i].*.f; + } else if (std.mem.eql(u8, types, "i")) { + uniform.value.INT = argv[0].*.i; + } else if (std.mem.eql(u8, types, "ii")) { + for (uniform.value.INT_VEC2) |*dest, i| + dest.* = argv[i].*.i; + } else if (std.mem.eql(u8, types, "iii")) { + for (uniform.value.INT_VEC3) |*dest, i| + dest.* = argv[i].*.i; + } else if (std.mem.eql(u8, types, "iiii")) { + for (uniform.value.INT_VEC4) |*dest, i| + dest.* = argv[i].*.i; + } else { + std.debug.warn("unsupported types: {s}\n", .{types}); + return 0; + } + uniform.setShaderValue(self.cache.shader.*); + } else { + std.debug.warn("param {s} doesn't exist\n", .{param_name}); + } return 0; } @@ -355,17 +355,25 @@ pub const ShaderProgram = struct { }; pub const UniformCache = struct { - uniforms: std.AutoHashMap([*]const u8, CachedUniform), + allocator: *std.mem.Allocator, + uniforms: std.StringHashMap(CachedUniform), shader: *ShaderProgram, pub fn init(allocator: *std.mem.Allocator, shader: *ShaderProgram) UniformCache { return UniformCache{ - .uniforms = std.AutoHashMap([*]const u8, CachedUniform).init(allocator), + .allocator = allocator, + .uniforms = std.StringHashMap(CachedUniform).init(allocator), .shader = shader, }; } pub fn deinit(self: *UniformCache) void { + var it = self.uniforms.iterator(); + while (it.next()) |entry| { + self.allocator.free(entry.key); + } + + self.uniforms.clear(); self.uniforms.deinit(); } @@ -374,8 +382,10 @@ pub const UniformCache = struct { c.glGetProgramiv(self.shader.program_id, c.GL_ACTIVE_UNIFORMS, &uniform_count); const count = self.uniforms.count(); - var existing_names = try c_allocator.alloc([*]const u8, count); + var existing_names = try c_allocator.alloc([]const u8, count); defer c_allocator.free(existing_names); + var existing_names_c = try c_allocator.alloc([*]const u8, count); + defer c_allocator.free(existing_names_c); var existing_indices = try c_allocator.alloc(c.GLuint, count); defer c_allocator.free(existing_indices); @@ -384,30 +394,38 @@ pub const UniformCache = struct { var i: usize = 0; while (it.next()) |entry| { existing_names[i] = entry.key; + existing_names_c[i] = entry.key.ptr; i += 1; } } - c.glGetUniformIndices(self.shader.program_id, @intCast(c.GLsizei, count), existing_names.ptr, existing_indices.ptr); + c.glGetUniformIndices(self.shader.program_id, @intCast(c.GLsizei, count), existing_names_c.ptr, existing_indices.ptr); for (existing_indices) |index, i| { const name = existing_names[i]; if (index == c.GL_INVALID_INDEX) { - _ = self.uniforms.remove(name); - // @TODO: remove OSC link + if (self.uniforms.remove(name)) |removed| { + // @TODO: remove OSC link + self.allocator.free(removed.key); + } } else { var uniform = self.uniforms.get(name).?.value; - uniform.location = self.shader.uniformLocation(name) catch unreachable; + uniform.location = self.shader.uniformLocation(name.ptr) catch unreachable; uniform.setShaderValue(self.shader.*); } } } - pub fn get(self: *UniformCache, name: [*]const u8) !?*CachedUniform { - var result = try self.uniforms.getOrPut(name); + // name has to be zero-terminated! + pub fn get(self: *UniformCache, name: []const u8) !?*CachedUniform { + const cloned_name = try std.mem.dupe(self.allocator, u8, name); + errdefer self.allocator.free(cloned_name); + + var result = try self.uniforms.getOrPut(cloned_name); if (!result.found_existing) { - result.kv.value = CachedUniform.init(self.shader.*, name) catch { - _ = self.uniforms.remove(name); + result.kv.value = CachedUniform.init(self.shader.*, name.ptr) catch { + _ = self.uniforms.remove(cloned_name); + self.allocator.free(cloned_name); return null; }; // @TODO: add OSC link diff --git a/src/main.zig b/src/main.zig index 37104da..3cec2c7 100644 --- a/src/main.zig +++ b/src/main.zig @@ -96,6 +96,9 @@ pub fn main() !void { ); defer main_program.destroy(); + var fbo = try gl.FramebufferObject.create(config.width, config.height); + defer fbo.destroy(); + const shader_file = try fs.cwd().openFile(config.fragment, .{}); var last_stat = try shader_file.stat(); try reloadShader(&main_program, shader_file, last_stat.size); @@ -103,10 +106,7 @@ pub fn main() !void { var cache = gl.UniformCache.init(std.heap.c_allocator, &main_program); defer cache.deinit(); - var fbo = try gl.FramebufferObject.create(config.width, config.height); - defer fbo.destroy(); - - const control = try ctrl.ControlServer.init(&arena.allocator, config.osc); + const control = try ctrl.ControlServer.init(&arena.allocator, config.osc, &cache); defer control.destroy(); _ = try cache.get("radius\x00"); @@ -131,7 +131,7 @@ pub fn main() !void { offset.setShaderValue(main_program); } - control.update(main_program); + control.update(); fbo.bind(); c.glClear(c.GL_COLOR_BUFFER_BIT); |
