summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/effects/rotating_cube_effect_v2.cc184
-rw-r--r--src/effects/rotating_cube_effect_v2.h49
-rw-r--r--src/gpu/shaders.cc4
-rw-r--r--src/gpu/shaders.h1
4 files changed, 238 insertions, 0 deletions
diff --git a/src/effects/rotating_cube_effect_v2.cc b/src/effects/rotating_cube_effect_v2.cc
new file mode 100644
index 0000000..02ed2d3
--- /dev/null
+++ b/src/effects/rotating_cube_effect_v2.cc
@@ -0,0 +1,184 @@
+// This file is part of the 64k demo project.
+// It implements RotatingCubeEffectV2 (simplified v2 port).
+
+#include "effects/rotating_cube_effect_v2.h"
+#include "gpu/bind_group_builder.h"
+#include "gpu/gpu.h"
+#include "gpu/shaders.h"
+
+RotatingCubeEffectV2::RotatingCubeEffectV2(const GpuContext& ctx,
+ const std::vector<std::string>& inputs,
+ const std::vector<std::string>& outputs)
+ : EffectV2(ctx, inputs, outputs), depth_node_(outputs[0] + "_depth") {
+ // Create uniform buffers
+ uniform_buffer_ =
+ gpu_create_buffer(ctx_.device, sizeof(Uniforms),
+ WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst);
+ object_buffer_ =
+ gpu_create_buffer(ctx_.device, sizeof(ObjectData),
+ WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst);
+
+ // Create bind group layout
+ WGPUBindGroupLayout bgl =
+ BindGroupLayoutBuilder()
+ .uniform(0, WGPUShaderStage_Vertex | WGPUShaderStage_Fragment,
+ sizeof(Uniforms))
+ .storage(1, WGPUShaderStage_Vertex | WGPUShaderStage_Fragment,
+ sizeof(ObjectData))
+ .build(ctx_.device);
+
+ const WGPUBindGroupLayout bgls[] = {bgl};
+ const WGPUPipelineLayoutDescriptor pl_desc = {
+ .bindGroupLayoutCount = 1,
+ .bindGroupLayouts = bgls,
+ };
+ WGPUPipelineLayout pipeline_layout =
+ wgpuDeviceCreatePipelineLayout(ctx_.device, &pl_desc);
+
+ // Load shader (TODO: create rotating_cube_v2.wgsl)
+ WGPUShaderSourceWGSL wgsl_src = {};
+ wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL;
+ wgsl_src.code = str_view(rotating_cube_v2_wgsl);
+
+ WGPUShaderModuleDescriptor shader_desc = {};
+ shader_desc.nextInChain = &wgsl_src.chain;
+ WGPUShaderModule shader_module =
+ wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc);
+
+ const WGPUColorTargetState color_target = {
+ .format = WGPUTextureFormat_RGBA8Unorm,
+ .writeMask = WGPUColorWriteMask_All,
+ };
+
+ const WGPUDepthStencilState depth_stencil = {
+ .format = WGPUTextureFormat_Depth24Plus,
+ .depthWriteEnabled = WGPUOptionalBool_True,
+ .depthCompare = WGPUCompareFunction_Less,
+ };
+
+ WGPUFragmentState fragment = {};
+ fragment.module = shader_module;
+ fragment.entryPoint = str_view("fs_main");
+ fragment.targetCount = 1;
+ fragment.targets = &color_target;
+
+ WGPURenderPipelineDescriptor pipeline_desc = {};
+ pipeline_desc.layout = pipeline_layout;
+ pipeline_desc.vertex.module = shader_module;
+ pipeline_desc.vertex.entryPoint = str_view("vs_main");
+ pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList;
+ pipeline_desc.primitive.cullMode = WGPUCullMode_Back;
+ pipeline_desc.depthStencil = &depth_stencil;
+ pipeline_desc.multisample.count = 1;
+ pipeline_desc.multisample.mask = 0xFFFFFFFF;
+ pipeline_desc.fragment = &fragment;
+
+ pipeline_ = wgpuDeviceCreateRenderPipeline(ctx_.device, &pipeline_desc);
+ wgpuShaderModuleRelease(shader_module);
+ wgpuPipelineLayoutRelease(pipeline_layout);
+
+ // Create bind group
+ const WGPUBindGroupEntry entries[] = {
+ {.binding = 0,
+ .buffer = uniform_buffer_.buffer,
+ .size = sizeof(Uniforms)},
+ {.binding = 1,
+ .buffer = object_buffer_.buffer,
+ .size = sizeof(ObjectData)},
+ };
+
+ const WGPUBindGroupDescriptor bg_desc = {
+ .layout = bgl,
+ .entryCount = 2,
+ .entries = entries,
+ };
+ bind_group_ = wgpuDeviceCreateBindGroup(ctx_.device, &bg_desc);
+ wgpuBindGroupLayoutRelease(bgl);
+}
+
+RotatingCubeEffectV2::~RotatingCubeEffectV2() {
+ if (bind_group_)
+ wgpuBindGroupRelease(bind_group_);
+ if (pipeline_)
+ wgpuRenderPipelineRelease(pipeline_);
+}
+
+void RotatingCubeEffectV2::declare_nodes(NodeRegistry& registry) {
+ // Declare depth buffer node
+ registry.declare_node(depth_node_, NodeType::DEPTH24, -1, -1);
+}
+
+void RotatingCubeEffectV2::render(WGPUCommandEncoder encoder,
+ const UniformsSequenceParams& params,
+ NodeRegistry& nodes) {
+ rotation_ += 0.016f * 1.5f;
+
+ // Camera setup
+ const vec3 camera_pos = vec3(0, 0, 5);
+ const vec3 target = vec3(0, 0, 0);
+ const vec3 up = vec3(0, 1, 0);
+
+ const mat4 view = mat4::look_at(camera_pos, target, up);
+ const float fov = 60.0f * 3.14159f / 180.0f;
+ const mat4 proj = mat4::perspective(fov, params.aspect_ratio, 0.1f, 100.0f);
+ const mat4 view_proj = proj * view;
+
+ // Cube transform
+ const quat rot = quat::from_axis(vec3(0.3f, 1.0f, 0.2f), rotation_);
+ const mat4 T = mat4::translate(vec3(0, 0, 0));
+ const mat4 R = rot.to_mat();
+ const mat4 S = mat4::scale(vec3(1.5f, 1.5f, 1.5f));
+ const mat4 model = T * R * S;
+
+ // Update uniforms
+ const Uniforms uniforms = {
+ .view_proj = view_proj,
+ .inv_view_proj = view_proj.inverse(),
+ .camera_pos_time = vec4(camera_pos.x, camera_pos.y, camera_pos.z, params.time),
+ .params = vec4(1.0f, 0.0f, 0.0f, 0.0f),
+ .resolution = params.resolution,
+ .aspect_ratio = params.aspect_ratio,
+ };
+
+ const ObjectData obj_data = {
+ .model = model,
+ .inv_model = model.inverse(),
+ .color = vec4(0.8f, 0.4f, 0.2f, 1.0f),
+ .params = vec4(1.0f, 0.0f, 0.0f, 0.0f),
+ };
+
+ wgpuQueueWriteBuffer(ctx_.queue, uniform_buffer_.buffer, 0, &uniforms,
+ sizeof(Uniforms));
+ wgpuQueueWriteBuffer(ctx_.queue, object_buffer_.buffer, 0, &obj_data,
+ sizeof(ObjectData));
+
+ // Get output views
+ WGPUTextureView color_view = nodes.get_view(output_nodes_[0]);
+ WGPUTextureView depth_view = nodes.get_view(depth_node_);
+
+ // Render pass with depth
+ WGPURenderPassColorAttachment color_attachment = {
+ .view = color_view,
+ .depthSlice = WGPU_DEPTH_SLICE_UNDEFINED,
+ .loadOp = WGPULoadOp_Clear,
+ .storeOp = WGPUStoreOp_Store,
+ .clearValue = {0.0, 0.0, 0.0, 1.0}};
+
+ WGPURenderPassDepthStencilAttachment depth_attachment = {
+ .view = depth_view,
+ .depthLoadOp = WGPULoadOp_Clear,
+ .depthStoreOp = WGPUStoreOp_Discard,
+ .depthClearValue = 1.0f};
+
+ WGPURenderPassDescriptor pass_desc = {
+ .colorAttachmentCount = 1,
+ .colorAttachments = &color_attachment,
+ .depthStencilAttachment = &depth_attachment};
+
+ WGPURenderPassEncoder pass = wgpuCommandEncoderBeginRenderPass(encoder, &pass_desc);
+ wgpuRenderPassEncoderSetPipeline(pass, pipeline_);
+ wgpuRenderPassEncoderSetBindGroup(pass, 0, bind_group_, 0, nullptr);
+ wgpuRenderPassEncoderDraw(pass, 36, 1, 0, 0); // 36 vertices for cube
+ wgpuRenderPassEncoderEnd(pass);
+ wgpuRenderPassEncoderRelease(pass);
+}
diff --git a/src/effects/rotating_cube_effect_v2.h b/src/effects/rotating_cube_effect_v2.h
new file mode 100644
index 0000000..19ef410
--- /dev/null
+++ b/src/effects/rotating_cube_effect_v2.h
@@ -0,0 +1,49 @@
+// This file is part of the 64k demo project.
+// It declares RotatingCubeEffectV2 (simplified v2 port).
+
+#pragma once
+
+#include "gpu/effect_v2.h"
+#include "gpu/gpu.h"
+#include "gpu/uniform_helper.h"
+#include "util/mini_math.h"
+
+class RotatingCubeEffectV2 : public EffectV2 {
+ public:
+ RotatingCubeEffectV2(const GpuContext& ctx,
+ const std::vector<std::string>& inputs,
+ const std::vector<std::string>& outputs);
+ ~RotatingCubeEffectV2() override;
+
+ void declare_nodes(NodeRegistry& registry) override;
+ void render(WGPUCommandEncoder encoder,
+ const UniformsSequenceParams& params,
+ NodeRegistry& nodes) override;
+
+ private:
+ struct Uniforms {
+ mat4 view_proj;
+ mat4 inv_view_proj;
+ vec4 camera_pos_time;
+ vec4 params;
+ vec2 resolution;
+ float aspect_ratio;
+ float _pad;
+ };
+ static_assert(sizeof(Uniforms) == 176, "Uniforms size mismatch");
+
+ struct ObjectData {
+ mat4 model;
+ mat4 inv_model;
+ vec4 color;
+ vec4 params;
+ };
+ static_assert(sizeof(ObjectData) == 160, "ObjectData size mismatch");
+
+ WGPURenderPipeline pipeline_ = nullptr;
+ WGPUBindGroup bind_group_ = nullptr;
+ GpuBuffer uniform_buffer_;
+ GpuBuffer object_buffer_;
+ float rotation_ = 0.0f;
+ std::string depth_node_;
+};
diff --git a/src/gpu/shaders.cc b/src/gpu/shaders.cc
index bea1eb9..9c8beca 100644
--- a/src/gpu/shaders.cc
+++ b/src/gpu/shaders.cc
@@ -181,3 +181,7 @@ const char* particle_compute_v2_wgsl =
const char* particle_render_v2_wgsl =
SafeGetAsset(AssetId::ASSET_SHADER_PARTICLE_RENDER_V2);
+
+const char* rotating_cube_v2_wgsl =
+
+ SafeGetAsset(AssetId::ASSET_SHADER_ROTATING_CUBE_V2);
diff --git a/src/gpu/shaders.h b/src/gpu/shaders.h
index b7ee226..ab5ddf2 100644
--- a/src/gpu/shaders.h
+++ b/src/gpu/shaders.h
@@ -35,3 +35,4 @@ extern const char* gaussian_blur_v2_shader_wgsl;
extern const char* heptagon_v2_shader_wgsl;
extern const char* particle_compute_v2_wgsl;
extern const char* particle_render_v2_wgsl;
+extern const char* rotating_cube_v2_wgsl;