diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-01 10:51:15 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-01 10:51:15 +0100 |
| commit | 8bdc4754647c9c6691130fa91d51fee93c5fc88f (patch) | |
| tree | 2cfd7f72a21541c488ea48629eef47a6774fc2c4 /src/gpu/texture_manager.cc | |
| parent | 7905abd9f7ad35231289e729b42e3ad57a943ff5 (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/texture_manager.cc')
| -rw-r--r-- | src/gpu/texture_manager.cc | 107 |
1 files changed, 107 insertions, 0 deletions
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; +} |
