aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2026-01-10 16:06:04 +0000
committers-ol <s+removethis@s-ol.nu>2026-01-10 16:51:43 +0000
commit60db3b8a87b4d356ab3c2c43e24a2c060961cd96 (patch)
treef3a6bae422d3182732d6265efd7c92cc0e246940
parentn outputs (diff)
downloadglsl-view-60db3b8a87b4d356ab3c2c43e24a2c060961cd96.tar.gz
glsl-view-60db3b8a87b4d356ab3c2c43e24a2c060961cd96.zip
pipe raw video to stdout
-rw-r--r--src/control.zig7
-rw-r--r--src/gl.zig15
-rw-r--r--src/main.zig20
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;
}
diff --git a/src/gl.zig b/src/gl.zig
index 7cdc204..2c7c865 100644
--- a/src/gl.zig
+++ b/src/gl.zig
@@ -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| {