From 71851a742ac7a12b741104ec028c5cbe048d6057 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Thu, 27 Nov 2025 20:20:15 +0800 Subject: [PATCH 01/66] feat: Update readme --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dbb24ff..89f72d0 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,15 @@ graph TD - [x] Shaders - [x] Textures - [x] Transformations - - [ ] Coordinate Systems + - [x] Coordinate Systems - [ ] Camera - [ ] Lighting + - [ ] Colors + - [ ] Basic Lighting + - [ ] Materials + - [ ] Lighting maps + - [ ] Light casters + - [ ] Multiple lights - [ ] Model Loading - [ ] Advanced OpenGL - [ ] Advanced Lighting From 827323b5411b49fbfa6456e82eaa888dda358b2d Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Thu, 27 Nov 2025 20:36:54 +0800 Subject: [PATCH 02/66] feat: ignore keyboard if imgui is handle keyboard --- main.cpp | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/main.cpp b/main.cpp index d9fa0e7..71cdf0a 100644 --- a/main.cpp +++ b/main.cpp @@ -559,26 +559,32 @@ void main() SDL_AppResult event(SDL_Event* event) override { ImGui_ImplSDL3_ProcessEvent(event); - if (event->type == SDL_EVENT_KEY_DOWN) + + ImGuiIO& io = ImGui::GetIO(); + + if (!io.WantCaptureKeyboard) { - switch (event->key.key) + if (event->type == SDL_EVENT_KEY_DOWN) { - case SDLK_UP: - pitch += 0.1F; - pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); - break; - case SDLK_DOWN: - pitch -= 0.1F; - pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); - break; - case SDLK_LEFT: - yaw -= 0.1F; - break; - case SDLK_RIGHT: - yaw += 0.1F; - break; - default: - break; + switch (event->key.key) + { + case SDLK_UP: + pitch += 0.1F; + pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); + break; + case SDLK_DOWN: + pitch -= 0.1F; + pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); + break; + case SDLK_LEFT: + yaw -= 0.1F; + break; + case SDLK_RIGHT: + yaw += 0.1F; + break; + default: + break; + } } } From 33b957a5b6b9ea2f7d7abfad60095ac5289d5ac1 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Thu, 27 Nov 2025 22:40:03 +0800 Subject: [PATCH 03/66] feat: change uv for squire --- sdl_wrapper/src/sdl_wrapper.render_data.cpp | 68 +++++++++++++++------ 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/sdl_wrapper/src/sdl_wrapper.render_data.cpp b/sdl_wrapper/src/sdl_wrapper.render_data.cpp index 2072587..1ca6f31 100644 --- a/sdl_wrapper/src/sdl_wrapper.render_data.cpp +++ b/sdl_wrapper/src/sdl_wrapper.render_data.cpp @@ -53,22 +53,38 @@ namespace sopho vertex_ptr[36] = -0.5; vertex_ptr[37] = -0.5; - vertex_ptr[3] = 1.0; - vertex_ptr[4] = 1.0; - vertex_ptr[8] = 1.0; - vertex_ptr[9] = 0; - vertex_ptr[13] = 0; - vertex_ptr[14] = 1.0; - vertex_ptr[18] = 0; - vertex_ptr[19] = 0; - vertex_ptr[23] = 0; - vertex_ptr[24] = 1.0; - vertex_ptr[28] = 0; - vertex_ptr[29] = 0; - vertex_ptr[33] = 1; - vertex_ptr[34] = 1.0; - vertex_ptr[38] = 1; - vertex_ptr[39] = 0; + // v0 uv + vertex_ptr[3] = 0.0f; + vertex_ptr[4] = 0.0f; + + // v1 uv + vertex_ptr[8] = 1.0f; + vertex_ptr[9] = 0.0f; + + // v2 uv + vertex_ptr[13] = 0.0f; + vertex_ptr[14] = 1.0f; + + // v3 uv + vertex_ptr[18] = 1.0f; + vertex_ptr[19] = 1.0f; + + // v4 uv + vertex_ptr[23] = 1.0f; + vertex_ptr[24] = 1.0f; + + // v5 uv + vertex_ptr[28] = 0.0f; + vertex_ptr[29] = 1.0f; + + // v6 uv + vertex_ptr[33] = 1.0f; + vertex_ptr[34] = 0.0f; + + // v7 uv + vertex_ptr[38] = 0.0f; + vertex_ptr[39] = 0.0f; + int* index_ptr = reinterpret_cast(index_buffer.value().cpu_buffer()); index_ptr[0] = 0; index_ptr[1] = 1; @@ -88,8 +104,24 @@ namespace sopho index_ptr[15] = 2; index_ptr[16] = 4; index_ptr[17] = 6; - index_ptr[18] = 0; - index_ptr[19] = 0; + index_ptr[18] = 2; + index_ptr[19] = 3; + index_ptr[20] = 6; + index_ptr[21] = 3; + index_ptr[22] = 6; + index_ptr[23] = 7; + index_ptr[24] = 1; + index_ptr[25] = 3; + index_ptr[26] = 5; + index_ptr[27] = 3; + index_ptr[28] = 5; + index_ptr[29] = 7; + index_ptr[30] = 4; + index_ptr[31] = 5; + index_ptr[32] = 6; + index_ptr[33] = 5; + index_ptr[34] = 6; + index_ptr[35] = 7; return std::make_shared(std::move(vertex_buffer.value()), std::move(index_buffer.value()), layout, vertex_count, index_count); } From 69d16f90d920b589e38994441316be210208f507 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Thu, 27 Nov 2025 22:53:04 +0800 Subject: [PATCH 04/66] feat: discard if alpha is near zero --- main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 71cdf0a..c4cd523 100644 --- a/main.cpp +++ b/main.cpp @@ -105,7 +105,8 @@ layout(set = 2, binding = 0) uniform sampler2D uTexture; void main() { FragColor = texture(uTexture, v_uv); - FragColor.a = 1; + if (FragColor.a <= 0.001) + discard; })WSQ"; public: From 8a57edd2949d4284dc23fca3fa6f7642deb085fb Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 09:03:46 +0800 Subject: [PATCH 05/66] fix: add check when width and height is zero --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index c4cd523..a67e815 100644 --- a/main.cpp +++ b/main.cpp @@ -459,7 +459,7 @@ void main() return SDL_APP_CONTINUE; } - if (win_w != width || win_h != height) + if ((win_w != width || win_h != height) && width != 0 && height != 0) { SDL_GPUTextureCreateInfo ci = { .type = SDL_GPU_TEXTURETYPE_2D, From e888f1ff805d577d0a74662890dc3cb6980b9c25 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 09:22:01 +0800 Subject: [PATCH 06/66] feat: split app into lifecycle module --- main.cpp | 1 + sdl_wrapper/CMakeLists.txt | 4 ++-- sdl_wrapper/modules/{sdl_wrapper.app.ixx => lifecycle.ixx} | 2 +- sdl_wrapper/modules/sdl_wrapper.ixx | 1 - sdl_wrapper/src/{sdl_callback_implement.cpp => lifecycle.cpp} | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename sdl_wrapper/modules/{sdl_wrapper.app.ixx => lifecycle.ixx} (93%) rename sdl_wrapper/src/{sdl_callback_implement.cpp => lifecycle.cpp} (99%) diff --git a/main.cpp b/main.cpp index a67e815..6f7f134 100644 --- a/main.cpp +++ b/main.cpp @@ -23,6 +23,7 @@ #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" +import lifecycle; import data_type; import glsl_reflector; import sdl_wrapper; diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 719526f..55c9d08 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -7,9 +7,9 @@ add_library(sdl_wrapper STATIC) target_sources(sdl_wrapper PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES + modules/lifecycle.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx - modules/sdl_wrapper.app.ixx modules/sdl_wrapper.render_procedural.ixx modules/sdl_wrapper.render_data.ixx modules/sdl_wrapper.render_data_impl.ixx @@ -20,10 +20,10 @@ target_sources(sdl_wrapper modules/sdl_wrapper.transfer_buffer.ixx modules/sdl_wrapper.texture.ixx PRIVATE + src/lifecycle.cpp src/sdl_wrapper.buffer.cpp src/sdl_wrapper.render_procedural.cpp src/sdl_wrapper.gpu.cpp - src/sdl_callback_implement.cpp src/sdl_wrapper.texture.cpp src/sdl_wrapper.transfer_buffer.cpp src/sdl_wrapper.render_data.cpp diff --git a/sdl_wrapper/modules/sdl_wrapper.app.ixx b/sdl_wrapper/modules/lifecycle.ixx similarity index 93% rename from sdl_wrapper/modules/sdl_wrapper.app.ixx rename to sdl_wrapper/modules/lifecycle.ixx index 253d070..9f13ca7 100644 --- a/sdl_wrapper/modules/sdl_wrapper.app.ixx +++ b/sdl_wrapper/modules/lifecycle.ixx @@ -3,7 +3,7 @@ // module; #include "SDL3/SDL_init.h" -export module sdl_wrapper:app; +export module lifecycle; export namespace sopho { class App diff --git a/sdl_wrapper/modules/sdl_wrapper.ixx b/sdl_wrapper/modules/sdl_wrapper.ixx index 430fbaf..cd1c961 100644 --- a/sdl_wrapper/modules/sdl_wrapper.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.ixx @@ -4,7 +4,6 @@ export module sdl_wrapper; export import :decl; -export import :app; export import :gpu; export import :render_procedural; export import :renderable; diff --git a/sdl_wrapper/src/sdl_callback_implement.cpp b/sdl_wrapper/src/lifecycle.cpp similarity index 99% rename from sdl_wrapper/src/sdl_callback_implement.cpp rename to sdl_wrapper/src/lifecycle.cpp index 9ad32fb..31478ba 100644 --- a/sdl_wrapper/src/sdl_callback_implement.cpp +++ b/sdl_wrapper/src/lifecycle.cpp @@ -4,7 +4,7 @@ #define SDL_MAIN_USE_CALLBACKS #include "SDL3/SDL.h" #include "SDL3/SDL_main.h" -import sdl_wrapper; +import lifecycle; import data_type; extern sopho::checkable create_app(int argc, char** argv); From 3728c0884b1382eca4f385d322a79560b7b49e57 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 09:24:23 +0800 Subject: [PATCH 07/66] feat: change sampler from linear to nearest --- sdl_wrapper/src/sdl_wrapper.texture.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdl_wrapper/src/sdl_wrapper.texture.cpp b/sdl_wrapper/src/sdl_wrapper.texture.cpp index 24f6b7c..4f4b903 100644 --- a/sdl_wrapper/src/sdl_wrapper.texture.cpp +++ b/sdl_wrapper/src/sdl_wrapper.texture.cpp @@ -98,8 +98,8 @@ namespace sopho SDL_SubmitGPUCommandBuffer(cmd); SDL_GPUSamplerCreateInfo info{}; - info.min_filter = SDL_GPU_FILTER_LINEAR; - info.mag_filter = SDL_GPU_FILTER_LINEAR; + info.min_filter = SDL_GPU_FILTER_NEAREST; + info.mag_filter = SDL_GPU_FILTER_NEAREST; info.max_anisotropy = 1.f; info.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR; info.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_REPEAT; From 621dcecf9a7eb4276bb35c9c44c7f3ccda2ed5b4 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 09:26:49 +0800 Subject: [PATCH 08/66] doc: add lifecycle module in readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 89f72d0..da95d76 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ graph TD sdl_wrapper logos end + + subgraph sdl_wrapper + lifecycle + end glslang --> shaderc SPIRVTools --> shaderc From 7fdd2315f69c3b26de8131a4516471ade5e0a0f0 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 10:07:10 +0800 Subject: [PATCH 09/66] fix: remove forward declaration --- sdl_wrapper/modules/sdl_wrapper.decl.ixx | 1 - 1 file changed, 1 deletion(-) diff --git a/sdl_wrapper/modules/sdl_wrapper.decl.ixx b/sdl_wrapper/modules/sdl_wrapper.decl.ixx index 646621f..3122832 100644 --- a/sdl_wrapper/modules/sdl_wrapper.decl.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.decl.ixx @@ -6,7 +6,6 @@ export module sdl_wrapper:decl; export namespace sopho { - class App; class GpuWrapper; class RenderProcedural; class RenderData; From ee65de4a1487c9941ba311eb49452baad0c06956 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 11:23:37 +0800 Subject: [PATCH 10/66] feat: add module sdl_raii and move GpuHandle into it. --- sdl_wrapper/CMakeLists.txt | 2 + .../modules/sdl_raii/sdl_raii.gpu_device.ixx | 47 +++++++++++++++++ sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 7 +++ sdl_wrapper/modules/sdl_wrapper.gpu.ixx | 51 +++---------------- 4 files changed, 64 insertions(+), 43 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 55c9d08..c07e74c 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -8,6 +8,8 @@ target_sources(sdl_wrapper PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES modules/lifecycle.ixx + modules/sdl_raii/sdl_raii.ixx + modules/sdl_raii/sdl_raii.gpu_device.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx new file mode 100644 index 0000000..c3b6868 --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx @@ -0,0 +1,47 @@ +// sdl_raii.gpu.ixx +// Created by wsqsy on 11/28/2025. +// +module; +#include "SDL3/SDL_gpu.h" +export module sdl_raii:gpu_device; +namespace sopho +{ + export struct GpuDeviceRaii + { + private: + SDL_GPUDevice* m_raw{}; + + public: + GpuDeviceRaii() noexcept = default; + explicit GpuDeviceRaii(SDL_GPUDevice* d) noexcept : m_raw(d) {} + + GpuDeviceRaii(GpuDeviceRaii&& other) noexcept : m_raw(other.m_raw) { other.m_raw = nullptr; } + GpuDeviceRaii& operator=(GpuDeviceRaii&& other) noexcept + { + if (this != &other) + { + reset(other.m_raw); + other.m_raw = nullptr; + } + return *this; + } + + GpuDeviceRaii(const GpuDeviceRaii&) = delete; + GpuDeviceRaii& operator=(const GpuDeviceRaii&) = delete; + + ~GpuDeviceRaii() noexcept { reset(); } + + void reset(SDL_GPUDevice* d = nullptr) noexcept + { + if (m_raw != d) + { + if (m_raw) + SDL_DestroyGPUDevice(m_raw); + m_raw = d; + } + } + [[nodiscard]] SDL_GPUDevice* raw() const noexcept { return m_raw; } + [[nodiscard]] bool valid() const noexcept { return m_raw != nullptr; } + [[nodiscard]] explicit operator bool() const noexcept { return m_raw != nullptr; } + }; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx new file mode 100644 index 0000000..2210ddf --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -0,0 +1,7 @@ +// sdl_raii.ixx +// Created by wsqsy on 11/28/2025. +// + +export module sdl_raii; + +export import :gpu_device; diff --git a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx index 4c54aad..514913a 100644 --- a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx @@ -10,46 +10,11 @@ module; #include "SDL3/SDL_video.h" #include "shaderc/shaderc.hpp" export module sdl_wrapper:gpu; +import sdl_raii; import :decl; import :render_procedural; export namespace sopho { - - struct DeviceHandle - { - SDL_GPUDevice* raw{}; - - explicit DeviceHandle(SDL_GPUDevice* d) noexcept : raw(d) {} - - DeviceHandle(DeviceHandle&& other) noexcept : raw(other.raw) { other.raw = nullptr; } - DeviceHandle& operator=(DeviceHandle&& other) noexcept - { - if (this != &other) - { - reset(); - raw = other.raw; - other.raw = nullptr; - } - return *this; - } - - DeviceHandle(const DeviceHandle&) = delete; - DeviceHandle& operator=(const DeviceHandle&) = delete; - - ~DeviceHandle() { reset(); } - - void reset() noexcept - { - if (raw) - { - SDL_DestroyGPUDevice(raw); - raw = nullptr; - } - } - - [[nodiscard]] bool valid() const noexcept { return raw != nullptr; } - }; - struct WindowHandle { SDL_Window* raw{}; @@ -136,11 +101,11 @@ export namespace sopho struct GpuContext { - DeviceHandle device; + GpuDeviceRaii device; WindowHandle window; ClaimedWindow claimed; - GpuContext(DeviceHandle d, WindowHandle w, ClaimedWindow c) noexcept : + GpuContext(GpuDeviceRaii d, WindowHandle w, ClaimedWindow c) noexcept : device(std::move(d)), window(std::move(w)), claimed(std::move(c)) { } @@ -151,7 +116,7 @@ export namespace sopho GpuContext(GpuContext&&) = default; GpuContext& operator=(GpuContext&&) = default; - [[nodiscard]] SDL_GPUDevice* device_raw() const noexcept { return device.raw; } + [[nodiscard]] SDL_GPUDevice* device_raw() const noexcept { return device.raw(); } [[nodiscard]] SDL_Window* window_raw() const noexcept { return window.raw; } }; @@ -165,7 +130,7 @@ export namespace sopho SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); return std::unexpected(GpuError::CREATE_DEVICE_FAILED); } - DeviceHandle device{dev_raw}; + GpuDeviceRaii device{dev_raw}; auto* win_raw = SDL_CreateWindow("Hello, Triangle!", 960, 540, SDL_WINDOW_RESIZABLE); if (!win_raw) @@ -175,12 +140,12 @@ export namespace sopho } WindowHandle window{win_raw}; - if (!SDL_ClaimWindowForGPUDevice(device.raw, window.raw)) + if (!SDL_ClaimWindowForGPUDevice(device.raw(), window.raw)) { SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); return std::unexpected(GpuError::CLAIM_WINDOW_FAILED); } - ClaimedWindow claimed{device.raw, window.raw}; + ClaimedWindow claimed{device.raw(), window.raw}; return GpuContext{std::move(device), std::move(window), std::move(claimed)}; } @@ -208,7 +173,7 @@ export namespace sopho GpuWrapper(GpuWrapper&&) = delete; GpuWrapper& operator=(GpuWrapper&&) = delete; - [[nodiscard]] auto device() const { return m_ctx.device.raw; } + [[nodiscard]] auto device() const { return m_ctx.device.raw(); } [[nodiscard]] SDL_Window* window() const { return m_ctx.window.raw; } auto release_buffer(SDL_GPUBuffer* buffer) From 11674bb6ed05e583ba4bc4d9cdfa273190d9c52b Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 11:25:44 +0800 Subject: [PATCH 11/66] fix:change header file format --- sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx index c3b6868..ba5c88b 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx @@ -2,7 +2,7 @@ // Created by wsqsy on 11/28/2025. // module; -#include "SDL3/SDL_gpu.h" +#include export module sdl_raii:gpu_device; namespace sopho { From 33dbd50e96aa1493239e0afd3a4435b483a309ce Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 11:35:13 +0800 Subject: [PATCH 12/66] fix:change header file --- sdl_wrapper/modules/sdl_wrapper.gpu.ixx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx index 514913a..85143af 100644 --- a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx @@ -5,10 +5,10 @@ module; #include #include -#include "SDL3/SDL_gpu.h" -#include "SDL3/SDL_log.h" -#include "SDL3/SDL_video.h" -#include "shaderc/shaderc.hpp" +#include +#include +#include +#include export module sdl_wrapper:gpu; import sdl_raii; import :decl; From 542414eee519930718d8617fe66f0e8d60a646d1 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 11:41:28 +0800 Subject: [PATCH 13/66] fix: move class window handle to sdl_raii module --- sdl_wrapper/CMakeLists.txt | 1 + sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 1 + .../modules/sdl_raii/sdl_raii.window.ixx | 50 ++++++++++++++++++ sdl_wrapper/modules/sdl_wrapper.gpu.ixx | 52 +++---------------- 4 files changed, 59 insertions(+), 45 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.window.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index c07e74c..8b1dd17 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -10,6 +10,7 @@ target_sources(sdl_wrapper modules/lifecycle.ixx modules/sdl_raii/sdl_raii.ixx modules/sdl_raii/sdl_raii.gpu_device.ixx + modules/sdl_raii/sdl_raii.window.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 2210ddf..d7f8468 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -5,3 +5,4 @@ export module sdl_raii; export import :gpu_device; +export import :window; diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.window.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.window.ixx new file mode 100644 index 0000000..7f87541 --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.window.ixx @@ -0,0 +1,50 @@ +// sdl_raii.window.ixx +// Created by wsqsy on 11/28/2025. +// +module; +#include +export module sdl_raii:window; +namespace sopho +{ + export struct WindowRaii + { + private: + SDL_Window* m_raw{}; + + public: + WindowRaii() = default; + + explicit WindowRaii(SDL_Window* w) noexcept : m_raw(w) {} + + WindowRaii(const WindowRaii&) = delete; + WindowRaii& operator=(const WindowRaii&) = delete; + + WindowRaii(WindowRaii&& other) noexcept : m_raw(other.m_raw) { other.m_raw = nullptr; } + + WindowRaii& operator=(WindowRaii&& other) noexcept + { + if (this != &other) + { + reset(other.m_raw); + other.m_raw = nullptr; + } + return *this; + } + + ~WindowRaii() noexcept { reset(); } + + void reset(SDL_Window* w = nullptr) noexcept + { + if (m_raw != w) + { + if (m_raw) + SDL_DestroyWindow(m_raw); + m_raw = w; + } + } + + [[nodiscard]] SDL_Window* raw() const noexcept { return m_raw; } + [[nodiscard]] bool valid() const noexcept { return m_raw != nullptr; } + [[nodiscard]] explicit operator bool() const noexcept { return m_raw != nullptr; } + }; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx index 85143af..c7dda82 100644 --- a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx @@ -15,44 +15,6 @@ import :decl; import :render_procedural; export namespace sopho { - struct WindowHandle - { - SDL_Window* raw{}; - - WindowHandle() = default; - - explicit WindowHandle(SDL_Window* w) noexcept : raw(w) {} - - WindowHandle(const WindowHandle&) = delete; - WindowHandle& operator=(const WindowHandle&) = delete; - - WindowHandle(WindowHandle&& other) noexcept : raw(other.raw) { other.raw = nullptr; } - - WindowHandle& operator=(WindowHandle&& other) noexcept - { - if (this != &other) - { - reset(); - raw = other.raw; - other.raw = nullptr; - } - return *this; - } - - ~WindowHandle() noexcept { reset(); } - - void reset() noexcept - { - if (raw) - { - SDL_DestroyWindow(raw); - raw = nullptr; - } - } - - [[nodiscard]] bool valid() const noexcept { return raw != nullptr; } - }; - struct ClaimedWindow { SDL_GPUDevice* device{}; @@ -102,10 +64,10 @@ export namespace sopho struct GpuContext { GpuDeviceRaii device; - WindowHandle window; + WindowRaii window; ClaimedWindow claimed; - GpuContext(GpuDeviceRaii d, WindowHandle w, ClaimedWindow c) noexcept : + GpuContext(GpuDeviceRaii d, WindowRaii w, ClaimedWindow c) noexcept : device(std::move(d)), window(std::move(w)), claimed(std::move(c)) { } @@ -117,7 +79,7 @@ export namespace sopho GpuContext& operator=(GpuContext&&) = default; [[nodiscard]] SDL_GPUDevice* device_raw() const noexcept { return device.raw(); } - [[nodiscard]] SDL_Window* window_raw() const noexcept { return window.raw; } + [[nodiscard]] SDL_Window* window_raw() const noexcept { return window.raw(); } }; using GpuContextResult = std::expected; @@ -138,14 +100,14 @@ export namespace sopho SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); return std::unexpected(GpuError::CREATE_WINDOW_FAILED); } - WindowHandle window{win_raw}; + WindowRaii window{win_raw}; - if (!SDL_ClaimWindowForGPUDevice(device.raw(), window.raw)) + if (!SDL_ClaimWindowForGPUDevice(device.raw(), window.raw())) { SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); return std::unexpected(GpuError::CLAIM_WINDOW_FAILED); } - ClaimedWindow claimed{device.raw(), window.raw}; + ClaimedWindow claimed{device.raw(), window.raw()}; return GpuContext{std::move(device), std::move(window), std::move(claimed)}; } @@ -174,7 +136,7 @@ export namespace sopho GpuWrapper& operator=(GpuWrapper&&) = delete; [[nodiscard]] auto device() const { return m_ctx.device.raw(); } - [[nodiscard]] SDL_Window* window() const { return m_ctx.window.raw; } + [[nodiscard]] SDL_Window* window() const { return m_ctx.window.raw(); } auto release_buffer(SDL_GPUBuffer* buffer) { From 9c46edf88070a5321d1d7aeec88cde0f2ed11dab Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 11:52:53 +0800 Subject: [PATCH 14/66] fix: move class claim window handle to sdl_raii module --- sdl_wrapper/CMakeLists.txt | 1 + .../sdl_raii/sdl_raii.claim_window.ixx | 59 +++++++++++++++++++ sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 1 + sdl_wrapper/modules/sdl_wrapper.gpu.ixx | 51 +--------------- 4 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.claim_window.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 8b1dd17..655d9ae 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -11,6 +11,7 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.ixx modules/sdl_raii/sdl_raii.gpu_device.ixx modules/sdl_raii/sdl_raii.window.ixx + modules/sdl_raii/sdl_raii.claim_window.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.claim_window.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.claim_window.ixx new file mode 100644 index 0000000..712fc81 --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.claim_window.ixx @@ -0,0 +1,59 @@ +// sdl_raii.claim_window.ixx +// Created by wsqsy on 11/28/2025. +// +module; +#include +export module sdl_raii:claim_window; +namespace sopho +{ + export struct ClaimWindowRaii + { + private: + SDL_GPUDevice* m_gpu_device{}; + SDL_Window* m_window{}; + + public: + ClaimWindowRaii() noexcept = default; + + ClaimWindowRaii(SDL_GPUDevice* d, SDL_Window* w) noexcept : m_gpu_device(d), m_window(w) {} + + ClaimWindowRaii(const ClaimWindowRaii&) = delete; + ClaimWindowRaii& operator=(const ClaimWindowRaii&) = delete; + + ClaimWindowRaii(ClaimWindowRaii&& other) noexcept : m_gpu_device(other.m_gpu_device), m_window(other.m_window) + { + other.m_gpu_device = nullptr; + other.m_window = nullptr; + } + + ClaimWindowRaii& operator=(ClaimWindowRaii&& other) noexcept + { + if (this != &other) + { + reset(); + m_gpu_device = other.m_gpu_device; + m_window = other.m_window; + other.m_gpu_device = nullptr; + other.m_window = nullptr; + } + return *this; + } + + ~ClaimWindowRaii() noexcept { reset(); } + + void reset(SDL_GPUDevice* d = nullptr, SDL_Window* w = nullptr) noexcept + { + if (m_gpu_device != d || m_window != w) + { + if (m_gpu_device && m_window) + SDL_ReleaseWindowFromGPUDevice(m_gpu_device, m_window); + + m_gpu_device = d; + m_window = w; + } + } + + [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_window != nullptr; } + [[nodiscard]] explicit operator bool() const noexcept { return valid(); } + }; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index d7f8468..9e1c409 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -6,3 +6,4 @@ export module sdl_raii; export import :gpu_device; export import :window; +export import :claim_window; diff --git a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx index c7dda82..f731bea 100644 --- a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx @@ -15,59 +15,14 @@ import :decl; import :render_procedural; export namespace sopho { - struct ClaimedWindow - { - SDL_GPUDevice* device{}; - SDL_Window* window{}; - - ClaimedWindow() = default; - - ClaimedWindow(SDL_GPUDevice* d, SDL_Window* w) noexcept : device(d), window(w) {} - - ClaimedWindow(const ClaimedWindow&) = delete; - ClaimedWindow& operator=(const ClaimedWindow&) = delete; - - ClaimedWindow(ClaimedWindow&& other) noexcept : device(other.device), window(other.window) - { - other.device = nullptr; - other.window = nullptr; - } - - ClaimedWindow& operator=(ClaimedWindow&& other) noexcept - { - if (this != &other) - { - reset(); - device = other.device; - window = other.window; - other.device = nullptr; - other.window = nullptr; - } - return *this; - } - - ~ClaimedWindow() noexcept { reset(); } - - void reset() noexcept - { - if (device && window) - { - SDL_ReleaseWindowFromGPUDevice(device, window); - device = nullptr; - window = nullptr; - } - } - - [[nodiscard]] bool valid() const noexcept { return device && window; } - }; struct GpuContext { GpuDeviceRaii device; WindowRaii window; - ClaimedWindow claimed; + ClaimWindowRaii claimed; - GpuContext(GpuDeviceRaii d, WindowRaii w, ClaimedWindow c) noexcept : + GpuContext(GpuDeviceRaii d, WindowRaii w, ClaimWindowRaii c) noexcept : device(std::move(d)), window(std::move(w)), claimed(std::move(c)) { } @@ -107,7 +62,7 @@ export namespace sopho SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); return std::unexpected(GpuError::CLAIM_WINDOW_FAILED); } - ClaimedWindow claimed{device.raw(), window.raw()}; + ClaimWindowRaii claimed{device.raw(), window.raw()}; return GpuContext{std::move(device), std::move(window), std::move(claimed)}; } From 7d656caa0fdfd77585ff62c7e110011cd0d295d1 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 12:17:39 +0800 Subject: [PATCH 15/66] fix: remove type alias --- sdl_wrapper/modules/sdl_wrapper.gpu.ixx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx index f731bea..4429ba2 100644 --- a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx @@ -37,9 +37,7 @@ export namespace sopho [[nodiscard]] SDL_Window* window_raw() const noexcept { return window.raw(); } }; - using GpuContextResult = std::expected; - - inline GpuContextResult create_gpu_context() + inline checkable create_gpu_context() { auto* dev_raw = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, true, nullptr); if (!dev_raw) From d7efbcfef214df004dabcda7caa024c906246688 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 13:42:54 +0800 Subject: [PATCH 16/66] feat: add class TransferBufferRaii --- sdl_wrapper/CMakeLists.txt | 1 + sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 1 + .../sdl_raii/sdl_raii.transfer_buffer.ixx | 59 +++++++++++++++++++ .../modules/sdl_wrapper.transfer_buffer.ixx | 19 +++--- .../src/sdl_wrapper.transfer_buffer.cpp | 25 ++------ 5 files changed, 75 insertions(+), 30 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 655d9ae..d75cd67 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -12,6 +12,7 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.gpu_device.ixx modules/sdl_raii/sdl_raii.window.ixx modules/sdl_raii/sdl_raii.claim_window.ixx + modules/sdl_raii/sdl_raii.transfer_buffer.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 9e1c409..af20149 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -7,3 +7,4 @@ export module sdl_raii; export import :gpu_device; export import :window; export import :claim_window; +export import :transfer_buffer; diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx new file mode 100644 index 0000000..70cb94c --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx @@ -0,0 +1,59 @@ +// sdl_raii.transfer_buffer.ixx +// Created by wsqsy on 11/28/2025. +// + +export module sdl_raii:transfer_buffer; +#include "SDL3/SDL_gpu.h" +namespace sopho +{ + export struct TransferBufferRaii + { + private: + SDL_GPUDevice* m_gpu_device{}; + SDL_GPUTransferBuffer* m_transfer_buffer{}; + + public: + TransferBufferRaii() noexcept = default; + explicit TransferBufferRaii(SDL_GPUDevice* device, SDL_GPUTransferBuffer* buffer) noexcept : + m_gpu_device(device), m_transfer_buffer(buffer) + { + } + TransferBufferRaii(const TransferBufferRaii&) = delete; + TransferBufferRaii& operator=(const TransferBufferRaii&) = delete; + TransferBufferRaii(TransferBufferRaii&& other) noexcept : + m_gpu_device(other.m_gpu_device), m_transfer_buffer(other.m_transfer_buffer) + { + other.m_gpu_device = nullptr; + other.m_transfer_buffer = nullptr; + } + TransferBufferRaii& operator=(TransferBufferRaii&& other) noexcept + { + if (this != &other) + { + reset(); + + m_gpu_device = other.m_gpu_device; + m_transfer_buffer = other.m_transfer_buffer; + + other.m_gpu_device = nullptr; + other.m_transfer_buffer = nullptr; + } + return *this; + } + ~TransferBufferRaii() noexcept { reset(); } + void reset(SDL_GPUTransferBuffer* buffer = nullptr, SDL_GPUDevice* device = nullptr) noexcept + { + if (m_transfer_buffer && m_gpu_device) + { + SDL_ReleaseGPUTransferBuffer(m_gpu_device, m_transfer_buffer); + } + + m_gpu_device = device; + + m_transfer_buffer = buffer; + } + [[nodiscard]] SDL_GPUTransferBuffer* raw() const noexcept { return m_transfer_buffer; } + [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_transfer_buffer != nullptr; } + [[nodiscard]] explicit operator bool() const noexcept { return valid(); } + }; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_wrapper.transfer_buffer.ixx b/sdl_wrapper/modules/sdl_wrapper.transfer_buffer.ixx index c169fe7..783bdee 100644 --- a/sdl_wrapper/modules/sdl_wrapper.transfer_buffer.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.transfer_buffer.ixx @@ -18,6 +18,7 @@ module; #include "SDL3/SDL_log.h" export module sdl_wrapper:transfer_buffer; import data_type; +import sdl_raii; import :decl; namespace sopho { @@ -29,28 +30,24 @@ namespace sopho { private: std::shared_ptr m_gpu{}; // Owns the device lifetime - SDL_GPUTransferBuffer* m_transfer_buffer{}; // The actual transfer buffer + TransferBufferRaii m_transfer_buffer{}; // The actual transfer buffer std::int32_t m_usage_limit{}; // Current usage count std::uint32_t m_size{}; // Size of the transfer buffer in bytes // Private constructor to ensure only Builder can create instances - TransferBufferWrapper(std::shared_ptr gpu, SDL_GPUTransferBuffer* transfer_buffer, + TransferBufferWrapper(std::shared_ptr gpu, TransferBufferRaii transfer_buffer, std::int32_t usage_limit, std::uint32_t size) noexcept : - m_gpu(std::move(gpu)), m_transfer_buffer(transfer_buffer), m_usage_limit(usage_limit), m_size(size) + m_gpu(std::move(gpu)), m_transfer_buffer(std::move(transfer_buffer)), m_usage_limit(usage_limit), + m_size(size) { } public: TransferBufferWrapper(const TransferBufferWrapper&) = delete; TransferBufferWrapper& operator=(const TransferBufferWrapper&) = delete; - TransferBufferWrapper(TransferBufferWrapper&& other) noexcept : - m_gpu(std::move(other.m_gpu)), m_transfer_buffer(other.m_transfer_buffer), - m_usage_limit(other.m_usage_limit), m_size(other.m_size) - { - other.m_transfer_buffer = nullptr; - } + TransferBufferWrapper(TransferBufferWrapper&& other) noexcept = default; - TransferBufferWrapper& operator=(TransferBufferWrapper&& other) noexcept; + TransferBufferWrapper& operator=(TransferBufferWrapper&& other) noexcept = default; /* * @brief Destructor that releases the transfer buffer. @@ -65,7 +62,7 @@ namespace sopho /* * @brief Returns the underlying SDL_GPUTransferBuffer pointer. */ - [[nodiscard]] SDL_GPUTransferBuffer* raw() const noexcept { return m_transfer_buffer; } + [[nodiscard]] SDL_GPUTransferBuffer* raw() const noexcept { return m_transfer_buffer.raw(); } /* * @brief Returns the size of the transfer buffer in bytes. diff --git a/sdl_wrapper/src/sdl_wrapper.transfer_buffer.cpp b/sdl_wrapper/src/sdl_wrapper.transfer_buffer.cpp index b11e8e2..3990803 100644 --- a/sdl_wrapper/src/sdl_wrapper.transfer_buffer.cpp +++ b/sdl_wrapper/src/sdl_wrapper.transfer_buffer.cpp @@ -14,32 +14,18 @@ import :transfer_buffer; import :gpu; namespace sopho { - TransferBufferWrapper& TransferBufferWrapper::operator=(TransferBufferWrapper&& other) noexcept - { - if (this != &other) - { - reset(); - m_gpu = std::move(other.m_gpu); - m_transfer_buffer = other.m_transfer_buffer; - m_usage_limit = other.m_usage_limit; - m_size = other.m_size; - other.m_transfer_buffer = nullptr; - } - return *this; - } void TransferBufferWrapper::reset() noexcept { - if (m_transfer_buffer && m_gpu && m_gpu->device()) + if (m_gpu && m_gpu->device()) { - SDL_ReleaseGPUTransferBuffer(m_gpu->device(), m_transfer_buffer); - m_transfer_buffer = nullptr; + m_transfer_buffer.reset(); } } checkable TransferBufferWrapper::submit(const void* data_source) { assert(m_usage_limit != 0); - void* dst = SDL_MapGPUTransferBuffer(m_gpu->device(), m_transfer_buffer, false); + void* dst = SDL_MapGPUTransferBuffer(m_gpu->device(), raw(), false); if (!dst) { SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d failed to map transfer buffer: %s", __FILE__, __LINE__, @@ -49,7 +35,7 @@ namespace sopho } SDL_memcpy(dst, data_source, m_size); - SDL_UnmapGPUTransferBuffer(m_gpu->device(), m_transfer_buffer); + SDL_UnmapGPUTransferBuffer(m_gpu->device(), raw()); if (m_usage_limit != -1) { m_usage_limit--; @@ -72,7 +58,8 @@ namespace sopho SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); return std::unexpected(GpuError::CREATE_TRANSFER_BUFFER_FAILED); } + TransferBufferRaii tb_raii{gpu.device(), transfer_buffer}; - return TransferBufferWrapper{gpu.shared_from_this(), transfer_buffer, usage_limit, size}; + return TransferBufferWrapper{gpu.shared_from_this(), std::move(tb_raii), usage_limit, size}; } } // namespace sopho From 57d5fea67af3080982d931c1185503fbfbe44507 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 13:52:27 +0800 Subject: [PATCH 17/66] fix:rename member variable --- .../sdl_raii/sdl_raii.transfer_buffer.ixx | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx index 70cb94c..99dd2de 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx @@ -3,28 +3,28 @@ // export module sdl_raii:transfer_buffer; -#include "SDL3/SDL_gpu.h" +#include namespace sopho { export struct TransferBufferRaii { private: SDL_GPUDevice* m_gpu_device{}; - SDL_GPUTransferBuffer* m_transfer_buffer{}; + SDL_GPUTransferBuffer* m_raw{}; public: TransferBufferRaii() noexcept = default; - explicit TransferBufferRaii(SDL_GPUDevice* device, SDL_GPUTransferBuffer* buffer) noexcept : - m_gpu_device(device), m_transfer_buffer(buffer) + TransferBufferRaii(SDL_GPUDevice* device, SDL_GPUTransferBuffer* buffer) noexcept : + m_gpu_device(device), m_raw(buffer) { } TransferBufferRaii(const TransferBufferRaii&) = delete; TransferBufferRaii& operator=(const TransferBufferRaii&) = delete; TransferBufferRaii(TransferBufferRaii&& other) noexcept : - m_gpu_device(other.m_gpu_device), m_transfer_buffer(other.m_transfer_buffer) + m_gpu_device(other.m_gpu_device), m_raw(other.m_raw) { other.m_gpu_device = nullptr; - other.m_transfer_buffer = nullptr; + other.m_raw = nullptr; } TransferBufferRaii& operator=(TransferBufferRaii&& other) noexcept { @@ -33,27 +33,27 @@ namespace sopho reset(); m_gpu_device = other.m_gpu_device; - m_transfer_buffer = other.m_transfer_buffer; + m_raw = other.m_raw; other.m_gpu_device = nullptr; - other.m_transfer_buffer = nullptr; + other.m_raw = nullptr; } return *this; } ~TransferBufferRaii() noexcept { reset(); } void reset(SDL_GPUTransferBuffer* buffer = nullptr, SDL_GPUDevice* device = nullptr) noexcept { - if (m_transfer_buffer && m_gpu_device) + if (m_raw && m_gpu_device) { - SDL_ReleaseGPUTransferBuffer(m_gpu_device, m_transfer_buffer); + SDL_ReleaseGPUTransferBuffer(m_gpu_device, m_raw); } m_gpu_device = device; - m_transfer_buffer = buffer; + m_raw = buffer; } - [[nodiscard]] SDL_GPUTransferBuffer* raw() const noexcept { return m_transfer_buffer; } - [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_transfer_buffer != nullptr; } + [[nodiscard]] SDL_GPUTransferBuffer* raw() const noexcept { return m_raw; } + [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_raw != nullptr; } [[nodiscard]] explicit operator bool() const noexcept { return valid(); } }; } // namespace sopho From a2f3c933020b4036dce8ca443f0431052a08b922 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 14:56:26 +0800 Subject: [PATCH 18/66] feat: add class GpuBufferRaii --- sdl_wrapper/CMakeLists.txt | 1 + .../modules/sdl_raii/sdl_raii.gpu_buffer.ixx | 63 +++++++++++++++++++ sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 1 + sdl_wrapper/modules/sdl_wrapper.buffer.ixx | 11 ++-- sdl_wrapper/src/sdl_wrapper.buffer.cpp | 27 ++------ 5 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index d75cd67..61d5e9e 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -13,6 +13,7 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.window.ixx modules/sdl_raii/sdl_raii.claim_window.ixx modules/sdl_raii/sdl_raii.transfer_buffer.ixx + modules/sdl_raii/sdl_raii.gpu_buffer.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx new file mode 100644 index 0000000..86125dd --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx @@ -0,0 +1,63 @@ +// sdl_raii.gpu_buffer.ixx +// Created by wsqsy on 11/28/2025. +// +module; +#include +export module sdl_raii:gpu_buffer; +namespace sopho +{ + export struct GpuBufferRaii + { + private: + SDL_GPUDevice* m_gpu_device{}; + SDL_GPUBuffer* m_raw{}; + + public: + GpuBufferRaii() noexcept = default; + + explicit GpuBufferRaii(SDL_GPUDevice* device, SDL_GPUBuffer* buffer) noexcept : + m_gpu_device(device), m_raw(buffer) + { + } + + GpuBufferRaii(const GpuBufferRaii&) = delete; + GpuBufferRaii& operator=(const GpuBufferRaii&) = delete; + + GpuBufferRaii(GpuBufferRaii&& other) noexcept : m_gpu_device(other.m_gpu_device), m_raw(other.m_raw) + { + other.m_gpu_device = nullptr; + other.m_raw = nullptr; + } + + GpuBufferRaii& operator=(GpuBufferRaii&& other) noexcept + { + if (this != &other) + { + reset(); + + m_gpu_device = other.m_gpu_device; + m_raw = other.m_raw; + + other.m_gpu_device = nullptr; + other.m_raw = nullptr; + } + return *this; + } + + ~GpuBufferRaii() noexcept { reset(); } + void reset(SDL_GPUBuffer* buffer = nullptr, SDL_GPUDevice* device = nullptr) noexcept + { + if (m_raw && m_gpu_device) + { + SDL_ReleaseGPUBuffer(m_gpu_device, m_raw); + } + + m_gpu_device = device; + m_raw = buffer; + } + + [[nodiscard]] SDL_GPUBuffer* raw() const noexcept { return m_raw; } + [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_raw != nullptr; } + [[nodiscard]] explicit operator bool() const noexcept { return valid(); } + }; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index af20149..8757153 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -8,3 +8,4 @@ export import :gpu_device; export import :window; export import :claim_window; export import :transfer_buffer; +export import :gpu_buffer; diff --git a/sdl_wrapper/modules/sdl_wrapper.buffer.ixx b/sdl_wrapper/modules/sdl_wrapper.buffer.ixx index 8294662..e047df0 100644 --- a/sdl_wrapper/modules/sdl_wrapper.buffer.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.buffer.ixx @@ -11,6 +11,7 @@ module; export module sdl_wrapper:buffer; import data_type; +import sdl_raii; import :decl; import :transfer_buffer; @@ -19,15 +20,15 @@ namespace sopho class BufferWrapper { std::shared_ptr m_gpu{}; // Owns the device lifetime - SDL_GPUBuffer* m_gpu_buffer{}; // Target GPU buffer + GpuBufferRaii m_gpu_buffer{}; // Target GPU buffer TransferBufferWrapper m_transfer_buffer; // Staging/transfer buffer std::uint32_t m_buffer_size{}; // Total size of the GPU buffer std::vector m_cpu_buffer{}; // Only GpuWrapper is allowed to construct this type. - BufferWrapper(std::shared_ptr gpu, SDL_GPUBuffer* gpu_buffer, TransferBufferWrapper transfer_buffer, + BufferWrapper(std::shared_ptr gpu, GpuBufferRaii gpu_buffer, TransferBufferWrapper transfer_buffer, std::uint32_t size) noexcept : - m_gpu(std::move(gpu)), m_gpu_buffer(gpu_buffer), m_transfer_buffer(std::move(transfer_buffer)), + m_gpu(std::move(gpu)), m_gpu_buffer(std::move(gpu_buffer)), m_transfer_buffer(std::move(transfer_buffer)), m_buffer_size(size) { m_cpu_buffer.resize(m_buffer_size); @@ -64,10 +65,10 @@ namespace sopho [[nodiscard]] std::expected upload(); /// Returns the underlying SDL_GPUBuffer pointer. - [[nodiscard]] SDL_GPUBuffer* gpu_buffer() const noexcept { return m_gpu_buffer; } + [[nodiscard]] SDL_GPUBuffer* gpu_buffer() const noexcept { return m_gpu_buffer.raw(); } [[nodiscard]] std::byte* cpu_buffer() noexcept { return m_cpu_buffer.data(); } - ~BufferWrapper() noexcept; + ~BufferWrapper() noexcept = default; friend class GpuWrapper; }; diff --git a/sdl_wrapper/src/sdl_wrapper.buffer.cpp b/sdl_wrapper/src/sdl_wrapper.buffer.cpp index 6454a93..01624ac 100644 --- a/sdl_wrapper/src/sdl_wrapper.buffer.cpp +++ b/sdl_wrapper/src/sdl_wrapper.buffer.cpp @@ -16,27 +16,6 @@ import :gpu; namespace sopho { - /** - * @brief Releases any owned GPU resources held by the wrapper. - * - * Ensures the associated GPU object is valid, then releases the GPU buffer and the - * GPU transfer buffer if they exist and clears their pointers. - */ - BufferWrapper::~BufferWrapper() noexcept - { - if (!m_gpu) - { - return; - } - - // Release gpu buffer - if (m_gpu_buffer) - { - m_gpu->release_buffer(m_gpu_buffer); - m_gpu_buffer = nullptr; - } - } - /** * @brief Uploads the internal CPU-side buffer to the GPU buffer via the transfer buffer and a GPU copy pass. * @@ -89,7 +68,7 @@ namespace sopho location.offset = 0; SDL_GPUBufferRegion region{}; - region.buffer = m_gpu_buffer; + region.buffer = m_gpu_buffer.raw(); region.size = size; region.offset = 0; @@ -114,6 +93,7 @@ namespace sopho SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); return std::unexpected(GpuError::CREATE_GPU_BUFFER_FAILED); } + GpuBufferRaii gpu_buffer_raii{gpu.device(), gpu_buffer}; auto transfer_buffer = TransferBufferWrapper::Builder{} .set_size(size) .set_usage(SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD) @@ -125,7 +105,8 @@ namespace sopho gpu.release_buffer(gpu_buffer); return std::unexpected(transfer_buffer.error()); } - return BufferWrapper{gpu.shared_from_this(), gpu_buffer, (std::move(transfer_buffer.value())), size}; + return BufferWrapper{gpu.shared_from_this(), std::move(gpu_buffer_raii), (std::move(transfer_buffer.value())), + size}; } } // namespace sopho From 11d219e9dc7894c7bbb7db44c2984fa7f280f1e5 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 15:01:27 +0800 Subject: [PATCH 19/66] fix: remove function release_buffer --- sdl_wrapper/modules/sdl_wrapper.gpu.ixx | 8 -------- sdl_wrapper/src/sdl_wrapper.buffer.cpp | 1 - 2 files changed, 9 deletions(-) diff --git a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx index 4429ba2..808e983 100644 --- a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx @@ -91,14 +91,6 @@ export namespace sopho [[nodiscard]] auto device() const { return m_ctx.device.raw(); } [[nodiscard]] SDL_Window* window() const { return m_ctx.window.raw(); } - auto release_buffer(SDL_GPUBuffer* buffer) - { - if (buffer) - { - SDL_ReleaseGPUBuffer(device(), buffer); - } - } - [[nodiscard]] std::expected create_render_procedural(); std::expected diff --git a/sdl_wrapper/src/sdl_wrapper.buffer.cpp b/sdl_wrapper/src/sdl_wrapper.buffer.cpp index 01624ac..c44aff0 100644 --- a/sdl_wrapper/src/sdl_wrapper.buffer.cpp +++ b/sdl_wrapper/src/sdl_wrapper.buffer.cpp @@ -102,7 +102,6 @@ namespace sopho if (!transfer_buffer) { SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); - gpu.release_buffer(gpu_buffer); return std::unexpected(transfer_buffer.error()); } return BufferWrapper{gpu.shared_from_this(), std::move(gpu_buffer_raii), (std::move(transfer_buffer.value())), From 694cdce65ecedbbe7b1d1b56539f6673462accfc Mon Sep 17 00:00:00 2001 From: Sophomore Date: Fri, 28 Nov 2025 15:37:39 +0800 Subject: [PATCH 20/66] feat:add template GpuResourceRaii --- sdl_wrapper/CMakeLists.txt | 4 +- .../modules/sdl_raii/sdl_raii.gpu_buffer.ixx | 57 ++-------------- .../sdl_raii/sdl_raii.gpu_resource.ixx | 66 +++++++++++++++++++ .../modules/sdl_raii/sdl_raii.gpu_shader.ixx | 21 ++++++ .../sdl_raii/sdl_raii.gpu_transfer_buffer.ixx | 18 +++++ sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 1 + .../sdl_raii/sdl_raii.transfer_buffer.ixx | 59 ----------------- .../modules/sdl_wrapper.transfer_buffer.ixx | 4 +- .../src/sdl_wrapper.transfer_buffer.cpp | 2 +- 9 files changed, 118 insertions(+), 114 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 61d5e9e..e5d5912 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -12,8 +12,10 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.gpu_device.ixx modules/sdl_raii/sdl_raii.window.ixx modules/sdl_raii/sdl_raii.claim_window.ixx - modules/sdl_raii/sdl_raii.transfer_buffer.ixx + modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx modules/sdl_raii/sdl_raii.gpu_buffer.ixx + modules/sdl_raii/sdl_raii.gpu_shader.ixx + modules/sdl_raii/sdl_raii.gpu_resource.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx index 86125dd..977b2be 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx @@ -4,60 +4,15 @@ module; #include export module sdl_raii:gpu_buffer; +import :gpu_resource; namespace sopho { - export struct GpuBufferRaii + template <> + struct GpuResourceTraits { - private: - SDL_GPUDevice* m_gpu_device{}; - SDL_GPUBuffer* m_raw{}; + using Device = SDL_GPUDevice; - public: - GpuBufferRaii() noexcept = default; - - explicit GpuBufferRaii(SDL_GPUDevice* device, SDL_GPUBuffer* buffer) noexcept : - m_gpu_device(device), m_raw(buffer) - { - } - - GpuBufferRaii(const GpuBufferRaii&) = delete; - GpuBufferRaii& operator=(const GpuBufferRaii&) = delete; - - GpuBufferRaii(GpuBufferRaii&& other) noexcept : m_gpu_device(other.m_gpu_device), m_raw(other.m_raw) - { - other.m_gpu_device = nullptr; - other.m_raw = nullptr; - } - - GpuBufferRaii& operator=(GpuBufferRaii&& other) noexcept - { - if (this != &other) - { - reset(); - - m_gpu_device = other.m_gpu_device; - m_raw = other.m_raw; - - other.m_gpu_device = nullptr; - other.m_raw = nullptr; - } - return *this; - } - - ~GpuBufferRaii() noexcept { reset(); } - void reset(SDL_GPUBuffer* buffer = nullptr, SDL_GPUDevice* device = nullptr) noexcept - { - if (m_raw && m_gpu_device) - { - SDL_ReleaseGPUBuffer(m_gpu_device, m_raw); - } - - m_gpu_device = device; - m_raw = buffer; - } - - [[nodiscard]] SDL_GPUBuffer* raw() const noexcept { return m_raw; } - [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_raw != nullptr; } - [[nodiscard]] explicit operator bool() const noexcept { return valid(); } + static void release(Device* device, SDL_GPUBuffer* buffer) noexcept { SDL_ReleaseGPUBuffer(device, buffer); } }; + export using GpuBufferRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx new file mode 100644 index 0000000..9828b6d --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx @@ -0,0 +1,66 @@ +// sdl_raii.gpu_resource.ixx +// Created by wsqsy on 11/28/2025. +// + +export module sdl_raii:gpu_resource; +namespace sopho +{ + template + struct GpuResourceTraits; + export template + struct GpuResourceRaii + { + using Traits = GpuResourceTraits; + using Device = typename Traits::Device; + + private: + Device* m_gpu_device{}; + T* m_raw{}; + + public: + GpuResourceRaii() noexcept = default; + + explicit GpuResourceRaii(Device* device, T* resource) noexcept : m_gpu_device(device), m_raw(resource) {} + + GpuResourceRaii(const GpuResourceRaii&) = delete; + GpuResourceRaii& operator=(const GpuResourceRaii&) = delete; + + GpuResourceRaii(GpuResourceRaii&& other) noexcept : m_gpu_device(other.m_gpu_device), m_raw(other.m_raw) + { + other.m_gpu_device = nullptr; + other.m_raw = nullptr; + } + + GpuResourceRaii& operator=(GpuResourceRaii&& other) noexcept + { + if (this != &other) + { + reset(); + + m_gpu_device = other.m_gpu_device; + m_raw = other.m_raw; + + other.m_gpu_device = nullptr; + other.m_raw = nullptr; + } + return *this; + } + + ~GpuResourceRaii() noexcept { reset(); } + + void reset(T* resource = nullptr, Device* device = nullptr) noexcept + { + if (m_raw && m_gpu_device) + { + Traits::release(m_gpu_device, m_raw); + } + + m_gpu_device = device; + m_raw = resource; + } + + [[nodiscard]] T* raw() const noexcept { return m_raw; } + [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_raw != nullptr; } + [[nodiscard]] explicit operator bool() const noexcept { return valid(); } + }; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx new file mode 100644 index 0000000..65ba84d --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx @@ -0,0 +1,21 @@ +// sdl_raii.shader.ixx +// Created by wsqsy on 11/28/2025. +// +module; +#include +export module sdl_raii:shader; +import :gpu_resource; +namespace sopho +{ + template<> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; + + static void release(Device* device, SDL_GPUShader* shader) noexcept + { + SDL_ReleaseGPUShader(device, shader); + } + }; + using GpuShaderRaii = GpuResourceRaii; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx new file mode 100644 index 0000000..00ac439 --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx @@ -0,0 +1,18 @@ +// sdl_raii.transfer_buffer.ixx +// Created by wsqsy on 11/28/2025. +// +module; +#include +export module sdl_raii:transfer_buffer; +import :gpu_resource; +namespace sopho +{ + template <> +struct GpuResourceTraits + { + using Device = SDL_GPUDevice; + + static void release(Device* device, SDL_GPUTransferBuffer* buffer) noexcept { SDL_ReleaseGPUTransferBuffer(device, buffer); } + }; + export using GpuTransferBufferRaii = GpuResourceRaii; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 8757153..53afbda 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -9,3 +9,4 @@ export import :window; export import :claim_window; export import :transfer_buffer; export import :gpu_buffer; +export import :shader; diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx deleted file mode 100644 index 99dd2de..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.transfer_buffer.ixx +++ /dev/null @@ -1,59 +0,0 @@ -// sdl_raii.transfer_buffer.ixx -// Created by wsqsy on 11/28/2025. -// - -export module sdl_raii:transfer_buffer; -#include -namespace sopho -{ - export struct TransferBufferRaii - { - private: - SDL_GPUDevice* m_gpu_device{}; - SDL_GPUTransferBuffer* m_raw{}; - - public: - TransferBufferRaii() noexcept = default; - TransferBufferRaii(SDL_GPUDevice* device, SDL_GPUTransferBuffer* buffer) noexcept : - m_gpu_device(device), m_raw(buffer) - { - } - TransferBufferRaii(const TransferBufferRaii&) = delete; - TransferBufferRaii& operator=(const TransferBufferRaii&) = delete; - TransferBufferRaii(TransferBufferRaii&& other) noexcept : - m_gpu_device(other.m_gpu_device), m_raw(other.m_raw) - { - other.m_gpu_device = nullptr; - other.m_raw = nullptr; - } - TransferBufferRaii& operator=(TransferBufferRaii&& other) noexcept - { - if (this != &other) - { - reset(); - - m_gpu_device = other.m_gpu_device; - m_raw = other.m_raw; - - other.m_gpu_device = nullptr; - other.m_raw = nullptr; - } - return *this; - } - ~TransferBufferRaii() noexcept { reset(); } - void reset(SDL_GPUTransferBuffer* buffer = nullptr, SDL_GPUDevice* device = nullptr) noexcept - { - if (m_raw && m_gpu_device) - { - SDL_ReleaseGPUTransferBuffer(m_gpu_device, m_raw); - } - - m_gpu_device = device; - - m_raw = buffer; - } - [[nodiscard]] SDL_GPUTransferBuffer* raw() const noexcept { return m_raw; } - [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_raw != nullptr; } - [[nodiscard]] explicit operator bool() const noexcept { return valid(); } - }; -} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_wrapper.transfer_buffer.ixx b/sdl_wrapper/modules/sdl_wrapper.transfer_buffer.ixx index 783bdee..efc5462 100644 --- a/sdl_wrapper/modules/sdl_wrapper.transfer_buffer.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.transfer_buffer.ixx @@ -30,12 +30,12 @@ namespace sopho { private: std::shared_ptr m_gpu{}; // Owns the device lifetime - TransferBufferRaii m_transfer_buffer{}; // The actual transfer buffer + GpuTransferBufferRaii m_transfer_buffer{}; // The actual transfer buffer std::int32_t m_usage_limit{}; // Current usage count std::uint32_t m_size{}; // Size of the transfer buffer in bytes // Private constructor to ensure only Builder can create instances - TransferBufferWrapper(std::shared_ptr gpu, TransferBufferRaii transfer_buffer, + TransferBufferWrapper(std::shared_ptr gpu, GpuTransferBufferRaii transfer_buffer, std::int32_t usage_limit, std::uint32_t size) noexcept : m_gpu(std::move(gpu)), m_transfer_buffer(std::move(transfer_buffer)), m_usage_limit(usage_limit), m_size(size) diff --git a/sdl_wrapper/src/sdl_wrapper.transfer_buffer.cpp b/sdl_wrapper/src/sdl_wrapper.transfer_buffer.cpp index 3990803..0201093 100644 --- a/sdl_wrapper/src/sdl_wrapper.transfer_buffer.cpp +++ b/sdl_wrapper/src/sdl_wrapper.transfer_buffer.cpp @@ -58,7 +58,7 @@ namespace sopho SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); return std::unexpected(GpuError::CREATE_TRANSFER_BUFFER_FAILED); } - TransferBufferRaii tb_raii{gpu.device(), transfer_buffer}; + GpuTransferBufferRaii tb_raii{gpu.device(), transfer_buffer}; return TransferBufferWrapper{gpu.shared_from_this(), std::move(tb_raii), usage_limit, size}; } From 507edda44bda299d80b083311f6fb75a736c42f4 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 20:25:07 +0800 Subject: [PATCH 21/66] fix: export partition module gpu resource --- sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 1 + 1 file changed, 1 insertion(+) diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 53afbda..3c03d0f 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -7,6 +7,7 @@ export module sdl_raii; export import :gpu_device; export import :window; export import :claim_window; +export import :gpu_resource; export import :transfer_buffer; export import :gpu_buffer; export import :shader; From 79a83bd32974839dceebfe7838d8c2ffa3007270 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 20:27:00 +0800 Subject: [PATCH 22/66] fix: using Gpu Shader Raii --- .../modules/sdl_raii/sdl_raii.gpu_shader.ixx | 2 +- .../sdl_raii/sdl_raii.gpu_transfer_buffer.ixx | 7 +++-- .../modules/sdl_wrapper.render_procedural.ixx | 5 ++-- .../src/sdl_wrapper.render_procedural.cpp | 28 ++----------------- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx index 65ba84d..814ec6b 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx @@ -17,5 +17,5 @@ namespace sopho SDL_ReleaseGPUShader(device, shader); } }; - using GpuShaderRaii = GpuResourceRaii; + export using GpuShaderRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx index 00ac439..422ed59 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx @@ -8,11 +8,14 @@ import :gpu_resource; namespace sopho { template <> -struct GpuResourceTraits + struct GpuResourceTraits { using Device = SDL_GPUDevice; - static void release(Device* device, SDL_GPUTransferBuffer* buffer) noexcept { SDL_ReleaseGPUTransferBuffer(device, buffer); } + static void release(Device* device, SDL_GPUTransferBuffer* buffer) noexcept + { + SDL_ReleaseGPUTransferBuffer(device, buffer); + } }; export using GpuTransferBufferRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx b/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx index 07bc7ca..fea33b4 100644 --- a/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx @@ -12,6 +12,7 @@ module; #include "shaderc/shaderc.hpp" export module sdl_wrapper:render_procedural; import data_type; +import sdl_raii; import :decl; // GpuError, forward declarations, etc. import :vertex_layout; export namespace sopho @@ -21,8 +22,8 @@ export namespace sopho std::shared_ptr m_gpu{}; SDL_GPUGraphicsPipeline* m_graphics_pipeline{}; - SDL_GPUShader* m_vertex_shader{}; - SDL_GPUShader* m_fragment_shader{}; + GpuShaderRaii m_vertex_shader{}; + GpuShaderRaii m_fragment_shader{}; std::vector m_vertex_buffer_descriptions{}; std::vector m_color_target_descriptions{}; diff --git a/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp b/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp index 11caa5d..bea2514 100644 --- a/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp +++ b/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp @@ -138,18 +138,6 @@ namespace sopho m_gpu->release_pipeline(m_graphics_pipeline); m_graphics_pipeline = nullptr; } - - if (m_vertex_shader) - { - m_gpu->release_shader(m_vertex_shader); - m_vertex_shader = nullptr; - } - - if (m_fragment_shader) - { - m_gpu->release_shader(m_fragment_shader); - m_fragment_shader = nullptr; - } } /** @@ -237,13 +225,7 @@ namespace sopho SDL_GPUShader* new_shader = shader_result.value(); - // Release previous shader, if any - if (m_vertex_shader) - { - m_gpu->release_shader(m_vertex_shader); - } - - m_vertex_shader = new_shader; + m_vertex_shader = GpuShaderRaii{m_gpu->device(), new_shader}; m_pipeline_info.vertex_shader = new_shader; m_modified = true; @@ -290,13 +272,7 @@ namespace sopho SDL_GPUShader* new_shader = shader_result.value(); - // Release previous shader, if any - if (m_fragment_shader) - { - m_gpu->release_shader(m_fragment_shader); - } - - m_fragment_shader = new_shader; + m_fragment_shader = GpuShaderRaii{m_gpu->device(), new_shader}; m_pipeline_info.fragment_shader = new_shader; m_modified = true; From ded13add287e9a84586b5b89fc92fc66120837ed Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 20:35:20 +0800 Subject: [PATCH 23/66] fix: Add pipeline raii --- main.cpp | 2 +- sdl_wrapper/CMakeLists.txt | 1 + .../modules/sdl_raii/sdl_raii.gpu_device.ixx | 2 +- .../sdl_raii.gpu_graphics_pipeline.ixx | 21 ++++++++++++++ .../modules/sdl_raii/sdl_raii.gpu_shader.ixx | 4 +-- .../sdl_raii/sdl_raii.gpu_transfer_buffer.ixx | 4 +-- sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 5 ++-- .../modules/sdl_wrapper.render_procedural.ixx | 6 ++-- .../src/sdl_wrapper.render_procedural.cpp | 29 +------------------ 9 files changed, 35 insertions(+), 39 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx diff --git a/main.cpp b/main.cpp index 6f7f134..42595ae 100644 --- a/main.cpp +++ b/main.cpp @@ -509,7 +509,7 @@ void main() // Bind pipeline if available. - SDL_BindGPUGraphicsPipeline(renderPass, m_renderable->procedural()->data()); + SDL_BindGPUGraphicsPipeline(renderPass, m_renderable->procedural()->raw()); // Compute camera matrix and upload as a vertex uniform. SDL_PushGPUVertexUniformData(commandBuffer, 0, diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index e5d5912..b52b2b6 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -16,6 +16,7 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.gpu_buffer.ixx modules/sdl_raii/sdl_raii.gpu_shader.ixx modules/sdl_raii/sdl_raii.gpu_resource.ixx + modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx index ba5c88b..ac38ba8 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx @@ -1,4 +1,4 @@ -// sdl_raii.gpu.ixx +// sdl_raii.gpu_device.ixx // Created by wsqsy on 11/28/2025. // module; diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx new file mode 100644 index 0000000..cb10dac --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx @@ -0,0 +1,21 @@ +// sdl_raii.gpu_graphics_pipeline.ixx +// Created by sophomore on 11/28/25. +// +module; +#include +export module sdl_raii:gpu_graphics_pipeline; +import :gpu_resource; +namespace sopho +{ + template <> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; + + static void release(Device* device, SDL_GPUGraphicsPipeline* raw) noexcept + { + SDL_ReleaseGPUGraphicsPipeline(device, raw); + } + }; + export using GPUGraphicsPipelineRaii = GpuResourceRaii; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx index 814ec6b..ec64465 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx @@ -1,9 +1,9 @@ -// sdl_raii.shader.ixx +// sdl_raii.gpu_shader.ixx // Created by wsqsy on 11/28/2025. // module; #include -export module sdl_raii:shader; +export module sdl_raii:gpu_shader; import :gpu_resource; namespace sopho { diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx index 422ed59..ec67a34 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx @@ -1,9 +1,9 @@ -// sdl_raii.transfer_buffer.ixx +// sdl_raii.gpu_transfer_buffer.ixx // Created by wsqsy on 11/28/2025. // module; #include -export module sdl_raii:transfer_buffer; +export module sdl_raii:gpu_transfer_buffer; import :gpu_resource; namespace sopho { diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 3c03d0f..5e12671 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -8,6 +8,7 @@ export import :gpu_device; export import :window; export import :claim_window; export import :gpu_resource; -export import :transfer_buffer; +export import :gpu_transfer_buffer; export import :gpu_buffer; -export import :shader; +export import :gpu_shader; +export import :gpu_graphics_pipeline; diff --git a/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx b/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx index fea33b4..839fd91 100644 --- a/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx @@ -21,7 +21,7 @@ export namespace sopho { std::shared_ptr m_gpu{}; - SDL_GPUGraphicsPipeline* m_graphics_pipeline{}; + GPUGraphicsPipelineRaii m_graphics_pipeline{}; GpuShaderRaii m_vertex_shader{}; GpuShaderRaii m_fragment_shader{}; @@ -43,10 +43,10 @@ export namespace sopho RenderProcedural& operator=(const RenderProcedural&) = delete; RenderProcedural(RenderProcedural&&) noexcept = default; RenderProcedural& operator=(RenderProcedural&&) = delete; - ~RenderProcedural() noexcept; + ~RenderProcedural() noexcept = default; /// Returns the underlying SDL_GPUGraphicsPipeline*. - [[nodiscard]] SDL_GPUGraphicsPipeline* data() const noexcept { return m_graphics_pipeline; } + [[nodiscard]] SDL_GPUGraphicsPipeline* raw() const noexcept { return m_graphics_pipeline.raw(); } /// Rebuilds the graphics pipeline if any state has been modified. /// diff --git a/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp b/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp index bea2514..b34b393 100644 --- a/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp +++ b/sdl_wrapper/src/sdl_wrapper.render_procedural.cpp @@ -119,27 +119,6 @@ namespace sopho m_modified = true; } - /** - * @brief Releases owned GPU pipeline and shader resources and clears their handles. - * - * If a GPU wrapper is available, releases the graphics pipeline, vertex shader, - * and fragment shader held by this object (if present) and resets their pointers - * to nullptr. - */ - RenderProcedural::~RenderProcedural() noexcept - { - if (!m_gpu) - { - return; - } - - if (m_graphics_pipeline) - { - m_gpu->release_pipeline(m_graphics_pipeline); - m_graphics_pipeline = nullptr; - } - } - /** * @brief Ensures the GPU graphics pipeline matches the current pipeline description, creating or replacing the * pipeline if changes are pending. @@ -180,13 +159,7 @@ namespace sopho SDL_GPUGraphicsPipeline* new_pipeline = pipeline_result.value(); - // Replace previous pipeline if any. - if (m_graphics_pipeline) - { - m_gpu->release_pipeline(m_graphics_pipeline); - } - - m_graphics_pipeline = new_pipeline; + m_graphics_pipeline = GPUGraphicsPipelineRaii{m_gpu->device(), new_pipeline}; m_modified = false; return std::monostate{}; From e072adbed7da675072ac01096bad7b4c5af02929 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 20:37:58 +0800 Subject: [PATCH 24/66] fix: Remove unused function --- sdl_wrapper/modules/sdl_wrapper.gpu.ixx | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx index 808e983..838bea8 100644 --- a/sdl_wrapper/modules/sdl_wrapper.gpu.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.gpu.ixx @@ -105,14 +105,6 @@ export namespace sopho return pipeline; } - auto release_pipeline(SDL_GPUGraphicsPipeline* graphics_pipeline) - { - if (graphics_pipeline) - { - SDL_ReleaseGPUGraphicsPipeline(device(), graphics_pipeline); - } - } - [[nodiscard]] auto create_shader(const std::vector& shader, SDL_GPUShaderStage stage, uint32_t num_uniform_buffers, uint32_t num_samplers) -> std::expected @@ -136,14 +128,6 @@ export namespace sopho return s; } - auto release_shader(SDL_GPUShader* shader) - { - if (shader) - { - SDL_ReleaseGPUShader(device(), shader); - } - } - [[nodiscard]] std::expected get_texture_format() const { auto format = SDL_GetGPUSwapchainTextureFormat(device(), window()); From 2993eeef8f58f9130a0dccaaffb28c60cc84a283 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 20:44:25 +0800 Subject: [PATCH 25/66] feat: add class texture raii --- sdl_wrapper/CMakeLists.txt | 1 + .../modules/sdl_raii/sdl_raii.gpu_shader.ixx | 4 ++-- .../modules/sdl_raii/sdl_raii.gpu_texture.ixx | 18 ++++++++++++++++++ sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 1 + sdl_wrapper/modules/sdl_wrapper.texture.ixx | 17 ++++++++--------- sdl_wrapper/src/sdl_wrapper.texture.cpp | 12 +++--------- 6 files changed, 33 insertions(+), 20 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index b52b2b6..73d3cef 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -17,6 +17,7 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.gpu_shader.ixx modules/sdl_raii/sdl_raii.gpu_resource.ixx modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx + modules/sdl_raii/sdl_raii.gpu_texture.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx index ec64465..fa05a61 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx @@ -12,9 +12,9 @@ namespace sopho { using Device = SDL_GPUDevice; - static void release(Device* device, SDL_GPUShader* shader) noexcept + static void release(Device* device, SDL_GPUShader* raw) noexcept { - SDL_ReleaseGPUShader(device, shader); + SDL_ReleaseGPUShader(device, raw); } }; export using GpuShaderRaii = GpuResourceRaii; diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx new file mode 100644 index 0000000..454c2e3 --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx @@ -0,0 +1,18 @@ +// sdl_raii.gpu_texture.ixx +// Created by sophomore on 11/28/25. +// +module; +#include +export module sdl_raii:gpu_texture; +import :gpu_resource; +namespace sopho +{ + template <> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; + + static void release(Device* device, SDL_GPUTexture* raw) noexcept { SDL_ReleaseGPUTexture(device, raw); } + }; + export using GpuTextureRaii = GpuResourceRaii; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 5e12671..77006af 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -12,3 +12,4 @@ export import :gpu_transfer_buffer; export import :gpu_buffer; export import :gpu_shader; export import :gpu_graphics_pipeline; +export import :gpu_texture; diff --git a/sdl_wrapper/modules/sdl_wrapper.texture.ixx b/sdl_wrapper/modules/sdl_wrapper.texture.ixx index ec3a6db..4ee0932 100644 --- a/sdl_wrapper/modules/sdl_wrapper.texture.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.texture.ixx @@ -9,6 +9,7 @@ module; #include export module sdl_wrapper:texture; import data_type; +import sdl_raii; import :decl; namespace sopho @@ -16,23 +17,22 @@ namespace sopho export class TextureWrapper { std::shared_ptr m_gpu{}; - SDL_GPUTexture* m_texture{}; + GpuTextureRaii m_texture{}; SDL_GPUSampler* m_sampler{}; SDL_GPUTextureSamplerBinding m_tex_binding{}; - TextureWrapper(std::shared_ptr gpu, SDL_GPUTexture* texture, SDL_GPUSampler* sampler) noexcept : - m_gpu(std::move(gpu)), m_texture(texture), m_sampler(sampler) + TextureWrapper(std::shared_ptr gpu, GpuTextureRaii texture, SDL_GPUSampler* sampler) noexcept : + m_gpu(std::move(gpu)), m_texture(std::move(texture)), m_sampler(sampler) { - m_tex_binding.texture = m_texture; + m_tex_binding.texture = m_texture.raw(); m_tex_binding.sampler = m_sampler; } public: TextureWrapper(const TextureWrapper&) = delete; TextureWrapper& operator=(const TextureWrapper&) = delete; - TextureWrapper(TextureWrapper&& other) noexcept : m_gpu(std::move(other.m_gpu)), m_texture(other.m_texture), m_sampler(other.m_sampler),m_tex_binding(other.m_tex_binding) + TextureWrapper(TextureWrapper&& other) noexcept : m_gpu(std::move(other.m_gpu)), m_texture(std::move(other.m_texture)), m_sampler(other.m_sampler),m_tex_binding(other.m_tex_binding) { - other.m_texture = nullptr; other.m_sampler = nullptr; other.m_tex_binding = {}; } @@ -43,12 +43,11 @@ namespace sopho { reset(); m_gpu = std::move(other.m_gpu); - m_texture = other.m_texture; - other.m_texture = nullptr; + m_texture = std::move(other.m_texture); m_sampler = other.m_sampler; other.m_sampler = nullptr; other.m_tex_binding = {}; - m_tex_binding.texture = m_texture; + m_tex_binding.texture = m_texture.raw(); m_tex_binding.sampler = m_sampler; } return *this; diff --git a/sdl_wrapper/src/sdl_wrapper.texture.cpp b/sdl_wrapper/src/sdl_wrapper.texture.cpp index 4f4b903..9b7fb0a 100644 --- a/sdl_wrapper/src/sdl_wrapper.texture.cpp +++ b/sdl_wrapper/src/sdl_wrapper.texture.cpp @@ -15,11 +15,6 @@ namespace sopho void TextureWrapper::reset() noexcept { - if (m_texture && m_gpu) - { - SDL_ReleaseGPUTexture(m_gpu->device(), m_texture); - m_texture = nullptr; - } if (m_sampler && m_gpu) { SDL_ReleaseGPUSampler(m_gpu->device(), m_sampler); @@ -45,6 +40,7 @@ namespace sopho SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create GPU texture: %s", SDL_GetError()); return std::unexpected(GpuError::CREATE_TEXTURE_FAILED); } + GpuTextureRaii texture_raii{gpu.device(), texture}; auto c_tb = TransferBufferWrapper::Builder{} @@ -56,7 +52,6 @@ namespace sopho auto submit_result = c_tb.and_then([&](auto& tb) { return tb.submit(img_data.pixels.data()); }); if (!submit_result) { - SDL_ReleaseGPUTexture(gpu.device(), texture); return std::unexpected{submit_result.error()}; } SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(gpu.device()); @@ -70,7 +65,6 @@ namespace sopho if (!copy_pass) { SDL_SubmitGPUCommandBuffer(cmd); - SDL_ReleaseGPUTexture(gpu.device(), texture); SDL_Log("SDL_BeginGPUCopyPass failed: %s", SDL_GetError()); return std::unexpected{GpuError::BEGIN_COPY_PASS_FAILED}; } @@ -82,7 +76,7 @@ namespace sopho src.rows_per_layer = 0; SDL_GPUTextureRegion dst{}; - dst.texture = texture; + dst.texture = texture_raii.raw(); dst.mip_level = 0; dst.layer = 0; dst.x = 0; @@ -118,6 +112,6 @@ namespace sopho return std::unexpected{GpuError::CREATE_SAMPLER_FAILED}; } - return TextureWrapper{gpu.shared_from_this(), texture, sampler}; + return TextureWrapper{gpu.shared_from_this(), std::move(texture_raii), sampler}; } } // namespace sopho From 9965ea32358e74af35afac38fe86b5ee26fa754b Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 20:50:06 +0800 Subject: [PATCH 26/66] feat: add class sampler raii --- sdl_wrapper/CMakeLists.txt | 1 + .../modules/sdl_raii/sdl_raii.gpu_sampler.ixx | 21 ++++++++++ sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 1 + sdl_wrapper/modules/sdl_wrapper.texture.ixx | 40 ++++--------------- sdl_wrapper/src/sdl_wrapper.texture.cpp | 12 +----- 5 files changed, 33 insertions(+), 42 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 73d3cef..a5185e0 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -18,6 +18,7 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.gpu_resource.ixx modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx modules/sdl_raii/sdl_raii.gpu_texture.ixx + modules/sdl_raii/sdl_raii.gpu_sampler.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx new file mode 100644 index 0000000..f10c53c --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx @@ -0,0 +1,21 @@ +// sdl_raii.gpu_sampler.ixx +// Created by sophomore on 11/28/25. +// +module; +#include "SDL3/SDL_gpu.h" +export module sdl_raii:gpu_sampler; +import :gpu_resource; +namespace sopho +{ + template<> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; + + static void release(Device* device, SDL_GPUSampler* raw) noexcept + { + SDL_ReleaseGPUSampler(device, raw); + } + }; + export using GPUSamplerRaii = GpuResourceRaii; +} // namespace sopho \ No newline at end of file diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 77006af..498c54f 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -13,3 +13,4 @@ export import :gpu_buffer; export import :gpu_shader; export import :gpu_graphics_pipeline; export import :gpu_texture; +export import :gpu_sampler; diff --git a/sdl_wrapper/modules/sdl_wrapper.texture.ixx b/sdl_wrapper/modules/sdl_wrapper.texture.ixx index 4ee0932..c93199c 100644 --- a/sdl_wrapper/modules/sdl_wrapper.texture.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.texture.ixx @@ -18,49 +18,25 @@ namespace sopho { std::shared_ptr m_gpu{}; GpuTextureRaii m_texture{}; - SDL_GPUSampler* m_sampler{}; + GPUSamplerRaii m_sampler{}; SDL_GPUTextureSamplerBinding m_tex_binding{}; - TextureWrapper(std::shared_ptr gpu, GpuTextureRaii texture, SDL_GPUSampler* sampler) noexcept : - m_gpu(std::move(gpu)), m_texture(std::move(texture)), m_sampler(sampler) + TextureWrapper(std::shared_ptr gpu, GpuTextureRaii texture, GPUSamplerRaii sampler) noexcept : + m_gpu(std::move(gpu)), m_texture(std::move(texture)), m_sampler(std::move(sampler)) { m_tex_binding.texture = m_texture.raw(); - m_tex_binding.sampler = m_sampler; + m_tex_binding.sampler = m_sampler.raw(); } public: TextureWrapper(const TextureWrapper&) = delete; TextureWrapper& operator=(const TextureWrapper&) = delete; - TextureWrapper(TextureWrapper&& other) noexcept : m_gpu(std::move(other.m_gpu)), m_texture(std::move(other.m_texture)), m_sampler(other.m_sampler),m_tex_binding(other.m_tex_binding) - { - other.m_sampler = nullptr; - other.m_tex_binding = {}; - } - - TextureWrapper& operator=(TextureWrapper&& other) noexcept - { - if (this != &other) - { - reset(); - m_gpu = std::move(other.m_gpu); - m_texture = std::move(other.m_texture); - m_sampler = other.m_sampler; - other.m_sampler = nullptr; - other.m_tex_binding = {}; - m_tex_binding.texture = m_texture.raw(); - m_tex_binding.sampler = m_sampler; - } - return *this; - } - - [[nodiscard]] const SDL_GPUTextureSamplerBinding* get() const noexcept - { - return &m_tex_binding; - } + TextureWrapper(TextureWrapper&& other) noexcept = default; + TextureWrapper& operator=(TextureWrapper&& other) noexcept = default; + ~TextureWrapper() noexcept = default; - void reset() noexcept; + [[nodiscard]] const SDL_GPUTextureSamplerBinding* get() const noexcept { return &m_tex_binding; } - ~TextureWrapper() noexcept { reset(); } struct Builder { diff --git a/sdl_wrapper/src/sdl_wrapper.texture.cpp b/sdl_wrapper/src/sdl_wrapper.texture.cpp index 9b7fb0a..128d76e 100644 --- a/sdl_wrapper/src/sdl_wrapper.texture.cpp +++ b/sdl_wrapper/src/sdl_wrapper.texture.cpp @@ -13,15 +13,6 @@ import :gpu; namespace sopho { - void TextureWrapper::reset() noexcept - { - if (m_sampler && m_gpu) - { - SDL_ReleaseGPUSampler(m_gpu->device(), m_sampler); - m_sampler = nullptr; - } - } - std::expected TextureWrapper::Builder::build(GpuWrapper& gpu) { SDL_GPUTextureCreateInfo create_info{.type = SDL_GPU_TEXTURETYPE_2D, @@ -111,7 +102,8 @@ namespace sopho SDL_ReleaseGPUTexture(gpu.device(), texture); return std::unexpected{GpuError::CREATE_SAMPLER_FAILED}; } + GPUSamplerRaii sampler_raii{gpu.device(), sampler}; - return TextureWrapper{gpu.shared_from_this(), std::move(texture_raii), sampler}; + return TextureWrapper{gpu.shared_from_this(), std::move(texture_raii), std::move(sampler_raii)}; } } // namespace sopho From d69db40031a27e22a08a4626e8f607cb4e2c3bd5 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 21:06:57 +0800 Subject: [PATCH 27/66] fix:change structure of sdl_raii --- .../modules/sdl_raii/sdl_raii.gpu_buffer.ixx | 1 - .../sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx | 1 - .../modules/sdl_raii/sdl_raii.gpu_sampler.ixx | 10 +++------- .../modules/sdl_raii/sdl_raii.gpu_shader.ixx | 1 - .../modules/sdl_raii/sdl_raii.gpu_texture.ixx | 1 - .../sdl_raii/sdl_raii.gpu_transfer_buffer.ixx | 5 ++--- sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 15 +++++++++++++-- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx index 977b2be..955167d 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx @@ -14,5 +14,4 @@ namespace sopho static void release(Device* device, SDL_GPUBuffer* buffer) noexcept { SDL_ReleaseGPUBuffer(device, buffer); } }; - export using GpuBufferRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx index cb10dac..b55ffa9 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx @@ -17,5 +17,4 @@ namespace sopho SDL_ReleaseGPUGraphicsPipeline(device, raw); } }; - export using GPUGraphicsPipelineRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx index f10c53c..eacb52f 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx @@ -7,15 +7,11 @@ export module sdl_raii:gpu_sampler; import :gpu_resource; namespace sopho { - template<> + template <> struct GpuResourceTraits { using Device = SDL_GPUDevice; - static void release(Device* device, SDL_GPUSampler* raw) noexcept - { - SDL_ReleaseGPUSampler(device, raw); - } + static void release(Device* device, SDL_GPUSampler* raw) noexcept { SDL_ReleaseGPUSampler(device, raw); } }; - export using GPUSamplerRaii = GpuResourceRaii; -} // namespace sopho \ No newline at end of file +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx index fa05a61..33ec580 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx @@ -17,5 +17,4 @@ namespace sopho SDL_ReleaseGPUShader(device, raw); } }; - export using GpuShaderRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx index 454c2e3..74bc34c 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx @@ -14,5 +14,4 @@ namespace sopho static void release(Device* device, SDL_GPUTexture* raw) noexcept { SDL_ReleaseGPUTexture(device, raw); } }; - export using GpuTextureRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx index ec67a34..281b9e4 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx @@ -12,10 +12,9 @@ namespace sopho { using Device = SDL_GPUDevice; - static void release(Device* device, SDL_GPUTransferBuffer* buffer) noexcept + static void release(Device* device, SDL_GPUTransferBuffer* raw) noexcept { - SDL_ReleaseGPUTransferBuffer(device, buffer); + SDL_ReleaseGPUTransferBuffer(device, raw); } }; - export using GpuTransferBufferRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 498c54f..37b2efa 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -1,16 +1,27 @@ // sdl_raii.ixx // Created by wsqsy on 11/28/2025. // - +module; +#include export module sdl_raii; export import :gpu_device; export import :window; export import :claim_window; -export import :gpu_resource; export import :gpu_transfer_buffer; export import :gpu_buffer; export import :gpu_shader; export import :gpu_graphics_pipeline; export import :gpu_texture; export import :gpu_sampler; +export import :gpu_resource; + +export namespace sopho +{ + using GpuTextureRaii = GpuResourceRaii; + using GpuShaderRaii = GpuResourceRaii; + using GpuTransferBufferRaii = GpuResourceRaii; + using GPUSamplerRaii = GpuResourceRaii; + using GPUGraphicsPipelineRaii = GpuResourceRaii; + using GpuBufferRaii = GpuResourceRaii; +} // namespace sopho From 5dde83f9f0eb4db6ed811b5ddba28e0a7ad21ac3 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 21:30:22 +0800 Subject: [PATCH 28/66] fix:rename file --- sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx b/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx index 839fd91..0384874 100644 --- a/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.render_procedural.ixx @@ -1,4 +1,4 @@ -// sdl_wrapper.pipeline.ixx +// sdl_wrapper.render_procedural.ixx // Created by sophomore on 11/11/25. // module; From 25f5175a2fcbbbf3c767a05d6b996eed7d83cfe2 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 21:32:12 +0800 Subject: [PATCH 29/66] Revert "fix:change structure of sdl_raii" This reverts commit d69db40031a27e22a08a4626e8f607cb4e2c3bd5. --- .../modules/sdl_raii/sdl_raii.gpu_buffer.ixx | 1 + .../sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx | 1 + .../modules/sdl_raii/sdl_raii.gpu_sampler.ixx | 10 +++++++--- .../modules/sdl_raii/sdl_raii.gpu_shader.ixx | 1 + .../modules/sdl_raii/sdl_raii.gpu_texture.ixx | 1 + .../sdl_raii/sdl_raii.gpu_transfer_buffer.ixx | 5 +++-- sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 15 ++------------- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx index 955167d..977b2be 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx @@ -14,4 +14,5 @@ namespace sopho static void release(Device* device, SDL_GPUBuffer* buffer) noexcept { SDL_ReleaseGPUBuffer(device, buffer); } }; + export using GpuBufferRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx index b55ffa9..cb10dac 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx @@ -17,4 +17,5 @@ namespace sopho SDL_ReleaseGPUGraphicsPipeline(device, raw); } }; + export using GPUGraphicsPipelineRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx index eacb52f..f10c53c 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx @@ -7,11 +7,15 @@ export module sdl_raii:gpu_sampler; import :gpu_resource; namespace sopho { - template <> + template<> struct GpuResourceTraits { using Device = SDL_GPUDevice; - static void release(Device* device, SDL_GPUSampler* raw) noexcept { SDL_ReleaseGPUSampler(device, raw); } + static void release(Device* device, SDL_GPUSampler* raw) noexcept + { + SDL_ReleaseGPUSampler(device, raw); + } }; -} // namespace sopho + export using GPUSamplerRaii = GpuResourceRaii; +} // namespace sopho \ No newline at end of file diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx index 33ec580..fa05a61 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx @@ -17,4 +17,5 @@ namespace sopho SDL_ReleaseGPUShader(device, raw); } }; + export using GpuShaderRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx index 74bc34c..454c2e3 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx @@ -14,4 +14,5 @@ namespace sopho static void release(Device* device, SDL_GPUTexture* raw) noexcept { SDL_ReleaseGPUTexture(device, raw); } }; + export using GpuTextureRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx index 281b9e4..ec67a34 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx @@ -12,9 +12,10 @@ namespace sopho { using Device = SDL_GPUDevice; - static void release(Device* device, SDL_GPUTransferBuffer* raw) noexcept + static void release(Device* device, SDL_GPUTransferBuffer* buffer) noexcept { - SDL_ReleaseGPUTransferBuffer(device, raw); + SDL_ReleaseGPUTransferBuffer(device, buffer); } }; + export using GpuTransferBufferRaii = GpuResourceRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 37b2efa..498c54f 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -1,27 +1,16 @@ // sdl_raii.ixx // Created by wsqsy on 11/28/2025. // -module; -#include + export module sdl_raii; export import :gpu_device; export import :window; export import :claim_window; +export import :gpu_resource; export import :gpu_transfer_buffer; export import :gpu_buffer; export import :gpu_shader; export import :gpu_graphics_pipeline; export import :gpu_texture; export import :gpu_sampler; -export import :gpu_resource; - -export namespace sopho -{ - using GpuTextureRaii = GpuResourceRaii; - using GpuShaderRaii = GpuResourceRaii; - using GpuTransferBufferRaii = GpuResourceRaii; - using GPUSamplerRaii = GpuResourceRaii; - using GPUGraphicsPipelineRaii = GpuResourceRaii; - using GpuBufferRaii = GpuResourceRaii; -} // namespace sopho From 6ac17a408964d47f517b2e65085d5386a43c38e1 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 21:35:25 +0800 Subject: [PATCH 30/66] fix:Add default GpuResourceTraits --- sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx index 9828b6d..0b9c9e8 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx @@ -6,7 +6,10 @@ export module sdl_raii:gpu_resource; namespace sopho { template - struct GpuResourceTraits; + struct GpuResourceTraits + { + using Device = void; + }; export template struct GpuResourceRaii { From 57dce1918857735ce2a6579af28893a9720f303b Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 21:59:50 +0800 Subject: [PATCH 31/66] fix:Move template --- sdl_wrapper/CMakeLists.txt | 7 +- .../modules/sdl_raii/sdl_raii.gpu_buffer.ixx | 18 ---- .../sdl_raii.gpu_graphics_pipeline.ixx | 21 ----- .../sdl_raii/sdl_raii.gpu_resource.ixx | 91 +++++++++---------- .../sdl_raii/sdl_raii.gpu_resource_raii.ixx | 65 +++++++++++++ .../modules/sdl_raii/sdl_raii.gpu_sampler.ixx | 21 ----- .../modules/sdl_raii/sdl_raii.gpu_shader.ixx | 21 ----- .../modules/sdl_raii/sdl_raii.gpu_texture.ixx | 18 ---- .../sdl_raii/sdl_raii.gpu_transfer_buffer.ixx | 21 ----- sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 20 ++-- 10 files changed, 122 insertions(+), 181 deletions(-) delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource_raii.ixx delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index a5185e0..086f118 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -12,13 +12,8 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.gpu_device.ixx modules/sdl_raii/sdl_raii.window.ixx modules/sdl_raii/sdl_raii.claim_window.ixx - modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx - modules/sdl_raii/sdl_raii.gpu_buffer.ixx - modules/sdl_raii/sdl_raii.gpu_shader.ixx modules/sdl_raii/sdl_raii.gpu_resource.ixx - modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx - modules/sdl_raii/sdl_raii.gpu_texture.ixx - modules/sdl_raii/sdl_raii.gpu_sampler.ixx + modules/sdl_raii/sdl_raii.gpu_resource_raii.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx deleted file mode 100644 index 977b2be..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_buffer.ixx +++ /dev/null @@ -1,18 +0,0 @@ -// sdl_raii.gpu_buffer.ixx -// Created by wsqsy on 11/28/2025. -// -module; -#include -export module sdl_raii:gpu_buffer; -import :gpu_resource; -namespace sopho -{ - template <> - struct GpuResourceTraits - { - using Device = SDL_GPUDevice; - - static void release(Device* device, SDL_GPUBuffer* buffer) noexcept { SDL_ReleaseGPUBuffer(device, buffer); } - }; - export using GpuBufferRaii = GpuResourceRaii; -} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx deleted file mode 100644 index cb10dac..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_graphics_pipeline.ixx +++ /dev/null @@ -1,21 +0,0 @@ -// sdl_raii.gpu_graphics_pipeline.ixx -// Created by sophomore on 11/28/25. -// -module; -#include -export module sdl_raii:gpu_graphics_pipeline; -import :gpu_resource; -namespace sopho -{ - template <> - struct GpuResourceTraits - { - using Device = SDL_GPUDevice; - - static void release(Device* device, SDL_GPUGraphicsPipeline* raw) noexcept - { - SDL_ReleaseGPUGraphicsPipeline(device, raw); - } - }; - export using GPUGraphicsPipelineRaii = GpuResourceRaii; -} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx index 0b9c9e8..90e106e 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx @@ -1,69 +1,64 @@ // sdl_raii.gpu_resource.ixx // Created by wsqsy on 11/28/2025. // - +module; +#include export module sdl_raii:gpu_resource; namespace sopho { template - struct GpuResourceTraits - { - using Device = void; - }; - export template - struct GpuResourceRaii - { - using Traits = GpuResourceTraits; - using Device = typename Traits::Device; - - private: - Device* m_gpu_device{}; - T* m_raw{}; + struct GpuResourceTraits; - public: - GpuResourceRaii() noexcept = default; + // Due to Windows msvc problem, we need to put all template in one module partition. - explicit GpuResourceRaii(Device* device, T* resource) noexcept : m_gpu_device(device), m_raw(resource) {} + template <> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; - GpuResourceRaii(const GpuResourceRaii&) = delete; - GpuResourceRaii& operator=(const GpuResourceRaii&) = delete; + static void release(Device* device, SDL_GPUBuffer* buffer) noexcept { SDL_ReleaseGPUBuffer(device, buffer); } + }; + template <> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; - GpuResourceRaii(GpuResourceRaii&& other) noexcept : m_gpu_device(other.m_gpu_device), m_raw(other.m_raw) + static void release(Device* device, SDL_GPUGraphicsPipeline* raw) noexcept { - other.m_gpu_device = nullptr; - other.m_raw = nullptr; + SDL_ReleaseGPUGraphicsPipeline(device, raw); } + }; + template <> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; - GpuResourceRaii& operator=(GpuResourceRaii&& other) noexcept - { - if (this != &other) - { - reset(); - - m_gpu_device = other.m_gpu_device; - m_raw = other.m_raw; + static void release(Device* device, SDL_GPUSampler* raw) noexcept { SDL_ReleaseGPUSampler(device, raw); } + }; + template <> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; - other.m_gpu_device = nullptr; - other.m_raw = nullptr; - } - return *this; - } + static void release(Device* device, SDL_GPUShader* raw) noexcept { SDL_ReleaseGPUShader(device, raw); } + }; + template <> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; - ~GpuResourceRaii() noexcept { reset(); } + static void release(Device* device, SDL_GPUTexture* raw) noexcept { SDL_ReleaseGPUTexture(device, raw); } + }; + template <> + struct GpuResourceTraits + { + using Device = SDL_GPUDevice; - void reset(T* resource = nullptr, Device* device = nullptr) noexcept + static void release(Device* device, SDL_GPUTransferBuffer* buffer) noexcept { - if (m_raw && m_gpu_device) - { - Traits::release(m_gpu_device, m_raw); - } - - m_gpu_device = device; - m_raw = resource; + SDL_ReleaseGPUTransferBuffer(device, buffer); } - - [[nodiscard]] T* raw() const noexcept { return m_raw; } - [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_raw != nullptr; } - [[nodiscard]] explicit operator bool() const noexcept { return valid(); } }; + + } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource_raii.ixx new file mode 100644 index 0000000..1c42213 --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource_raii.ixx @@ -0,0 +1,65 @@ +// sdl_raii.gpu_resource_raii.ixx +// Created by sophomore on 11/28/25. +// + +export module sdl_raii:gpu_resource_raii; +import :gpu_resource; +namespace sopho +{ + export template + struct GpuResourceRaii + { + using Traits = GpuResourceTraits; + using Device = typename Traits::Device; + + private: + Device* m_gpu_device{}; + T* m_raw{}; + + public: + GpuResourceRaii() noexcept = default; + + explicit GpuResourceRaii(Device* device, T* resource) noexcept : m_gpu_device(device), m_raw(resource) {} + + GpuResourceRaii(const GpuResourceRaii&) = delete; + GpuResourceRaii& operator=(const GpuResourceRaii&) = delete; + + GpuResourceRaii(GpuResourceRaii&& other) noexcept : m_gpu_device(other.m_gpu_device), m_raw(other.m_raw) + { + other.m_gpu_device = nullptr; + other.m_raw = nullptr; + } + + GpuResourceRaii& operator=(GpuResourceRaii&& other) noexcept + { + if (this != &other) + { + reset(); + + m_gpu_device = other.m_gpu_device; + m_raw = other.m_raw; + + other.m_gpu_device = nullptr; + other.m_raw = nullptr; + } + return *this; + } + + ~GpuResourceRaii() noexcept { reset(); } + + void reset(T* resource = nullptr, Device* device = nullptr) noexcept + { + if (m_raw && m_gpu_device) + { + Traits::release(m_gpu_device, m_raw); + } + + m_gpu_device = device; + m_raw = resource; + } + + [[nodiscard]] T* raw() const noexcept { return m_raw; } + [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_raw != nullptr; } + [[nodiscard]] explicit operator bool() const noexcept { return valid(); } + }; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx deleted file mode 100644 index f10c53c..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_sampler.ixx +++ /dev/null @@ -1,21 +0,0 @@ -// sdl_raii.gpu_sampler.ixx -// Created by sophomore on 11/28/25. -// -module; -#include "SDL3/SDL_gpu.h" -export module sdl_raii:gpu_sampler; -import :gpu_resource; -namespace sopho -{ - template<> - struct GpuResourceTraits - { - using Device = SDL_GPUDevice; - - static void release(Device* device, SDL_GPUSampler* raw) noexcept - { - SDL_ReleaseGPUSampler(device, raw); - } - }; - export using GPUSamplerRaii = GpuResourceRaii; -} // namespace sopho \ No newline at end of file diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx deleted file mode 100644 index fa05a61..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_shader.ixx +++ /dev/null @@ -1,21 +0,0 @@ -// sdl_raii.gpu_shader.ixx -// Created by wsqsy on 11/28/2025. -// -module; -#include -export module sdl_raii:gpu_shader; -import :gpu_resource; -namespace sopho -{ - template<> - struct GpuResourceTraits - { - using Device = SDL_GPUDevice; - - static void release(Device* device, SDL_GPUShader* raw) noexcept - { - SDL_ReleaseGPUShader(device, raw); - } - }; - export using GpuShaderRaii = GpuResourceRaii; -} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx deleted file mode 100644 index 454c2e3..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_texture.ixx +++ /dev/null @@ -1,18 +0,0 @@ -// sdl_raii.gpu_texture.ixx -// Created by sophomore on 11/28/25. -// -module; -#include -export module sdl_raii:gpu_texture; -import :gpu_resource; -namespace sopho -{ - template <> - struct GpuResourceTraits - { - using Device = SDL_GPUDevice; - - static void release(Device* device, SDL_GPUTexture* raw) noexcept { SDL_ReleaseGPUTexture(device, raw); } - }; - export using GpuTextureRaii = GpuResourceRaii; -} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx deleted file mode 100644 index ec67a34..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_transfer_buffer.ixx +++ /dev/null @@ -1,21 +0,0 @@ -// sdl_raii.gpu_transfer_buffer.ixx -// Created by wsqsy on 11/28/2025. -// -module; -#include -export module sdl_raii:gpu_transfer_buffer; -import :gpu_resource; -namespace sopho -{ - template <> - struct GpuResourceTraits - { - using Device = SDL_GPUDevice; - - static void release(Device* device, SDL_GPUTransferBuffer* buffer) noexcept - { - SDL_ReleaseGPUTransferBuffer(device, buffer); - } - }; - export using GpuTransferBufferRaii = GpuResourceRaii; -} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 498c54f..4f480cd 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -1,16 +1,22 @@ // sdl_raii.ixx // Created by wsqsy on 11/28/2025. // - +module; +#include export module sdl_raii; export import :gpu_device; export import :window; export import :claim_window; export import :gpu_resource; -export import :gpu_transfer_buffer; -export import :gpu_buffer; -export import :gpu_shader; -export import :gpu_graphics_pipeline; -export import :gpu_texture; -export import :gpu_sampler; +export import :gpu_resource_raii; + +export namespace sopho +{ + using GpuBufferRaii = GpuResourceRaii; + using GPUGraphicsPipelineRaii = GpuResourceRaii; + using GPUSamplerRaii = GpuResourceRaii; + using GpuShaderRaii = GpuResourceRaii; + using GpuTextureRaii = GpuResourceRaii; + using GpuTransferBufferRaii = GpuResourceRaii; +} // namespace sopho From ddff90e528f8293a32724f85594c3d8e41e04b7d Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Fri, 28 Nov 2025 22:10:13 +0800 Subject: [PATCH 32/66] doc: add node in graph --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index da95d76..8e6f1e7 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ graph TD subgraph sdl_wrapper lifecycle + sdl_raii end glslang --> shaderc From 3f08a52b92f0b5242ff32ce7065a2ee20c4250c5 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 00:06:40 +0800 Subject: [PATCH 33/66] feat: rename template and class --- sdl_wrapper/CMakeLists.txt | 4 ++-- ...ource_raii.ixx => sdl_raii.bound_raii.ixx} | 24 +++++++++---------- ...resource.ixx => sdl_raii.bound_traits.ixx} | 18 +++++++------- sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 16 ++++++------- 4 files changed, 31 insertions(+), 31 deletions(-) rename sdl_wrapper/modules/sdl_raii/{sdl_raii.gpu_resource_raii.ixx => sdl_raii.bound_raii.ixx} (63%) rename sdl_wrapper/modules/sdl_raii/{sdl_raii.gpu_resource.ixx => sdl_raii.bound_traits.ixx} (78%) diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 086f118..6c8e82c 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -12,8 +12,8 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.gpu_device.ixx modules/sdl_raii/sdl_raii.window.ixx modules/sdl_raii/sdl_raii.claim_window.ixx - modules/sdl_raii/sdl_raii.gpu_resource.ixx - modules/sdl_raii/sdl_raii.gpu_resource_raii.ixx + modules/sdl_raii/sdl_raii.bound_raii.ixx + modules/sdl_raii/sdl_raii.bound_traits.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_raii.ixx similarity index 63% rename from sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource_raii.ixx rename to sdl_wrapper/modules/sdl_raii/sdl_raii.bound_raii.ixx index 1c42213..767bb5e 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_raii.ixx @@ -1,15 +1,15 @@ -// sdl_raii.gpu_resource_raii.ixx +// sdl_raii.bound_raii.ixx // Created by sophomore on 11/28/25. // -export module sdl_raii:gpu_resource_raii; -import :gpu_resource; +export module sdl_raii:bound_raii; +import :bound_traits; namespace sopho { export template - struct GpuResourceRaii + struct BoundRaii { - using Traits = GpuResourceTraits; + using Traits = BoundTraits; using Device = typename Traits::Device; private: @@ -17,20 +17,20 @@ namespace sopho T* m_raw{}; public: - GpuResourceRaii() noexcept = default; + BoundRaii() noexcept = default; - explicit GpuResourceRaii(Device* device, T* resource) noexcept : m_gpu_device(device), m_raw(resource) {} + explicit BoundRaii(Device* device, T* resource) noexcept : m_gpu_device(device), m_raw(resource) {} - GpuResourceRaii(const GpuResourceRaii&) = delete; - GpuResourceRaii& operator=(const GpuResourceRaii&) = delete; + BoundRaii(const BoundRaii&) = delete; + BoundRaii& operator=(const BoundRaii&) = delete; - GpuResourceRaii(GpuResourceRaii&& other) noexcept : m_gpu_device(other.m_gpu_device), m_raw(other.m_raw) + BoundRaii(BoundRaii&& other) noexcept : m_gpu_device(other.m_gpu_device), m_raw(other.m_raw) { other.m_gpu_device = nullptr; other.m_raw = nullptr; } - GpuResourceRaii& operator=(GpuResourceRaii&& other) noexcept + BoundRaii& operator=(BoundRaii&& other) noexcept { if (this != &other) { @@ -45,7 +45,7 @@ namespace sopho return *this; } - ~GpuResourceRaii() noexcept { reset(); } + ~BoundRaii() noexcept { reset(); } void reset(T* resource = nullptr, Device* device = nullptr) noexcept { diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_traits.ixx similarity index 78% rename from sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx rename to sdl_wrapper/modules/sdl_raii/sdl_raii.bound_traits.ixx index 90e106e..2b01d2a 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_resource.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_traits.ixx @@ -1,25 +1,25 @@ -// sdl_raii.gpu_resource.ixx +// sdl_raii.bound_traits.ixx // Created by wsqsy on 11/28/2025. // module; #include -export module sdl_raii:gpu_resource; +export module sdl_raii:bound_traits; namespace sopho { template - struct GpuResourceTraits; + struct BoundTraits; // Due to Windows msvc problem, we need to put all template in one module partition. template <> - struct GpuResourceTraits + struct BoundTraits { using Device = SDL_GPUDevice; static void release(Device* device, SDL_GPUBuffer* buffer) noexcept { SDL_ReleaseGPUBuffer(device, buffer); } }; template <> - struct GpuResourceTraits + struct BoundTraits { using Device = SDL_GPUDevice; @@ -29,28 +29,28 @@ namespace sopho } }; template <> - struct GpuResourceTraits + struct BoundTraits { using Device = SDL_GPUDevice; static void release(Device* device, SDL_GPUSampler* raw) noexcept { SDL_ReleaseGPUSampler(device, raw); } }; template <> - struct GpuResourceTraits + struct BoundTraits { using Device = SDL_GPUDevice; static void release(Device* device, SDL_GPUShader* raw) noexcept { SDL_ReleaseGPUShader(device, raw); } }; template <> - struct GpuResourceTraits + struct BoundTraits { using Device = SDL_GPUDevice; static void release(Device* device, SDL_GPUTexture* raw) noexcept { SDL_ReleaseGPUTexture(device, raw); } }; template <> - struct GpuResourceTraits + struct BoundTraits { using Device = SDL_GPUDevice; diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 4f480cd..ce62ac7 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -8,15 +8,15 @@ export module sdl_raii; export import :gpu_device; export import :window; export import :claim_window; -export import :gpu_resource; -export import :gpu_resource_raii; +export import :bound_traits; +export import :bound_raii; export namespace sopho { - using GpuBufferRaii = GpuResourceRaii; - using GPUGraphicsPipelineRaii = GpuResourceRaii; - using GPUSamplerRaii = GpuResourceRaii; - using GpuShaderRaii = GpuResourceRaii; - using GpuTextureRaii = GpuResourceRaii; - using GpuTransferBufferRaii = GpuResourceRaii; + using GpuBufferRaii = BoundRaii; + using GPUGraphicsPipelineRaii = BoundRaii; + using GPUSamplerRaii = BoundRaii; + using GpuShaderRaii = BoundRaii; + using GpuTextureRaii = BoundRaii; + using GpuTransferBufferRaii = BoundRaii; } // namespace sopho From 7b60ea09a7b7243cc09e887d3675f7a8fcb10730 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 00:19:58 +0800 Subject: [PATCH 34/66] feat: Add template pure raii and command buffer raii --- main.cpp | 32 +++++------ sdl_wrapper/CMakeLists.txt | 2 + sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 3 ++ .../modules/sdl_raii/sdl_raii.pure_raii.ixx | 53 +++++++++++++++++++ .../modules/sdl_raii/sdl_raii.pure_traits.ixx | 19 +++++++ 5 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.pure_raii.ixx create mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx diff --git a/main.cpp b/main.cpp index 42595ae..d9b80c1 100644 --- a/main.cpp +++ b/main.cpp @@ -25,6 +25,7 @@ import lifecycle; import data_type; +import sdl_raii; import glsl_reflector; import sdl_wrapper; import logos; @@ -434,12 +435,16 @@ void main() SDL_LogError(SDL_LOG_CATEGORY_GPU, "GpuWrapper::device() returned null in draw()"); return SDL_APP_CONTINUE; } - - SDL_GPUCommandBuffer* commandBuffer = SDL_AcquireGPUCommandBuffer(device); - if (!commandBuffer) + sopho::GpuCommandBufferRaii command_buffer_raii{}; { - SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire GPU command buffer"); - return SDL_APP_CONTINUE; + + SDL_GPUCommandBuffer* command_buffer = SDL_AcquireGPUCommandBuffer(device); + if (!command_buffer) + { + SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire GPU command buffer"); + return SDL_APP_CONTINUE; + } + command_buffer_raii.reset(command_buffer); } SDL_GPUTexture* swapchainTexture = nullptr; @@ -449,14 +454,13 @@ void main() if (!window) { SDL_LogError(SDL_LOG_CATEGORY_GPU, "GpuWrapper::window() returned null in draw()"); - SDL_SubmitGPUCommandBuffer(commandBuffer); return SDL_APP_CONTINUE; } - if (!SDL_WaitAndAcquireGPUSwapchainTexture(commandBuffer, window, &swapchainTexture, &width, &height)) + if (!SDL_WaitAndAcquireGPUSwapchainTexture(command_buffer_raii.raw(), window, &swapchainTexture, &width, + &height)) { SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire swapchain texture: %s", SDL_GetError()); - SDL_SubmitGPUCommandBuffer(commandBuffer); return SDL_APP_CONTINUE; } @@ -481,11 +485,10 @@ void main() if (swapchainTexture == nullptr) { // You must always submit the command buffer, even if no texture is available. - SDL_SubmitGPUCommandBuffer(commandBuffer); return SDL_APP_CONTINUE; } - ImGui_ImplSDLGPU3_PrepareDrawData(draw_data, commandBuffer); + ImGui_ImplSDLGPU3_PrepareDrawData(draw_data, command_buffer_raii.raw()); // Create the color target. SDL_GPUColorTargetInfo colorTargetInfo{}; @@ -505,14 +508,14 @@ void main() depthStencilTargetInfo.stencil_store_op = SDL_GPU_STOREOP_STORE; SDL_GPURenderPass* renderPass = - SDL_BeginGPURenderPass(commandBuffer, &colorTargetInfo, 1, &depthStencilTargetInfo); + SDL_BeginGPURenderPass(command_buffer_raii.raw(), &colorTargetInfo, 1, &depthStencilTargetInfo); // Bind pipeline if available. SDL_BindGPUGraphicsPipeline(renderPass, m_renderable->procedural()->raw()); // Compute camera matrix and upload as a vertex uniform. - SDL_PushGPUVertexUniformData(commandBuffer, 0, + SDL_PushGPUVertexUniformData(command_buffer_raii.raw(), 0, (sopho::perspective(1, static_cast(width) / height, 0.1, 10) * sopho::translate(0, 0, -5) * sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)) .data(), @@ -539,11 +542,10 @@ void main() colorTargetInfo.load_op = SDL_GPU_LOADOP_LOAD; - renderPass = SDL_BeginGPURenderPass(commandBuffer, &colorTargetInfo, 1, nullptr); - ImGui_ImplSDLGPU3_RenderDrawData(draw_data, commandBuffer, renderPass); + renderPass = SDL_BeginGPURenderPass(command_buffer_raii.raw(), &colorTargetInfo, 1, nullptr); + ImGui_ImplSDLGPU3_RenderDrawData(draw_data, command_buffer_raii.raw(), renderPass); SDL_EndGPURenderPass(renderPass); - SDL_SubmitGPUCommandBuffer(commandBuffer); return SDL_APP_CONTINUE; } diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 6c8e82c..980d969 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -14,6 +14,8 @@ target_sources(sdl_wrapper modules/sdl_raii/sdl_raii.claim_window.ixx modules/sdl_raii/sdl_raii.bound_raii.ixx modules/sdl_raii/sdl_raii.bound_traits.ixx + modules/sdl_raii/sdl_raii.pure_raii.ixx + modules/sdl_raii/sdl_raii.pure_traits.ixx modules/sdl_wrapper.ixx modules/sdl_wrapper.buffer.ixx modules/sdl_wrapper.render_procedural.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index ce62ac7..601e50b 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -10,6 +10,8 @@ export import :window; export import :claim_window; export import :bound_traits; export import :bound_raii; +export import :pure_traits; +export import :pure_raii; export namespace sopho { @@ -19,4 +21,5 @@ export namespace sopho using GpuShaderRaii = BoundRaii; using GpuTextureRaii = BoundRaii; using GpuTransferBufferRaii = BoundRaii; + using GpuCommandBufferRaii = PureRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_raii.ixx new file mode 100644 index 0000000..f4dbf6a --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_raii.ixx @@ -0,0 +1,53 @@ +// sdl_raii.pure_raii.ixx +// Created by sophomore on 11/29/25. +// + +export module sdl_raii:pure_raii; +import :pure_traits; +namespace sopho +{ + export template + struct PureRaii + { + using Traits = PureTraits; + + private: + T* m_raw{}; + + public: + PureRaii() noexcept = default; + + explicit PureRaii(T* raw) noexcept : m_raw(raw) {} + + PureRaii(const PureRaii&) = delete; + PureRaii& operator=(const PureRaii&) = delete; + + PureRaii(PureRaii&& other) noexcept : m_raw(other.m_raw) { other.m_raw = nullptr; } + PureRaii& operator=(PureRaii&& other) noexcept + { + if (this != &other) + { + reset(); + m_raw = other.m_raw; + other.m_raw = nullptr; + } + return *this; + } + + ~PureRaii() noexcept { reset(); } + + void reset(T* raw = nullptr) noexcept + { + if (m_raw) + { + Traits::release(m_raw); + } + + m_raw = raw; + } + + [[nodiscard]] T* raw() const noexcept { return m_raw; } + [[nodiscard]] bool valid() const noexcept { return m_raw != nullptr; } + [[nodiscard]] explicit operator bool() const noexcept { return valid(); } + }; +} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx new file mode 100644 index 0000000..aeac2f6 --- /dev/null +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx @@ -0,0 +1,19 @@ +// sdl_raii.pure_traits.ixx +// Created by sophomore on 11/29/25. +// +module; +#include +export module sdl_raii:pure_traits; +namespace sopho +{ + template + struct PureTraits; + + // Due to Windows msvc problem, we need to put all template in one module partition. + + template <> + struct PureTraits + { + static void release(SDL_GPUCommandBuffer* raw) noexcept { SDL_SubmitGPUCommandBuffer(raw); } + }; +} // namespace sopho \ No newline at end of file From 24d5d17baee0ef23d9b19c02f2500c7eec1c0812 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 00:24:29 +0800 Subject: [PATCH 35/66] fix: using GpuCommandBufferRaii --- sdl_wrapper/src/sdl_wrapper.texture.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/sdl_wrapper/src/sdl_wrapper.texture.cpp b/sdl_wrapper/src/sdl_wrapper.texture.cpp index 128d76e..9c7e5d3 100644 --- a/sdl_wrapper/src/sdl_wrapper.texture.cpp +++ b/sdl_wrapper/src/sdl_wrapper.texture.cpp @@ -7,6 +7,7 @@ module; #include "SDL3/SDL_gpu.h" #include "SDL3/SDL_log.h" module sdl_wrapper; +import sdl_raii; import :texture; import :transfer_buffer; import :gpu; @@ -45,17 +46,20 @@ namespace sopho { return std::unexpected{submit_result.error()}; } - SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(gpu.device()); - if (!cmd) + GpuCommandBufferRaii command_buffer_raii; { - SDL_Log("SDL_AcquireGPUCommandBuffer failed: %s", SDL_GetError()); - return std::unexpected{GpuError::ACQUIRE_COMMAND_BUFFER_FAILED}; + SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(gpu.device()); + if (!cmd) + { + SDL_Log("SDL_AcquireGPUCommandBuffer failed: %s", SDL_GetError()); + return std::unexpected{GpuError::ACQUIRE_COMMAND_BUFFER_FAILED}; + } + command_buffer_raii.reset(cmd); } - SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(cmd); + SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(command_buffer_raii.raw()); if (!copy_pass) { - SDL_SubmitGPUCommandBuffer(cmd); SDL_Log("SDL_BeginGPUCopyPass failed: %s", SDL_GetError()); return std::unexpected{GpuError::BEGIN_COPY_PASS_FAILED}; } @@ -80,7 +84,6 @@ namespace sopho SDL_UploadToGPUTexture(copy_pass, &src, &dst, false); SDL_EndGPUCopyPass(copy_pass); - SDL_SubmitGPUCommandBuffer(cmd); SDL_GPUSamplerCreateInfo info{}; info.min_filter = SDL_GPU_FILTER_NEAREST; From c4d0291410454fc4977be90069406c660c14f0b7 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 00:26:30 +0800 Subject: [PATCH 36/66] fix: clean code --- .../modules/sdl_raii/sdl_raii.bound_raii.ixx | 2 +- sdl_wrapper/src/sdl_wrapper.texture.cpp | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_raii.ixx index 767bb5e..888997b 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_raii.ixx @@ -47,7 +47,7 @@ namespace sopho ~BoundRaii() noexcept { reset(); } - void reset(T* resource = nullptr, Device* device = nullptr) noexcept + void reset(Device* device = nullptr ,T* resource = nullptr) noexcept { if (m_raw && m_gpu_device) { diff --git a/sdl_wrapper/src/sdl_wrapper.texture.cpp b/sdl_wrapper/src/sdl_wrapper.texture.cpp index 9c7e5d3..578e635 100644 --- a/sdl_wrapper/src/sdl_wrapper.texture.cpp +++ b/sdl_wrapper/src/sdl_wrapper.texture.cpp @@ -26,13 +26,17 @@ namespace sopho .sample_count = SDL_GPU_SAMPLECOUNT_1, .props = 0}; - auto* texture = SDL_CreateGPUTexture(gpu.device(), &create_info); - if (!texture) + GpuTextureRaii texture_raii{}; { - SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create GPU texture: %s", SDL_GetError()); - return std::unexpected(GpuError::CREATE_TEXTURE_FAILED); + + auto* texture = SDL_CreateGPUTexture(gpu.device(), &create_info); + if (!texture) + { + SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create GPU texture: %s", SDL_GetError()); + return std::unexpected(GpuError::CREATE_TEXTURE_FAILED); + } + texture_raii.reset(gpu.device(), texture); } - GpuTextureRaii texture_raii{gpu.device(), texture}; auto c_tb = TransferBufferWrapper::Builder{} @@ -102,7 +106,6 @@ namespace sopho if (!sampler) { SDL_Log("SDL_CreateGPUSampler failed: %s", SDL_GetError()); - SDL_ReleaseGPUTexture(gpu.device(), texture); return std::unexpected{GpuError::CREATE_SAMPLER_FAILED}; } GPUSamplerRaii sampler_raii{gpu.device(), sampler}; From 6ac0afc80933a8f32ec046623f912e3b75642dfb Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 08:50:17 +0800 Subject: [PATCH 37/66] fix: Using command line raii --- sdl_wrapper/src/sdl_wrapper.buffer.cpp | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/sdl_wrapper/src/sdl_wrapper.buffer.cpp b/sdl_wrapper/src/sdl_wrapper.buffer.cpp index c44aff0..f9a12e4 100644 --- a/sdl_wrapper/src/sdl_wrapper.buffer.cpp +++ b/sdl_wrapper/src/sdl_wrapper.buffer.cpp @@ -42,24 +42,26 @@ namespace sopho SDL_GetError()); return std::unexpected(rst.error()); } - - // 3. Acquire a command buffer and enqueue the copy pass. - auto* command_buffer = SDL_AcquireGPUCommandBuffer(device); - if (!command_buffer) + GpuCommandBufferRaii command_buffer_raii; { - SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d failed to acquire GPU command buffer: %s", __FILE__, __LINE__, - SDL_GetError()); + // 3. Acquire a command buffer and enqueue the copy pass. + auto* command_buffer = SDL_AcquireGPUCommandBuffer(device); + if (!command_buffer) + { + SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d failed to acquire GPU command buffer: %s", __FILE__, __LINE__, + SDL_GetError()); - return std::unexpected(GpuError::ACQUIRE_COMMAND_BUFFER_FAILED); + return std::unexpected(GpuError::ACQUIRE_COMMAND_BUFFER_FAILED); + } + command_buffer_raii.reset(command_buffer); } - auto* copy_pass = SDL_BeginGPUCopyPass(command_buffer); + auto* copy_pass = SDL_BeginGPUCopyPass(command_buffer_raii.raw()); if (!copy_pass) { SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d failed to begin GPU copy pass: %s", __FILE__, __LINE__, SDL_GetError()); - SDL_SubmitGPUCommandBuffer(command_buffer); return std::unexpected(GpuError::BEGIN_COPY_PASS_FAILED); } @@ -75,11 +77,6 @@ namespace sopho SDL_UploadToGPUBuffer(copy_pass, &location, ®ion, false); SDL_EndGPUCopyPass(copy_pass); - if (!SDL_SubmitGPUCommandBuffer(command_buffer)) - { - SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s:%d %s", __FILE__, __LINE__, SDL_GetError()); - return std::unexpected(GpuError::SUBMIT_COMMAND_FAILED); - } return std::monostate{}; } From 84bd9abb41518ac881cfbea7d8511644d9675ac2 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 10:32:14 +0800 Subject: [PATCH 38/66] fix: remove class gpu device --- sdl_wrapper/CMakeLists.txt | 1 - .../modules/sdl_raii/sdl_raii.gpu_device.ixx | 47 ------------------- sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 2 +- .../modules/sdl_raii/sdl_raii.pure_traits.ixx | 7 ++- 4 files changed, 7 insertions(+), 50 deletions(-) delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 980d969..5c8178d 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -9,7 +9,6 @@ target_sources(sdl_wrapper FILE_SET cxx_modules TYPE CXX_MODULES FILES modules/lifecycle.ixx modules/sdl_raii/sdl_raii.ixx - modules/sdl_raii/sdl_raii.gpu_device.ixx modules/sdl_raii/sdl_raii.window.ixx modules/sdl_raii/sdl_raii.claim_window.ixx modules/sdl_raii/sdl_raii.bound_raii.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx deleted file mode 100644 index ac38ba8..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.gpu_device.ixx +++ /dev/null @@ -1,47 +0,0 @@ -// sdl_raii.gpu_device.ixx -// Created by wsqsy on 11/28/2025. -// -module; -#include -export module sdl_raii:gpu_device; -namespace sopho -{ - export struct GpuDeviceRaii - { - private: - SDL_GPUDevice* m_raw{}; - - public: - GpuDeviceRaii() noexcept = default; - explicit GpuDeviceRaii(SDL_GPUDevice* d) noexcept : m_raw(d) {} - - GpuDeviceRaii(GpuDeviceRaii&& other) noexcept : m_raw(other.m_raw) { other.m_raw = nullptr; } - GpuDeviceRaii& operator=(GpuDeviceRaii&& other) noexcept - { - if (this != &other) - { - reset(other.m_raw); - other.m_raw = nullptr; - } - return *this; - } - - GpuDeviceRaii(const GpuDeviceRaii&) = delete; - GpuDeviceRaii& operator=(const GpuDeviceRaii&) = delete; - - ~GpuDeviceRaii() noexcept { reset(); } - - void reset(SDL_GPUDevice* d = nullptr) noexcept - { - if (m_raw != d) - { - if (m_raw) - SDL_DestroyGPUDevice(m_raw); - m_raw = d; - } - } - [[nodiscard]] SDL_GPUDevice* raw() const noexcept { return m_raw; } - [[nodiscard]] bool valid() const noexcept { return m_raw != nullptr; } - [[nodiscard]] explicit operator bool() const noexcept { return m_raw != nullptr; } - }; -} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 601e50b..dc7f780 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -5,7 +5,6 @@ module; #include export module sdl_raii; -export import :gpu_device; export import :window; export import :claim_window; export import :bound_traits; @@ -22,4 +21,5 @@ export namespace sopho using GpuTextureRaii = BoundRaii; using GpuTransferBufferRaii = BoundRaii; using GpuCommandBufferRaii = PureRaii; + using GpuDeviceRaii = PureRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx index aeac2f6..ff0994c 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx @@ -16,4 +16,9 @@ namespace sopho { static void release(SDL_GPUCommandBuffer* raw) noexcept { SDL_SubmitGPUCommandBuffer(raw); } }; -} // namespace sopho \ No newline at end of file + template <> + struct PureTraits + { + static void release(SDL_GPUDevice* raw) noexcept { SDL_DestroyGPUDevice(raw); } + }; +} // namespace sopho From 39e467db0b202617a069aecd6fd95dfe6b6e3707 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 10:36:26 +0800 Subject: [PATCH 39/66] fix: remove file sdl_raii.window.ixx --- sdl_wrapper/CMakeLists.txt | 1 - sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 2 +- .../modules/sdl_raii/sdl_raii.pure_traits.ixx | 5 ++ .../modules/sdl_raii/sdl_raii.window.ixx | 50 ------------------- 4 files changed, 6 insertions(+), 52 deletions(-) delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.window.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 5c8178d..4b5fb4e 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -9,7 +9,6 @@ target_sources(sdl_wrapper FILE_SET cxx_modules TYPE CXX_MODULES FILES modules/lifecycle.ixx modules/sdl_raii/sdl_raii.ixx - modules/sdl_raii/sdl_raii.window.ixx modules/sdl_raii/sdl_raii.claim_window.ixx modules/sdl_raii/sdl_raii.bound_raii.ixx modules/sdl_raii/sdl_raii.bound_traits.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index dc7f780..860f93a 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -5,7 +5,6 @@ module; #include export module sdl_raii; -export import :window; export import :claim_window; export import :bound_traits; export import :bound_raii; @@ -22,4 +21,5 @@ export namespace sopho using GpuTransferBufferRaii = BoundRaii; using GpuCommandBufferRaii = PureRaii; using GpuDeviceRaii = PureRaii; + using WindowRaii = PureRaii; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx index ff0994c..cc20651 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.pure_traits.ixx @@ -21,4 +21,9 @@ namespace sopho { static void release(SDL_GPUDevice* raw) noexcept { SDL_DestroyGPUDevice(raw); } }; + template <> + struct PureTraits + { + static void release(SDL_Window* raw) noexcept { SDL_DestroyWindow(raw); } + }; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.window.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.window.ixx deleted file mode 100644 index 7f87541..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.window.ixx +++ /dev/null @@ -1,50 +0,0 @@ -// sdl_raii.window.ixx -// Created by wsqsy on 11/28/2025. -// -module; -#include -export module sdl_raii:window; -namespace sopho -{ - export struct WindowRaii - { - private: - SDL_Window* m_raw{}; - - public: - WindowRaii() = default; - - explicit WindowRaii(SDL_Window* w) noexcept : m_raw(w) {} - - WindowRaii(const WindowRaii&) = delete; - WindowRaii& operator=(const WindowRaii&) = delete; - - WindowRaii(WindowRaii&& other) noexcept : m_raw(other.m_raw) { other.m_raw = nullptr; } - - WindowRaii& operator=(WindowRaii&& other) noexcept - { - if (this != &other) - { - reset(other.m_raw); - other.m_raw = nullptr; - } - return *this; - } - - ~WindowRaii() noexcept { reset(); } - - void reset(SDL_Window* w = nullptr) noexcept - { - if (m_raw != w) - { - if (m_raw) - SDL_DestroyWindow(m_raw); - m_raw = w; - } - } - - [[nodiscard]] SDL_Window* raw() const noexcept { return m_raw; } - [[nodiscard]] bool valid() const noexcept { return m_raw != nullptr; } - [[nodiscard]] explicit operator bool() const noexcept { return m_raw != nullptr; } - }; -} // namespace sopho From 6a01627ee0f7af0b02f0013b38b2a9c6bbf8f89a Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 10:39:20 +0800 Subject: [PATCH 40/66] fix: remove file sdl_raii.claim_window.ixx --- sdl_wrapper/CMakeLists.txt | 1 - .../sdl_raii/sdl_raii.bound_traits.ixx | 7 +++ .../sdl_raii/sdl_raii.claim_window.ixx | 59 ------------------- sdl_wrapper/modules/sdl_raii/sdl_raii.ixx | 2 +- 4 files changed, 8 insertions(+), 61 deletions(-) delete mode 100644 sdl_wrapper/modules/sdl_raii/sdl_raii.claim_window.ixx diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 4b5fb4e..886c84f 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -9,7 +9,6 @@ target_sources(sdl_wrapper FILE_SET cxx_modules TYPE CXX_MODULES FILES modules/lifecycle.ixx modules/sdl_raii/sdl_raii.ixx - modules/sdl_raii/sdl_raii.claim_window.ixx modules/sdl_raii/sdl_raii.bound_raii.ixx modules/sdl_raii/sdl_raii.bound_traits.ixx modules/sdl_raii/sdl_raii.pure_raii.ixx diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_traits.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_traits.ixx index 2b01d2a..0ec7cd0 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_traits.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.bound_traits.ixx @@ -59,6 +59,13 @@ namespace sopho SDL_ReleaseGPUTransferBuffer(device, buffer); } }; + template <> + struct BoundTraits + { + using Device = SDL_GPUDevice; + + static void release(Device* device, SDL_Window* raw) noexcept { SDL_ReleaseWindowFromGPUDevice(device, raw); } + }; } // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.claim_window.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.claim_window.ixx deleted file mode 100644 index 712fc81..0000000 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.claim_window.ixx +++ /dev/null @@ -1,59 +0,0 @@ -// sdl_raii.claim_window.ixx -// Created by wsqsy on 11/28/2025. -// -module; -#include -export module sdl_raii:claim_window; -namespace sopho -{ - export struct ClaimWindowRaii - { - private: - SDL_GPUDevice* m_gpu_device{}; - SDL_Window* m_window{}; - - public: - ClaimWindowRaii() noexcept = default; - - ClaimWindowRaii(SDL_GPUDevice* d, SDL_Window* w) noexcept : m_gpu_device(d), m_window(w) {} - - ClaimWindowRaii(const ClaimWindowRaii&) = delete; - ClaimWindowRaii& operator=(const ClaimWindowRaii&) = delete; - - ClaimWindowRaii(ClaimWindowRaii&& other) noexcept : m_gpu_device(other.m_gpu_device), m_window(other.m_window) - { - other.m_gpu_device = nullptr; - other.m_window = nullptr; - } - - ClaimWindowRaii& operator=(ClaimWindowRaii&& other) noexcept - { - if (this != &other) - { - reset(); - m_gpu_device = other.m_gpu_device; - m_window = other.m_window; - other.m_gpu_device = nullptr; - other.m_window = nullptr; - } - return *this; - } - - ~ClaimWindowRaii() noexcept { reset(); } - - void reset(SDL_GPUDevice* d = nullptr, SDL_Window* w = nullptr) noexcept - { - if (m_gpu_device != d || m_window != w) - { - if (m_gpu_device && m_window) - SDL_ReleaseWindowFromGPUDevice(m_gpu_device, m_window); - - m_gpu_device = d; - m_window = w; - } - } - - [[nodiscard]] bool valid() const noexcept { return m_gpu_device != nullptr && m_window != nullptr; } - [[nodiscard]] explicit operator bool() const noexcept { return valid(); } - }; -} // namespace sopho diff --git a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx index 860f93a..4701971 100644 --- a/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx +++ b/sdl_wrapper/modules/sdl_raii/sdl_raii.ixx @@ -5,7 +5,6 @@ module; #include export module sdl_raii; -export import :claim_window; export import :bound_traits; export import :bound_raii; export import :pure_traits; @@ -19,6 +18,7 @@ export namespace sopho using GpuShaderRaii = BoundRaii; using GpuTextureRaii = BoundRaii; using GpuTransferBufferRaii = BoundRaii; + using ClaimWindowRaii = BoundRaii; using GpuCommandBufferRaii = PureRaii; using GpuDeviceRaii = PureRaii; using WindowRaii = PureRaii; From 0e64b735af63bf52cbe9745fc3fcaa2094fe1c2e Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 11:07:08 +0800 Subject: [PATCH 41/66] fix: Upload vertex data from main.cpp --- main.cpp | 11 ++++ .../modules/sdl_wrapper.render_data.ixx | 12 ++++ sdl_wrapper/src/sdl_wrapper.render_data.cpp | 60 ++----------------- 3 files changed, 27 insertions(+), 56 deletions(-) diff --git a/main.cpp b/main.cpp index d9b80c1..72f2a19 100644 --- a/main.cpp +++ b/main.cpp @@ -30,6 +30,11 @@ import glsl_reflector; import sdl_wrapper; import logos; +struct VertexType +{ + float x{}, y{}, z{}, u{}, v{}; +}; + /** * @brief Loads image data from the test texture file. * @@ -155,11 +160,17 @@ void main() return SDL_APP_FAILURE; } + std::vector vertices{ + {0.5, 0.5, 0.5, 0., 0.}, {-0.5, 0.5, 0.5, 1., 0.}, {0.5, -0.5, 0.5, 0., 1.}, {-0.5, -0.5, 0.5, 1., 1.}, + {0.5, 0.5, -0.5, 1., 1.}, {-0.5, 0.5, -0.5, 0., 1.}, {0.5, -0.5, -0.5, 1., 0.}, {-0.5, -0.5, -0.5, 0., 0.}, + }; + // 3. Create vertex buffer. auto render_data = sopho::RenderData::Builder{} .set_vertex_layout(pw_result.value().vertex_layout()) .set_vertex_count(8) .set_index_count(36) + .set_vertices(std::span(vertices)) .build(*m_gpu.get()); if (!render_data) { diff --git a/sdl_wrapper/modules/sdl_wrapper.render_data.ixx b/sdl_wrapper/modules/sdl_wrapper.render_data.ixx index f0997c8..20bea50 100644 --- a/sdl_wrapper/modules/sdl_wrapper.render_data.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.render_data.ixx @@ -7,6 +7,7 @@ module; #include #include #include +#include #include #include export module sdl_wrapper:render_data; @@ -22,6 +23,7 @@ namespace sopho VertexLayout layout{}; std::uint32_t vertex_count{}; std::uint32_t index_count{}; + std::vector vertex_data{}; Builder& set_vertex_layout(VertexLayout new_layout) { @@ -41,6 +43,16 @@ namespace sopho return *this; } + template + Builder& set_vertices(std::span vertices) + { + static_assert(std::is_trivially_copyable_v, "VertexType must be trivially copyable"); + vertex_data = + std::vector(reinterpret_cast(vertices.data()), + reinterpret_cast(vertices.data()) + vertices.size_bytes()); + return *this; + } + checkable> build(GpuWrapper& gpu); }; struct VertexView diff --git a/sdl_wrapper/src/sdl_wrapper.render_data.cpp b/sdl_wrapper/src/sdl_wrapper.render_data.cpp index 1ca6f31..47651f2 100644 --- a/sdl_wrapper/src/sdl_wrapper.render_data.cpp +++ b/sdl_wrapper/src/sdl_wrapper.render_data.cpp @@ -27,63 +27,11 @@ namespace sopho { return std::unexpected(index_buffer.error()); } - float* vertex_ptr = reinterpret_cast(vertex_buffer.value().cpu_buffer()); - vertex_ptr[0] = 0.5; - vertex_ptr[1] = 0.5; - vertex_ptr[2] = 0.5; - vertex_ptr[5] = -0.5; - vertex_ptr[6] = 0.5; - vertex_ptr[7] = 0.5; - vertex_ptr[10] = 0.5; - vertex_ptr[11] = -0.5; - vertex_ptr[12] = 0.5; - vertex_ptr[15] = -0.5; - vertex_ptr[16] = -0.5; - vertex_ptr[17] = 0.5; - vertex_ptr[20] = 0.5; - vertex_ptr[21] = 0.5; - vertex_ptr[22] = -0.5; - vertex_ptr[25] = -0.5; - vertex_ptr[26] = 0.5; - vertex_ptr[27] = -0.5; - vertex_ptr[30] = 0.5; - vertex_ptr[31] = -0.5; - vertex_ptr[32] = -0.5; - vertex_ptr[35] = -0.5; - vertex_ptr[36] = -0.5; - vertex_ptr[37] = -0.5; - // v0 uv - vertex_ptr[3] = 0.0f; - vertex_ptr[4] = 0.0f; - - // v1 uv - vertex_ptr[8] = 1.0f; - vertex_ptr[9] = 0.0f; - - // v2 uv - vertex_ptr[13] = 0.0f; - vertex_ptr[14] = 1.0f; - - // v3 uv - vertex_ptr[18] = 1.0f; - vertex_ptr[19] = 1.0f; - - // v4 uv - vertex_ptr[23] = 1.0f; - vertex_ptr[24] = 1.0f; - - // v5 uv - vertex_ptr[28] = 0.0f; - vertex_ptr[29] = 1.0f; - - // v6 uv - vertex_ptr[33] = 1.0f; - vertex_ptr[34] = 0.0f; - - // v7 uv - vertex_ptr[38] = 0.0f; - vertex_ptr[39] = 0.0f; + for (int i = 0;i(size,vertex_data.size());++i) + { + vertex_buffer->cpu_buffer()[i] = vertex_data[i]; + } int* index_ptr = reinterpret_cast(index_buffer.value().cpu_buffer()); index_ptr[0] = 0; From 5d3738a445b14df935b10aa86c8c0b0a07434992 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sat, 29 Nov 2025 12:16:13 +0800 Subject: [PATCH 42/66] fix: Upload index data from main.cpp --- main.cpp | 4 ++ .../modules/sdl_wrapper.render_data.ixx | 8 ++++ sdl_wrapper/src/sdl_wrapper.render_data.cpp | 43 +++---------------- 3 files changed, 17 insertions(+), 38 deletions(-) diff --git a/main.cpp b/main.cpp index 72f2a19..46e1a81 100644 --- a/main.cpp +++ b/main.cpp @@ -165,12 +165,16 @@ void main() {0.5, 0.5, -0.5, 1., 1.}, {-0.5, 0.5, -0.5, 0., 1.}, {0.5, -0.5, -0.5, 1., 0.}, {-0.5, -0.5, -0.5, 0., 0.}, }; + std::vector indices{0, 1, 2, 1, 2, 3, 0, 1, 4, 1, 4, 5, 0, 2, 4, 2, 4, 6, + 2, 3, 6, 3, 6, 7, 1, 3, 5, 3, 5, 7, 4, 5, 6, 5, 6, 7}; + // 3. Create vertex buffer. auto render_data = sopho::RenderData::Builder{} .set_vertex_layout(pw_result.value().vertex_layout()) .set_vertex_count(8) .set_index_count(36) .set_vertices(std::span(vertices)) + .set_indices(std::span(indices)) .build(*m_gpu.get()); if (!render_data) { diff --git a/sdl_wrapper/modules/sdl_wrapper.render_data.ixx b/sdl_wrapper/modules/sdl_wrapper.render_data.ixx index 20bea50..c8f6c23 100644 --- a/sdl_wrapper/modules/sdl_wrapper.render_data.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.render_data.ixx @@ -24,6 +24,7 @@ namespace sopho std::uint32_t vertex_count{}; std::uint32_t index_count{}; std::vector vertex_data{}; + std::vector index_data{}; Builder& set_vertex_layout(VertexLayout new_layout) { @@ -52,6 +53,13 @@ namespace sopho reinterpret_cast(vertices.data()) + vertices.size_bytes()); return *this; } + Builder& set_indices(std::span indices) + { + index_data = + std::vector(reinterpret_cast(indices.data()), + reinterpret_cast(indices.data()) + indices.size_bytes()); + return *this; + } checkable> build(GpuWrapper& gpu); }; diff --git a/sdl_wrapper/src/sdl_wrapper.render_data.cpp b/sdl_wrapper/src/sdl_wrapper.render_data.cpp index 47651f2..ec0136f 100644 --- a/sdl_wrapper/src/sdl_wrapper.render_data.cpp +++ b/sdl_wrapper/src/sdl_wrapper.render_data.cpp @@ -28,48 +28,15 @@ namespace sopho return std::unexpected(index_buffer.error()); } - for (int i = 0;i(size,vertex_data.size());++i) + for (int i = 0; i < std::min(size, vertex_data.size()); ++i) { vertex_buffer->cpu_buffer()[i] = vertex_data[i]; } - int* index_ptr = reinterpret_cast(index_buffer.value().cpu_buffer()); - index_ptr[0] = 0; - index_ptr[1] = 1; - index_ptr[2] = 2; - index_ptr[3] = 1; - index_ptr[4] = 2; - index_ptr[5] = 3; - index_ptr[6] = 0; - index_ptr[7] = 1; - index_ptr[8] = 4; - index_ptr[9] = 1; - index_ptr[10] = 4; - index_ptr[11] = 5; - index_ptr[12] = 0; - index_ptr[13] = 2; - index_ptr[14] = 4; - index_ptr[15] = 2; - index_ptr[16] = 4; - index_ptr[17] = 6; - index_ptr[18] = 2; - index_ptr[19] = 3; - index_ptr[20] = 6; - index_ptr[21] = 3; - index_ptr[22] = 6; - index_ptr[23] = 7; - index_ptr[24] = 1; - index_ptr[25] = 3; - index_ptr[26] = 5; - index_ptr[27] = 3; - index_ptr[28] = 5; - index_ptr[29] = 7; - index_ptr[30] = 4; - index_ptr[31] = 5; - index_ptr[32] = 6; - index_ptr[33] = 5; - index_ptr[34] = 6; - index_ptr[35] = 7; + for (int i = 0; i < std::min(index_count * sizeof(int), index_data.size()); ++i) + { + index_buffer->cpu_buffer()[i] = index_data[i]; + } return std::make_shared(std::move(vertex_buffer.value()), std::move(index_buffer.value()), layout, vertex_count, index_count); } From ac378d1657b238ebc4adc8e5e6a41bc225a73fc1 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Sun, 30 Nov 2025 22:47:30 +0800 Subject: [PATCH 43/66] feat: add assert to check --- sdl_wrapper/src/sdl_wrapper.render_data.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sdl_wrapper/src/sdl_wrapper.render_data.cpp b/sdl_wrapper/src/sdl_wrapper.render_data.cpp index ec0136f..240ee82 100644 --- a/sdl_wrapper/src/sdl_wrapper.render_data.cpp +++ b/sdl_wrapper/src/sdl_wrapper.render_data.cpp @@ -2,6 +2,7 @@ // Created by sophomore on 11/26/25. // module; +#include #include #include #include "SDL3/SDL_gpu.h" @@ -27,13 +28,14 @@ namespace sopho { return std::unexpected(index_buffer.error()); } - - for (int i = 0; i < std::min(size, vertex_data.size()); ++i) + assert(vertex_data.size() <= size); + for (int i = 0; i < vertex_data.size(); ++i) { vertex_buffer->cpu_buffer()[i] = vertex_data[i]; } - for (int i = 0; i < std::min(index_count * sizeof(int), index_data.size()); ++i) + assert(index_data.size() <= index_count * sizeof(int)); + for (int i = 0; i < index_data.size(); ++i) { index_buffer->cpu_buffer()[i] = index_data[i]; } From 81be1207dee8c2856472bc7a077ab1cfc3efb6ee Mon Sep 17 00:00:00 2001 From: Sophomore Date: Mon, 1 Dec 2025 16:30:26 +0800 Subject: [PATCH 44/66] feat:add header file --- main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/main.cpp b/main.cpp index 46e1a81..31b49a0 100644 --- a/main.cpp +++ b/main.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "imgui.h" #include "imgui_impl_sdl3.h" From 224587517a7a41008b9dde29915bd2482cee9355 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Mon, 1 Dec 2025 17:03:32 +0800 Subject: [PATCH 45/66] feat:add function Renderable::draw --- main.cpp | 35 ++++--------------- sdl_wrapper/CMakeLists.txt | 3 +- sdl_wrapper/modules/sdl_wrapper.decl.ixx | 1 + .../modules/sdl_wrapper.renderable.ixx | 25 ++++++++----- sdl_wrapper/src/sdl_wrapper.renderable.cpp | 32 +++++++++++++++++ 5 files changed, 58 insertions(+), 38 deletions(-) create mode 100644 sdl_wrapper/src/sdl_wrapper.renderable.cpp diff --git a/main.cpp b/main.cpp index 31b49a0..34fd11b 100644 --- a/main.cpp +++ b/main.cpp @@ -8,9 +8,9 @@ #include #include #include +#include #include #include -#include #include "imgui.h" #include "imgui_impl_sdl3.h" @@ -526,33 +526,12 @@ void main() SDL_GPURenderPass* renderPass = SDL_BeginGPURenderPass(command_buffer_raii.raw(), &colorTargetInfo, 1, &depthStencilTargetInfo); - // Bind pipeline if available. - - SDL_BindGPUGraphicsPipeline(renderPass, m_renderable->procedural()->raw()); - - // Compute camera matrix and upload as a vertex uniform. - SDL_PushGPUVertexUniformData(command_buffer_raii.raw(), 0, - (sopho::perspective(1, static_cast(width) / height, 0.1, 10) * - sopho::translate(0, 0, -5) * sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)) - .data(), - sizeof(sopho::Mat)); - - SDL_BindGPUVertexBuffers(renderPass, 0, m_renderable->data()->get_vertex_buffer_binding().data(), - m_renderable->data()->get_vertex_buffer_binding().size()); - - SDL_BindGPUIndexBuffer(renderPass, &m_renderable->data()->get_index_buffer_binding(), - SDL_GPU_INDEXELEMENTSIZE_32BIT); - if (m_texture_wrapper) - { - SDL_BindGPUFragmentSamplers(renderPass, 0, m_texture_wrapper->get(), 1); - } - else - { - SDL_LogError(SDL_LOG_CATEGORY_GPU, "Texture not available, skip binding sampler"); - } - - - SDL_DrawGPUIndexedPrimitives(renderPass, 36, 1, 0, 0, 0); + m_renderable->draw( + sopho::RenderContex{.render_pass = renderPass, + .command_buffer = command_buffer_raii.raw(), + .camera_mat = sopho::perspective(1, static_cast(width) / height, 0.1, 10) * + sopho::translate(0, 0, -5) * sopho::rotation_x(-pitch) * sopho::rotation_y(yaw), + .texture_wrapper = m_texture_wrapper}); SDL_EndGPURenderPass(renderPass); diff --git a/sdl_wrapper/CMakeLists.txt b/sdl_wrapper/CMakeLists.txt index 886c84f..ac643a5 100644 --- a/sdl_wrapper/CMakeLists.txt +++ b/sdl_wrapper/CMakeLists.txt @@ -32,6 +32,7 @@ target_sources(sdl_wrapper src/sdl_wrapper.texture.cpp src/sdl_wrapper.transfer_buffer.cpp src/sdl_wrapper.render_data.cpp + src/sdl_wrapper.renderable.cpp ) -target_link_libraries(sdl_wrapper PUBLIC SDL3::SDL3 shaderc glsl_reflector data_type) +target_link_libraries(sdl_wrapper PUBLIC SDL3::SDL3 shaderc glsl_reflector data_type logos) diff --git a/sdl_wrapper/modules/sdl_wrapper.decl.ixx b/sdl_wrapper/modules/sdl_wrapper.decl.ixx index 3122832..e0875fa 100644 --- a/sdl_wrapper/modules/sdl_wrapper.decl.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.decl.ixx @@ -9,4 +9,5 @@ export namespace sopho class GpuWrapper; class RenderProcedural; class RenderData; + class TextureWrapper; } diff --git a/sdl_wrapper/modules/sdl_wrapper.renderable.ixx b/sdl_wrapper/modules/sdl_wrapper.renderable.ixx index 5e253d9..cdf9dcf 100644 --- a/sdl_wrapper/modules/sdl_wrapper.renderable.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.renderable.ixx @@ -2,23 +2,30 @@ // Created by wsqsy on 11/19/2025. // module; +#include #include export module sdl_wrapper:renderable; +import logos; +import data_type; import :decl; namespace sopho { + + export struct RenderContex + { + SDL_GPURenderPass* render_pass{}; + SDL_GPUCommandBuffer* command_buffer{}; + Mat camera_mat{}; + std::shared_ptr texture_wrapper{}; + }; + export class Renderable { public: std::shared_ptr m_render_procedural{}; std::shared_ptr m_render_data{}; - auto & procedural() - { - return m_render_procedural; - } - std::shared_ptr & data() - { - return m_render_data; - } + auto& procedural() { return m_render_procedural; } + std::shared_ptr& data() { return m_render_data; } + checkable draw(RenderContex render_contex); }; -} +} // namespace sopho diff --git a/sdl_wrapper/src/sdl_wrapper.renderable.cpp b/sdl_wrapper/src/sdl_wrapper.renderable.cpp new file mode 100644 index 0000000..7862530 --- /dev/null +++ b/sdl_wrapper/src/sdl_wrapper.renderable.cpp @@ -0,0 +1,32 @@ +// sdl_wrapper.renderable.cpp +// Created by wsqsy on 12/1/2025. +// +module; +#include +module sdl_wrapper; +import logos; +import :renderable; +import :render_procedural; +import :render_data; +namespace sopho +{ + checkable Renderable::draw(RenderContex render_contex) + { + auto submit_result = procedural()->submit(); + if (!submit_result) + { + return std::unexpected(submit_result.error()); + } + SDL_BindGPUGraphicsPipeline(render_contex.render_pass, procedural()->raw()); + SDL_PushGPUVertexUniformData(render_contex.command_buffer, 0, render_contex.camera_mat.data(), + sizeof(Mat)); + SDL_BindGPUVertexBuffers(render_contex.render_pass, 0, data()->get_vertex_buffer_binding().data(), + data()->get_vertex_buffer_binding().size()); + + SDL_BindGPUIndexBuffer(render_contex.render_pass, &data()->get_index_buffer_binding(), + SDL_GPU_INDEXELEMENTSIZE_32BIT); + SDL_BindGPUFragmentSamplers(render_contex.render_pass, 0, render_contex.texture_wrapper->get(), 1); + SDL_DrawGPUIndexedPrimitives(render_contex.render_pass, data()->index_view().index_count, 1, 0, 0, 0); + return std::monostate{}; + } +} // namespace sopho From 8d20d3fbae46b038140b94d509bb912bf5664b64 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Mon, 1 Dec 2025 17:13:18 +0800 Subject: [PATCH 46/66] feat:change type of m_renderables temporal remove imgui logic --- main.cpp | 273 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 138 insertions(+), 135 deletions(-) diff --git a/main.cpp b/main.cpp index 34fd11b..412450c 100644 --- a/main.cpp +++ b/main.cpp @@ -72,7 +72,7 @@ class UserApp : public sopho::App // GPU + resources std::shared_ptr m_gpu{}; - std::shared_ptr m_renderable{}; + std::vector> m_renderables{}; sopho::ImageData m_image_data; std::shared_ptr m_texture_wrapper{}; @@ -194,9 +194,9 @@ void main() return SDL_APP_FAILURE; } - m_renderable = std::make_shared(sopho::Renderable{ + m_renderables.emplace_back(std::make_shared(sopho::Renderable{ .m_render_procedural = std::make_shared(std::move(pw_result.value())), - .m_render_data = std::move(render_data.value())}); + .m_render_data = std::move(render_data.value())})); // 7. Setup Dear ImGui context. IMGUI_CHECKVERSION(); @@ -299,122 +299,131 @@ void main() std::array items = {"Node", "Vertex", "Fragment"}; ImGui::Combo("##Object", ¤t, items.data(), static_cast(items.size())); - switch (current) - { - case 0: // Vertex Edit - { - bool changed = false; - auto editor_data = m_renderable->data()->vertex_view(); - auto raw_ptr = editor_data.raw; - for (int vertex_index = 0; vertex_index < editor_data.vertex_count; ++vertex_index) - { - for (const auto& format : editor_data.layout.get_vertex_reflection().inputs) - { - switch (format.basic_type) - { - case sopho::BasicType::FLOAT: - { - switch (format.vector_size) - { - case 2: - changed |= ImGui::DragFloat2(std::format("{}{}", format.name, vertex_index).data(), - reinterpret_cast(raw_ptr), 0.01f, -1.f, 1.f); - break; - case 3: - changed |= ImGui::DragFloat3(std::format("{}{}", format.name, vertex_index).data(), - reinterpret_cast(raw_ptr), 0.01f, -1.f, 1.f); - break; - case 4: - changed |= ImGui::DragFloat4(std::format("{}{}", format.name, vertex_index).data(), - reinterpret_cast(raw_ptr), 0.01f, -1.f, 1.f); - break; - default: - SDL_Log("Not implemented size"); - assert(false); - break; - } - } - break; - default: - SDL_Log("Not implemented Basic type"); - assert(false); - break; - } - auto size = sopho::get_size(sopho::to_sdl_format(format.basic_type, format.vector_size)); - raw_ptr += size; - } - } - auto index_view = m_renderable->data()->index_view(); - auto index_ptr = index_view.raw; - for (int index_index = 0; index_index < index_view.index_count; index_index += 3) - { - changed |= ImGui::InputInt3(std::format("index_{}", index_index).data(), - reinterpret_cast(index_ptr)); - index_ptr += 3 * sizeof(int); - } - if (changed) - { - auto upload_result = m_renderable->data()->upload(); - if (!upload_result) - { - SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to upload vertex buffer in tick(), error = %d", - static_cast(upload_result.error())); - } - } - } - break; - - case 1: // Vertex shader editor - { - auto line_count = std::count(vertex_source.begin(), vertex_source.end(), '\n'); - ImVec2 size(ImGui::GetContentRegionAvail().x, - std::min(ImGui::GetTextLineHeight() * (line_count + 3), ImGui::GetContentRegionAvail().y)); - - if (ImGui::InputTextMultiline("##vertex editor", &vertex_source, size, - ImGuiInputTextFlags_AllowTabInput)) - { - auto result = m_renderable->procedural()->set_vertex_shader(vertex_source); - if (!result) - { - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to set vertex shader from editor, error = %d", - static_cast(result.error())); - } - else - { - auto new_data = sopho::RenderData::Builder{} - .set_vertex_layout(m_renderable->procedural()->vertex_layout()) - .set_vertex_count(8) - .set_index_count(36) - .build(*m_gpu.get()); - m_renderable->data() = std::move(new_data.value()); - m_renderable->data()->upload(); - } - } - } - break; - - case 2: // Fragment shader editor - { - auto line_count = std::count(fragment_source.begin(), fragment_source.end(), '\n'); - ImVec2 size(ImGui::GetContentRegionAvail().x, - std::min(ImGui::GetTextLineHeight() * (line_count + 3), ImGui::GetContentRegionAvail().y)); - - if (ImGui::InputTextMultiline("##fragment editor", &fragment_source, size, - ImGuiInputTextFlags_AllowTabInput)) - { - auto result = m_renderable->procedural()->set_fragment_shader(fragment_source); - if (!result) - { - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to set fragment shader from editor, error = %d", - static_cast(result.error())); - } - } - } - break; - - default: - break; - } + // switch (current) + // { + // case 0: // Vertex Edit + // { + // bool changed = false; + // auto editor_data = m_renderable->data()->vertex_view(); + // auto raw_ptr = editor_data.raw; + // for (int vertex_index = 0; vertex_index < editor_data.vertex_count; ++vertex_index) + // { + // for (const auto& format : editor_data.layout.get_vertex_reflection().inputs) + // { + // switch (format.basic_type) + // { + // case sopho::BasicType::FLOAT: + // { + // switch (format.vector_size) + // { + // case 2: + // changed |= ImGui::DragFloat2(std::format("{}{}", format.name, + // vertex_index).data(), + // reinterpret_cast(raw_ptr), 0.01f, + // -1.f, 1.f); + // break; + // case 3: + // changed |= ImGui::DragFloat3(std::format("{}{}", format.name, + // vertex_index).data(), + // reinterpret_cast(raw_ptr), 0.01f, + // -1.f, 1.f); + // break; + // case 4: + // changed |= ImGui::DragFloat4(std::format("{}{}", format.name, + // vertex_index).data(), + // reinterpret_cast(raw_ptr), 0.01f, + // -1.f, 1.f); + // break; + // default: + // SDL_Log("Not implemented size"); + // assert(false); + // break; + // } + // } + // break; + // default: + // SDL_Log("Not implemented Basic type"); + // assert(false); + // break; + // } + // auto size = sopho::get_size(sopho::to_sdl_format(format.basic_type, format.vector_size)); + // raw_ptr += size; + // } + // } + // auto index_view = m_renderable->data()->index_view(); + // auto index_ptr = index_view.raw; + // for (int index_index = 0; index_index < index_view.index_count; index_index += 3) + // { + // changed |= ImGui::InputInt3(std::format("index_{}", index_index).data(), + // reinterpret_cast(index_ptr)); + // index_ptr += 3 * sizeof(int); + // } + // if (changed) + // { + // auto upload_result = m_renderable->data()->upload(); + // if (!upload_result) + // { + // SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to upload vertex buffer in tick(), error = %d", + // static_cast(upload_result.error())); + // } + // } + // } + // break; + // + // case 1: // Vertex shader editor + // { + // auto line_count = std::count(vertex_source.begin(), vertex_source.end(), '\n'); + // ImVec2 size(ImGui::GetContentRegionAvail().x, + // std::min(ImGui::GetTextLineHeight() * (line_count + 3), + // ImGui::GetContentRegionAvail().y)); + // + // if (ImGui::InputTextMultiline("##vertex editor", &vertex_source, size, + // ImGuiInputTextFlags_AllowTabInput)) + // { + // auto result = m_renderable->procedural()->set_vertex_shader(vertex_source); + // if (!result) + // { + // SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to set vertex shader from editor, error = %d", + // static_cast(result.error())); + // } + // else + // { + // auto new_data = sopho::RenderData::Builder{} + // .set_vertex_layout(m_renderable->procedural()->vertex_layout()) + // .set_vertex_count(8) + // .set_index_count(36) + // .build(*m_gpu.get()); + // m_renderable->data() = std::move(new_data.value()); + // m_renderable->data()->upload(); + // } + // } + // } + // break; + // + // case 2: // Fragment shader editor + // { + // auto line_count = std::count(fragment_source.begin(), fragment_source.end(), '\n'); + // ImVec2 size(ImGui::GetContentRegionAvail().x, + // std::min(ImGui::GetTextLineHeight() * (line_count + 3), + // ImGui::GetContentRegionAvail().y)); + // + // if (ImGui::InputTextMultiline("##fragment editor", &fragment_source, size, + // ImGuiInputTextFlags_AllowTabInput)) + // { + // auto result = m_renderable->procedural()->set_fragment_shader(fragment_source); + // if (!result) + // { + // SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to set fragment shader from editor, error = + // %d", + // static_cast(result.error())); + // } + // } + // } + // break; + // + // default: + // break; + // } ImGui::End(); ImGui::EndFrame(); @@ -435,16 +444,6 @@ void main() ImGui::Render(); ImDrawData* draw_data = ImGui::GetDrawData(); - // Rebuild pipeline if needed. - auto pipeline_submit = m_renderable->procedural()->submit(); - if (!pipeline_submit) - { - SDL_LogError(SDL_LOG_CATEGORY_GPU, "Pipeline submit failed, error = %d", - static_cast(pipeline_submit.error())); - // Upload pipeline failed, no need to draw. - return SDL_APP_CONTINUE; - } - SDL_GPUDevice* device = m_gpu->device(); if (!device) { @@ -526,12 +525,16 @@ void main() SDL_GPURenderPass* renderPass = SDL_BeginGPURenderPass(command_buffer_raii.raw(), &colorTargetInfo, 1, &depthStencilTargetInfo); - m_renderable->draw( - sopho::RenderContex{.render_pass = renderPass, - .command_buffer = command_buffer_raii.raw(), - .camera_mat = sopho::perspective(1, static_cast(width) / height, 0.1, 10) * - sopho::translate(0, 0, -5) * sopho::rotation_x(-pitch) * sopho::rotation_y(yaw), - .texture_wrapper = m_texture_wrapper}); + auto camera_mat = sopho::perspective(1, static_cast(width) / height, 0.1, 10) * + sopho::translate(0, 0, -5) * sopho::rotation_x(-pitch) * sopho::rotation_y(yaw); + + for (auto renderable : m_renderables) + { + renderable->draw(sopho::RenderContex{.render_pass = renderPass, + .command_buffer = command_buffer_raii.raw(), + .camera_mat = camera_mat, + .texture_wrapper = m_texture_wrapper}); + } SDL_EndGPURenderPass(renderPass); From 88c7a46015eb15dd7ce5e7a6577a6e0d03021b8c Mon Sep 17 00:00:00 2001 From: Sophomore Date: Mon, 1 Dec 2025 17:28:19 +0800 Subject: [PATCH 47/66] feat:Draw multi box --- main.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 412450c..cb917dd 100644 --- a/main.cpp +++ b/main.cpp @@ -197,6 +197,9 @@ void main() m_renderables.emplace_back(std::make_shared(sopho::Renderable{ .m_render_procedural = std::make_shared(std::move(pw_result.value())), .m_render_data = std::move(render_data.value())})); + m_renderables.emplace_back(std::make_shared(sopho::Renderable{ + .m_render_procedural = m_renderables[0]->procedural(), + .m_render_data = m_renderables[0]->data()})); // 7. Setup Dear ImGui context. IMGUI_CHECKVERSION(); @@ -525,11 +528,12 @@ void main() SDL_GPURenderPass* renderPass = SDL_BeginGPURenderPass(command_buffer_raii.raw(), &colorTargetInfo, 1, &depthStencilTargetInfo); - auto camera_mat = sopho::perspective(1, static_cast(width) / height, 0.1, 10) * - sopho::translate(0, 0, -5) * sopho::rotation_x(-pitch) * sopho::rotation_y(yaw); - for (auto renderable : m_renderables) + for (int i = 0; i < m_renderables.size(); i++) { + auto renderable = m_renderables[i]; + auto camera_mat = sopho::perspective(1, static_cast(width) / height, 0.1, 10) * + sopho::translate(0, 0.5 * i, -i - 5) * sopho::rotation_x(-pitch) * sopho::rotation_y(yaw); renderable->draw(sopho::RenderContex{.render_pass = renderPass, .command_buffer = command_buffer_raii.raw(), .camera_mat = camera_mat, From e3a51b7d8c5467e52953dd8381d64117a0a4ac8e Mon Sep 17 00:00:00 2001 From: Sophomore Date: Mon, 1 Dec 2025 17:35:29 +0800 Subject: [PATCH 48/66] feat:add location movement of camera --- main.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index cb917dd..0f54465 100644 --- a/main.cpp +++ b/main.cpp @@ -82,6 +82,8 @@ class UserApp : public sopho::App float yaw = 0.0f; float pitch = 0.0f; + sopho::Mat location{}; + int win_w = 0, win_h = 0; std::string vertex_source = @@ -198,8 +200,7 @@ void main() .m_render_procedural = std::make_shared(std::move(pw_result.value())), .m_render_data = std::move(render_data.value())})); m_renderables.emplace_back(std::make_shared(sopho::Renderable{ - .m_render_procedural = m_renderables[0]->procedural(), - .m_render_data = m_renderables[0]->data()})); + .m_render_procedural = m_renderables[0]->procedural(), .m_render_data = m_renderables[0]->data()})); // 7. Setup Dear ImGui context. IMGUI_CHECKVERSION(); @@ -533,7 +534,8 @@ void main() { auto renderable = m_renderables[i]; auto camera_mat = sopho::perspective(1, static_cast(width) / height, 0.1, 10) * - sopho::translate(0, 0.5 * i, -i - 5) * sopho::rotation_x(-pitch) * sopho::rotation_y(yaw); + sopho::rotation_x(-pitch) * sopho::rotation_y(yaw) * + sopho::translate(0 - location(0), 0.5 * i - location(1), -i - 5 - location(2)); renderable->draw(sopho::RenderContex{.render_pass = renderPass, .command_buffer = command_buffer_raii.raw(), .camera_mat = camera_mat, @@ -588,6 +590,18 @@ void main() case SDLK_RIGHT: yaw += 0.1F; break; + case SDLK_W: + location(2) -= 0.1; + break; + case SDLK_S: + location(2) += 0.1; + break; + case SDLK_A: + location(0) -= 0.1; + break; + case SDLK_D: + location(0) += 0.1; + break; default: break; } From 906355d2598ec900426ac0f2852b3305a7af83ad Mon Sep 17 00:00:00 2001 From: Sophomore Date: Mon, 1 Dec 2025 17:44:56 +0800 Subject: [PATCH 49/66] feat:move direction decide by camera direction --- main.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/main.cpp b/main.cpp index 0f54465..5b65a3b 100644 --- a/main.cpp +++ b/main.cpp @@ -591,16 +591,32 @@ void main() yaw += 0.1F; break; case SDLK_W: - location(2) -= 0.1; + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{0.f, 0.f, -1.f, 1.f}) + .resize<1, 3>() * + 0.1; break; case SDLK_S: - location(2) += 0.1; + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{0.f, 0.f, -1.f, 1.f}) + .resize<1, 3>() * + -0.1; break; case SDLK_A: - location(0) -= 0.1; + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{1.f, 0.f, 0.f, 1.f}) + .resize<1, 3>() * + -0.1; break; case SDLK_D: - location(0) += 0.1; + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{1.f, 0.f, 0.f, 1.f}) + .resize<1, 3>() * + 0.1; break; default: break; From 81cc4e3c85346871206dc50a9211bb7066eb2c41 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Mon, 1 Dec 2025 17:46:08 +0800 Subject: [PATCH 50/66] fix: add missing Header --- sdl_wrapper/modules/sdl_wrapper.renderable.ixx | 1 + 1 file changed, 1 insertion(+) diff --git a/sdl_wrapper/modules/sdl_wrapper.renderable.ixx b/sdl_wrapper/modules/sdl_wrapper.renderable.ixx index cdf9dcf..62c7379 100644 --- a/sdl_wrapper/modules/sdl_wrapper.renderable.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.renderable.ixx @@ -4,6 +4,7 @@ module; #include #include +#include export module sdl_wrapper:renderable; import logos; import data_type; From 88e71267d20a4039b0329eef9f6ee660e18eca38 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Mon, 1 Dec 2025 17:57:40 +0800 Subject: [PATCH 51/66] fix: add missing Header --- sdl_wrapper/src/sdl_wrapper.renderable.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sdl_wrapper/src/sdl_wrapper.renderable.cpp b/sdl_wrapper/src/sdl_wrapper.renderable.cpp index 7862530..a05da46 100644 --- a/sdl_wrapper/src/sdl_wrapper.renderable.cpp +++ b/sdl_wrapper/src/sdl_wrapper.renderable.cpp @@ -3,6 +3,7 @@ // module; #include +#include module sdl_wrapper; import logos; import :renderable; From 60580a90ac9a2d03d835f759b2fc5b9e8f13d731 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:11:51 +0800 Subject: [PATCH 52/66] fix: add missing header --- sdl_wrapper/src/sdl_wrapper.renderable.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sdl_wrapper/src/sdl_wrapper.renderable.cpp b/sdl_wrapper/src/sdl_wrapper.renderable.cpp index a05da46..a527648 100644 --- a/sdl_wrapper/src/sdl_wrapper.renderable.cpp +++ b/sdl_wrapper/src/sdl_wrapper.renderable.cpp @@ -3,6 +3,7 @@ // module; #include +#include #include module sdl_wrapper; import logos; From 5c6c7e8e6f26e9d43ff27f30f4859ec650d82832 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:30:42 +0800 Subject: [PATCH 53/66] feat: add function update add log for fps --- main.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 5b65a3b..3cf8ac7 100644 --- a/main.cpp +++ b/main.cpp @@ -22,6 +22,9 @@ #include "SDL3/SDL_keycode.h" #define STB_IMAGE_IMPLEMENTATION +#include + + #include "stb_image.h" import lifecycle; @@ -69,6 +72,9 @@ sopho::ImageData load_image() class UserApp : public sopho::App { + std::chrono::steady_clock::time_point m_last_time{std::chrono::steady_clock::now()}; + double m_fps_accumulator = 0.0; + int m_fps_frames = 0; // GPU + resources std::shared_ptr m_gpu{}; @@ -276,6 +282,19 @@ void main() return SDL_APP_CONTINUE; } + SDL_AppResult update(float dt) + { + m_fps_frames++; + m_fps_accumulator += dt; + if (m_fps_accumulator >= 1) + { + SDL_Log("Fps: %f",m_fps_frames / m_fps_accumulator); + m_fps_frames = 0; + m_fps_accumulator = 0.0; + } + return SDL_APP_CONTINUE; + } + /** * @brief Advance the UI frame and present editors for vertex data and shader sources. * @@ -556,7 +575,14 @@ void main() SDL_AppResult iterate() override { - auto result = tick(); + auto now{std::chrono::steady_clock::now()}; + std::chrono::duration delta = now - m_last_time; + m_last_time = now; + auto result = update(delta.count()); + if (result == SDL_APP_CONTINUE) + { + result = tick(); + } if (result == SDL_APP_CONTINUE) { result = draw(); From 270c739d60b17ca84cbda8617b09337204b021c9 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:32:12 +0800 Subject: [PATCH 54/66] log: add for duration time --- main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index 3cf8ac7..509924c 100644 --- a/main.cpp +++ b/main.cpp @@ -74,7 +74,7 @@ class UserApp : public sopho::App { std::chrono::steady_clock::time_point m_last_time{std::chrono::steady_clock::now()}; double m_fps_accumulator = 0.0; - int m_fps_frames = 0; + int m_fps_frames = 0; // GPU + resources std::shared_ptr m_gpu{}; @@ -288,7 +288,7 @@ void main() m_fps_accumulator += dt; if (m_fps_accumulator >= 1) { - SDL_Log("Fps: %f",m_fps_frames / m_fps_accumulator); + SDL_Log("Fps: %f in %f s", m_fps_frames / m_fps_accumulator, m_fps_accumulator); m_fps_frames = 0; m_fps_accumulator = 0.0; } From 3e88255ff5620389e8a3486ab6a5815c763feb32 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:51:07 +0800 Subject: [PATCH 55/66] feat: make rotation smooth --- main.cpp | 148 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 46 deletions(-) diff --git a/main.cpp b/main.cpp index 509924c..a15f68f 100644 --- a/main.cpp +++ b/main.cpp @@ -86,7 +86,9 @@ class UserApp : public sopho::App // camera state float yaw = 0.0f; + float yaw_speed = 0.0f; float pitch = 0.0f; + float pitch_speed = 0.0f; sopho::Mat location{}; @@ -292,6 +294,9 @@ void main() m_fps_frames = 0; m_fps_accumulator = 0.0; } + pitch += pitch_speed * dt; + pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); + yaw += yaw_speed * dt; return SDL_APP_CONTINUE; } @@ -598,55 +603,106 @@ void main() if (!io.WantCaptureKeyboard) { - if (event->type == SDL_EVENT_KEY_DOWN) + switch (event->type) { - switch (event->key.key) + case SDL_EVENT_KEY_DOWN: { - case SDLK_UP: - pitch += 0.1F; - pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); - break; - case SDLK_DOWN: - pitch -= 0.1F; - pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); - break; - case SDLK_LEFT: - yaw -= 0.1F; - break; - case SDLK_RIGHT: - yaw += 0.1F; - break; - case SDLK_W: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{0.f, 0.f, -1.f, 1.f}) - .resize<1, 3>() * - 0.1; - break; - case SDLK_S: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{0.f, 0.f, -1.f, 1.f}) - .resize<1, 3>() * - -0.1; - break; - case SDLK_A: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{1.f, 0.f, 0.f, 1.f}) - .resize<1, 3>() * - -0.1; - break; - case SDLK_D: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{1.f, 0.f, 0.f, 1.f}) - .resize<1, 3>() * - 0.1; - break; - default: - break; + switch (event->key.key) + { + case SDLK_UP: + pitch_speed = 0.5F; + break; + case SDLK_DOWN: + pitch_speed = -0.5F; + break; + case SDLK_LEFT: + yaw_speed = -0.5F; + break; + case SDLK_RIGHT: + yaw_speed = 0.5F; + break; + case SDLK_W: + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{0.f, 0.f, -1.f, 1.f}) + .resize<1, 3>() * + 0.1; + break; + case SDLK_S: + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{0.f, 0.f, -1.f, 1.f}) + .resize<1, 3>() * + -0.1; + break; + case SDLK_A: + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{1.f, 0.f, 0.f, 1.f}) + .resize<1, 3>() * + -0.1; + break; + case SDLK_D: + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{1.f, 0.f, 0.f, 1.f}) + .resize<1, 3>() * + 0.1; + break; + default: + break; + } } + break; + case SDL_EVENT_KEY_UP: + { + switch (event->key.key) + { + case SDLK_UP: + pitch_speed = 0.F; + break; + case SDLK_DOWN: + pitch_speed = 0.F; + break; + case SDLK_LEFT: + yaw_speed = 0.F; + break; + case SDLK_RIGHT: + yaw_speed = 0.F; + break; + case SDLK_W: + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{0.f, 0.f, -1.f, 1.f}) + .resize<1, 3>() * + 0.1; + break; + case SDLK_S: + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{0.f, 0.f, -1.f, 1.f}) + .resize<1, 3>() * + -0.1; + break; + case SDLK_A: + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{1.f, 0.f, 0.f, 1.f}) + .resize<1, 3>() * + -0.1; + break; + case SDLK_D: + location = location + + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * + sopho::Mat{1.f, 0.f, 0.f, 1.f}) + .resize<1, 3>() * + 0.1; + break; + default: + break; + } + } + break; } } From c52c53ba09789451cbc3613c1c665c0ae2c454cf Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:58:08 +0800 Subject: [PATCH 56/66] feat: make movement smooth --- main.cpp | 51 +++++++++++---------------------------------------- 1 file changed, 11 insertions(+), 40 deletions(-) diff --git a/main.cpp b/main.cpp index a15f68f..e424857 100644 --- a/main.cpp +++ b/main.cpp @@ -91,6 +91,7 @@ class UserApp : public sopho::App float pitch_speed = 0.0f; sopho::Mat location{}; + sopho::Mat speed{}; int win_w = 0, win_h = 0; @@ -297,6 +298,8 @@ void main() pitch += pitch_speed * dt; pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); yaw += yaw_speed * dt; + location = + location + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * speed).resize<1, 3>() * 0.1; return SDL_APP_CONTINUE; } @@ -622,32 +625,16 @@ void main() yaw_speed = 0.5F; break; case SDLK_W: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{0.f, 0.f, -1.f, 1.f}) - .resize<1, 3>() * - 0.1; + speed(2) = -1.F; break; case SDLK_S: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{0.f, 0.f, -1.f, 1.f}) - .resize<1, 3>() * - -0.1; + speed(2) = 1.F; break; case SDLK_A: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{1.f, 0.f, 0.f, 1.f}) - .resize<1, 3>() * - -0.1; + speed(0) = -1.F; break; case SDLK_D: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{1.f, 0.f, 0.f, 1.f}) - .resize<1, 3>() * - 0.1; + speed(0) = 1.F; break; default: break; @@ -671,32 +658,16 @@ void main() yaw_speed = 0.F; break; case SDLK_W: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{0.f, 0.f, -1.f, 1.f}) - .resize<1, 3>() * - 0.1; + speed(2) = 0.F; break; case SDLK_S: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{0.f, 0.f, -1.f, 1.f}) - .resize<1, 3>() * - -0.1; + speed(2) = 0.F; break; case SDLK_A: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{1.f, 0.f, 0.f, 1.f}) - .resize<1, 3>() * - -0.1; + speed(0) = 0.F; break; case SDLK_D: - location = location + - ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * - sopho::Mat{1.f, 0.f, 0.f, 1.f}) - .resize<1, 3>() * - 0.1; + speed(0) = 0.F; break; default: break; From 07b074faeb791f5e467f0d447630e2d726c3e268 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 21:05:18 +0800 Subject: [PATCH 57/66] feat: Add check for texture wrapper --- sdl_wrapper/src/sdl_wrapper.renderable.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdl_wrapper/src/sdl_wrapper.renderable.cpp b/sdl_wrapper/src/sdl_wrapper.renderable.cpp index a527648..b41ca5b 100644 --- a/sdl_wrapper/src/sdl_wrapper.renderable.cpp +++ b/sdl_wrapper/src/sdl_wrapper.renderable.cpp @@ -27,7 +27,10 @@ namespace sopho SDL_BindGPUIndexBuffer(render_contex.render_pass, &data()->get_index_buffer_binding(), SDL_GPU_INDEXELEMENTSIZE_32BIT); - SDL_BindGPUFragmentSamplers(render_contex.render_pass, 0, render_contex.texture_wrapper->get(), 1); + if (render_contex.texture_wrapper) + { + SDL_BindGPUFragmentSamplers(render_contex.render_pass, 0, render_contex.texture_wrapper->get(), 1); + } SDL_DrawGPUIndexedPrimitives(render_contex.render_pass, data()->index_view().index_count, 1, 0, 0, 0); return std::monostate{}; } From b11719b63446a281c00027769976a0454c5683f6 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 22:07:57 +0800 Subject: [PATCH 58/66] feat: draw different box --- main.cpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index e424857..f43efdd 100644 --- a/main.cpp +++ b/main.cpp @@ -128,6 +128,17 @@ void main() discard; })WSQ"; + std::string fragment_source2 = + R"WSQ(#version 460 + +layout (location = 0) in vec2 v_uv; +layout (location = 0) out vec4 FragColor; + +void main() +{ + FragColor = vec4(1,1,1,1); +})WSQ"; + public: /** * @brief Initialize application GPU resources, shaders, vertex data, camera, and Dear ImGui. @@ -208,8 +219,20 @@ void main() m_renderables.emplace_back(std::make_shared(sopho::Renderable{ .m_render_procedural = std::make_shared(std::move(pw_result.value())), .m_render_data = std::move(render_data.value())})); + + auto pw_result2 = m_gpu->create_render_procedural(); + pipeline_init = pw_result2.and_then([&](auto& pipeline) { return pipeline.set_vertex_shader(vertex_source); }) + .and_then([&](std::monostate) { return pw_result2->set_fragment_shader(fragment_source2); }) + .and_then([&](std::monostate) { return pw_result2->submit(); }); + if (!pipeline_init) + { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to initialize pipeline, error = %d", + static_cast(pipeline_init.error())); + return SDL_APP_FAILURE; + } m_renderables.emplace_back(std::make_shared(sopho::Renderable{ - .m_render_procedural = m_renderables[0]->procedural(), .m_render_data = m_renderables[0]->data()})); + .m_render_procedural = std::make_shared(std::move(pw_result2.value())), + .m_render_data = m_renderables[0]->data()})); // 7. Setup Dear ImGui context. IMGUI_CHECKVERSION(); @@ -566,7 +589,7 @@ void main() renderable->draw(sopho::RenderContex{.render_pass = renderPass, .command_buffer = command_buffer_raii.raw(), .camera_mat = camera_mat, - .texture_wrapper = m_texture_wrapper}); + .texture_wrapper = i == 0 ? m_texture_wrapper : nullptr}); } SDL_EndGPURenderPass(renderPass); From d6f662996415d16de06035c21fff0d1512759319 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 22:08:21 +0800 Subject: [PATCH 59/66] feat: add q e for moving up and down --- main.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/main.cpp b/main.cpp index f43efdd..9a9c621 100644 --- a/main.cpp +++ b/main.cpp @@ -659,6 +659,12 @@ void main() case SDLK_D: speed(0) = 1.F; break; + case SDLK_E: + speed(1) = 1.F; + break; + case SDLK_Q: + speed(1) = -1.F; + break; default: break; } @@ -692,6 +698,12 @@ void main() case SDLK_D: speed(0) = 0.F; break; + case SDLK_Q: + speed(1) = 0.F; + break; + case SDLK_E: + speed(1) = 0.F; + break; default: break; } From 5063a530d2c5d0d2e48532166dd0827bb4f6f885 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 22:23:31 +0800 Subject: [PATCH 60/66] feat: Add camera control logic --- main.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index 9a9c621..cc061b2 100644 --- a/main.cpp +++ b/main.cpp @@ -92,6 +92,8 @@ class UserApp : public sopho::App sopho::Mat location{}; sopho::Mat speed{}; + bool m_dragging{}; + float m_last_x{}, m_last_y{}; int win_w = 0, win_h = 0; @@ -712,6 +714,49 @@ void main() } } + if (!io.WantCaptureMouse) + { + switch (event->type) + { + case SDL_EVENT_MOUSE_BUTTON_DOWN: + if (event->button.button == SDL_BUTTON_LEFT) + { + m_dragging = true; + m_last_x = event->button.x; + m_last_y = event->button.y; + } + break; + + case SDL_EVENT_MOUSE_BUTTON_UP: + if (event->button.button == SDL_BUTTON_LEFT) + { + m_dragging = false; + } + break; + + case SDL_EVENT_MOUSE_MOTION: + if (m_dragging) + { + float x = event->motion.x; + float y = event->motion.y; + + float dx = x - m_last_x; + float dy = y - m_last_y; + + m_last_x = x; + m_last_y = y; + + // 你自己的 yaw/pitch 变量(示例) + yaw += dx * 0.01; + pitch -= dy * 0.01; + + // 可选:限制 pitch 防止翻转 + pitch = std::clamp(pitch, -1.55f, 1.55f); // ~(-89°, 89°) + } + break; + } + } + if (event->type == SDL_EVENT_WINDOW_CLOSE_REQUESTED) { return SDL_APP_SUCCESS; @@ -735,7 +780,7 @@ void main() * * @param argc Program argument count as passed to main. * @param argv Program argument vector as passed to main. - * @return sopho::App* Pointer to a heap-allocated application object; the caller takes ownership and is responsible for - * deleting it. + * @return sopho::App* Pointer to a heap-allocated application object; the caller takes ownership and is responsible + * for deleting it. */ sopho::checkable create_app(int argc, char** argv) { return new UserApp(); } From b858f6e6e1fe0e6134455583398d744e54c7b47d Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 22:25:33 +0800 Subject: [PATCH 61/66] feat: change clear color --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index cc061b2..44a422f 100644 --- a/main.cpp +++ b/main.cpp @@ -563,7 +563,7 @@ void main() // Create the color target. SDL_GPUColorTargetInfo colorTargetInfo{}; - colorTargetInfo.clear_color = {240 / 255.0F, 240 / 255.0F, 240 / 255.0F, 255 / 255.0F}; + colorTargetInfo.clear_color = {135 / 255.0F, 135 / 255.0F, 135 / 255.0F, 255 / 255.0F}; colorTargetInfo.load_op = SDL_GPU_LOADOP_CLEAR; colorTargetInfo.store_op = SDL_GPU_STOREOP_STORE; colorTargetInfo.texture = swapchainTexture; From 2bb49e3db9db015d810d835e151fa8f7be91cc39 Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 22:30:49 +0800 Subject: [PATCH 62/66] doc: mark camera and colors finished --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8e6f1e7..72a9cf0 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ graph TD ## Track -- [ ] Getting started +- [x] Getting started - [x] OpenGL - [x] Creating a window - [x] Hello Window @@ -58,9 +58,9 @@ graph TD - [x] Textures - [x] Transformations - [x] Coordinate Systems - - [ ] Camera + - [x] Camera - [ ] Lighting - - [ ] Colors + - [x] Colors - [ ] Basic Lighting - [ ] Materials - [ ] Lighting maps From bc41959ef757d8e1077a2952feed0982a872850a Mon Sep 17 00:00:00 2001 From: Sophomore <17792626+WSQS@users.noreply.github.com> Date: Mon, 1 Dec 2025 22:43:50 +0800 Subject: [PATCH 63/66] fix: rename struct name --- main.cpp | 2 +- sdl_wrapper/modules/sdl_wrapper.renderable.ixx | 4 ++-- sdl_wrapper/src/sdl_wrapper.renderable.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/main.cpp b/main.cpp index 44a422f..1b20e16 100644 --- a/main.cpp +++ b/main.cpp @@ -588,7 +588,7 @@ void main() auto camera_mat = sopho::perspective(1, static_cast(width) / height, 0.1, 10) * sopho::rotation_x(-pitch) * sopho::rotation_y(yaw) * sopho::translate(0 - location(0), 0.5 * i - location(1), -i - 5 - location(2)); - renderable->draw(sopho::RenderContex{.render_pass = renderPass, + renderable->draw(sopho::RenderContext{.render_pass = renderPass, .command_buffer = command_buffer_raii.raw(), .camera_mat = camera_mat, .texture_wrapper = i == 0 ? m_texture_wrapper : nullptr}); diff --git a/sdl_wrapper/modules/sdl_wrapper.renderable.ixx b/sdl_wrapper/modules/sdl_wrapper.renderable.ixx index 62c7379..42ea672 100644 --- a/sdl_wrapper/modules/sdl_wrapper.renderable.ixx +++ b/sdl_wrapper/modules/sdl_wrapper.renderable.ixx @@ -12,7 +12,7 @@ import :decl; namespace sopho { - export struct RenderContex + export struct RenderContext { SDL_GPURenderPass* render_pass{}; SDL_GPUCommandBuffer* command_buffer{}; @@ -27,6 +27,6 @@ namespace sopho std::shared_ptr m_render_data{}; auto& procedural() { return m_render_procedural; } std::shared_ptr& data() { return m_render_data; } - checkable draw(RenderContex render_contex); + checkable draw(RenderContext render_contex); }; } // namespace sopho diff --git a/sdl_wrapper/src/sdl_wrapper.renderable.cpp b/sdl_wrapper/src/sdl_wrapper.renderable.cpp index b41ca5b..de3a1fb 100644 --- a/sdl_wrapper/src/sdl_wrapper.renderable.cpp +++ b/sdl_wrapper/src/sdl_wrapper.renderable.cpp @@ -12,7 +12,7 @@ import :render_procedural; import :render_data; namespace sopho { - checkable Renderable::draw(RenderContex render_contex) + checkable Renderable::draw(RenderContext render_contex) { auto submit_result = procedural()->submit(); if (!submit_result) From 7e970c5e5d848e28f41e6cb0648df277d9c8fb8f Mon Sep 17 00:00:00 2001 From: "deepsource-autofix[bot]" <62050782+deepsource-autofix[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 14:48:16 +0000 Subject: [PATCH 64/66] style: format code with ClangFormat This commit fixes the style issues introduced in bc41959 according to the output from ClangFormat. Details: https://github.com/WSQS/sdl_test/pull/45 --- main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 1b20e16..3ed74e3 100644 --- a/main.cpp +++ b/main.cpp @@ -589,9 +589,9 @@ void main() sopho::rotation_x(-pitch) * sopho::rotation_y(yaw) * sopho::translate(0 - location(0), 0.5 * i - location(1), -i - 5 - location(2)); renderable->draw(sopho::RenderContext{.render_pass = renderPass, - .command_buffer = command_buffer_raii.raw(), - .camera_mat = camera_mat, - .texture_wrapper = i == 0 ? m_texture_wrapper : nullptr}); + .command_buffer = command_buffer_raii.raw(), + .camera_mat = camera_mat, + .texture_wrapper = i == 0 ? m_texture_wrapper : nullptr}); } SDL_EndGPURenderPass(renderPass); From cfa23466814f8507e260835e0a89083095dbf29c Mon Sep 17 00:00:00 2001 From: Sophomore Date: Tue, 2 Dec 2025 08:50:14 +0800 Subject: [PATCH 65/66] feat: remove chinese comment --- main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 3ed74e3..4eae8f6 100644 --- a/main.cpp +++ b/main.cpp @@ -746,12 +746,10 @@ void main() m_last_x = x; m_last_y = y; - // 你自己的 yaw/pitch 变量(示例) yaw += dx * 0.01; pitch -= dy * 0.01; - // 可选:限制 pitch 防止翻转 - pitch = std::clamp(pitch, -1.55f, 1.55f); // ~(-89°, 89°) + pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); } break; } From 7a00f100728356522f140535a05156f924188416 Mon Sep 17 00:00:00 2001 From: Sophomore Date: Tue, 2 Dec 2025 09:02:57 +0800 Subject: [PATCH 66/66] feat: change walking speed --- main.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/main.cpp b/main.cpp index 4eae8f6..ce687e3 100644 --- a/main.cpp +++ b/main.cpp @@ -324,7 +324,7 @@ void main() pitch = std::clamp(pitch, -std::numbers::pi_v / 2, +std::numbers::pi_v / 2); yaw += yaw_speed * dt; location = - location + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * speed).resize<1, 3>() * 0.1; + location + ((sopho::rotation_x(-pitch) * sopho::rotation_y(yaw)).transpose() * speed).resize<1, 3>() * dt; return SDL_APP_CONTINUE; } @@ -650,22 +650,22 @@ void main() yaw_speed = 0.5F; break; case SDLK_W: - speed(2) = -1.F; + speed(2) = -4.F; break; case SDLK_S: - speed(2) = 1.F; + speed(2) = 4.F; break; case SDLK_A: - speed(0) = -1.F; + speed(0) = -4.F; break; case SDLK_D: - speed(0) = 1.F; + speed(0) = 4.F; break; case SDLK_E: - speed(1) = 1.F; + speed(1) = 4.F; break; case SDLK_Q: - speed(1) = -1.F; + speed(1) = -4.F; break; default: break;