From de9c11d44788a9039ba1ef70f2d255898df37016 Mon Sep 17 00:00:00 2001 From: skal Date: Thu, 5 Feb 2026 20:03:21 +0100 Subject: fix(gpu): Use GetTextureAsset() for procedural texture loading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed demo64k crash caused by incorrect manual parsing of procedural texture headers in effects code. Problem: - Procedural textures (NOISE_TEX) have 8-byte header (width, height) - Effects checked size == 256*256*4 (262,144 bytes) - Actual size was 262,152 bytes (including header) - Size mismatch caused texture load failure → WebGPU bind group panic Solution: - Use GetTextureAsset() helper that properly parses header - Returns TextureAsset{width, height, pixels} with pixels pointing after header - Updated flash_cube_effect.cc and hybrid_3d_effect.cc Result: - Demo runs without crashes - NOISE_TEX loads correctly (256x256 RGBA8) - No more WebGPU bind group errors --- src/gpu/effects/hybrid_3d_effect.cc | 62 +++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 33 deletions(-) (limited to 'src/gpu/effects/hybrid_3d_effect.cc') diff --git a/src/gpu/effects/hybrid_3d_effect.cc b/src/gpu/effects/hybrid_3d_effect.cc index 0dbd786..cb77fef 100644 --- a/src/gpu/effects/hybrid_3d_effect.cc +++ b/src/gpu/effects/hybrid_3d_effect.cc @@ -33,10 +33,10 @@ void Hybrid3DEffect::init(MainSequence* demo) { texture_manager_.init(device_, queue_); // Load Noise Asset - 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); + TextureAsset noise_tex = GetTextureAsset(AssetId::ASSET_NOISE_TEX); + if (noise_tex.pixels && noise_tex.width == 256 && noise_tex.height == 256) { + texture_manager_.create_texture("noise", noise_tex.width, noise_tex.height, + noise_tex.pixels); renderer_.set_noise_texture(texture_manager_.get_texture_view("noise")); } else { std::cerr << "Failed to load NOISE_TEX asset." << std::endl; @@ -103,39 +103,35 @@ void Hybrid3DEffect::render(WGPURenderPassEncoder pass, float time, float beat, // Camera jumps every other pattern (2 seconds) for dramatic effect int pattern_num = (int)(time / 2.0f); - int camera_preset = pattern_num % 4; // Cycle through 4 different angles + int camera_preset = pattern_num % 4; // Cycle through 4 different angles vec3 cam_pos, cam_target; switch (camera_preset) { - case 0: // High angle, orbiting - { - float angle = time * 0.5f; - cam_pos = vec3(std::sin(angle) * 12.0f, 8.0f, std::cos(angle) * 12.0f); - cam_target = vec3(0, 0, 0); - } - break; - case 1: // Low angle, close-up - { - float angle = time * 0.3f + 1.57f; // Offset angle - cam_pos = vec3(std::sin(angle) * 6.0f, 2.0f, std::cos(angle) * 6.0f); - cam_target = vec3(0, 1, 0); - } - break; - case 2: // Side view, sweeping - { - float sweep = std::sin(time * 0.4f) * 10.0f; - cam_pos = vec3(sweep, 5.0f, 8.0f); - cam_target = vec3(0, 0, 0); - } - break; - case 3: // Top-down, rotating - { - float angle = time * 0.6f; - cam_pos = vec3(std::sin(angle) * 5.0f, 12.0f, std::cos(angle) * 5.0f); - cam_target = vec3(0, 0, 0); - } - break; + case 0: // High angle, orbiting + { + float angle = time * 0.5f; + cam_pos = vec3(std::sin(angle) * 12.0f, 8.0f, std::cos(angle) * 12.0f); + cam_target = vec3(0, 0, 0); + } break; + case 1: // Low angle, close-up + { + float angle = time * 0.3f + 1.57f; // Offset angle + cam_pos = vec3(std::sin(angle) * 6.0f, 2.0f, std::cos(angle) * 6.0f); + cam_target = vec3(0, 1, 0); + } break; + case 2: // Side view, sweeping + { + float sweep = std::sin(time * 0.4f) * 10.0f; + cam_pos = vec3(sweep, 5.0f, 8.0f); + cam_target = vec3(0, 0, 0); + } break; + case 3: // Top-down, rotating + { + float angle = time * 0.6f; + cam_pos = vec3(std::sin(angle) * 5.0f, 12.0f, std::cos(angle) * 5.0f); + cam_target = vec3(0, 0, 0); + } break; } camera_.set_look_at(cam_pos, cam_target, vec3(0, 1, 0)); -- cgit v1.2.3