diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-04 22:08:56 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-04 22:08:56 +0100 |
| commit | dd9d3013d260f27f86b268c203a290f91431d8e5 (patch) | |
| tree | 7ca8bb5e4c2eb2bff3736992e899e6ce676c6234 /src/gpu/effects/flash_cube_effect.cc | |
| parent | 91933ce05ba157dc549d52ed6c00c71c457fca05 (diff) | |
feat: Optional sequence end times and comprehensive effect documentation
This milestone implements several key enhancements to the sequencing system
and developer documentation:
## Optional Sequence End Times (New Feature)
- Added support for explicit sequence termination via [time] syntax
- Example: SEQUENCE 0 0 [30.0] forcefully ends all effects at 30 seconds
- Updated seq_compiler.cc to parse optional [time] parameter with brackets
- Added end_time_ field to Sequence class (default -1.0 = no explicit end)
- Modified update_active_list() to check sequence end time and deactivate
all effects when reached
- Fully backward compatible - existing sequences work unchanged
## Comprehensive Effect Documentation (demo.seq)
- Documented all effect constructor parameters (standard: device, queue, format)
- Added runtime parameter documentation (time, beat, intensity, aspect_ratio)
- Created detailed effect catalog with specific behaviors:
* Scene effects: HeptagonEffect, ParticlesEffect, Hybrid3DEffect, FlashCubeEffect
* Post-process effects: GaussianBlurEffect, SolarizeEffect, ChromaAberrationEffect,
ThemeModulationEffect, FadeEffect, FlashEffect
- Added examples section showing common usage patterns
- Documented exact parameter behaviors (e.g., blur pulsates 0.5x-2.5x,
flash triggers at intensity > 0.7, theme cycles every 8 seconds)
## Code Quality & Verification
- Audited all hardcoded 1280x720 dimensions throughout codebase
- Verified all shaders use uniforms.resolution and uniforms.aspect_ratio
- Confirmed Effect::resize() properly updates width_/height_ members
- No issues found - dimension handling is fully dynamic and robust
## Files Changed
- tools/seq_compiler.cc: Parse [end_time], generate set_end_time() calls
- src/gpu/effect.h: Added end_time_, set_end_time(), get_end_time()
- src/gpu/effect.cc: Check sequence end time in update_active_list()
- assets/demo.seq: Comprehensive syntax and effect documentation
- Generated files updated (timeline.cc, assets_data.cc, music_data.cc)
This work establishes a more flexible sequencing system and provides
developers with clear documentation for authoring demo timelines.
handoff(Claude): Optional sequence end times implemented, effect documentation
complete, dimension handling verified. Ready for next phase of development.
Diffstat (limited to 'src/gpu/effects/flash_cube_effect.cc')
| -rw-r--r-- | src/gpu/effects/flash_cube_effect.cc | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/gpu/effects/flash_cube_effect.cc b/src/gpu/effects/flash_cube_effect.cc new file mode 100644 index 0000000..44f6e2b --- /dev/null +++ b/src/gpu/effects/flash_cube_effect.cc @@ -0,0 +1,96 @@ +// This file is part of the 64k demo project. +// It implements the FlashCubeEffect - a flashing background cube with Perlin noise. + +#include "gpu/effects/flash_cube_effect.h" +#include "generated/assets.h" +#include "util/asset_manager.h" +#include <cmath> +#include <iostream> + +FlashCubeEffect::FlashCubeEffect(WGPUDevice device, WGPUQueue queue, + WGPUTextureFormat format) + : Effect(device, queue) { + (void)format; +} + +void FlashCubeEffect::resize(int width, int height) { + width_ = width; + height_ = height; + renderer_.resize(width_, height_); +} + +void FlashCubeEffect::init(MainSequence* demo) { + (void)demo; + WGPUTextureFormat format = demo->format; + + renderer_.init(device_, queue_, format); + renderer_.resize(width_, height_); + + // Texture Manager + texture_manager_.init(device_, queue_); + + // Load Perlin noise texture + size_t size = 0; + const uint8_t* noise_data = GetAsset(AssetId::ASSET_NOISE_TEX, &size); + if (noise_data && size == 256 * 256 * 4) { + texture_manager_.create_texture("noise", 256, 256, noise_data); + renderer_.set_noise_texture(texture_manager_.get_texture_view("noise")); + } else { + std::cerr << "Failed to load NOISE_TEX asset for FlashCubeEffect." << std::endl; + } + + // Create a very large background cube + // Scale and distance ensure it's clearly behind foreground objects + scene_.clear(); + Object3D cube(ObjectType::BOX); + cube.position = vec3(0, 0, 0); + cube.scale = vec3(100.0f, 100.0f, 100.0f); // Much larger cube + cube.color = vec4(0.3f, 0.3f, 0.5f, 1.0f); // Dark blue base color + scene_.add_object(cube); +} + +void FlashCubeEffect::render(WGPURenderPassEncoder pass, float time, float beat, + float intensity, float aspect_ratio) { + // Detect beat changes for flash trigger (using intensity as proxy for beat hits) + // Intensity spikes on beats, so we can use it to trigger flashes + if (intensity > 0.5f && flash_intensity_ < 0.3f) { // High intensity + flash cooled down + flash_intensity_ = 1.0f; // Trigger full flash + } + + // Exponential decay of flash + flash_intensity_ *= 0.90f; // Slower fade for more visible effect + + // Always have base brightness, add flash on top + float base_brightness = 0.2f; + float flash_boost = base_brightness + flash_intensity_ * 0.8f; // 0.2 to 1.0 range + + scene_.objects[0].color = vec4( + 0.4f * flash_boost, // Reddish tint + 0.6f * flash_boost, // More green + 1.0f * flash_boost, // Strong blue for background feel + 1.0f + ); + + // Slowly rotate the cube for visual interest + scene_.objects[0].rotation = quat::from_axis(vec3(0.3f, 1, 0.2f), time * 0.05f); + + // Position camera OUTSIDE the cube looking at it from a distance + // This way we see the cube as a background element + float cam_distance = 150.0f; // Much farther to ensure it's behind everything + float orbit_angle = time * 0.1f; + + camera_.set_look_at( + vec3(std::sin(orbit_angle) * cam_distance, + std::cos(orbit_angle * 0.3f) * 30.0f, + std::cos(orbit_angle) * cam_distance), // Camera orbits around + vec3(0, 0, 0), // Look at cube center + vec3(0, 1, 0) + ); + + camera_.aspect_ratio = aspect_ratio; + // Extend far plane to accommodate distant camera position (150 units + cube size) + camera_.far_plane = 300.0f; + + // Draw the cube + renderer_.draw(pass, scene_, camera_, time); +} |
