summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt11
-rw-r--r--LOG.txt42
-rw-r--r--src/3d/renderer.cc52
-rw-r--r--src/3d/renderer.h23
-rw-r--r--src/gpu/demo_effects.h7
-rw-r--r--src/gpu/effect.cc16
-rw-r--r--src/gpu/effect.h3
-rw-r--r--src/gpu/effects/hybrid_3d_effect.cc83
-rw-r--r--src/gpu/effects/hybrid_3d_effect.h10
-rw-r--r--src/gpu/texture_manager.cc12
-rw-r--r--src/gpu/texture_manager.h5
-rw-r--r--src/tests/test_assets.cc16
-rw-r--r--src/tests/test_sequence.cc4
-rw-r--r--src/util/asset_manager.cc68
-rw-r--r--src/util/asset_manager.h18
-rw-r--r--tools/asset_packer.cc189
16 files changed, 291 insertions, 268 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b9fe43..1ece90c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -89,7 +89,6 @@ set(GPU_SOURCES
src/gpu/texture_manager.cc
src/3d/renderer.cc
)
-set(UTIL_SOURCES src/util/asset_manager.cc ${GEN_DEMO_CC})
set(PLATFORM_SOURCES src/platform.cc third_party/glfw3webgpu/glfw3webgpu.c)
#-- - Tools Setup -- -
@@ -143,6 +142,8 @@ add_custom_target(generate_timeline ALL DEPENDS ${GENERATED_TIMELINE_CC})
pack_assets(assets ${CMAKE_CURRENT_SOURCE_DIR}/assets/final/demo_assets.txt GEN_DEMO_H GEN_DEMO_CC generate_demo_assets)
pack_assets(test_assets ${CMAKE_CURRENT_SOURCE_DIR}/assets/final/test_assets_list.txt GEN_TEST_H GEN_TEST_CC generate_test_assets)
+set(UTIL_SOURCES src/util/asset_manager.cc)
+
#-- - Main Demo -- -
add_executable(demo64k src/main.cc ${PLATFORM_SOURCES} ${GPU_SOURCES} ${AUDIO_SOURCES} ${PROCEDURAL_SOURCES} ${UTIL_SOURCES} ${GEN_DEMO_CC} ${GENERATED_TIMELINE_CC})
add_dependencies(demo64k generate_demo_assets generate_timeline)
@@ -185,9 +186,9 @@ if(DEMO_BUILD_TESTS)
set_source_files_properties(src/tests/test_assets.cc PROPERTIES COMPILE_DEFINITIONS "USE_TEST_ASSETS")
add_test(NAME AssetManagerTest COMMAND test_assets)
- add_executable(test_sequence src/tests/test_sequence.cc ${GPU_SOURCES} ${GENERATED_TIMELINE_CC} ${PLATFORM_SOURCES} ${UTIL_SOURCES})
+ add_executable(test_sequence src/tests/test_sequence.cc ${GPU_SOURCES} ${UTIL_SOURCES} ${GEN_DEMO_CC} ${PROCEDURAL_SOURCES} ${GENERATED_TIMELINE_CC} ${PLATFORM_SOURCES})
target_link_libraries(test_sequence PRIVATE ${DEMO_LIBS})
- add_dependencies(test_sequence generate_timeline)
+ add_dependencies(test_sequence generate_timeline generate_demo_assets)
add_test(NAME SequenceSystemTest COMMAND test_sequence)
add_executable(test_procedural src/tests/test_procedural.cc ${PROCEDURAL_SOURCES})
@@ -196,11 +197,11 @@ if(DEMO_BUILD_TESTS)
add_executable(test_3d src/tests/test_3d.cc)
add_test(NAME ThreeDSystemTest COMMAND test_3d)
- add_executable(test_texture_manager src/tests/test_texture_manager.cc ${GPU_SOURCES} ${PLATFORM_SOURCES} ${PROCEDURAL_SOURCES} ${AUDIO_SOURCES} ${GENERATED_TIMELINE_CC} ${UTIL_SOURCES})
+ add_executable(test_texture_manager src/tests/test_texture_manager.cc ${GPU_SOURCES} ${PLATFORM_SOURCES} ${PROCEDURAL_SOURCES} ${AUDIO_SOURCES} ${GENERATED_TIMELINE_CC} ${UTIL_SOURCES} ${GEN_DEMO_CC})
target_link_libraries(test_texture_manager PRIVATE ${DEMO_LIBS})
add_test(NAME TextureManagerTest COMMAND test_texture_manager)
- add_executable(test_3d_render src/tests/test_3d_render.cc src/3d/renderer.cc ${GPU_SOURCES} ${PLATFORM_SOURCES} ${PROCEDURAL_SOURCES} ${AUDIO_SOURCES} ${GENERATED_TIMELINE_CC} ${UTIL_SOURCES})
+ add_executable(test_3d_render src/tests/test_3d_render.cc src/3d/renderer.cc ${GPU_SOURCES} ${PLATFORM_SOURCES} ${PROCEDURAL_SOURCES} ${AUDIO_SOURCES} ${GENERATED_TIMELINE_CC} ${UTIL_SOURCES} ${GEN_DEMO_CC})
target_link_libraries(test_3d_render PRIVATE ${DEMO_LIBS})
endif()
diff --git a/LOG.txt b/LOG.txt
deleted file mode 100644
index 15e3624..0000000
--- a/LOG.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-
-thread '<unnamed>' (8339722) panicked at src/lib.rs:423:5:
-wgpu uncaptured error:
-Validation Error
-
-Caused by:
- In wgpuDeviceCreateShaderModule
-
-Shader '' parsing error: name `type` is a reserved keyword
- ┌─ wgsl:84:27
- │
-84 │ fn get_dist(p: vec3<f32>, type: f32) -> f32 {
- │ ^^^^ definition of `type`
-
-
-
-
-note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-
-thread '<unnamed>' (8339722) panicked at library/core/src/panicking.rs:230:5:
-panic in a function that cannot unwind
-stack backtrace:
- 0: 0x10351b5e0 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h5b9122f5e70f5951
- 1: 0x103539194 - core::fmt::write::h6a8a2c9e4d999818
- 2: 0x10351b854 - std::io::default_write_fmt::h89b6c507b2c6ffa7
- 3: 0x10351a488 - std::panicking::default_hook::{{closure}}::h24b4617c01d6581d
- 4: 0x10351a370 - std::panicking::default_hook::h1955ee9a9845dfef
- 5: 0x10351a754 - std::panicking::panic_with_hook::h8aad6dd2389d8f59
- 6: 0x10351a564 - std::panicking::panic_handler::{{closure}}::h3bd15449212d5b6e
- 7: 0x10351a1e4 - std::sys::backtrace::__rust_end_short_backtrace::h3b25181b9f11fe05
- 8: 0x103519660 - __rustc[18f9140b322fd06e]::rust_begin_unwind
- 9: 0x103565f6c - core::panicking::panic_nounwind_fmt::h7a4dae3ab8fc5259
- 10: 0x103565ed0 - core::panicking::panic_nounwind::h959d775d33fc4688
- 11: 0x103566070 - core::panicking::panic_cannot_unwind::hda7331a7075802a1
- 12: 0x103540fe0 - wgpu_native::default_uncaptured_error_handler::h5258404c53f3ccc3
- 13: 0x1031aef0c - wgpu_native::ErrorSinkRaw::handle_error::h097d2dd0698a0260
- 14: 0x1031af590 - wgpu_native::handle_error::h00f841fd1f822b11
- 15: 0x1031c88d0 - _wgpuDeviceCreateShaderModule
- 16: 0x102755f4c - __ZN10Renderer3D15create_pipelineEv
- 17: 0x102755cbc - __ZN10Renderer3D4initEP14WGPUDeviceImplP13WGPUQueueImpl17WGPUTextureFormat
- 18: 0x10275374c - _main
-thread caused non-unwinding panic. aborting.
diff --git a/src/3d/renderer.cc b/src/3d/renderer.cc
index 0a2ae9a..db9d73d 100644
--- a/src/3d/renderer.cc
+++ b/src/3d/renderer.cc
@@ -3,8 +3,8 @@
#include "3d/renderer.h"
#include <algorithm>
-#include <cstring>
#include <cassert>
+#include <cstring>
#include <iostream>
static const char* kShaderCode = R"(
@@ -429,17 +429,14 @@ void Renderer3D::update_uniforms(const Scene& scene, const Camera& camera,
}
}
-void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene, const Camera& camera, float time) {
-
+void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene,
+ const Camera& camera, float time) {
update_uniforms(scene, camera, time);
-
-
// Lazy Bind Group creation
- if (bind_group_) wgpuBindGroupRelease(bind_group_);
-
-
+ if (bind_group_)
+ wgpuBindGroupRelease(bind_group_);
WGPUBindGroupEntry bg_entries[4] = {};
@@ -463,8 +460,6 @@ void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene, const Came
bg_entries[3].sampler = default_sampler_;
-
-
WGPUBindGroupDescriptor bg_desc = {};
bg_desc.layout = wgpuRenderPipelineGetBindGroupLayout(pipeline_, 0);
@@ -477,35 +472,26 @@ void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene, const Came
wgpuBindGroupLayoutRelease(bg_desc.layout);
-
-
wgpuRenderPassEncoderSetPipeline(pass, pipeline_);
wgpuRenderPassEncoderSetBindGroup(pass, 0, bind_group_, 0, nullptr);
-
-
- uint32_t instance_count = (uint32_t)std::min((size_t)kMaxObjects, scene.objects.size());
+ uint32_t instance_count =
+ (uint32_t)std::min((size_t)kMaxObjects, scene.objects.size());
if (instance_count > 0) {
-
wgpuRenderPassEncoderDraw(pass, 36, instance_count, 0, 0);
-
}
-
}
-
-
void Renderer3D::render(const Scene& scene, const Camera& camera, float time,
- WGPUTextureView target_view, WGPUTextureView depth_view_opt) {
-
+ WGPUTextureView target_view,
+ WGPUTextureView depth_view_opt) {
WGPUTextureView depth_view = depth_view_opt ? depth_view_opt : depth_view_;
- if (!depth_view) return;
-
-
+ if (!depth_view)
+ return;
WGPURenderPassColorAttachment color_attachment = {};
@@ -513,8 +499,6 @@ void Renderer3D::render(const Scene& scene, const Camera& camera, float time,
color_attachment.clearValue = {0.05, 0.05, 0.1, 1.0};
-
-
WGPURenderPassDepthStencilAttachment depth_attachment = {};
depth_attachment.view = depth_view;
@@ -525,8 +509,6 @@ void Renderer3D::render(const Scene& scene, const Camera& camera, float time,
depth_attachment.depthClearValue = 1.0f;
-
-
WGPURenderPassDescriptor pass_desc = {};
pass_desc.colorAttachmentCount = 1;
@@ -535,30 +517,22 @@ void Renderer3D::render(const Scene& scene, const Camera& camera, float time,
pass_desc.depthStencilAttachment = &depth_attachment;
-
-
WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device_, nullptr);
- WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &pass_desc);
-
-
+ WGPURenderPassEncoder pass =
+ wgpuCommandEncoderBeginRenderPass(encoder, &pass_desc);
draw(pass, scene, camera, time);
-
-
wgpuRenderPassEncoderEnd(pass);
WGPUCommandBuffer commands = wgpuCommandEncoderFinish(encoder, nullptr);
wgpuQueueSubmit(queue_, 1, &commands);
-
-
wgpuRenderPassEncoderRelease(pass);
wgpuCommandBufferRelease(commands);
wgpuCommandEncoderRelease(encoder);
-
} \ No newline at end of file
diff --git a/src/3d/renderer.h b/src/3d/renderer.h
index e87d47a..8cb379b 100644
--- a/src/3d/renderer.h
+++ b/src/3d/renderer.h
@@ -28,25 +28,24 @@ class Renderer3D {
void init(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format);
void shutdown();
- // Renders the scene to the given texture view (Convenience: creates a pass)
+ // Renders the scene to the given texture view (Convenience: creates a pass)
- void render(const Scene& scene, const Camera& camera, float time,
+ void render(const Scene& scene, const Camera& camera, float time,
- WGPUTextureView target_view, WGPUTextureView depth_view_opt = nullptr);
+ WGPUTextureView target_view,
+ WGPUTextureView depth_view_opt = nullptr);
-
+ // Records draw commands to an existing pass.
- // Records draw commands to an existing pass.
+ // Assumes the pass has a compatible pipeline (or we set it here).
- // Assumes the pass has a compatible pipeline (or we set it here).
+ // Note: Caller must ensure depth/color attachments are set up correctly in
+ // the pass.
- // Note: Caller must ensure depth/color attachments are set up correctly in the pass.
+ void draw(WGPURenderPassEncoder pass, const Scene& scene,
+ const Camera& camera, float time);
- void draw(WGPURenderPassEncoder pass, const Scene& scene, const Camera& camera, float time);
-
-
-
- void set_noise_texture(WGPUTextureView noise_view);
+ void set_noise_texture(WGPUTextureView noise_view);
// Resize handler (if needed for internal buffers)
void resize(int width, int height);
diff --git a/src/gpu/demo_effects.h b/src/gpu/demo_effects.h
index 0ff75b9..1f3c526 100644
--- a/src/gpu/demo_effects.h
+++ b/src/gpu/demo_effects.h
@@ -2,13 +2,13 @@
// It declares the concrete effects used in the demo.
#pragma once
+#include "3d/camera.h"
+#include "3d/renderer.h"
+#include "3d/scene.h"
#include "effect.h"
#include "gpu/effects/post_process_helper.h"
#include "gpu/effects/shaders.h"
#include "gpu/gpu.h"
-#include "3d/renderer.h"
-#include "3d/scene.h"
-#include "3d/camera.h"
#include "gpu/texture_manager.h"
#include <memory>
@@ -118,6 +118,7 @@ class Hybrid3DEffect : public Effect {
void init(MainSequence* demo) override;
void render(WGPURenderPassEncoder pass, float time, float beat,
float intensity, float aspect_ratio) override;
+
private:
Renderer3D renderer_;
TextureManager texture_manager_;
diff --git a/src/gpu/effect.cc b/src/gpu/effect.cc
index fdc604c..b2e0c4e 100644
--- a/src/gpu/effect.cc
+++ b/src/gpu/effect.cc
@@ -131,6 +131,14 @@ void MainSequence::create_framebuffers(int width, int height) {
depth_view_ = wgpuTextureCreateView(depth_texture_, &depth_view_desc);
}
+void MainSequence::init_test(WGPUDevice d, WGPUQueue q, WGPUTextureFormat f) {
+ device = d;
+ queue = q;
+ format = f;
+ // No framebuffers or passthrough effect created in test mode.
+ // Test effects should not rely on these being real.
+}
+
void MainSequence::init(WGPUDevice d, WGPUQueue q, WGPUTextureFormat f,
int width, int height) {
device = d;
@@ -197,7 +205,7 @@ void MainSequence::render_frame(float global_time, float beat, float peak,
#if !defined(DEMO_CROSS_COMPILE_WIN32)
scene_attachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
#endif /* !defined(DEMO_CROSS_COMPILE_WIN32) */
-
+
WGPURenderPassDepthStencilAttachment depth_attachment = {};
depth_attachment.view = depth_view_;
depth_attachment.depthLoadOp = WGPULoadOp_Clear;
@@ -206,7 +214,8 @@ void MainSequence::render_frame(float global_time, float beat, float peak,
WGPURenderPassDescriptor scene_desc = {.colorAttachmentCount = 1,
.colorAttachments = &scene_attachment,
- .depthStencilAttachment = &depth_attachment};
+ .depthStencilAttachment =
+ &depth_attachment};
WGPURenderPassEncoder scene_pass =
wgpuCommandEncoderBeginRenderPass(encoder, &scene_desc);
for (const SequenceItem* item : scene_effects) {
@@ -224,7 +233,8 @@ void MainSequence::render_frame(float global_time, float beat, float peak,
final_view = wgpuTextureCreateView(st.texture, nullptr);
// Safely cast to PostProcessEffect to call update_bind_group
- PostProcessEffect* pp_effect = (PostProcessEffect*)passthrough_effect_.get();
+ PostProcessEffect* pp_effect =
+ (PostProcessEffect*)passthrough_effect_.get();
pp_effect->update_bind_group(framebuffer_view_a_);
WGPURenderPassColorAttachment final_attachment = {};
diff --git a/src/gpu/effect.h b/src/gpu/effect.h
index 5d6b666..29f8e85 100644
--- a/src/gpu/effect.h
+++ b/src/gpu/effect.h
@@ -100,6 +100,7 @@ class MainSequence {
void init(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format,
int width, int height);
+ void init_test(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format);
void add_sequence(std::shared_ptr<Sequence> seq, float start_time,
int priority = 0);
void render_frame(float global_time, float beat, float peak,
@@ -122,7 +123,7 @@ class MainSequence {
WGPUTextureView framebuffer_view_a_ = nullptr;
WGPUTexture framebuffer_b_ = nullptr;
WGPUTextureView framebuffer_view_b_ = nullptr;
-
+
WGPUTexture depth_texture_ = nullptr;
WGPUTextureView depth_view_ = nullptr;
diff --git a/src/gpu/effects/hybrid_3d_effect.cc b/src/gpu/effects/hybrid_3d_effect.cc
index 41ede0b..6af2bd4 100644
--- a/src/gpu/effects/hybrid_3d_effect.cc
+++ b/src/gpu/effects/hybrid_3d_effect.cc
@@ -2,34 +2,38 @@
// It implements the Hybrid3DEffect.
#include "gpu/effects/hybrid_3d_effect.h"
-#include "util/asset_manager.h"
#include "generated/assets.h"
-#include <cmath>
+#include "util/asset_manager.h"
#include <cassert>
+#include <cmath>
#include <iostream>
-Hybrid3DEffect::Hybrid3DEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : Effect(device, queue), width_(1280), height_(720) {
+Hybrid3DEffect::Hybrid3DEffect(WGPUDevice device, WGPUQueue queue,
+ WGPUTextureFormat format)
+ : Effect(device, queue), width_(1280), height_(720) {
(void)format; // Passed to base, not directly used here.
}
void Hybrid3DEffect::init(MainSequence* demo) {
- (void)demo;
- WGPUTextureFormat format = demo->format; // Get current format from MainSequence (might be different than constructor if resized)
-
+ (void)demo;
+ WGPUTextureFormat format =
+ demo->format; // Get current format from MainSequence (might be different
+ // than constructor if resized)
+
renderer_.init(device_, queue_, format);
renderer_.resize(width_, height_);
// Texture Manager
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);
- renderer_.set_noise_texture(texture_manager_.get_texture_view("noise"));
+ 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." << std::endl;
+ std::cerr << "Failed to load NOISE_TEX asset." << std::endl;
}
// Setup Scene
@@ -41,40 +45,45 @@ void Hybrid3DEffect::init(MainSequence* demo) {
for (int i = 0; i < 8; ++i) {
ObjectType type = ObjectType::SPHERE;
- if (i % 3 == 1) type = ObjectType::TORUS;
- if (i % 3 == 2) type = ObjectType::BOX;
-
+ if (i % 3 == 1)
+ type = ObjectType::TORUS;
+ if (i % 3 == 2)
+ type = ObjectType::BOX;
+
Object3D obj(type);
float angle = (i / 8.0f) * 6.28318f;
obj.position = vec3(std::cos(angle) * 4.0f, 0, std::sin(angle) * 4.0f);
obj.scale = vec3(0.5f, 0.5f, 0.5f);
-
- if (type == ObjectType::SPHERE) obj.color = vec4(0, 1, 0, 1);
- else if (type == ObjectType::TORUS) obj.color = vec4(0, 0.5, 1, 1);
- else obj.color = vec4(1, 1, 0, 1);
-
+
+ if (type == ObjectType::SPHERE)
+ obj.color = vec4(0, 1, 0, 1);
+ else if (type == ObjectType::TORUS)
+ obj.color = vec4(0, 0.5, 1, 1);
+ else
+ obj.color = vec4(1, 1, 0, 1);
+
scene_.add_object(obj);
}
}
-void Hybrid3DEffect::render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) {
- // Animate Objects
- for (size_t i = 1; i < scene_.objects.size(); ++i) {
- scene_.objects[i].rotation = quat::from_axis(vec3(0, 1, 0), time * 2.0f + i);
- scene_.objects[i].position.y = std::sin(time * 3.0f + i) * 1.5f;
- }
-
- // Animate Camera
- float cam_radius = 10.0f + std::sin(time * 0.3f) * 4.0f;
- float cam_height = 5.0f + std::cos(time * 0.4f) * 3.0f;
- camera_.set_look_at(
- vec3(std::sin(time * 0.5f) * cam_radius, cam_height, std::cos(time * 0.5f) * cam_radius),
- vec3(0, 0, 0),
- vec3(0, 1, 0)
- );
-
- camera_.aspect_ratio = aspect_ratio;
+void Hybrid3DEffect::render(WGPURenderPassEncoder pass, float time, float beat,
+ float intensity, float aspect_ratio) {
+ // Animate Objects
+ for (size_t i = 1; i < scene_.objects.size(); ++i) {
+ scene_.objects[i].rotation =
+ quat::from_axis(vec3(0, 1, 0), time * 2.0f + i);
+ scene_.objects[i].position.y = std::sin(time * 3.0f + i) * 1.5f;
+ }
+
+ // Animate Camera
+ float cam_radius = 10.0f + std::sin(time * 0.3f) * 4.0f;
+ float cam_height = 5.0f + std::cos(time * 0.4f) * 3.0f;
+ camera_.set_look_at(vec3(std::sin(time * 0.5f) * cam_radius, cam_height,
+ std::cos(time * 0.5f) * cam_radius),
+ vec3(0, 0, 0), vec3(0, 1, 0));
+
+ camera_.aspect_ratio = aspect_ratio;
- // Draw
- renderer_.draw(pass, scene_, camera_, time);
+ // Draw
+ renderer_.draw(pass, scene_, camera_, time);
}
diff --git a/src/gpu/effects/hybrid_3d_effect.h b/src/gpu/effects/hybrid_3d_effect.h
index 1b0eab7..ef62883 100644
--- a/src/gpu/effects/hybrid_3d_effect.h
+++ b/src/gpu/effects/hybrid_3d_effect.h
@@ -1,12 +1,13 @@
// This file is part of the 64k demo project.
-// It defines the Hybrid3DEffect, integrating the 3D renderer into the demo timeline.
+// It defines the Hybrid3DEffect, integrating the 3D renderer into the demo
+// timeline.
#pragma once
-#include "gpu/effect.h"
+#include "3d/camera.h"
#include "3d/renderer.h"
#include "3d/scene.h"
-#include "3d/camera.h"
+#include "gpu/effect.h"
#include "gpu/texture_manager.h"
class Hybrid3DEffect : public Effect {
@@ -15,7 +16,8 @@ class Hybrid3DEffect : public Effect {
virtual ~Hybrid3DEffect() override = default;
void init(MainSequence* demo) override;
- void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override;
+ void render(WGPURenderPassEncoder pass, float time, float beat,
+ float intensity, float aspect_ratio) override;
private:
Renderer3D renderer_;
diff --git a/src/gpu/texture_manager.cc b/src/gpu/texture_manager.cc
index f2d93ad..5da82c0 100644
--- a/src/gpu/texture_manager.cc
+++ b/src/gpu/texture_manager.cc
@@ -44,13 +44,13 @@ void TextureManager::create_procedural_texture(
#endif
}
-void TextureManager::create_texture(const std::string& name, int width, int height, const uint8_t* data) {
+void TextureManager::create_texture(const std::string& name, int width,
+ int height, const uint8_t* data) {
WGPUExtent3D tex_size = {(uint32_t)width, (uint32_t)height, 1};
// 2. Create GPU Texture
WGPUTextureDescriptor tex_desc = {};
- tex_desc.usage =
- WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst;
+ tex_desc.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst;
tex_desc.dimension = WGPUTextureDimension_2D;
tex_desc.size = tex_size;
tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
@@ -76,8 +76,8 @@ void TextureManager::create_texture(const std::string& name, int width, int heig
source_layout.bytesPerRow = width * 4;
source_layout.rowsPerImage = height;
- wgpuQueueWriteTexture(queue_, &destination, data,
- width * height * 4, &source_layout, &tex_size);
+ wgpuQueueWriteTexture(queue_, &destination, data, width * height * 4,
+ &source_layout, &tex_size);
// 4. Create View
WGPUTextureViewDescriptor view_desc = {};
@@ -97,7 +97,7 @@ void TextureManager::create_texture(const std::string& name, int width, int heig
gpu_tex.view = view;
gpu_tex.width = width;
gpu_tex.height = height;
-
+
textures_[name] = gpu_tex;
}
diff --git a/src/gpu/texture_manager.h b/src/gpu/texture_manager.h
index 54dcfeb..b97e6a8 100644
--- a/src/gpu/texture_manager.h
+++ b/src/gpu/texture_manager.h
@@ -37,9 +37,10 @@ class TextureManager {
// Registers and generates a texture immediately
void create_procedural_texture(const std::string& name,
const ProceduralTextureDef& def);
-
+
// Creates a texture from existing data (RGBA8)
- void create_texture(const std::string& name, int width, int height, const uint8_t* data);
+ void create_texture(const std::string& name, int width, int height,
+ const uint8_t* data);
// Retrieves a texture view by name (returns nullptr if not found)
WGPUTextureView get_texture_view(const std::string& name);
diff --git a/src/tests/test_assets.cc b/src/tests/test_assets.cc
index dd77b73..c7d41e5 100644
--- a/src/tests/test_assets.cc
+++ b/src/tests/test_assets.cc
@@ -51,11 +51,13 @@ int main() {
// Test procedural asset
printf("\nRunning Procedural Asset test...\n");
size_t proc_size = 0;
- const uint8_t* proc_data_1 = GetAsset(AssetId::ASSET_PROC_NOISE_256, &proc_size);
+ const uint8_t* proc_data_1 =
+ GetAsset(AssetId::ASSET_PROC_NOISE_256, &proc_size);
assert(proc_data_1 != nullptr);
assert(proc_size == 256 * 256 * 4); // 256x256 RGBA8
-
- // Verify first few bytes are not all zero (noise should produce non-zero data)
+
+ // Verify first few bytes are not all zero (noise should produce non-zero
+ // data)
bool non_zero_data = false;
for (size_t i = 0; i < 16; ++i) { // Check first 16 bytes
if (proc_data_1[i] != 0) {
@@ -69,10 +71,12 @@ int main() {
// Test DropAsset for procedural asset and re-generation
DropAsset(AssetId::ASSET_PROC_NOISE_256, proc_data_1);
// After dropping, GetAsset should generate new data
- const uint8_t* proc_data_2 = GetAsset(AssetId::ASSET_PROC_NOISE_256, &proc_size);
+ const uint8_t* proc_data_2 =
+ GetAsset(AssetId::ASSET_PROC_NOISE_256, &proc_size);
assert(proc_data_2 != nullptr);
- // assert(proc_data_1 != proc_data_2); // Removed: Allocator might reuse the same address
-
+ // assert(proc_data_1 != proc_data_2); // Removed: Allocator might reuse the
+ // same address
+
// Verify content again to ensure it was re-generated correctly
non_zero_data = false;
for (size_t i = 0; i < 16; ++i) {
diff --git a/src/tests/test_sequence.cc b/src/tests/test_sequence.cc
index a48c733..788e0b1 100644
--- a/src/tests/test_sequence.cc
+++ b/src/tests/test_sequence.cc
@@ -99,7 +99,7 @@ class DummyPostProcessEffect : public PostProcessEffect {
void test_effect_lifecycle() {
printf(" test_effect_lifecycle...\n");
MainSequence main_seq;
- main_seq.init(dummy_device, dummy_queue, dummy_format, 320, 200);
+ main_seq.init_test(dummy_device, dummy_queue, dummy_format);
auto effect1 = std::make_shared<DummyEffect>(dummy_device, dummy_queue);
auto seq1 = std::make_shared<Sequence>();
@@ -145,7 +145,7 @@ void test_simulate_until() {
#if !defined(STRIP_ALL)
printf(" test_simulate_until...\n");
MainSequence main_seq;
- main_seq.init(dummy_device, dummy_queue, dummy_format, 320, 240);
+ main_seq.init_test(dummy_device, dummy_queue, dummy_format);
auto effect1 = std::make_shared<DummyEffect>(dummy_device, dummy_queue);
auto seq1 = std::make_shared<Sequence>();
diff --git a/src/util/asset_manager.cc b/src/util/asset_manager.cc
index 2ad8ef9..845934b 100644
--- a/src/util/asset_manager.cc
+++ b/src/util/asset_manager.cc
@@ -8,12 +8,12 @@
#include "generated/assets.h"
#endif /* defined(USE_TEST_ASSETS) */
-#include <vector> // For potential dynamic allocation for procedural assets
-#include <new> // For placement new
-#include <cstdlib> // For free
-#include <iostream> // For std::cerr
-#include <map> // For kAssetManagerProcGenFuncMap
-#include <string> // For std::string in map
+#include <cstdlib> // For free
+#include <iostream> // For std::cerr
+#include <map> // For kAssetManagerProcGenFuncMap
+#include <new> // For placement new
+#include <string> // For std::string in map
+#include <vector> // For potential dynamic allocation for procedural assets
#include "procedural/generator.h" // For ProcGenFunc and procedural functions
@@ -41,17 +41,17 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) {
uint16_t index = (uint16_t)asset_id;
// Assert that ASSET_LAST_ID is not used for retrieval.
- // This ensures the size of the cache is correctly used and not accessed out of bounds.
- // If this assert fails, it means assets.txt has an ID larger than expected
- // or ASSET_LAST_ID is not correctly generated/updated.
- // This is a design decision: ASSET_LAST_ID is purely for sizing and range checking,
- // not for a valid asset retrieval itself.
+ // This ensures the size of the cache is correctly used and not accessed out
+ // of bounds. If this assert fails, it means assets.txt has an ID larger than
+ // expected or ASSET_LAST_ID is not correctly generated/updated. This is a
+ // design decision: ASSET_LAST_ID is purely for sizing and range checking, not
+ // for a valid asset retrieval itself.
if (index >= (uint16_t)AssetId::ASSET_LAST_ID) {
if (out_size)
*out_size = 0;
return nullptr; // Invalid asset_id
}
-
+
// Check cache first
if (g_asset_cache[index].data != nullptr) {
if (out_size)
@@ -59,7 +59,8 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) {
return g_asset_cache[index].data;
}
- // Not in cache, retrieve from static data (packed in binary) or generate procedurally
+ // Not in cache, retrieve from static data (packed in binary) or generate
+ // procedurally
if (index >= g_assets_count) {
if (out_size)
*out_size = 0;
@@ -71,36 +72,44 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) {
if (source_record.is_procedural) {
// Dynamically generate the asset
- auto it = kAssetManagerProcGenFuncMap.find(source_record.proc_func_name_str);
+ auto it =
+ kAssetManagerProcGenFuncMap.find(source_record.proc_func_name_str);
if (it == kAssetManagerProcGenFuncMap.end()) {
- std::cerr << "Error: Unknown procedural function at runtime: " << source_record.proc_func_name_str << std::endl;
- if (out_size) *out_size = 0;
- return nullptr; // Procedural asset without a generation function.
+ std::cerr << "Error: Unknown procedural function at runtime: "
+ << source_record.proc_func_name_str << std::endl;
+ if (out_size)
+ *out_size = 0;
+ return nullptr; // Procedural asset without a generation function.
}
ProcGenFunc proc_gen_func_ptr = it->second;
- // For this demo, assuming procedural textures are RGBA8 256x256 (for simplicity and bump mapping).
- // A more generic solution would pass dimensions in proc_params.
+ // For this demo, assuming procedural textures are RGBA8 256x256 (for
+ // simplicity and bump mapping). A more generic solution would pass
+ // dimensions in proc_params.
int width = 256, height = 256;
size_t data_size = width * height * 4; // RGBA8
uint8_t* generated_data = new (std::nothrow) uint8_t[data_size];
if (!generated_data) {
- std::cerr << "Error: Failed to allocate memory for procedural asset." << std::endl;
- if (out_size) *out_size = 0;
- return nullptr;
+ std::cerr << "Error: Failed to allocate memory for procedural asset."
+ << std::endl;
+ if (out_size)
+ *out_size = 0;
+ return nullptr;
}
- proc_gen_func_ptr(generated_data, width, height, source_record.proc_params, source_record.num_proc_params);
-
+ proc_gen_func_ptr(generated_data, width, height, source_record.proc_params,
+ source_record.num_proc_params);
+
cached_record.data = generated_data;
cached_record.size = data_size;
cached_record.is_procedural = true;
- // proc_gen_func, proc_params, num_proc_params already copied from source_record
+ // proc_gen_func, proc_params, num_proc_params already copied from
+ // source_record
} else {
// Static asset (copy from g_assets)
cached_record.is_procedural = false;
}
-
+
// Store in cache for future use
g_asset_cache[index] = cached_record;
@@ -115,9 +124,10 @@ void DropAsset(AssetId asset_id, const uint8_t* asset) {
return; // Invalid asset_id
}
- // Check if the asset is in cache and is procedural, and if the pointer matches.
- // This prevents accidentally freeing static data or freeing twice.
- if (g_asset_cache[index].data == asset && g_asset_cache[index].is_procedural) {
+ // Check if the asset is in cache and is procedural, and if the pointer
+ // matches. This prevents accidentally freeing static data or freeing twice.
+ if (g_asset_cache[index].data == asset &&
+ g_asset_cache[index].is_procedural) {
delete[] g_asset_cache[index].data;
g_asset_cache[index] = {}; // Zero out the struct to force re-generation
}
diff --git a/src/util/asset_manager.h b/src/util/asset_manager.h
index 00aafc0..b9cd778 100644
--- a/src/util/asset_manager.h
+++ b/src/util/asset_manager.h
@@ -8,16 +8,20 @@
enum class AssetId : uint16_t; // Forward declaration
-// Type for procedural generation functions: (buffer, width, height, params, num_params)
+// Type for procedural generation functions: (buffer, width, height, params,
+// num_params)
typedef void (*ProcGenFunc)(uint8_t*, int, int, const float*, int);
struct AssetRecord {
- const uint8_t* data; // Pointer to asset data (static or dynamic)
- size_t size; // Size of the asset data
- bool is_procedural; // True if data was dynamically allocated by a procedural generator
- const char* proc_func_name_str; // Name of procedural generation function (string literal)
- const float* proc_params; // Parameters for procedural generation (static, from assets.txt)
- int num_proc_params; // Number of procedural parameters
+ const uint8_t* data; // Pointer to asset data (static or dynamic)
+ size_t size; // Size of the asset data
+ bool is_procedural; // True if data was dynamically allocated by a procedural
+ // generator
+ const char* proc_func_name_str; // Name of procedural generation function
+ // (string literal)
+ const float* proc_params; // Parameters for procedural generation (static,
+ // from assets.txt)
+ int num_proc_params; // Number of procedural parameters
};
// Generic interface
diff --git a/tools/asset_packer.cc b/tools/asset_packer.cc
index a91552a..46934ce 100644
--- a/tools/asset_packer.cc
+++ b/tools/asset_packer.cc
@@ -2,18 +2,19 @@
// It implements the asset packer tool for demoscene resource management.
// Converts external files into embedded C++ byte arrays and look-up records.
-#include <cstdio> // for simplicity, use fprintf() for output generation
+#include <cstdio> // for simplicity, use fprintf() for output generation
#include <fstream>
#include <map>
+#include <regex> // For std::regex
+#include <stdexcept> // For std::stof exceptions
#include <string>
#include <vector>
-#include <stdexcept> // For std::stof exceptions
-#include <regex> // For std::regex
#include "procedural/generator.h" // For ProcGenFunc and procedural functions
#include "util/asset_manager.h" // For AssetRecord and AssetId
-// Map of procedural function names to their pointers (used only internally by asset_packer here, not generated)
+// Map of procedural function names to their pointers (used only internally by
+// asset_packer here, not generated)
static const std::map<std::string, ProcGenFunc> kAssetPackerProcGenFuncMap = {
{"gen_noise", procedural::gen_noise},
{"gen_grid", procedural::gen_grid},
@@ -22,21 +23,24 @@ static const std::map<std::string, ProcGenFunc> kAssetPackerProcGenFuncMap = {
// Helper struct to hold all information about an asset during parsing
struct AssetBuildInfo {
- std::string name;
- std::string filename; // Original filename for static assets
- bool is_procedural;
- std::string proc_func_name; // Function name string
+ std::string name;
+ std::string filename; // Original filename for static assets
+ bool is_procedural;
+ std::string proc_func_name; // Function name string
std::vector<float> proc_params; // Parameters for procedural function
// For generated C++ code
- std::string data_array_name; // ASSET_DATA_xxx for static
- std::string params_array_name; // ASSET_PROC_PARAMS_xxx for procedural
+ std::string data_array_name; // ASSET_DATA_xxx for static
+ std::string params_array_name; // ASSET_PROC_PARAMS_xxx for procedural
std::string func_name_str_name; // ASSET_PROC_FUNC_STR_xxx for procedural
};
int main(int argc, char* argv[]) {
if (argc != 4) {
- fprintf(stderr, "Usage: %s <assets.txt_path> <output_assets_h_path> <output_assets_data_cc_path>\n", argv[0]);
+ fprintf(stderr,
+ "Usage: %s <assets.txt_path> <output_assets_h_path> "
+ "<output_assets_data_cc_path>\n",
+ argv[0]);
return 1;
}
@@ -46,57 +50,77 @@ int main(int argc, char* argv[]) {
std::ifstream assets_txt_file(assets_txt_path);
if (!assets_txt_file.is_open()) {
- fprintf(stderr, "Error: Could not open assets.txt at %s\n", assets_txt_path.c_str());
+ fprintf(stderr, "Error: Could not open assets.txt at %s\n",
+ assets_txt_path.c_str());
return 1;
}
FILE* assets_h_file = std::fopen(output_assets_h_path.c_str(), "w");
if (!assets_h_file) {
- fprintf(stderr, "Error: Could not open output assets.h at %s\n", output_assets_h_path.c_str());
+ fprintf(stderr, "Error: Could not open output assets.h at %s\n",
+ output_assets_h_path.c_str());
return 1;
}
- FILE* assets_data_cc_file = std::fopen(output_assets_data_cc_path.c_str(), "w");
+ FILE* assets_data_cc_file =
+ std::fopen(output_assets_data_cc_path.c_str(), "w");
if (!assets_data_cc_file) {
- fprintf(stderr, "Error: Could not open output assets_data.cc at %s\n", output_assets_data_cc_path.c_str());
+ fprintf(stderr, "Error: Could not open output assets_data.cc at %s\n",
+ output_assets_data_cc_path.c_str());
return 1;
}
// Generate assets.h header
- fprintf(assets_h_file, "// This file is auto-generated by asset_packer.cc. Do not edit.\n\n");
+ fprintf(
+ assets_h_file,
+ "// This file is auto-generated by asset_packer.cc. Do not edit.\n\n");
fprintf(assets_h_file, "#pragma once\n");
fprintf(assets_h_file, "#include <cstdint>\n\n");
fprintf(assets_h_file, "enum class AssetId : uint16_t {\n");
- std::string generated_header_name = output_assets_h_path.substr(output_assets_h_path.find_last_of("/\\") + 1);
+ std::string generated_header_name =
+ output_assets_h_path.substr(output_assets_h_path.find_last_of("/\\") + 1);
// Generate assets_data.cc header
- fprintf(assets_data_cc_file, "// This file is auto-generated by asset_packer.cc. Do not edit.\n\n");
+ fprintf(
+ assets_data_cc_file,
+ "// This file is auto-generated by asset_packer.cc. Do not edit.\n\n");
fprintf(assets_data_cc_file, "#include \"util/asset_manager.h\"\n");
- fprintf(assets_data_cc_file, "#include \"generated/%s\"\n\n", generated_header_name.c_str());
+ fprintf(assets_data_cc_file, "#include \"generated/%s\"\n\n",
+ generated_header_name.c_str());
// Forward declare procedural functions for AssetRecord initialization
- fprintf(assets_data_cc_file, "namespace procedural { void gen_noise(uint8_t*, int, int, const float*, int); }\n");
- fprintf(assets_data_cc_file, "namespace procedural { void gen_grid(uint8_t*, int, int, const float*, int); }\n");
- fprintf(assets_data_cc_file, "namespace procedural { void make_periodic(uint8_t*, int, int, const float*, int); }\n\n");
+ fprintf(assets_data_cc_file,
+ "namespace procedural { void gen_noise(uint8_t*, int, int, const "
+ "float*, int); }\n");
+ fprintf(assets_data_cc_file,
+ "namespace procedural { void gen_grid(uint8_t*, int, int, const "
+ "float*, int); }\n");
+ fprintf(assets_data_cc_file,
+ "namespace procedural { void make_periodic(uint8_t*, int, int, const "
+ "float*, int); }\n\n");
std::vector<AssetBuildInfo> asset_build_infos;
int asset_id_counter = 0;
std::string line;
- // Updated regex pattern for new asset list format (Name, CompressionType, Filename, Description)
+ // Updated regex pattern for new asset list format (Name, CompressionType,
+ // Filename, Description)
std::regex asset_line_regex(
R"(^\s*([A-Z0-9_]+)\s*,\s*(PROC\([^)]*\)|[^,]+)\s*(?:,\s*([^,]*))?\s*(?:,\s*\"(.*)\")?\s*$)");
while (std::getline(assets_txt_file, line)) {
- if (line.empty() || line[0] == '#') continue;
+ if (line.empty() || line[0] == '#')
+ continue;
std::smatch matches;
- if (std::regex_search(line, matches, asset_line_regex) && matches.size() >= 3) {
+ if (std::regex_search(line, matches, asset_line_regex) &&
+ matches.size() >= 3) {
AssetBuildInfo info;
info.name = matches[1].str();
std::string compression_type_str = matches[2].str();
// Filename is now matches[3]
- info.filename = (matches.size() >= 4 && matches[3].matched) ? matches[3].str() : "_";
+ info.filename =
+ (matches.size() >= 4 && matches[3].matched) ? matches[3].str() : "_";
info.data_array_name = "ASSET_DATA_" + info.name;
info.params_array_name = "ASSET_PROC_PARAMS_" + info.name;
@@ -107,103 +131,128 @@ int main(int argc, char* argv[]) {
info.is_procedural = true;
size_t open_paren = compression_type_str.find('(');
size_t close_paren = compression_type_str.rfind(')');
- if (open_paren == std::string::npos || close_paren == std::string::npos) {
- fprintf(stderr, "Error: Invalid PROC() syntax for asset: %s, string: [%s]\n", info.name.c_str(), compression_type_str.c_str());
+ if (open_paren == std::string::npos ||
+ close_paren == std::string::npos) {
+ fprintf(stderr,
+ "Error: Invalid PROC() syntax for asset: %s, string: [%s]\n",
+ info.name.c_str(), compression_type_str.c_str());
return 1;
}
- std::string func_and_params_str = compression_type_str.substr(open_paren + 1, close_paren - open_paren - 1);
-
+ std::string func_and_params_str = compression_type_str.substr(
+ open_paren + 1, close_paren - open_paren - 1);
+
size_t params_start = func_and_params_str.find(',');
if (params_start != std::string::npos) {
std::string params_str = func_and_params_str.substr(params_start + 1);
info.proc_func_name = func_and_params_str.substr(0, params_start);
-
+
size_t current_pos = 0;
while (current_pos < params_str.length()) {
size_t comma_pos = params_str.find(',', current_pos);
- std::string param_val_str = (comma_pos == std::string::npos) ? params_str.substr(current_pos) : params_str.substr(current_pos, comma_pos - current_pos);
+ std::string param_val_str =
+ (comma_pos == std::string::npos)
+ ? params_str.substr(current_pos)
+ : params_str.substr(current_pos, comma_pos - current_pos);
param_val_str.erase(0, param_val_str.find_first_not_of(" \t\r\n"));
param_val_str.erase(param_val_str.find_last_not_of(" \t\r\n") + 1);
try {
info.proc_params.push_back(std::stof(param_val_str));
} catch (...) {
- fprintf(stderr, "Error: Invalid proc param for %s: %s\n", info.name.c_str(), param_val_str.c_str());
+ fprintf(stderr, "Error: Invalid proc param for %s: %s\n",
+ info.name.c_str(), param_val_str.c_str());
return 1;
}
- if (comma_pos == std::string::npos) break;
+ if (comma_pos == std::string::npos)
+ break;
current_pos = comma_pos + 1;
}
} else {
- info.proc_func_name = func_and_params_str;
+ info.proc_func_name = func_and_params_str;
}
// Validate procedural function name
// kAssetPackerProcGenFuncMap is defined globally for validation
- if (kAssetPackerProcGenFuncMap.find(info.proc_func_name) == kAssetPackerProcGenFuncMap.end()) {
- fprintf(stderr, "Error: Unknown procedural function: %s for asset: %s\n", info.proc_func_name.c_str(), info.name.c_str());
+ if (kAssetPackerProcGenFuncMap.find(info.proc_func_name) ==
+ kAssetPackerProcGenFuncMap.end()) {
+ fprintf(stderr,
+ "Error: Unknown procedural function: %s for asset: %s\n",
+ info.proc_func_name.c_str(), info.name.c_str());
return 1;
}
}
-
+
asset_build_infos.push_back(info);
- fprintf(assets_h_file, " ASSET_%s = %d,\n", info.name.c_str(), asset_id_counter++);
+ fprintf(assets_h_file, " ASSET_%s = %d,\n", info.name.c_str(),
+ asset_id_counter++);
} else {
- fprintf(stderr, "Warning: Skipping malformed line in assets.txt: %s\n", line.c_str());
+ fprintf(stderr, "Warning: Skipping malformed line in assets.txt: %s\n",
+ line.c_str());
}
}
fprintf(assets_h_file, " ASSET_LAST_ID = %d,\n", asset_id_counter);
fprintf(assets_h_file, "};\n");
- fprintf(assets_h_file, "#include \"util/asset_manager.h\"\n"); // Include here AFTER enum definition
+ fprintf(assets_h_file,
+ "#include \"util/asset_manager.h\"\n"); // Include here AFTER enum
+ // definition
std::fclose(assets_h_file);
for (const auto& info : asset_build_infos) {
- if (!info.is_procedural) {
- std::string base_dir = assets_txt_path.substr(0, assets_txt_path.find_last_of("/\\") + 1);
- std::ifstream asset_file(base_dir + info.filename, std::ios::binary);
- if (!asset_file.is_open()) {
- fprintf(stderr, "Error: Could not open asset file: %s\n", (base_dir + info.filename).c_str());
- return 1;
- }
- std::vector<uint8_t> buffer((std::istreambuf_iterator<char>(asset_file)), std::istreambuf_iterator<char>());
- fprintf(assets_data_cc_file, "static const uint8_t %s[] = {\n ", info.data_array_name.c_str());
- for (size_t i = 0; i < buffer.size(); ++i) {
- if (i > 0 && i % 12 == 0) fprintf(assets_data_cc_file, "\n ");
- fprintf(assets_data_cc_file, "0x%02x%s", buffer[i], (i == buffer.size() - 1 ? "" : ", "));
- }
- fprintf(assets_data_cc_file, "\n};\n");
- } else {
- fprintf(assets_data_cc_file, "static const float %s[] = {", info.params_array_name.c_str());
- for (size_t i = 0; i < info.proc_params.size(); ++i) {
- if (i > 0) fprintf(assets_data_cc_file, ", ");
- fprintf(assets_data_cc_file, "%f", info.proc_params[i]);
- }
- fprintf(assets_data_cc_file, "};\n\n");
- fprintf(assets_data_cc_file, "static const char* %s = \"%s\";\n\n", info.func_name_str_name.c_str(), info.proc_func_name.c_str());
+ if (!info.is_procedural) {
+ std::string base_dir =
+ assets_txt_path.substr(0, assets_txt_path.find_last_of("/\\") + 1);
+ std::ifstream asset_file(base_dir + info.filename, std::ios::binary);
+ if (!asset_file.is_open()) {
+ fprintf(stderr, "Error: Could not open asset file: %s\n",
+ (base_dir + info.filename).c_str());
+ return 1;
}
+ std::vector<uint8_t> buffer((std::istreambuf_iterator<char>(asset_file)),
+ std::istreambuf_iterator<char>());
+ fprintf(assets_data_cc_file, "static const uint8_t %s[] = {\n ",
+ info.data_array_name.c_str());
+ for (size_t i = 0; i < buffer.size(); ++i) {
+ if (i > 0 && i % 12 == 0)
+ fprintf(assets_data_cc_file, "\n ");
+ fprintf(assets_data_cc_file, "0x%02x%s", buffer[i],
+ (i == buffer.size() - 1 ? "" : ", "));
+ }
+ fprintf(assets_data_cc_file, "\n};\n");
+ } else {
+ fprintf(assets_data_cc_file, "static const float %s[] = {",
+ info.params_array_name.c_str());
+ for (size_t i = 0; i < info.proc_params.size(); ++i) {
+ if (i > 0)
+ fprintf(assets_data_cc_file, ", ");
+ fprintf(assets_data_cc_file, "%f", info.proc_params[i]);
+ }
+ fprintf(assets_data_cc_file, "};\n\n");
+ fprintf(assets_data_cc_file, "static const char* %s = \"%s\";\n\n",
+ info.func_name_str_name.c_str(), info.proc_func_name.c_str());
+ }
}
fprintf(assets_data_cc_file, "extern const AssetRecord g_assets[] = {\n");
for (const auto& info : asset_build_infos) {
fprintf(assets_data_cc_file, " { ");
if (info.is_procedural) {
- fprintf(assets_data_cc_file, "nullptr, 0, true, %s, %s, %zu",
- info.func_name_str_name.c_str(),
- info.params_array_name.c_str(),
+ fprintf(assets_data_cc_file, "nullptr, 0, true, %s, %s, %zu",
+ info.func_name_str_name.c_str(), info.params_array_name.c_str(),
info.proc_params.size());
} else {
fprintf(assets_data_cc_file, "%s, sizeof(%s), false, nullptr, nullptr, 0",
- info.data_array_name.c_str(),
- info.data_array_name.c_str());
+ info.data_array_name.c_str(), info.data_array_name.c_str());
}
fprintf(assets_data_cc_file, " },\n");
}
fprintf(assets_data_cc_file, "};\n");
- fprintf(assets_data_cc_file, "extern const size_t g_assets_count = sizeof(g_assets) / sizeof(g_assets[0]);\n");
+ fprintf(assets_data_cc_file,
+ "extern const size_t g_assets_count = sizeof(g_assets) / "
+ "sizeof(g_assets[0]);\n");
std::fclose(assets_data_cc_file);
-
+
printf("Asset packer successfully generated records for %zu assets.\n",
asset_build_infos.size());