diff --git a/scripts/wlbg/src/Gfx.zig b/scripts/wlbg/src/Gfx.zig index b2ff20f..20f37e3 100644 --- a/scripts/wlbg/src/Gfx.zig +++ b/scripts/wlbg/src/Gfx.zig @@ -2,6 +2,7 @@ const std = @import("std"); const c = @import("ffi.zig").c; const glutil = @import("glutil.zig"); +const options = @import("options.zig"); const OutputInfo = @import("OutputInfo.zig"); const OutputWindow = @import("OutputWindow.zig"); @@ -261,17 +262,19 @@ pub fn drawBackground( ) !void { // There's just about a 0% chance this works properly when monitors have different resolutions, // but I can't even begin thinking about that. - const xoff = @as(f32, @floatFromInt(info.x - base_off[0])) / @as(f32, @floatFromInt(info.width)); - const yoff = @as(f32, @floatFromInt(info.y - base_off[1])) / @as(f32, @floatFromInt(info.height)); + const off: struct { x: f32, y: f32 } = if (options.multihead_mode == .combined) .{ + .x = @as(f32, @floatFromInt(info.x - base_off[0])) / @as(f32, @floatFromInt(info.width)), + .y = @as(f32, @floatFromInt(info.y - base_off[1])) / @as(f32, @floatFromInt(info.height)), + } else .{ .x = 0, .y = 0 }; const vertices = [_]f32{ - -1.0, -1.0, 0.0, xoff, yoff, - 1.0, -1.0, 0.0, xoff, yoff, - 1.0, 1.0, 0.0, xoff, yoff, + -1.0, -1.0, 0.0, + 1.0, -1.0, 0.0, + 1.0, 1.0, 0.0, - -1.0, -1.0, 0.0, xoff, yoff, - 1.0, 1.0, 0.0, xoff, yoff, - -1.0, 1.0, 0.0, xoff, yoff, + -1.0, -1.0, 0.0, + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0, }; c.glBindFramebuffer(c.GL_FRAMEBUFFER, self.bg_bufs.get(output_idx).framebuffer); @@ -281,12 +284,10 @@ pub fn drawBackground( c.glUseProgram(self.bg_shader_program); - c.glVertexAttribPointer(0, 3, c.GL_FLOAT, c.GL_FALSE, @sizeOf(f32) * 5, &vertices); + c.glVertexAttribPointer(0, 3, c.GL_FLOAT, c.GL_FALSE, 0, &vertices); c.glEnableVertexAttribArray(0); - c.glVertexAttribPointer(1, 2, c.GL_FLOAT, c.GL_FALSE, @sizeOf(f32) * 5, @ptrFromInt(@intFromPtr(&vertices) + @sizeOf(f32) * 3)); - c.glEnableVertexAttribArray(1); - + c.glUniform2f(c.glGetUniformLocation(self.bg_shader_program, "offset"), off.x, off.y); c.glUniform1f(c.glGetUniformLocation(self.bg_shader_program, "time"), rand * 2000.0 - 1000.0); c.glDrawArrays(c.GL_TRIANGLES, 0, vertices.len / 3); diff --git a/scripts/wlbg/src/bg_frag.glsl b/scripts/wlbg/src/bg_frag.glsl index e5a89ba..a1aa5f3 100644 --- a/scripts/wlbg/src/bg_frag.glsl +++ b/scripts/wlbg/src/bg_frag.glsl @@ -3,67 +3,77 @@ precision highp float; uniform float time; -uniform vec2 offset; in vec2 fragCoord; -// shader: https://www.shadertoy.com/view/tsXBzS +// shader: https://www.shadertoy.com/view/ttKGDt -vec3 palette(float d){ - return mix(vec3(0.2,0.0,0.0),vec3(.5,0.,0.),d); +mat2 rot(float a) { + float c = cos(a), s = sin(a); + return mat2(c,s,-s,c); } -vec2 rotate(vec2 p,float a){ - float c = cos(a); - float s = sin(a); - return p*mat2(c,s,-s,c); +const float pi = acos(-1.0); +const float pi2 = pi*2.0; + +vec2 pmod(vec2 p, float r) { + float a = atan(p.x, p.y) + pi/r; + float n = pi2 / r; + a = floor(a/n)*n; + return p*rot(-a); } -float map(vec3 p){ - for( int i = 0; i<8; ++i){ - float t = time*0.2; - p.xz =rotate(p.xz,t); - p.xy =rotate(p.xy,t*1.89); - p.xz = abs(p.xz); - p.xz-=.5; - } - return dot(sign(p),p)/5.; +float box( vec3 p, vec3 b ) { + vec3 d = abs(p) - b; + return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); } -vec4 rm (vec3 ro, vec3 rd){ - float t = 0.; - vec3 col = vec3(0.); - float d; - for(float i =0.; i<64.; i++){ - vec3 p = ro + rd*t; - d = map(p)*.5; - if(d<0.02){ - break; - } - if(d>100.){ - break; - } - //col+=vec3(0.6,0.8,0.8)/(400.*(d)); - col+=palette(length(p)*.1)/(400.*(d)); - t+=d; +float ifsBox(vec3 p) { + for (int i=0; i<5; i++) { + p = abs(p) - 1.0; + p.xy *= rot(time*0.3); + p.xz *= rot(time*0.1); } - return vec4(col,1./(d*100.)); + p.xz *= rot(time); + return box(p, vec3(0.4,0.8,0.3)); } -void main() -{ - vec2 uv = fragCoord / 5.0; - vec3 ro = vec3(0.,0.,-50.); - ro.xz = rotate(ro.xz,time); - vec3 cf = normalize(-ro); - vec3 cs = normalize(cross(cf,vec3(0.,1.,0.))); - vec3 cu = normalize(cross(cf,cs)); - - vec3 uuv = ro+cf*3. + uv.x*cs + uv.y*cu; - - vec3 rd = normalize(uuv-ro); - - vec4 col = rm(ro,rd); - - - gl_FragColor = col; + +float map(vec3 p, vec3 cPos) { + vec3 p1 = p; + p1.x = mod(p1.x-5., 10.) - 5.; + p1.y = mod(p1.y-5., 10.) - 5.; + p1.z = mod(p1.z, 16.)-8.; + p1.xy = pmod(p1.xy, 5.0); + return ifsBox(p1); +} + +void main() { + vec2 p = fragCoord; + + vec3 cPos = vec3(0.0,0.0, -3.0 * time); + // vec3 cPos = vec3(0.3*sin(time*0.8), 0.4*cos(time*0.3), -6.0 * time); + vec3 cDir = normalize(vec3(0.0, 0.0, -1.0)); + vec3 cUp = vec3(sin(time), 1.0, 0.0); + vec3 cSide = cross(cDir, cUp); + + vec3 ray = normalize(cSide * p.x + cUp * p.y + cDir); + + float acc = 0.0; + float acc2 = 0.0; + float t = 0.0; + for (int i = 0; i < 99; i++) { + vec3 pos = cPos + ray * t; + float dist = map(pos, cPos); + dist = max(abs(dist), 0.02); + float a = exp(-dist*3.0); + if (mod(length(pos)+24.0*time, 30.0) < 3.0) { + a *= 2.0; + acc2 += a; + } + acc += a; + t += dist * 0.5; + } + + vec3 col = vec3(acc * 0.001, acc * 0.001 + acc2*0.002, acc * 0.002+ acc2*0.005); + gl_FragColor = vec4(col, 1.0 - t * 0.03); } diff --git a/scripts/wlbg/src/bg_vert.glsl b/scripts/wlbg/src/bg_vert.glsl index f7a079c..5356098 100644 --- a/scripts/wlbg/src/bg_vert.glsl +++ b/scripts/wlbg/src/bg_vert.glsl @@ -2,12 +2,13 @@ precision mediump float; +uniform vec2 offset; + attribute vec4 vPos; -attribute vec2 monitorOffset; out vec2 fragCoord; void main() { gl_Position = vPos; - fragCoord = vPos.xy + monitorOffset * 2.0; + fragCoord = vPos.xy + offset * 2.0; } diff --git a/scripts/wlbg/src/main.zig b/scripts/wlbg/src/main.zig index f49d832..a930518 100644 --- a/scripts/wlbg/src/main.zig +++ b/scripts/wlbg/src/main.zig @@ -3,6 +3,7 @@ const xev = @import("xev"); const wayland = @import("wayland"); const c = @import("ffi.zig").c; +const options = @import("options.zig"); const Gfx = @import("Gfx.zig"); const Globals = @import("Globals.zig"); @@ -18,8 +19,6 @@ pub const std_options = struct { pub const log_level = .debug; }; -const fps = 30; - pub fn main() !void { std.log.info("initializing event loop", .{}); var loop = try xev.Loop.init(.{}); @@ -141,21 +140,26 @@ pub fn main() !void { defer pointer.destroy(); pointer.setListener(*PointerState, pointerListener, &pointer_state); - var total_width: i32 = 0; - var total_height: i32 = 0; + const base_offset: [2]i32 = off: { + if (comptime options.multihead_mode == .individual) break :off .{ 0, 0 }; - for (output_info) |inf| { - const xmax = inf.x; - const ymax = inf.y; + var total_width: i32 = 0; + var total_height: i32 = 0; + for (output_info) |inf| { + const xmax = inf.x; + const ymax = inf.y; - if (xmax > total_width) - total_width = xmax; - if (ymax > total_height) - total_height = ymax; - } + if (xmax > total_width) + total_width = xmax; + if (ymax > total_height) + total_height = ymax; + } - const base_xoff = @divTrunc(total_width, 2); - const base_yoff = @divTrunc(total_height, 2); + break :off .{ + @divTrunc(total_width, 2), + @divTrunc(total_height, 2), + }; + }; if (c.eglMakeCurrent( egl_dpy, @@ -174,7 +178,7 @@ pub fn main() !void { .outputs = output_windows, .output_info = output_info, .last_time = loop.now(), - .base_offset = .{ base_xoff, base_yoff }, + .base_offset = base_offset, .pointer_state = &pointer_state, }; @@ -238,7 +242,7 @@ fn renderCb( const delta_time = now - data.?.last_time; data.?.last_time = now; - resetXevTimerCompletion(completion, now, 1000 / fps); + resetXevTimerCompletion(completion, now, 1000 / options.fps); data.?.gfx.preDraw( delta_time, @@ -287,11 +291,11 @@ fn renderBackgroundCb( ) xev.CallbackAction { result catch unreachable; - resetXevTimerCompletion(completion, loop.now(), std.time.ms_per_min); + resetXevTimerCompletion(completion, loop.now(), options.refresh_time); - const rand = std.crypto.random.float(f32); - for (data.?.outputs, data.?.output_info, 0..) |output, info, i| { - _ = output; + var rand: f32 = if (options.multihead_mode == .combined) std.crypto.random.float(f32) else 0.0; + for (data.?.output_info, 0..) |info, i| { + if (options.multihead_mode == .individual) rand = std.crypto.random.float(f32); data.?.gfx.drawBackground( info, i, diff --git a/scripts/wlbg/src/options.zig b/scripts/wlbg/src/options.zig new file mode 100644 index 0000000..47414ac --- /dev/null +++ b/scripts/wlbg/src/options.zig @@ -0,0 +1,10 @@ +const std = @import("std"); + +// Framerate +pub const fps = 30; + +// Draw backgrounds aligned with same value or individually with different val. +pub const multihead_mode: enum { combined, individual } = .combined; + +// Time between background changes +pub const refresh_time = std.time.ms_per_min * 5;