diff options
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); +} |
