diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-02 15:55:03 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-02 15:55:03 +0100 |
| commit | c194f59e171a1e58ce1704f37d99ffcd09a42433 (patch) | |
| tree | f77a32f2c4c23b335209b8df11cc82920388b51a /src/gpu | |
| parent | 316825883c705ed0fe927c32e072f98141d3eaa3 (diff) | |
fix(gpu): Resolve high-DPI squished rendering and 3D shadow bugs
- Implemented dynamic resolution support in all shaders and effects.
- Added explicit viewport setting for all render passes to ensure correct scaling.
- Fixed 3D shadow mapping by adding PLANE support and standardizing soft shadow logic.
- Propagated resize events through the Effect hierarchy.
- Applied project-wide code formatting.
Diffstat (limited to 'src/gpu')
| -rw-r--r-- | src/gpu/effect.cc | 40 | ||||
| -rw-r--r-- | src/gpu/effect.h | 10 | ||||
| -rw-r--r-- | src/gpu/effects/chroma_aberration_effect.cc | 6 | ||||
| -rw-r--r-- | src/gpu/effects/distort_effect.cc | 6 | ||||
| -rw-r--r-- | src/gpu/effects/gaussian_blur_effect.cc | 6 | ||||
| -rw-r--r-- | src/gpu/effects/hybrid_3d_effect.cc | 2 | ||||
| -rw-r--r-- | src/gpu/effects/hybrid_3d_effect.h | 2 | ||||
| -rw-r--r-- | src/gpu/effects/moving_ellipse_effect.cc | 6 | ||||
| -rw-r--r-- | src/gpu/effects/particle_spray_effect.cc | 6 | ||||
| -rw-r--r-- | src/gpu/effects/passthrough_effect.cc | 6 | ||||
| -rw-r--r-- | src/gpu/effects/shaders.cc | 28 | ||||
| -rw-r--r-- | src/gpu/effects/solarize_effect.cc | 6 | ||||
| -rw-r--r-- | src/gpu/gpu.cc | 10 | ||||
| -rw-r--r-- | src/gpu/gpu.h | 4 |
14 files changed, 99 insertions, 39 deletions
diff --git a/src/gpu/effect.cc b/src/gpu/effect.cc index f115ac5..f24fa96 100644 --- a/src/gpu/effect.cc +++ b/src/gpu/effect.cc @@ -150,13 +150,17 @@ void MainSequence::init(WGPUDevice d, WGPUQueue q, WGPUTextureFormat f, device = d; queue = q; format = f; + width_ = width; + height_ = height; create_framebuffers(width, height); passthrough_effect_ = std::make_unique<PassthroughEffect>(device, queue, format); + passthrough_effect_->resize(width, height); for (ActiveSequence& entry : sequences_) { entry.seq->init(this); + entry.seq->resize(width, height); } } @@ -166,6 +170,7 @@ void MainSequence::add_sequence(std::shared_ptr<Sequence> seq, float start_time, // If MainSequence is already initialized, init the new sequence immediately if (device) { seq->init(this); + seq->resize(width_, height_); } std::sort(sequences_.begin(), sequences_.end(), [](const ActiveSequence& a, const ActiveSequence& b) { @@ -174,17 +179,29 @@ void MainSequence::add_sequence(std::shared_ptr<Sequence> seq, float start_time, } void MainSequence::resize(int width, int height) { + width_ = width; + height_ = height; // Release old resources - if (framebuffer_view_a_) wgpuTextureViewRelease(framebuffer_view_a_); - if (framebuffer_a_) wgpuTextureRelease(framebuffer_a_); - if (framebuffer_view_b_) wgpuTextureViewRelease(framebuffer_view_b_); - if (framebuffer_b_) wgpuTextureRelease(framebuffer_b_); - if (depth_view_) wgpuTextureViewRelease(depth_view_); - if (depth_texture_) wgpuTextureRelease(depth_texture_); + if (framebuffer_view_a_) + wgpuTextureViewRelease(framebuffer_view_a_); + if (framebuffer_a_) + wgpuTextureRelease(framebuffer_a_); + if (framebuffer_view_b_) + wgpuTextureViewRelease(framebuffer_view_b_); + if (framebuffer_b_) + wgpuTextureRelease(framebuffer_b_); + if (depth_view_) + wgpuTextureViewRelease(depth_view_); + if (depth_texture_) + wgpuTextureRelease(depth_texture_); // Recreate with new size create_framebuffers(width, height); + if (passthrough_effect_) { + passthrough_effect_->resize(width, height); + } + // Propagate to all sequences for (ActiveSequence& entry : sequences_) { entry.seq->resize(width, height); @@ -193,6 +210,11 @@ void MainSequence::resize(int width, int height) { void MainSequence::render_frame(float global_time, float beat, float peak, float aspect_ratio, WGPUSurface surface) { + static bool first_frame = true; + if (first_frame) { + printf("MainSequence First Frame: %dx%d\n", width_, height_); + first_frame = false; + } WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device, nullptr); std::vector<SequenceItem*> scene_effects; @@ -242,6 +264,8 @@ void MainSequence::render_frame(float global_time, float beat, float peak, &depth_attachment}; WGPURenderPassEncoder scene_pass = wgpuCommandEncoderBeginRenderPass(encoder, &scene_desc); + wgpuRenderPassEncoderSetViewport(scene_pass, 0.0f, 0.0f, (float)width_, + (float)height_, 0.0f, 1.0f); for (const SequenceItem* item : scene_effects) { item->effect->render(scene_pass, global_time - item->start_time, beat, peak, aspect_ratio); @@ -273,6 +297,8 @@ void MainSequence::render_frame(float global_time, float beat, float peak, .colorAttachmentCount = 1, .colorAttachments = &final_attachment}; WGPURenderPassEncoder final_pass = wgpuCommandEncoderBeginRenderPass(encoder, &final_desc); + wgpuRenderPassEncoderSetViewport(final_pass, 0.0f, 0.0f, (float)width_, + (float)height_, 0.0f, 1.0f); passthrough_effect_->render(final_pass, 0, 0, 0, aspect_ratio); wgpuRenderPassEncoderEnd(final_pass); } else { @@ -307,6 +333,8 @@ void MainSequence::render_frame(float global_time, float beat, float peak, .colorAttachments = &pp_attachment}; WGPURenderPassEncoder pp_pass = wgpuCommandEncoderBeginRenderPass(encoder, &pp_desc); + wgpuRenderPassEncoderSetViewport(pp_pass, 0.0f, 0.0f, (float)width_, + (float)height_, 0.0f, 1.0f); pp->render(pp_pass, global_time - post_effects[i]->start_time, beat, peak, aspect_ratio); wgpuRenderPassEncoderEnd(pp_pass); diff --git a/src/gpu/effect.h b/src/gpu/effect.h index e7453c7..7e5e2ce 100644 --- a/src/gpu/effect.h +++ b/src/gpu/effect.h @@ -33,7 +33,10 @@ class Effect { } virtual void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) = 0; - virtual void resize(int width, int height) {} + virtual void resize(int width, int height) { + width_ = width; + height_ = height; + } virtual void end() { } @@ -46,6 +49,8 @@ class Effect { WGPUDevice device_; WGPUQueue queue_; GpuBuffer uniforms_; + int width_ = 1280; + int height_ = 720; }; class PostProcessEffect : public Effect { @@ -123,6 +128,9 @@ class MainSequence { }; std::vector<ActiveSequence> sequences_; + int width_ = 1280; + int height_ = 720; + WGPUTexture framebuffer_a_ = nullptr; WGPUTextureView framebuffer_view_a_ = nullptr; WGPUTexture framebuffer_b_ = nullptr; diff --git a/src/gpu/effects/chroma_aberration_effect.cc b/src/gpu/effects/chroma_aberration_effect.cc index ef9e963..6e64988 100644 --- a/src/gpu/effects/chroma_aberration_effect.cc +++ b/src/gpu/effects/chroma_aberration_effect.cc @@ -10,7 +10,7 @@ ChromaAberrationEffect::ChromaAberrationEffect(WGPUDevice device, WGPUTextureFormat format) : PostProcessEffect(device, queue) { uniforms_ = - gpu_create_buffer(device_, sizeof(float) * 4, + gpu_create_buffer(device_, sizeof(float) * 6, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); pipeline_ = create_post_process_pipeline(device_, format, chroma_aberration_shader_wgsl); @@ -18,8 +18,8 @@ ChromaAberrationEffect::ChromaAberrationEffect(WGPUDevice device, void ChromaAberrationEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { struct { - float t, b, i, a; - } u = {t, b, i, a}; + float t, b, i, a, w, h; + } u = {t, b, i, a, (float)width_, (float)height_}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); PostProcessEffect::render(pass, t, b, i, a); } diff --git a/src/gpu/effects/distort_effect.cc b/src/gpu/effects/distort_effect.cc index d9aa308..0d4bb36 100644 --- a/src/gpu/effects/distort_effect.cc +++ b/src/gpu/effects/distort_effect.cc @@ -9,7 +9,7 @@ DistortEffect::DistortEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : PostProcessEffect(device, queue) { uniforms_ = - gpu_create_buffer(device_, sizeof(float) * 4, + gpu_create_buffer(device_, sizeof(float) * 6, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); pipeline_ = create_post_process_pipeline(device_, format, distort_shader_wgsl); @@ -17,8 +17,8 @@ DistortEffect::DistortEffect(WGPUDevice device, WGPUQueue queue, void DistortEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { struct { - float t, b, i, a; - } u = {t, b, i, a}; + float t, b, i, a, w, h; + } u = {t, b, i, a, (float)width_, (float)height_}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); PostProcessEffect::render(pass, t, b, i, a); } diff --git a/src/gpu/effects/gaussian_blur_effect.cc b/src/gpu/effects/gaussian_blur_effect.cc index 28f5b97..ad9bf4b 100644 --- a/src/gpu/effects/gaussian_blur_effect.cc +++ b/src/gpu/effects/gaussian_blur_effect.cc @@ -9,7 +9,7 @@ GaussianBlurEffect::GaussianBlurEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : PostProcessEffect(device, queue) { uniforms_ = - gpu_create_buffer(device_, sizeof(float) * 4, + gpu_create_buffer(device_, sizeof(float) * 6, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); pipeline_ = create_post_process_pipeline(device_, format, gaussian_blur_shader_wgsl); @@ -17,8 +17,8 @@ GaussianBlurEffect::GaussianBlurEffect(WGPUDevice device, WGPUQueue queue, void GaussianBlurEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { struct { - float t, b, i, a; - } u = {t, b, i, a}; + float t, b, i, a, w, h; + } u = {t, b, i, a, (float)width_, (float)height_}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); PostProcessEffect::render(pass, t, b, i, a); } diff --git a/src/gpu/effects/hybrid_3d_effect.cc b/src/gpu/effects/hybrid_3d_effect.cc index af956cd..ee2dd57 100644 --- a/src/gpu/effects/hybrid_3d_effect.cc +++ b/src/gpu/effects/hybrid_3d_effect.cc @@ -10,7 +10,7 @@ Hybrid3DEffect::Hybrid3DEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) - : Effect(device, queue), width_(1280), height_(720) { + : Effect(device, queue) { (void)format; // Passed to base, not directly used here. } diff --git a/src/gpu/effects/hybrid_3d_effect.h b/src/gpu/effects/hybrid_3d_effect.h index 8eedeb2..8e2fef9 100644 --- a/src/gpu/effects/hybrid_3d_effect.h +++ b/src/gpu/effects/hybrid_3d_effect.h @@ -25,6 +25,4 @@ class Hybrid3DEffect : public Effect { TextureManager texture_manager_; Scene scene_; Camera camera_; - int width_ = 1280; - int height_ = 720; }; diff --git a/src/gpu/effects/moving_ellipse_effect.cc b/src/gpu/effects/moving_ellipse_effect.cc index b46eecd..3b73697 100644 --- a/src/gpu/effects/moving_ellipse_effect.cc +++ b/src/gpu/effects/moving_ellipse_effect.cc @@ -9,7 +9,7 @@ MovingEllipseEffect::MovingEllipseEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : Effect(device, queue) { uniforms_ = - gpu_create_buffer(device_, sizeof(float) * 4, + gpu_create_buffer(device_, sizeof(float) * 6, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); ResourceBinding bindings[] = {{uniforms_, WGPUBufferBindingType_Uniform}}; pass_ = @@ -19,8 +19,8 @@ MovingEllipseEffect::MovingEllipseEffect(WGPUDevice device, WGPUQueue queue, void MovingEllipseEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { struct { - float t, b, i, a; - } u = {t, b, i, a}; + float t, b, i, a, w, h; + } u = {t, b, i, a, (float)width_, (float)height_}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); wgpuRenderPassEncoderSetPipeline(pass, pass_.pipeline); wgpuRenderPassEncoderSetBindGroup(pass, 0, pass_.bind_group, 0, nullptr); diff --git a/src/gpu/effects/particle_spray_effect.cc b/src/gpu/effects/particle_spray_effect.cc index b5c5f42..e8ead0a 100644 --- a/src/gpu/effects/particle_spray_effect.cc +++ b/src/gpu/effects/particle_spray_effect.cc @@ -10,7 +10,7 @@ ParticleSprayEffect::ParticleSprayEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : Effect(device, queue) { uniforms_ = - gpu_create_buffer(device_, sizeof(float) * 4, + gpu_create_buffer(device_, sizeof(float) * 6, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); std::vector<Particle> init_p(NUM_PARTICLES); for (Particle& p : init_p) @@ -34,8 +34,8 @@ ParticleSprayEffect::ParticleSprayEffect(WGPUDevice device, WGPUQueue queue, void ParticleSprayEffect::compute(WGPUCommandEncoder e, float t, float b, float i, float a) { struct { - float i, a, t, b; - } u = {i, a, t, b}; + float i, a, t, b, w, h; + } u = {i, a, t, b, (float)width_, (float)height_}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); WGPUComputePassEncoder pass = wgpuCommandEncoderBeginComputePass(e, nullptr); wgpuComputePassEncoderSetPipeline(pass, compute_pass_.pipeline); diff --git a/src/gpu/effects/passthrough_effect.cc b/src/gpu/effects/passthrough_effect.cc index cb92ba1..7825c0a 100644 --- a/src/gpu/effects/passthrough_effect.cc +++ b/src/gpu/effects/passthrough_effect.cc @@ -9,11 +9,15 @@ PassthroughEffect::PassthroughEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : PostProcessEffect(device, queue) { uniforms_ = - gpu_create_buffer(device_, sizeof(float) * 4, + gpu_create_buffer(device_, sizeof(float) * 6, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); pipeline_ = create_post_process_pipeline(device_, format, passthrough_shader_wgsl); } void PassthroughEffect::update_bind_group(WGPUTextureView input_view) { + struct { + float t, b, i, a, w, h; + } u = {0, 0, 0, 0, (float)width_, (float)height_}; + wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); pp_update_bind_group(device_, pipeline_, &bind_group_, input_view, uniforms_); } diff --git a/src/gpu/effects/shaders.cc b/src/gpu/effects/shaders.cc index 0e80230..ac0bba9 100644 --- a/src/gpu/effects/shaders.cc +++ b/src/gpu/effects/shaders.cc @@ -122,6 +122,15 @@ const char* passthrough_shader_wgsl = R"( @group(0) @binding(0) var smplr: sampler; @group(0) @binding(1) var txt: texture_2d<f32>; +struct Uniforms { + time: f32, + beat: f32, + intensity: f32, + aspect_ratio: f32, + resolution: vec2<f32>, +}; +@group(0) @binding(2) var<uniform> uniforms: Uniforms; + @vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4<f32> { var pos = array<vec2<f32>, 3>( vec2<f32>(-1, -1), @@ -132,7 +141,7 @@ const char* passthrough_shader_wgsl = R"( } @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { - return textureSample(txt, smplr, p.xy / vec2<f32>(1280.0, 720.0)); + return textureSample(txt, smplr, p.xy / uniforms.resolution); })"; const char* ellipse_shader_wgsl = R"( @@ -141,6 +150,7 @@ struct Uniforms { beat: f32, intensity: f32, aspect_ratio: f32, + resolution: vec2<f32>, }; @group(0) @binding(0) var<uniform> uniforms: Uniforms; @@ -187,7 +197,7 @@ fn sdEllipse(p: vec2<f32>, ab: vec2<f32>) -> f32 { } @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { - let uv = (p.xy / vec2<f32>(1280.0, 720.0) - 0.5) * 2.0; + let uv = (p.xy / uniforms.resolution - 0.5) * 2.0; let movement = vec2<f32>(sin(uniforms.time * 0.7), cos(uniforms.time * 0.5)); let d = sdEllipse((uv * vec2<f32>(uniforms.aspect_ratio, 1.0)) - movement, vec2<f32>(0.5, 0.3) * (1.0 + uniforms.beat * 0.2)); return mix(vec4<f32>(0.2, 0.8, 0.4, 1.0), vec4<f32>(0.0), smoothstep(0.0, 0.01, d)); @@ -244,6 +254,7 @@ struct Uniforms { beat: f32, intensity: f32, aspect_ratio: f32, + resolution: vec2<f32>, }; @group(0) @binding(2) var<uniform> uniforms: Uniforms; @@ -258,12 +269,12 @@ struct Uniforms { } @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { - let uv = p.xy / vec2<f32>(1280.0, 720.0); + let uv = p.xy / uniforms.resolution; var res = vec4<f32>(0.0); let size = 5.0 * uniforms.intensity; for (var x: f32 = -2.0; x <= 2.0; x += 1.0) { for (var y: f32 = -2.0; y <= 2.0; y += 1.0) { - res += textureSample(txt, smplr, uv + vec2<f32>(x, y) * size / 1280.0); + res += textureSample(txt, smplr, uv + vec2<f32>(x, y) * size / uniforms.resolution.x); } } return res / 25.0; @@ -278,6 +289,7 @@ struct Uniforms { beat: f32, intensity: f32, aspect_ratio: f32, + resolution: vec2<f32>, }; @group(0) @binding(2) var<uniform> uniforms: Uniforms; @@ -292,7 +304,7 @@ struct Uniforms { } @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { - let uv = p.xy / vec2<f32>(1280.0, 720.0); + let uv = p.xy / uniforms.resolution; var col = textureSample(txt, smplr, uv); let thr = 0.5 + 0.3 * sin(uniforms.time); if (col.r < thr) { @@ -316,6 +328,7 @@ struct Uniforms { beat: f32, intensity: f32, aspect_ratio: f32, + resolution: vec2<f32>, }; @group(0) @binding(2) var<uniform> uniforms: Uniforms; @@ -330,7 +343,7 @@ struct Uniforms { } @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { - let uv = p.xy / vec2<f32>(1280.0, 720.0); + let uv = p.xy / uniforms.resolution; let dist = 0.1 * uniforms.intensity * sin(uv.y * 20.0 + uniforms.time * 5.0); return textureSample(txt, smplr, uv + vec2<f32>(dist, 0.0)); })"; @@ -344,6 +357,7 @@ struct Uniforms { beat: f32, intensity: f32, aspect_ratio: f32, + resolution: vec2<f32>, }; @group(0) @binding(2) var<uniform> uniforms: Uniforms; @@ -358,7 +372,7 @@ struct Uniforms { } @fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { - let uv = p.xy / vec2<f32>(1280.0, 720.0); + let uv = p.xy / uniforms.resolution; let off = 0.02 * uniforms.intensity; let r = textureSample(txt, smplr, uv + vec2<f32>(off, 0.0)).r; let g = textureSample(txt, smplr, uv).g; diff --git a/src/gpu/effects/solarize_effect.cc b/src/gpu/effects/solarize_effect.cc index f8a7f33..a0bc971 100644 --- a/src/gpu/effects/solarize_effect.cc +++ b/src/gpu/effects/solarize_effect.cc @@ -9,7 +9,7 @@ SolarizeEffect::SolarizeEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : PostProcessEffect(device, queue) { uniforms_ = - gpu_create_buffer(device_, sizeof(float) * 4, + gpu_create_buffer(device_, sizeof(float) * 6, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); pipeline_ = create_post_process_pipeline(device_, format, solarize_shader_wgsl); @@ -17,8 +17,8 @@ SolarizeEffect::SolarizeEffect(WGPUDevice device, WGPUQueue queue, void SolarizeEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { struct { - float t, b, i, a; - } u = {t, b, i, a}; + float t, b, i, a, w, h; + } u = {t, b, i, a, (float)width_, (float)height_}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); PostProcessEffect::render(pass, t, b, i, a); } diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index 7b8e012..5537433 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -367,6 +367,7 @@ void gpu_init(PlatformState* platform_state) { g_config.usage = WGPUTextureUsage_RenderAttachment; g_config.width = platform_state->width; g_config.height = platform_state->height; + printf("WebGPU Init: %dx%d\n", g_config.width, g_config.height); g_config.presentMode = WGPUPresentMode_Fifo; g_config.alphaMode = WGPUCompositeAlphaMode_Opaque; wgpuSurfaceConfigure(g_surface, &g_config); @@ -381,6 +382,15 @@ void gpu_draw(float audio_peak, float aspect_ratio, float time, float beat) { g_main_sequence.render_frame(time, beat, audio_peak, aspect_ratio, g_surface); } +void gpu_resize(int width, int height) { + if (width <= 0 || height <= 0) + return; + g_config.width = width; + g_config.height = height; + wgpuSurfaceConfigure(g_surface, &g_config); + g_main_sequence.resize(width, height); +} + #if !defined(STRIP_ALL) void gpu_simulate_until(float time) { g_main_sequence.simulate_until(time, 1.0f / 60.0f); diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h index 768b238..f47355c 100644 --- a/src/gpu/gpu.h +++ b/src/gpu/gpu.h @@ -100,9 +100,7 @@ struct RenderPass { void gpu_init(PlatformState* platform_state); void gpu_draw(float audio_peak, float aspect_ratio, float time, float beat); -#if !defined(STRIP_ALL) -void gpu_simulate_until(float time); -#endif /* !defined(STRIP_ALL) */ +void gpu_resize(int width, int height); void gpu_shutdown(); // Helper functions (exposed for internal/future use) |
