summaryrefslogtreecommitdiff
path: root/src/gpu/effect.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/effect.h')
-rw-r--r--src/gpu/effect.h76
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);
};