diff options
| author | s-ol <s+removethis@s-ol.nu> | 2026-01-10 16:06:04 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2026-01-10 16:51:43 +0000 |
| commit | 60db3b8a87b4d356ab3c2c43e24a2c060961cd96 (patch) | |
| tree | f3a6bae422d3182732d6265efd7c92cc0e246940 | |
| parent | n outputs (diff) | |
| download | glsl-view-60db3b8a87b4d356ab3c2c43e24a2c060961cd96.tar.gz glsl-view-60db3b8a87b4d356ab3c2c43e24a2c060961cd96.zip | |
pipe raw video to stdout
| -rw-r--r-- | src/control.zig | 7 | ||||
| -rw-r--r-- | src/gl.zig | 15 | ||||
| -rw-r--r-- | src/main.zig | 20 |
3 files changed, 40 insertions, 2 deletions
diff --git a/src/control.zig b/src/control.zig index 053f985..9810645 100644 --- a/src/control.zig +++ b/src/control.zig @@ -110,6 +110,8 @@ pub const ControlServer = struct { progress: std.Progress.Node, allocator: std.mem.Allocator, + dirty: bool, + pub fn init( allocator: std.mem.Allocator, progress: std.Progress.Node, @@ -127,6 +129,8 @@ pub const ControlServer = struct { .constants = constants, .progress = progress, .allocator = allocator, + + .dirty = false, }; self.server = c.lo_server_new_from_url(config.osc.ptr, handle_error); @@ -221,7 +225,8 @@ pub const ControlServer = struct { const code: [*:0]const u8 = @ptrCast(&argv[0].*.s); try self.cache.shader.loadString(std.mem.span(code)); try self.cache.refresh(); - std.debug.print("reloaded\n", .{}); + self.dirty = true; + return true; } @@ -1008,6 +1008,21 @@ pub const FramebufferObject = struct { c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0); } + pub fn read(self: FramebufferObject, width: c.GLint, height: c.GLint, data: []u8) void { + _ = self; + c.glReadBuffer(c.GL_COLOR_ATTACHMENT0); + c.glReadnPixels( + 0, + 0, + width, + height, + c.GL_RGBA, + c.GL_UNSIGNED_BYTE, + @intCast(data.len), + data.ptr, + ); + } + pub fn create(width: i32, height: i32) !FramebufferObject { var self: FramebufferObject = undefined; c.glGenFramebuffers(1, &self.buffer_id); diff --git a/src/main.zig b/src/main.zig index 6d70a14..fbe006e 100644 --- a/src/main.zig +++ b/src/main.zig @@ -118,6 +118,15 @@ pub fn main() !void { defer control.destroy(); var loops: u8 = 0; + + const stdout = std.fs.File.stdout(); + var tex_buffer: ?[]u8 = null; + + if (!stdout.isTty()) { + tex_buffer = try std.heap.c_allocator.alloc(u8, @intCast(config.width * config.height * 4)); + } + defer if (tex_buffer) |buf| std.heap.c_allocator.free(buf); + while (c.glfwWindowShouldClose(window) == c.GL_FALSE) { c.glfwMakeContextCurrent(window); @@ -135,7 +144,7 @@ pub fn main() !void { // control.reload_requested = false; // } - { + if (control.dirty) { c.glFinish(); var timer = try std.time.Timer.start(); @@ -144,6 +153,13 @@ pub fn main() !void { main_program.bind(); constants.normalized_quad.draw(); + + if (tex_buffer) |buf| { + fbo.read(config.width, config.height, buf); + std.debug.print("writing {} bytes\n", .{buf.len}); + _ = try stdout.write(buf); + } + fbo.unbind(); c.glFinish(); @@ -152,6 +168,8 @@ pub fn main() !void { if (loops == 0) { std.debug.print("\rrendered in {d:.2}ms\n", .{@as(f64, @floatFromInt(fps)) / std.time.ns_per_ms}); } + + control.dirty = false; } for (outputs.items, 0..) |output, i| { |
