diff options
| author | skal <pascal.massimino@gmail.com> | 2026-01-28 02:06:05 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-01-28 02:06:05 +0100 |
| commit | 5bbe2204f1d30e99ee442e287167ef14ad51af75 (patch) | |
| tree | ed4a30ef91ed9e928bda0af07f44c8ecd0a9d76a /src/gpu/gpu.cc | |
| parent | 164c471fb9488f7013be0bcaef7f790020aee916 (diff) | |
fix(gpu): Add aspect ratio correction to shader
Implements aspect ratio correction to prevent the pulsating heptagon from being distorted when the window is resized.
- The main loop now queries the framebuffer size and calculates the aspect ratio each frame.
- This aspect ratio is passed to the GPU via an updated uniform buffer.
- The vertex shader in shader.wgsl now uses the aspect ratio to correctly scale the X coordinates of the vertices, ensuring the shape remains proportional.
Diffstat (limited to 'src/gpu/gpu.cc')
| -rw-r--r-- | src/gpu/gpu.cc | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index 9eb2437..707ffe2 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -7,6 +7,7 @@ #include <algorithm> #include <cassert> +#include <cstdint> #include <cstring> #include <vector> @@ -86,6 +87,7 @@ static void handle_device_error(WGPUDevice const *device, WGPUErrorType type, const char *shader_wgsl_code = R"( struct Uniforms { audio_peak : f32, + aspect_ratio: f32, }; @group(0) @binding(0) var<uniform> uniforms : Uniforms; @@ -108,7 +110,7 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32) -> @builtin(position) vec4< let i = tri_idx + f32(sub_idx - 1u); let angle = i * 2.0 * PI / num_sides; - let x = scale * cos(angle); + let x = scale * cos(angle) / uniforms.aspect_ratio; let y = scale * sin(angle); return vec4<f32>(x, y, 0.0, 1.0); @@ -179,14 +181,14 @@ void gpu_init(GLFWwindow *window) { WGPUBufferDescriptor uniform_buffer_desc = {}; uniform_buffer_desc.label = str_view("Uniform Buffer"); uniform_buffer_desc.usage = WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst; - uniform_buffer_desc.size = sizeof(float); + uniform_buffer_desc.size = sizeof(float) * 2; 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); + bgl_entry.buffer.minBindingSize = sizeof(float) * 2; WGPUBindGroupLayoutDescriptor bgl_desc = {}; bgl_desc.entryCount = 1; @@ -197,7 +199,7 @@ void gpu_init(GLFWwindow *window) { WGPUBindGroupEntry bg_entry = {}; bg_entry.binding = 0; bg_entry.buffer = g_uniform_buffer; - bg_entry.size = sizeof(float); + bg_entry.size = sizeof(float) * 2; WGPUBindGroupDescriptor bg_desc = {}; bg_desc.layout = bind_group_layout; @@ -236,6 +238,7 @@ void gpu_init(GLFWwindow *window) { glfwGetFramebufferSize(window, &width, &height); g_config.device = g_device; g_config.format = swap_chain_format; + g_config.usage = WGPUTextureUsage_RenderAttachment; g_config.width = width; g_config.height = height; g_config.presentMode = WGPUPresentMode_Fifo; @@ -244,7 +247,7 @@ void gpu_init(GLFWwindow *window) { wgpuSurfaceConfigure(g_surface, &g_config); } -void gpu_draw(float audio_peak) { +void gpu_draw(float audio_peak, float aspect_ratio) { WGPUSurfaceTexture surface_texture; wgpuSurfaceGetCurrentTexture(g_surface, &surface_texture); if (surface_texture.status != WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal && @@ -253,7 +256,11 @@ void gpu_draw(float audio_peak) { WGPUTextureView view = wgpuTextureCreateView(surface_texture.texture, nullptr); - wgpuQueueWriteBuffer(g_queue, g_uniform_buffer, 0, &audio_peak, sizeof(float)); + struct { + float audio_peak; + float aspect_ratio; + } uniforms = {audio_peak, aspect_ratio}; + wgpuQueueWriteBuffer(g_queue, g_uniform_buffer, 0, &uniforms, sizeof(uniforms)); WGPUCommandEncoderDescriptor encoder_desc = {}; WGPUCommandEncoder encoder = @@ -261,9 +268,11 @@ void gpu_draw(float audio_peak) { WGPURenderPassColorAttachment color_attachment = {}; color_attachment.view = view; + color_attachment.resolveTarget = nullptr; color_attachment.loadOp = WGPULoadOp_Clear; color_attachment.storeOp = WGPUStoreOp_Store; color_attachment.clearValue = {0.1, 0.2, 0.3, 1.0}; + color_attachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; WGPURenderPassDescriptor render_pass_desc = {}; render_pass_desc.colorAttachmentCount = 1; |
