summaryrefslogtreecommitdiff
path: root/src/gpu/gpu.cc
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-01-28 10:34:15 +0100
committerskal <pascal.massimino@gmail.com>2026-01-28 10:34:15 +0100
commitc384515c8ea933757c97886c3bf1554e2fd62b04 (patch)
tree79f7047d10777210dfb31185adc9dda282d09387 /src/gpu/gpu.cc
parentf12b5ebc74825817df54677e261b92200bfac84a (diff)
feat(visuals): Add rotation, color shifts, and improved beat-sync
Implements a more dynamic and reactive visual system. - Updated synth.cc: Faster peak decay for better response. - Updated gpu.cc: Added time-based rotation and Hue shifting; implemented reactive clear-color flashes. - Updated main.cc: Corrected peak scaling (8x multiplier) and integrated time-based animation.
Diffstat (limited to 'src/gpu/gpu.cc')
-rw-r--r--src/gpu/gpu.cc50
1 files changed, 30 insertions, 20 deletions
diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc
index 1f2c7f8..6e058bb 100644
--- a/src/gpu/gpu.cc
+++ b/src/gpu/gpu.cc
@@ -99,6 +99,7 @@ const char *shader_wgsl_code = R"(
struct Uniforms {
audio_peak : f32,
aspect_ratio: f32,
+ time: f32,
};
@group(0) @binding(0) var<uniform> uniforms : Uniforms;
@@ -108,8 +109,9 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32) -> @builtin(position) vec4<
let PI = 3.14159265;
let num_sides = 7.0;
+ // Pulse scale based on audio peak
let base_scale = 0.5;
- let pulse_scale = 0.2 * uniforms.audio_peak;
+ let pulse_scale = 0.3 * uniforms.audio_peak;
let scale = base_scale + pulse_scale;
let tri_idx = f32(vertex_index / 3u);
@@ -119,8 +121,10 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32) -> @builtin(position) vec4<
return vec4<f32>(0.0, 0.0, 0.0, 1.0);
}
+ // Apply rotation based on time
+ let rotation = uniforms.time * 0.5;
let i = tri_idx + f32(sub_idx - 1u);
- let angle = i * 2.0 * PI / num_sides;
+ let angle = i * 2.0 * PI / num_sides + rotation;
let x = scale * cos(angle) / uniforms.aspect_ratio;
let y = scale * sin(angle);
@@ -129,12 +133,15 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32) -> @builtin(position) vec4<
@fragment
fn fs_main() -> @location(0) vec4<f32> {
- // More vibrant hue: shift through colors based on peak
- let h = uniforms.audio_peak * 2.0;
+ // Dynamic color shifting based on time and responsiveness to peak
+ let h = uniforms.time * 2.0 + uniforms.audio_peak * 3.0;
let r = sin(h + 0.0) * 0.5 + 0.5;
let g = sin(h + 2.0) * 0.5 + 0.5;
let b = sin(h + 4.0) * 0.5 + 0.5;
- return vec4<f32>(r, g, b, 1.0);
+
+ // Add brightness boost on peak
+ let boost = uniforms.audio_peak * 0.5;
+ return vec4<f32>(r + boost, g + boost, b + boost, 1.0);
}
)";
@@ -149,9 +156,10 @@ void gpu_init(GLFWwindow *window) {
adapter_opts.compatibleSurface = g_surface;
adapter_opts.powerPreference = WGPUPowerPreference_HighPerformance;
- wgpuInstanceRequestAdapter(g_instance, &adapter_opts,
- {nullptr, WGPUCallbackMode_WaitAnyOnly,
- handle_request_adapter, &g_adapter, nullptr});
+ wgpuInstanceRequestAdapter(
+ g_instance, &adapter_opts,
+ {nullptr, WGPUCallbackMode_WaitAnyOnly, handle_request_adapter, &g_adapter,
+ nullptr});
while (!g_adapter) {
wgpuInstanceWaitAny(g_instance, 0, nullptr, 0);
@@ -163,9 +171,10 @@ void gpu_init(GLFWwindow *window) {
device_desc.uncapturedErrorCallbackInfo.callback = handle_device_error;
#endif
- wgpuAdapterRequestDevice(g_adapter, &device_desc,
- {nullptr, WGPUCallbackMode_WaitAnyOnly,
- handle_request_device, &g_device, nullptr});
+ wgpuAdapterRequestDevice(
+ g_adapter, &device_desc,
+ {nullptr, WGPUCallbackMode_WaitAnyOnly, handle_request_device, &g_device,
+ nullptr});
while (!g_device) {
wgpuInstanceWaitAny(g_instance, 0, nullptr, 0);
@@ -191,14 +200,14 @@ void gpu_init(GLFWwindow *window) {
WGPUBufferDescriptor uniform_buffer_desc = {};
uniform_buffer_desc.label = label_view("Uniform Buffer");
uniform_buffer_desc.usage = WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst;
- uniform_buffer_desc.size = sizeof(float) * 2;
+ uniform_buffer_desc.size = sizeof(float) * 4; // Padding to 16 bytes
g_uniform_buffer = wgpuDeviceCreateBuffer(g_device, &uniform_buffer_desc);
WGPUBindGroupLayoutEntry bgl_entry = {};
bgl_entry.binding = 0;
bgl_entry.visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment;
bgl_entry.buffer.type = WGPUBufferBindingType_Uniform;
- bgl_entry.buffer.minBindingSize = sizeof(float) * 2;
+ bgl_entry.buffer.minBindingSize = sizeof(float) * 3;
WGPUBindGroupLayoutDescriptor bgl_desc = {};
bgl_desc.label = label_view("Uniform Bind Group Layout");
@@ -210,7 +219,7 @@ void gpu_init(GLFWwindow *window) {
WGPUBindGroupEntry bg_entry = {};
bg_entry.binding = 0;
bg_entry.buffer = g_uniform_buffer;
- bg_entry.size = sizeof(float) * 2;
+ bg_entry.size = sizeof(float) * 3;
WGPUBindGroupDescriptor bg_desc = {};
bg_desc.label = label_view("Uniform Bind Group");
@@ -261,7 +270,7 @@ void gpu_init(GLFWwindow *window) {
wgpuSurfaceConfigure(g_surface, &g_config);
}
-void gpu_draw(float audio_peak, float aspect_ratio) {
+void gpu_draw(float audio_peak, float aspect_ratio, float time) {
WGPUSurfaceTexture surface_texture;
wgpuSurfaceGetCurrentTexture(g_surface, &surface_texture);
if (surface_texture.status !=
@@ -276,7 +285,9 @@ void gpu_draw(float audio_peak, float aspect_ratio) {
struct {
float audio_peak;
float aspect_ratio;
- } uniforms = {audio_peak, aspect_ratio};
+ float time;
+ float padding;
+ } uniforms = {audio_peak, aspect_ratio, time, 0.0f};
wgpuQueueWriteBuffer(g_queue, g_uniform_buffer, 0, &uniforms,
sizeof(uniforms));
@@ -291,8 +302,8 @@ void gpu_draw(float audio_peak, float aspect_ratio) {
color_attachment.loadOp = WGPULoadOp_Clear;
color_attachment.storeOp = WGPUStoreOp_Store;
- // Background flash based on peak
- float flash = uniforms.audio_peak * 0.4f;
+ // Background flash effect
+ float flash = audio_peak * 0.6f;
color_attachment.clearValue = {0.05 + flash, 0.1 + flash, 0.2 + flash, 1.0};
color_attachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
@@ -320,5 +331,4 @@ void gpu_draw(float audio_peak, float aspect_ratio) {
wgpuTextureRelease(surface_texture.texture);
}
-void gpu_shutdown() {
-}
+void gpu_shutdown() {} \ No newline at end of file