summaryrefslogtreecommitdiff
path: root/src/gpu
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-01 10:51:15 +0100
committerskal <pascal.massimino@gmail.com>2026-02-01 10:51:15 +0100
commit8bdc4754647c9c6691130fa91d51fee93c5fc88f (patch)
tree2cfd7f72a21541c488ea48629eef47a6774fc2c4 /src/gpu
parent7905abd9f7ad35231289e729b42e3ad57a943ff5 (diff)
feat: Implement 3D system and procedural texture manager
- Extended mini_math.h with mat4 multiplication and affine transforms. - Implemented TextureManager for runtime procedural texture generation and GPU upload. - Added 3D system components: Camera, Object, Scene, and Renderer3D. - Created test_3d_render mini-demo for interactive 3D verification. - Fixed WebGPU validation errors regarding depthSlice and unimplemented WaitAny.
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/gpu.cc8
-rw-r--r--src/gpu/gpu.h10
-rw-r--r--src/gpu/texture_manager.cc107
-rw-r--r--src/gpu/texture_manager.h48
4 files changed, 165 insertions, 8 deletions
diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc
index a097efa..3cdf9aa 100644
--- a/src/gpu/gpu.cc
+++ b/src/gpu/gpu.cc
@@ -131,14 +131,6 @@ RenderPass gpu_create_render_pass(WGPUDevice device, WGPUTextureFormat format,
color_target.blend = nullptr;
// Add additive blending for particles
- WGPUBlendState blend = {};
- blend.color.srcFactor = WGPUBlendFactor_SrcAlpha;
- blend.color.dstFactor = WGPUBlendFactor_One;
- blend.color.operation = WGPUBlendOperation_Add;
- blend.alpha.srcFactor = WGPUBlendFactor_SrcAlpha;
- blend.alpha.dstFactor = WGPUBlendFactor_One;
- blend.alpha.operation = WGPUBlendOperation_Add;
- color_target.blend = &blend;
WGPUFragmentState fragment_state = {};
fragment_state.module = shader_module;
diff --git a/src/gpu/gpu.h b/src/gpu/gpu.h
index 8814cbc..b71e144 100644
--- a/src/gpu/gpu.h
+++ b/src/gpu/gpu.h
@@ -110,6 +110,16 @@ struct ResourceBinding {
// WGPUBufferBindingType_Storage
};
+// Cross-platform helper for color attachment initialization
+inline void gpu_init_color_attachment(WGPURenderPassColorAttachment& attachment, WGPUTextureView view) {
+ attachment.view = view;
+ attachment.loadOp = WGPULoadOp_Clear;
+ attachment.storeOp = WGPUStoreOp_Store;
+#if !defined(DEMO_CROSS_COMPILE_WIN32)
+ attachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
+#endif
+}
+
GpuBuffer gpu_create_buffer(WGPUDevice device, size_t size, uint32_t usage,
const void* data = nullptr);
ComputePass gpu_create_compute_pass(WGPUDevice device, const char* shader_code,
diff --git a/src/gpu/texture_manager.cc b/src/gpu/texture_manager.cc
new file mode 100644
index 0000000..7c314d2
--- /dev/null
+++ b/src/gpu/texture_manager.cc
@@ -0,0 +1,107 @@
+// This file is part of the 64k demo project.
+// It implements the TextureManager.
+
+#include "gpu/texture_manager.h"
+#include <iostream>
+#include <vector>
+
+#if defined(DEMO_CROSS_COMPILE_WIN32)
+// Old API
+#define WGPU_TEX_COPY_INFO WGPUImageCopyTexture
+#define WGPU_TEX_DATA_LAYOUT WGPUTextureDataLayout
+#else
+// New API
+#define WGPU_TEX_COPY_INFO WGPUTexelCopyTextureInfo
+#define WGPU_TEX_DATA_LAYOUT WGPUTexelCopyBufferLayout
+#endif
+
+void TextureManager::init(WGPUDevice device, WGPUQueue queue) {
+ device_ = device;
+ queue_ = queue;
+}
+
+void TextureManager::shutdown() {
+ for (auto& pair : textures_) {
+ wgpuTextureViewRelease(pair.second.view);
+ wgpuTextureRelease(pair.second.texture);
+ }
+ textures_.clear();
+}
+
+void TextureManager::create_procedural_texture(
+ const std::string& name, const ProceduralTextureDef& def) {
+ // 1. Generate Data on CPU
+ std::vector<uint8_t> pixel_data;
+ pixel_data.resize(def.width * def.height * 4);
+ def.gen_func(pixel_data.data(), def.width, def.height, def.params.data(),
+ (int)def.params.size());
+
+ WGPUExtent3D tex_size = {(uint32_t)def.width, (uint32_t)def.height, 1};
+
+ // 2. Create GPU Texture
+ WGPUTextureDescriptor tex_desc = {};
+ tex_desc.usage =
+ WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst;
+ tex_desc.dimension = WGPUTextureDimension_2D;
+ tex_desc.size = tex_size;
+ tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
+ tex_desc.mipLevelCount = 1;
+ tex_desc.sampleCount = 1;
+#if defined(DEMO_CROSS_COMPILE_WIN32)
+ tex_desc.label = nullptr;
+#else
+ tex_desc.label = {nullptr, 0};
+#endif
+
+ WGPUTexture texture = wgpuDeviceCreateTexture(device_, &tex_desc);
+
+ // 3. Upload Data
+ WGPU_TEX_COPY_INFO destination = {};
+ destination.texture = texture;
+ destination.mipLevel = 0;
+ destination.origin = {0, 0, 0};
+ destination.aspect = WGPUTextureAspect_All;
+
+ WGPU_TEX_DATA_LAYOUT source_layout = {};
+ source_layout.offset = 0;
+ source_layout.bytesPerRow = def.width * 4;
+ source_layout.rowsPerImage = def.height;
+
+ wgpuQueueWriteTexture(queue_, &destination, pixel_data.data(),
+ pixel_data.size(), &source_layout, &tex_size);
+
+
+ // 4. Create View
+ WGPUTextureViewDescriptor view_desc = {};
+ view_desc.format = WGPUTextureFormat_RGBA8Unorm;
+ view_desc.dimension = WGPUTextureViewDimension_2D;
+ view_desc.baseMipLevel = 0;
+ view_desc.mipLevelCount = 1;
+ view_desc.baseArrayLayer = 0;
+ view_desc.arrayLayerCount = 1;
+ view_desc.aspect = WGPUTextureAspect_All;
+
+ WGPUTextureView view = wgpuTextureCreateView(texture, &view_desc);
+
+ // 5. Store
+ GpuTexture gpu_tex;
+ gpu_tex.texture = texture;
+ gpu_tex.view = view;
+ gpu_tex.width = def.width;
+ gpu_tex.height = def.height;
+
+ textures_[name] = gpu_tex;
+
+#if !defined(STRIP_ALL)
+ std::cout << "Generated procedural texture: " << name << " (" << def.width
+ << "x" << def.height << ")" << std::endl;
+#endif
+}
+
+WGPUTextureView TextureManager::get_texture_view(const std::string& name) {
+ auto it = textures_.find(name);
+ if (it != textures_.end()) {
+ return it->second.view;
+ }
+ return nullptr;
+}
diff --git a/src/gpu/texture_manager.h b/src/gpu/texture_manager.h
new file mode 100644
index 0000000..3faf74c
--- /dev/null
+++ b/src/gpu/texture_manager.h
@@ -0,0 +1,48 @@
+// This file is part of the 64k demo project.
+// It defines the TextureManager for procedural assets.
+// Handles generation and GPU upload of procedural textures.
+
+#pragma once
+
+#include "gpu/gpu.h"
+#include <map>
+#include <string>
+#include <vector>
+
+#if defined(DEMO_CROSS_COMPILE_WIN32)
+#include <webgpu/webgpu.h>
+#else
+#include <webgpu.h>
+#endif
+
+struct ProceduralTextureDef {
+ int width;
+ int height;
+ void (*gen_func)(uint8_t*, int, int, const float*, int);
+ std::vector<float> params;
+};
+
+struct GpuTexture {
+ WGPUTexture texture;
+ WGPUTextureView view;
+ int width;
+ int height;
+};
+
+class TextureManager {
+ public:
+ void init(WGPUDevice device, WGPUQueue queue);
+ void shutdown();
+
+ // Registers and generates a texture immediately
+ void create_procedural_texture(const std::string& name,
+ const ProceduralTextureDef& def);
+
+ // Retrieves a texture view by name (returns nullptr if not found)
+ WGPUTextureView get_texture_view(const std::string& name);
+
+ private:
+ WGPUDevice device_;
+ WGPUQueue queue_;
+ std::map<std::string, GpuTexture> textures_;
+};