diff options
Diffstat (limited to 'src/gpu/effect.h')
| -rw-r--r-- | src/gpu/effect.h | 76 |
1 files changed, 52 insertions, 24 deletions
diff --git a/src/gpu/effect.h b/src/gpu/effect.h index f92e3ef..5f49041 100644 --- a/src/gpu/effect.h +++ b/src/gpu/effect.h @@ -1,12 +1,11 @@ // This file is part of the 64k demo project. // It defines the Effect interface and Sequence management system. -// Used for choreographing visual effects. #pragma once -#include <vector> -#include <memory> #include <algorithm> +#include <memory> +#include <vector> #if defined(DEMO_CROSS_COMPILE_WIN32) #include <webgpu/webgpu.h> @@ -15,6 +14,7 @@ #endif class MainSequence; +class PostProcessEffect; // Abstract base class for all visual effects class Effect { @@ -22,7 +22,6 @@ public: virtual ~Effect() = default; // One-time setup (load assets, create buffers). - // Idempotent: safe to call multiple times if effect is shared. virtual void init(MainSequence *demo) { (void)demo; } // Called when the effect starts playing in a sequence segment. @@ -44,8 +43,29 @@ public: // Called when the effect finishes in a sequence segment. virtual void end() {} - + bool is_initialized = false; + virtual bool is_post_process() const { return false; } +}; + +// Base class for all post-processing effects +class PostProcessEffect : public Effect { +public: + bool is_post_process() const override { return true; } + + // Post-process effects don't have a compute phase by default + void compute(WGPUCommandEncoder, float, float, float, float) override {} + + // Fullscreen quad render + void render(WGPURenderPassEncoder pass, float time, float beat, + float intensity, float aspect_ratio) override; + + // Called by MainSequence to update which texture this effect reads from + virtual void update_bind_group(WGPUTextureView input_view) = 0; + +protected: + WGPURenderPipeline pipeline_ = nullptr; + WGPUBindGroup bind_group_ = nullptr; }; struct SequenceItem { @@ -61,24 +81,17 @@ public: int priority = 0; // Render order of this sequence (higher = later/top) void init(MainSequence *demo); - + // Add an effect to the sequence. - // start_time, end_time: Relative to sequence start. - // priority: Drawing order within this sequence. void add_effect(std::shared_ptr<Effect> effect, float start_time, float end_time, int priority = 0); // Updates active state of effects based on sequence-local time. - // seq_time: Time relative to sequence start. void update_active_list(float seq_time); - // Calls compute() on all active effects (sorted by priority). - void dispatch_compute(WGPUCommandEncoder encoder, float seq_time, float beat, - float intensity, float aspect_ratio); - - // Calls render() on all active effects (sorted by priority). - void dispatch_render(WGPURenderPassEncoder pass, float seq_time, float beat, - float intensity, float aspect_ratio); + // Gathers active effects into lists for processing. + void collect_active_effects(std::vector<SequenceItem *> &scene_effects, + std::vector<SequenceItem *> &post_effects); void reset(); @@ -90,26 +103,30 @@ private: class MainSequence { public: + MainSequence(); + ~MainSequence(); // Defined in .cc to handle unique_ptr to incomplete type + WGPUDevice device; WGPUQueue queue; WGPUTextureFormat format; - void init(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format); - + void init(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format, + int width, int height); + // Add a sequence to the demo. - // start_time: Global time when this sequence starts. - // priority: Layering order (higher = on top). - void add_sequence(std::shared_ptr<Sequence> seq, float start_time, int priority = 0); + void add_sequence(std::shared_ptr<Sequence> seq, float start_time, + int priority = 0); // Renders the full frame: updates sequences, runs compute, runs render pass. void render_frame(float global_time, float beat, float peak, float aspect_ratio, WGPUSurface surface); + void shutdown(); + +#ifndef STRIP_ALL // Fast-forwards the simulation (updates & compute) without rendering. - // Used for seeking/debugging. void simulate_until(float target_time, float step_rate); - - void shutdown(); +#endif private: struct ActiveSequence { @@ -118,4 +135,15 @@ private: int priority; }; std::vector<ActiveSequence> sequences_; + + // Framebuffers for post-processing + WGPUTexture framebuffer_a_ = nullptr; + WGPUTextureView framebuffer_view_a_ = nullptr; + WGPUTexture framebuffer_b_ = nullptr; + WGPUTextureView framebuffer_view_b_ = nullptr; + + // Default passthrough effect for blitting + std::unique_ptr<PostProcessEffect> passthrough_effect_; + + void create_framebuffers(int width, int height); }; |
