From 122da9aed6e5437c591ddaf714809e8aef0fb63c Mon Sep 17 00:00:00 2001 From: Steven French Date: Sun, 3 Aug 2025 07:47:44 +1200 Subject: [PATCH 1/5] Fix LSP errors (includes) Change-Id: If04c9a37990a5d862cb372a8d6d776b84b15ea73 --- include/dz/AssetPack.hpp | 1 + include/dz/ECS/Material.hpp | 5 + include/dz/ECS/SubMesh.hpp | 21 +- include/dz/ReflectedStructView.hpp | 2 +- include/dz/Shader.hpp | 2 + src/AssetPack.cpp | 3 + src/BufferGroup.cpp | 12 +- src/BufferGroup.cpp.hpp | 11 + src/D7Stream.cpp | 2 + src/DirectZ.cpp | 22 +- src/Directz.cpp.hpp | 36 ++- src/ECS/Camera.cpp | 2 + src/ECS/Entity.cpp | 1 + src/ECS/Light.cpp | 1 + src/ECS/Material.cpp | 1 + src/ECS/Mesh.cpp | 2 + src/ECS/SubMesh.cpp | 6 +- src/FileHandle.cpp | 2 + src/Framebuffer.cpp | 38 +--- src/Framebuffer.cpp.hpp | 39 ++++ src/ImGuiLayer.cpp | 1 + src/Image.cpp | 41 +--- src/Image.cpp.hpp | 40 ++++ src/Loaders/Assimp_Loader.cpp | 14 +- src/Loaders/STB_Image_Loader.cpp | 14 +- src/Renderer.cpp | 2 + src/Shader.cpp | 228 +------------------ src/Shader.cpp.hpp | 231 +++++++++++++++++++ src/Window.cpp | 2 + src/env.cpp | 2 + src/path.cpp | 2 + tests/ECS.cpp | 350 +++++++++++++++-------------- 32 files changed, 622 insertions(+), 514 deletions(-) create mode 100644 src/BufferGroup.cpp.hpp create mode 100644 src/Framebuffer.cpp.hpp create mode 100644 src/Image.cpp.hpp create mode 100644 src/Shader.cpp.hpp diff --git a/include/dz/AssetPack.hpp b/include/dz/AssetPack.hpp index 4b5a1507..637bce06 100644 --- a/include/dz/AssetPack.hpp +++ b/include/dz/AssetPack.hpp @@ -4,6 +4,7 @@ */ #pragma once #include "FileHandle.hpp" +#include "size_ptr.hpp" namespace dz { diff --git a/include/dz/ECS/Material.hpp b/include/dz/ECS/Material.hpp index d85599ea..93fc5ffd 100644 --- a/include/dz/ECS/Material.hpp +++ b/include/dz/ECS/Material.hpp @@ -3,6 +3,11 @@ #include "../Image.hpp" namespace dz::ecs { + + struct MaterialIndexReflectable { + int material_index = 0; + }; + struct Material : Provider { vec atlas_pack = {-1.0f, -1.0f, -1.0f, -1.0f}; vec albedo = {1.0f, 1.0f, 1.0f, 1.0f}; diff --git a/include/dz/ECS/SubMesh.hpp b/include/dz/ECS/SubMesh.hpp index 0e6aca3e..35ec96b9 100644 --- a/include/dz/ECS/SubMesh.hpp +++ b/include/dz/ECS/SubMesh.hpp @@ -1,6 +1,7 @@ #pragma once #include "Provider.hpp" #include "Mesh.hpp" +#include "Material.hpp" namespace dz::ecs { inline static std::string Meshs_Str = "Meshs"; @@ -38,28 +39,16 @@ struct SubMesh { int uid; std::string name; inline static std::unordered_map> prop_name_indexes = { - {"parent_index", {0, 0}}, - {"parent_cid", {1, 0}}, - {"mesh_index", {2, 0}}, - {"material_index", {3, 0}} + {"Material", {0, 0}} }; inline static std::unordered_map prop_index_names = { - {0, "parent_index"}, - {1, "parent_cid"}, - {2, "mesh_index"}, - {3, "material_index"} + {0, "Material"} }; inline static std::vector prop_names = { - "parent_index", - "parent_cid", - "mesh_index", - "material_index" + "Material" }; inline static const std::vector typeinfos = { - &typeid(int), - &typeid(int), - &typeid(int), - &typeid(int) + &typeid(MaterialIndexReflectable) }; public: diff --git a/include/dz/ReflectedStructView.hpp b/include/dz/ReflectedStructView.hpp index 6c4dd10f..86bd6054 100644 --- a/include/dz/ReflectedStructView.hpp +++ b/include/dz/ReflectedStructView.hpp @@ -13,7 +13,7 @@ namespace dz { * @param base_ptr A pointer to the start of the struct element's data in the buffer. * @param struct_def The ReflectedStruct definition for this element. */ - ReflectedStructView(uint8_t* base_ptr, const ReflectedStruct& struct_def); + explicit ReflectedStructView(uint8_t* base_ptr, const ReflectedStruct& struct_def); /** * @brief Sets the value of a member within the struct. diff --git a/include/dz/Shader.hpp b/include/dz/Shader.hpp index 2d68f597..bab127fc 100644 --- a/include/dz/Shader.hpp +++ b/include/dz/Shader.hpp @@ -46,6 +46,7 @@ namespace dz */ void shader_set_render_pass(Shader*, Framebuffer*); + struct AssetPack; /** * @brief Sets the include path to an asset_pack for include lookup */ @@ -68,6 +69,7 @@ namespace dz */ void shader_add_module_from_file(Shader*, const std::filesystem::path& file_path); + struct BufferGroup; /** * @brief Binds a BufferGroup to the shader. * diff --git a/src/AssetPack.cpp b/src/AssetPack.cpp index 7cf75d80..123904e3 100644 --- a/src/AssetPack.cpp +++ b/src/AssetPack.cpp @@ -1,3 +1,6 @@ +#include +#include + namespace dz { struct AssetPack { diff --git a/src/BufferGroup.cpp b/src/BufferGroup.cpp index 964eadb7..1d57c0b1 100644 --- a/src/BufferGroup.cpp +++ b/src/BufferGroup.cpp @@ -1,6 +1,10 @@ -namespace dz { - void buffer_group_destroy(BufferGroup* bg); +#include +#include +#include "BufferGroup.cpp.hpp" +#include "Directz.cpp.hpp" +#include "Shader.cpp.hpp" +namespace dz { BufferGroup* buffer_group_create(const std::string& group_name) { auto& bg = (dr.buffer_groups[group_name] = std::shared_ptr( new BufferGroup{ @@ -15,7 +19,7 @@ namespace dz { } void buffer_group_initialize(BufferGroup* buffer_group) { - for (auto& sp: buffer_group->shaders) { + for (auto& sp : buffer_group->shaders) { auto shader = sp.first; shader->bound_buffer_groups.push_back(buffer_group); shader_initialize(shader); @@ -92,8 +96,6 @@ namespace dz { buffer_group->restricted_to_keys[key] = true; } - bool buffer_group_resize_gpu_buffer(const std::string& name, ShaderBuffer& buffer); - /** * @brief For dynamic SSBOs, sets the number of elements the buffer should hold. * This MUST be called before shader_create_resources(). diff --git a/src/BufferGroup.cpp.hpp b/src/BufferGroup.cpp.hpp new file mode 100644 index 00000000..4fdd67d8 --- /dev/null +++ b/src/BufferGroup.cpp.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "Directz.cpp.hpp" + +namespace dz { + void buffer_group_destroy(BufferGroup* bg); + + VkImageUsageFlags infer_image_usage_flags(const std::unordered_map& types); + + bool buffer_group_resize_gpu_buffer(const std::string& name, ShaderBuffer& buffer); +} \ No newline at end of file diff --git a/src/D7Stream.cpp b/src/D7Stream.cpp index f7fe6c41..1f80c22c 100644 --- a/src/D7Stream.cpp +++ b/src/D7Stream.cpp @@ -1,3 +1,5 @@ +#include + namespace dz { size_t* D7Stream::addStreamPoint(const StreamPoint& point) { diff --git a/src/DirectZ.cpp b/src/DirectZ.cpp index a6370c05..156e4384 100644 --- a/src/DirectZ.cpp +++ b/src/DirectZ.cpp @@ -1,7 +1,5 @@ #include #include "Directz.cpp.hpp" -extern "C" DirectRegistry* dr_ptr; -extern "C" DirectRegistry& dr; namespace dz { DirectRegistry*& get_direct_registry() @@ -27,9 +25,9 @@ namespace dz void free_direct_registry() { ImGuiLayer::Shutdown(dr); - while (!dr.layout_queue.empty()) { - auto layout = dr.layout_queue.front(); - dr.layout_queue.pop(); + while (!dr.layoutQueue.empty()) { + auto layout = dr.layoutQueue.front(); + dr.layoutQueue.pop(); vkDestroyDescriptorSetLayout(dr.device, layout, 0); } #ifdef __ANDROID__ @@ -46,20 +44,6 @@ namespace dz auto direct_registry = get_direct_registry(); delete direct_registry; } - struct Renderer; - struct WINDOW; - Renderer* renderer_init(WINDOW* window); - void renderer_render(Renderer* renderer); - void renderer_free(Renderer* renderer); - void create_surface(Renderer* renderer); - bool create_swap_chain(Renderer* renderer); - void create_image_views(Renderer* renderer); - void create_framebuffers(Renderer* renderer); - uint32_t find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties); - VkCommandBuffer begin_single_time_commands(); - void end_single_time_commands(VkCommandBuffer command_buffer); - struct ShaderBuffer; - void buffer_group_make_gpu_buffer(const std::string& name, ShaderBuffer& buffer); std::vector::iterator dr_get_windows_begin() { return dr.window_ptrs.begin(); } diff --git a/src/Directz.cpp.hpp b/src/Directz.cpp.hpp index 984a0022..987ee38e 100644 --- a/src/Directz.cpp.hpp +++ b/src/Directz.cpp.hpp @@ -1,3 +1,4 @@ +#pragma once #include using namespace dz; #include @@ -15,6 +16,7 @@ using namespace dz; #include #include #include +#include #include #include #include @@ -45,6 +47,15 @@ namespace dz { * @brief Creates a Window given a Serial interface */ WINDOW* window_create_from_serial(Serial& serial); + + void set_env(const std::string& key, const std::string& value); + std::string get_env(const std::string& key); + void append_vk_icd_filename(const std::string& swiftshader_icd_path); + + std::filesystem::path getUserDirectoryPath(); + std::filesystem::path getProgramDirectoryPath(); + std::filesystem::path getProgramDataPath(); + std::filesystem::path getExecutableName(); } static std::unordered_map stageEShaderc = { {ShaderModuleType::Vertex, shaderc_vertex_shader}, @@ -106,7 +117,7 @@ struct DirectRegistry bool swiftshader_fallback = false; std::atomic window_count = 0; ImGuiLayer imguiLayer; - std::queue layout_queue; + std::queue layoutQueue; #ifdef _WIN32 HWND hwnd_root; #endif @@ -115,10 +126,29 @@ struct DirectRegistry AConfiguration* android_config = 0; #endif }; -struct DirectRegistry; namespace dz { + struct Renderer; + struct WINDOW; + Renderer* renderer_init(WINDOW* window); + void renderer_render(Renderer* renderer); + void renderer_free(Renderer* renderer); + void create_surface(Renderer* renderer); + bool create_swap_chain(Renderer* renderer); + void create_image_views(Renderer* renderer); + void create_framebuffers(Renderer* renderer); + uint32_t find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties); + VkCommandBuffer begin_single_time_commands(); + void end_single_time_commands(VkCommandBuffer command_buffer); + struct ShaderBuffer; + void buffer_group_make_gpu_buffer(const std::string& name, ShaderBuffer& buffer); + std::vector::iterator dr_get_windows_begin(); + std::vector::iterator dr_get_windows_end(); + std::vector::iterator dr_get_window_reflectable_entries_begin(); + std::vector::iterator dr_get_window_reflectable_entries_end(); bool vk_check(const char* fn, VkResult result); void vk_log(const char* fn, VkResult result); bool recreate_swap_chain(Renderer* renderer); -} \ No newline at end of file +} +extern "C" DirectRegistry* dr_ptr; +extern "C" DirectRegistry& dr; \ No newline at end of file diff --git a/src/ECS/Camera.cpp b/src/ECS/Camera.cpp index 0700c60f..f31dcfc6 100644 --- a/src/ECS/Camera.cpp +++ b/src/ECS/Camera.cpp @@ -1,4 +1,6 @@ #include +#include + void dz::ecs::CameraInit( Camera& camera, vec position, diff --git a/src/ECS/Entity.cpp b/src/ECS/Entity.cpp index 1073ce29..db4018e3 100644 --- a/src/ECS/Entity.cpp +++ b/src/ECS/Entity.cpp @@ -1,4 +1,5 @@ #include +#include dz::ecs::Entity::EntityTransformReflectable::EntityTransformReflectable(const std::function& get_entity_function): get_entity_function(get_entity_function), diff --git a/src/ECS/Light.cpp b/src/ECS/Light.cpp index 74551914..85c71473 100644 --- a/src/ECS/Light.cpp +++ b/src/ECS/Light.cpp @@ -1,4 +1,5 @@ #include +#include dz::ecs::LightMetaReflectable::LightMetaReflectable( const std::function& get_light_function, diff --git a/src/ECS/Material.cpp b/src/ECS/Material.cpp index 94ac5d16..968636a1 100644 --- a/src/ECS/Material.cpp +++ b/src/ECS/Material.cpp @@ -1,4 +1,5 @@ #include +#include dz::ecs::Material::MaterialReflectable::MaterialReflectable(const std::function& get_material_function): get_material_function(get_material_function), diff --git a/src/ECS/Mesh.cpp b/src/ECS/Mesh.cpp index 11370df7..48c0e61e 100644 --- a/src/ECS/Mesh.cpp +++ b/src/ECS/Mesh.cpp @@ -1,4 +1,6 @@ #include +#include +#include dz::ecs::Mesh::MeshReflectable::MeshReflectable(const std::function& get_mesh_function): get_mesh_function(get_mesh_function), diff --git a/src/ECS/SubMesh.cpp b/src/ECS/SubMesh.cpp index 3e5edee5..d903f406 100644 --- a/src/ECS/SubMesh.cpp +++ b/src/ECS/SubMesh.cpp @@ -1,4 +1,5 @@ #include +#include dz::ecs::SubMesh::SubMeshReflectable::SubMeshReflectable(const std::function& get_submesh_function): get_submesh_function(get_submesh_function), @@ -19,10 +20,7 @@ void* dz::ecs::SubMesh::SubMeshReflectable::GetVoidPropertyByIndex(int prop_inde assert(mesh_ptr); auto& mesh = *mesh_ptr; switch (prop_index) { - case 0: return &mesh.parent_index; - case 1: return &mesh.parent_cid; - case 2: return &mesh.mesh_index; - case 3: return &mesh.material_index; + case 0: return &mesh.material_index; default: return nullptr; } } diff --git a/src/FileHandle.cpp b/src/FileHandle.cpp index 15b27cc0..f673cf89 100644 --- a/src/FileHandle.cpp +++ b/src/FileHandle.cpp @@ -1,3 +1,5 @@ +#include + namespace dz { std::shared_ptr FileHandle::open(std::ios_base::openmode ios) { diff --git a/src/Framebuffer.cpp b/src/Framebuffer.cpp index 478d39ed..c88e4918 100644 --- a/src/Framebuffer.cpp +++ b/src/Framebuffer.cpp @@ -1,41 +1,11 @@ #include +#include +#include "Directz.cpp.hpp" +#include "Framebuffer.cpp.hpp" +#include "Image.cpp.hpp" namespace dz { - struct Framebuffer { - Image** pImages; - int imagesCount; - AttachmentType* pAttachmentTypes; - int attachmentTypesCount; - BlendState blendState; - bool own_images; - - VkCommandBuffer commandBuffer; - VkRenderPass renderPass; - VkFramebuffer framebuffer; - uint32_t attachmentsSize; - uint32_t width; - uint32_t height; - VkEvent event; - - VkRenderPassBeginInfo renderPassInfo{}; - bool render_pass_info_changed = true; - - VkCommandBufferBeginInfo beginInfo = {}; - bool begin_info_changed = true; - - std::vector clearValues; - bool clear_changed = true; - VkClearColorValue clear_color; - VkClearDepthStencilValue clear_depth_stencil; - - VkSubmitInfo submitInfo = {}; - bool submit_info_changed = true; - - Image** new_pImages = 0; - VkFramebuffer new_framebuffer = VK_NULL_HANDLE; - }; - void transitionDepthLayoutForWriting(Framebuffer&); void transitionDepthLayoutForReading(Framebuffer&); void transitionColorLayoutForWriting(Framebuffer&); diff --git a/src/Framebuffer.cpp.hpp b/src/Framebuffer.cpp.hpp new file mode 100644 index 00000000..4f57be32 --- /dev/null +++ b/src/Framebuffer.cpp.hpp @@ -0,0 +1,39 @@ +#pragma once +#include +#include "Directz.cpp.hpp" + +namespace dz { + struct Framebuffer { + Image** pImages; + int imagesCount; + AttachmentType* pAttachmentTypes; + int attachmentTypesCount; + BlendState blendState; + bool own_images; + + VkCommandBuffer commandBuffer; + VkRenderPass renderPass; + VkFramebuffer framebuffer; + uint32_t attachmentsSize; + uint32_t width; + uint32_t height; + VkEvent event; + + VkRenderPassBeginInfo renderPassInfo{}; + bool render_pass_info_changed = true; + + VkCommandBufferBeginInfo beginInfo = {}; + bool begin_info_changed = true; + + std::vector clearValues; + bool clear_changed = true; + VkClearColorValue clear_color; + VkClearDepthStencilValue clear_depth_stencil; + + VkSubmitInfo submitInfo = {}; + bool submit_info_changed = true; + + Image** new_pImages = 0; + VkFramebuffer new_framebuffer = VK_NULL_HANDLE; + }; +} \ No newline at end of file diff --git a/src/ImGuiLayer.cpp b/src/ImGuiLayer.cpp index 25c91737..7ee8a7cd 100644 --- a/src/ImGuiLayer.cpp +++ b/src/ImGuiLayer.cpp @@ -1,3 +1,4 @@ +#include #include "fa-solid-900-ttf.c" namespace dz { VkDescriptorPool CreateImGuiDescriptorPool(VkDevice device) diff --git a/src/Image.cpp b/src/Image.cpp index d01ea599..035cf2d5 100644 --- a/src/Image.cpp +++ b/src/Image.cpp @@ -1,39 +1,8 @@ +#include +#include "Directz.cpp.hpp" +#include "Image.cpp.hpp" + namespace dz { - struct Image - { - uint32_t width; - uint32_t height; - uint32_t depth; - VkFormat format; - VkImageUsageFlags usage; - VkImageType image_type; - VkImageViewType view_type; - VkImageTiling tiling; - VkMemoryPropertyFlags memory_properties; - VkImage image = VK_NULL_HANDLE; - VkImageView imageView = VK_NULL_HANDLE; - VkBuffer buffer = VK_NULL_HANDLE; - VkDeviceMemory memory = VK_NULL_HANDLE; - VkSampler sampler = VK_NULL_HANDLE; - VkImageLayout current_layout = VK_IMAGE_LAYOUT_UNDEFINED; - VkSampleCountFlagBits multisampling; - std::shared_ptr data; - }; - - struct ImageCreateInfoInternal - { - uint32_t width = 1; - uint32_t height = 1; - uint32_t depth = 1; - VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; - VkImageUsageFlags usage; - VkImageType image_type = VK_IMAGE_TYPE_2D; - VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_2D; - VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; - VkMemoryPropertyFlags memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - VkSampleCountFlagBits multisampling = VK_SAMPLE_COUNT_1_BIT; - void* data = nullptr; - }; void upload_image_data(Image* image); @@ -472,7 +441,7 @@ namespace dz { vkUpdateDescriptorSets(dr.device, 1, &descriptorWrite, 0, nullptr); - dr.layout_queue.push(layout); + dr.layoutQueue.push(layout); return {layout, descriptorSet}; } diff --git a/src/Image.cpp.hpp b/src/Image.cpp.hpp new file mode 100644 index 00000000..6bec75f8 --- /dev/null +++ b/src/Image.cpp.hpp @@ -0,0 +1,40 @@ +#pragma once +#include "Directz.cpp.hpp" + +namespace dz { + struct Image + { + uint32_t width; + uint32_t height; + uint32_t depth; + VkFormat format; + VkImageUsageFlags usage; + VkImageType image_type; + VkImageViewType view_type; + VkImageTiling tiling; + VkMemoryPropertyFlags memory_properties; + VkImage image = VK_NULL_HANDLE; + VkImageView imageView = VK_NULL_HANDLE; + VkBuffer buffer = VK_NULL_HANDLE; + VkDeviceMemory memory = VK_NULL_HANDLE; + VkSampler sampler = VK_NULL_HANDLE; + VkImageLayout current_layout = VK_IMAGE_LAYOUT_UNDEFINED; + VkSampleCountFlagBits multisampling; + std::shared_ptr data; + }; + + struct ImageCreateInfoInternal + { + uint32_t width = 1; + uint32_t height = 1; + uint32_t depth = 1; + VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; + VkImageUsageFlags usage; + VkImageType image_type = VK_IMAGE_TYPE_2D; + VkImageViewType view_type = VK_IMAGE_VIEW_TYPE_2D; + VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; + VkMemoryPropertyFlags memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + VkSampleCountFlagBits multisampling = VK_SAMPLE_COUNT_1_BIT; + void* data = nullptr; + }; +} \ No newline at end of file diff --git a/src/Loaders/Assimp_Loader.cpp b/src/Loaders/Assimp_Loader.cpp index 65361499..ff2cc030 100644 --- a/src/Loaders/Assimp_Loader.cpp +++ b/src/Loaders/Assimp_Loader.cpp @@ -1,5 +1,6 @@ #include #include "../Assimp/Assimp.hpp" +#include namespace dz::loaders::assimp_loader { Assimp::Importer importer; @@ -9,11 +10,12 @@ namespace dz::loaders::assimp_loader { }; void InitContext(AssimpContext& context, const Assimp_Info& info) { if (!info.path.empty()) { - const aiScene *scene_ptr = importer.ReadFile(info.path.c_str(), aiProcess_Triangulate | aiProcessPreset_TargetRealtime_Fast | aiProcess_FlipUVs | aiProcess_CalcTangentSpace); + auto info_path_string = info.path.string(); + const aiScene *scene_ptr = importer.ReadFile(info_path_string.c_str(), aiProcess_Triangulate | aiProcessPreset_TargetRealtime_Fast | aiProcess_FlipUVs | aiProcess_CalcTangentSpace); if (!scene_ptr || scene_ptr->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene_ptr->mRootNode) { std::cerr << importer.GetErrorString() << std::endl; - return nullptr; + return; } context.scene_ptr = scene_ptr; } @@ -22,7 +24,7 @@ namespace dz::loaders::assimp_loader { if (!scene_ptr || scene_ptr->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene_ptr->mRootNode) { std::cerr << importer.GetErrorString() << std::endl; - return nullptr; + return; } context.scene_ptr = scene_ptr; } @@ -34,7 +36,7 @@ namespace dz::loaders::assimp_loader { context.totalNodes++; for (uint32_t i = 0; i < node->mNumChildren; i++) { - totalNodes(context, node->mChildren[i]); + CountNodes(context, node->mChildren[i]); } } @@ -43,8 +45,8 @@ namespace dz::loaders::assimp_loader { } dz::loaders::MeshPair AssimpLoad(AssimpContext& context, const Assimp_Info& info) { - CountNodes(context, info.scene_ptr->mRootNode); - return ProcessNode(context, info.scene_ptr->mRootNode); + CountNodes(context, context.scene_ptr->mRootNode); + return ProcessNode(context, context.scene_ptr->mRootNode); } } dz::loaders::MeshPair dz::loaders::Assimp_Loader::Load(const info_type& info) { diff --git a/src/Loaders/STB_Image_Loader.cpp b/src/Loaders/STB_Image_Loader.cpp index ed9399e2..02b9e8f3 100644 --- a/src/Loaders/STB_Image_Loader.cpp +++ b/src/Loaders/STB_Image_Loader.cpp @@ -1,19 +1,19 @@ #include - +#include #define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_STATIC #include -Image* STB_Image_load_rgba(const uint8_t* ptr, int width, int height) { - ImageCreateInfo info{ +dz::Image* STB_Image_load_rgba(const uint8_t* ptr, int width, int height) { + dz::ImageCreateInfo info{ .width = (uint32_t)width, .height = (uint32_t)height, .data = (void*)ptr }; - return image_create(info); + return dz::image_create(info); } -Image* STB_Image_load_path(const std::filesystem::path& path) { +dz::Image* STB_Image_load_path(const std::filesystem::path& path) { int nrChannels; int width = 0, height = 0; std::string path_string = path.string(); @@ -24,7 +24,7 @@ Image* STB_Image_load_path(const std::filesystem::path& path) { return STB_Image_load_rgba(imageData, width, height); } -Image* STB_Image_load_bytes(const std::shared_ptr& bytes, size_t bytes_length) { +dz::Image* STB_Image_load_bytes(const std::shared_ptr& bytes, size_t bytes_length) { int nrChannels; int width = 0, height = 0; uint8_t *imageData = stbi_load_from_memory( @@ -35,7 +35,7 @@ Image* STB_Image_load_bytes(const std::shared_ptr& bytes, size_t bytes_len return STB_Image_load_rgba(imageData, width, height); } -Image* dz::loaders::STB_Image_Loader::Load(const dz::loaders::STB_Image_Info& info) { +dz::Image* dz::loaders::STB_Image_Loader::Load(const dz::loaders::STB_Image_Info& info) { if (!info.path.empty()) return STB_Image_load_path(info.path); if (info.bytes && info.bytes_length) diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 39a32c64..62e21318 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -1,3 +1,5 @@ +#include "RendererImpl.hpp" + namespace dz { struct QueueFamilyIndices { diff --git a/src/Shader.cpp b/src/Shader.cpp index a51b70c7..3600f059 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -1,223 +1,19 @@ +#include +#include #include #include +#include +#include +#include +#include +#include "BufferGroup.cpp.hpp" +#include +#include +#include "Directz.cpp.hpp" +#include "Shader.cpp.hpp" +#include "Framebuffer.cpp.hpp" namespace dz { - struct ReflectedType { - uint32_t id; - std::string name; - std::string type_kind; // e.g., "float", "vec3", "mat4", "struct", "array" - uint32_t size_in_bytes = 0; // Size of the type in bytes (computed or derived) - SpvReflectTypeDescription type_desc; - SpvReflectDecorationFlags decorations; // Decorations applied to the type - uint32_t array_stride; - }; - - bool hasCanonicalStruct(const ReflectedType& type); - - uint32_t GetMinimumTypeSizeInBytes(const SpvReflectTypeDescription& type_desc); - uint32_t CalculateStructSize(const SpvReflectTypeDescription& type_desc); - bool CreateAndBindShaderBuffers(BufferGroup* buffer_group, Shader* shader); - VkShaderStageFlags GetShaderStageFromModuleType(ShaderModuleType type); - - struct ReflectedVariable { - std::string name; - uint32_t location = static_cast(-1); - uint32_t binding = static_cast(-1); - uint32_t set = static_cast(-1); - uint32_t offset = static_cast(-1); // Byte offset within its parent block/struct - uint32_t array_stride = 0; // Stride for array types (if applicable) - SpvReflectDescriptorType descriptor_type = (SpvReflectDescriptorType)-1; - ReflectedType type; - SpvReflectDecorationFlags decorations; // Decorations applied to the variable - }; - - struct ReflectedBlock { - std::string name; - uint32_t binding; - uint32_t set; - std::vector members; - ReflectedType type; // Represents the type of the block itself (e.g., UniformBufferObject) - }; - - struct ReflectedStruct { - std::string name; - uint32_t id; - SpvReflectTypeDescription type; - - std::map member_type_descs; // Maps member name (e.g., "model") to its SpvReflectTypeDescription - std::map member_offsets_map; // Maps member name to its offset within the struct - std::map member_sizes_map; // Maps member name to its reflected size - - ReflectedStruct() = default; - ReflectedStruct(std::string n, uint32_t i, SpvReflectTypeDescription td) : name(std::move(n)), id(i), type(td) { - uint32_t offset = 0; - for (uint32_t j = 0; j < type.member_count; ++j) { - auto type_desc = type.members[j]; - auto name = type_desc.struct_member_name ? type_desc.struct_member_name : type_desc.type_name; - if (name) { - auto size = GetMinimumTypeSizeInBytes(type_desc); - member_type_descs[name] = type_desc; - member_offsets_map[name] = offset; - member_sizes_map[name] = size; - offset += size; - } - } - } - }; - - ReflectedStructView::ReflectedStructView(uint8_t* base_ptr, const ReflectedStruct& struct_def) - : m_base_ptr(base_ptr), m_struct_def(struct_def) { - if (!m_base_ptr) { - throw std::runtime_error("ReflectedStructView: Base pointer for element is null."); - } - if (m_struct_def.type.op != SpvOpTypeStruct) { - throw std::runtime_error("ReflectedStructView: Provided ReflectedType is not a struct."); - } - } - - void ReflectedStructView::set_member(const std::string& member_name, const void* data_ptr, size_t data_size_bytes) { - auto offset_it = m_struct_def.member_offsets_map.find(member_name); - auto size_it = m_struct_def.member_sizes_map.find(member_name); - - if (offset_it == m_struct_def.member_offsets_map.end() || - size_it == m_struct_def.member_sizes_map.end()) { - throw std::runtime_error("ReflectedStructView Error: Member '" + member_name + "' not found in struct '" - + m_struct_def.name + "'."); - } - - uint32_t member_offset = offset_it->second; - uint32_t reflected_size = size_it->second; - - if (!(reflected_size == data_size_bytes)) { - throw std::runtime_error("ReflectedSize does not match data_size (bytes)"); - } - - uint8_t* target_addr = m_base_ptr + member_offset; - size_t bytes_to_copy = std::min(data_size_bytes, (size_t)reflected_size); - - memcpy(target_addr, data_ptr, bytes_to_copy); - } - - uint8_t* ReflectedStructView::get_member(const std::string& member_name, size_t data_size_bytes) { - auto offset_it = m_struct_def.member_offsets_map.find(member_name); - auto size_it = m_struct_def.member_sizes_map.find(member_name); - - if (offset_it == m_struct_def.member_offsets_map.end() || - size_it == m_struct_def.member_sizes_map.end()) { - throw std::runtime_error("ReflectedStructView Error: Member '" + member_name + "' not found in struct '" - + m_struct_def.name + "'."); - } - - uint32_t member_offset = offset_it->second; - uint32_t reflected_size = size_it->second; - - if (!(reflected_size == data_size_bytes)) { - throw std::runtime_error("ReflectedSize does not match data_size (bytes)"); - } - - return m_base_ptr + member_offset; - } - - struct SPIRVReflection { - std::vector inputs; - std::vector outputs; - std::vector ssbos; - std::vector ubos; - std::vector push_constants; // Added for clarity - std::unordered_map structs_by_name; - std::unordered_map structs_by_id; - std::unordered_map named_types; - std::shared_ptr module_ptr = std::shared_ptr(new SpvReflectShaderModule, [](SpvReflectShaderModule* module) { - spvReflectDestroyShaderModule(module); - delete module; - }); - }; - - const ReflectedStruct& getCanonicalStruct(const SPIRVReflection& reflection, const ReflectedType& type); - - struct ShaderModule { - std::vector spirv_vec; - VkShaderModule vk_module; - ShaderModuleType type; - SPIRVReflection reflection; - }; - - struct GpuBuffer { - VkBuffer buffer = VK_NULL_HANDLE; - VkDeviceMemory memory = VK_NULL_HANDLE; - void* mapped_memory = nullptr; // Persistently mapped pointer - VkDeviceSize size = 0; - }; - - struct ShaderBuffer { - std::string name; // Name from GLSL (e.g., "ubo_scene", "particles") - uint32_t set = 0; - uint32_t binding = 0; - VkDescriptorType descriptor_type = VK_DESCRIPTOR_TYPE_MAX_ENUM; - - // Data layout from reflection - VkDeviceSize static_size = 0; // Full size for UBOs, or size of ONE element for SSBOs - uint32_t element_stride = 0; // Stride of one element in an array (for SSBOs) - bool is_dynamic_sized = false; // Is this a runtime-sized SSBO? - ReflectedType element_type; - - // Application-controlled data - uint32_t element_count = 1; // Application sets this for dynamic SSBOs - - // The smart pointer that will point to CPU data initially, then GPU mapped memory. - // The custom deleter will be empty for GPU memory, preventing crashes. - std::shared_ptr data_ptr = nullptr; - - // The final Vulkan resource - GpuBuffer gpu_buffer; - }; - - struct ShaderImage { - std::string name; - uint32_t set = 0; - uint32_t binding = 0; - std::unordered_map descriptor_types; - VkImageViewType viewType; - VkFormat format; - std::unordered_map expected_layouts; - }; - - struct PushConstant { - std::shared_ptr ptr; - uint32_t size = 0; - uint32_t offset = 0; - VkShaderStageFlags stageFlags = (VkShaderStageFlags)0; - }; - - struct Shader { - bool initialized = false; - std::map module_map; - std::map descriptor_set_layouts; - VkDescriptorPool descriptor_pool = VK_NULL_HANDLE; - std::map descriptor_sets; - std::map buffer_groups; - std::vector bound_buffer_groups; - VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; - VkPipeline graphics_pipeline = VK_NULL_HANDLE; - VkRenderPass render_pass = VK_NULL_HANDLE; - std::map define_map; - std::unordered_map push_constants_name_index; - std::map push_constants; - AssetPack* include_asset_pack = 0; - ShaderTopology topology; - VkRenderPass renderPass = VK_NULL_HANDLE; - std::unordered_map sampler_key_image_override_map; - std::unordered_map keyed_set_binding_index_map; - }; - - struct BufferGroup { - std::string group_name; - std::unordered_map buffers; - std::unordered_map images; - std::unordered_map> runtime_images; - std::unordered_map shaders; - std::unordered_map restricted_to_keys; - }; class DynamicIncluder : public shaderc::CompileOptions::IncluderInterface { Shader* shader = nullptr; diff --git a/src/Shader.cpp.hpp b/src/Shader.cpp.hpp new file mode 100644 index 00000000..18a5cc8d --- /dev/null +++ b/src/Shader.cpp.hpp @@ -0,0 +1,231 @@ + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace dz { + struct ReflectedType { + uint32_t id; + std::string name; + std::string type_kind; // e.g., "float", "vec3", "mat4", "struct", "array" + uint32_t size_in_bytes = 0; // Size of the type in bytes (computed or derived) + SpvReflectTypeDescription type_desc; + SpvReflectDecorationFlags decorations; // Decorations applied to the type + uint32_t array_stride; + }; + + bool hasCanonicalStruct(const ReflectedType& type); + + uint32_t GetMinimumTypeSizeInBytes(const SpvReflectTypeDescription& type_desc); + uint32_t CalculateStructSize(const SpvReflectTypeDescription& type_desc); + bool CreateAndBindShaderBuffers(BufferGroup* buffer_group, Shader* shader); + VkShaderStageFlags GetShaderStageFromModuleType(ShaderModuleType type); + + struct ReflectedVariable { + std::string name; + uint32_t location = static_cast(-1); + uint32_t binding = static_cast(-1); + uint32_t set = static_cast(-1); + uint32_t offset = static_cast(-1); // Byte offset within its parent block/struct + uint32_t array_stride = 0; // Stride for array types (if applicable) + SpvReflectDescriptorType descriptor_type = (SpvReflectDescriptorType)-1; + ReflectedType type; + SpvReflectDecorationFlags decorations; // Decorations applied to the variable + }; + + struct ReflectedBlock { + std::string name; + uint32_t binding; + uint32_t set; + std::vector members; + ReflectedType type; // Represents the type of the block itself (e.g., UniformBufferObject) + }; + + struct ReflectedStruct { + std::string name; + uint32_t id; + SpvReflectTypeDescription type; + + std::map member_type_descs; // Maps member name (e.g., "model") to its SpvReflectTypeDescription + std::map member_offsets_map; // Maps member name to its offset within the struct + std::map member_sizes_map; // Maps member name to its reflected size + + ReflectedStruct() = default; + ReflectedStruct(std::string n, uint32_t i, SpvReflectTypeDescription td) : name(std::move(n)), id(i), type(td) { + uint32_t offset = 0; + for (uint32_t j = 0; j < type.member_count; ++j) { + auto type_desc = type.members[j]; + auto name = type_desc.struct_member_name ? type_desc.struct_member_name : type_desc.type_name; + if (name) { + auto size = GetMinimumTypeSizeInBytes(type_desc); + member_type_descs[name] = type_desc; + member_offsets_map[name] = offset; + member_sizes_map[name] = size; + offset += size; + } + } + } + }; + + ReflectedStructView::ReflectedStructView(uint8_t* base_ptr, const ReflectedStruct& struct_def) + : m_base_ptr(base_ptr), m_struct_def(struct_def) { + if (!m_base_ptr) { + throw std::runtime_error("ReflectedStructView: Base pointer for element is null."); + } + if (m_struct_def.type.op != SpvOpTypeStruct) { + throw std::runtime_error("ReflectedStructView: Provided ReflectedType is not a struct."); + } + } + + void ReflectedStructView::set_member(const std::string& member_name, const void* data_ptr, size_t data_size_bytes) { + auto offset_it = m_struct_def.member_offsets_map.find(member_name); + auto size_it = m_struct_def.member_sizes_map.find(member_name); + + if (offset_it == m_struct_def.member_offsets_map.end() || + size_it == m_struct_def.member_sizes_map.end()) { + throw std::runtime_error("ReflectedStructView Error: Member '" + member_name + "' not found in struct '" + + m_struct_def.name + "'."); + } + + uint32_t member_offset = offset_it->second; + uint32_t reflected_size = size_it->second; + + if (!(reflected_size == data_size_bytes)) { + throw std::runtime_error("ReflectedSize does not match data_size (bytes)"); + } + + uint8_t* target_addr = m_base_ptr + member_offset; + size_t bytes_to_copy = std::min(data_size_bytes, (size_t)reflected_size); + + memcpy(target_addr, data_ptr, bytes_to_copy); + } + + uint8_t* ReflectedStructView::get_member(const std::string& member_name, size_t data_size_bytes) { + auto offset_it = m_struct_def.member_offsets_map.find(member_name); + auto size_it = m_struct_def.member_sizes_map.find(member_name); + + if (offset_it == m_struct_def.member_offsets_map.end() || + size_it == m_struct_def.member_sizes_map.end()) { + throw std::runtime_error("ReflectedStructView Error: Member '" + member_name + "' not found in struct '" + + m_struct_def.name + "'."); + } + + uint32_t member_offset = offset_it->second; + uint32_t reflected_size = size_it->second; + + if (!(reflected_size == data_size_bytes)) { + throw std::runtime_error("ReflectedSize does not match data_size (bytes)"); + } + + return m_base_ptr + member_offset; + } + + struct SPIRVReflection { + std::vector inputs; + std::vector outputs; + std::vector ssbos; + std::vector ubos; + std::vector push_constants; // Added for clarity + std::unordered_map structs_by_name; + std::unordered_map structs_by_id; + std::unordered_map named_types; + std::shared_ptr module_ptr = std::shared_ptr(new SpvReflectShaderModule, [](SpvReflectShaderModule* module) { + spvReflectDestroyShaderModule(module); + delete module; + }); + }; + + const ReflectedStruct& getCanonicalStruct(const SPIRVReflection& reflection, const ReflectedType& type); + + struct ShaderModule { + std::vector spirv_vec; + VkShaderModule vk_module; + ShaderModuleType type; + SPIRVReflection reflection; + }; + + struct GpuBuffer { + VkBuffer buffer = VK_NULL_HANDLE; + VkDeviceMemory memory = VK_NULL_HANDLE; + void* mapped_memory = nullptr; // Persistently mapped pointer + VkDeviceSize size = 0; + }; + + struct ShaderBuffer { + std::string name; // Name from GLSL (e.g., "ubo_scene", "particles") + uint32_t set = 0; + uint32_t binding = 0; + VkDescriptorType descriptor_type = VK_DESCRIPTOR_TYPE_MAX_ENUM; + + // Data layout from reflection + VkDeviceSize static_size = 0; // Full size for UBOs, or size of ONE element for SSBOs + uint32_t element_stride = 0; // Stride of one element in an array (for SSBOs) + bool is_dynamic_sized = false; // Is this a runtime-sized SSBO? + ReflectedType element_type; + + // Application-controlled data + uint32_t element_count = 1; // Application sets this for dynamic SSBOs + + // The smart pointer that will point to CPU data initially, then GPU mapped memory. + // The custom deleter will be empty for GPU memory, preventing crashes. + std::shared_ptr data_ptr = nullptr; + + // The final Vulkan resource + GpuBuffer gpu_buffer; + }; + + struct ShaderImage { + std::string name; + uint32_t set = 0; + uint32_t binding = 0; + std::unordered_map descriptor_types; + VkImageViewType viewType; + VkFormat format; + std::unordered_map expected_layouts; + }; + + struct PushConstant { + std::shared_ptr ptr; + uint32_t size = 0; + uint32_t offset = 0; + VkShaderStageFlags stageFlags = (VkShaderStageFlags)0; + }; + + struct Shader { + bool initialized = false; + std::map module_map; + std::map descriptor_set_layouts; + VkDescriptorPool descriptor_pool = VK_NULL_HANDLE; + std::map descriptor_sets; + std::map buffer_groups; + std::vector bound_buffer_groups; + VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; + VkPipeline graphics_pipeline = VK_NULL_HANDLE; + VkRenderPass render_pass = VK_NULL_HANDLE; + std::map define_map; + std::unordered_map push_constants_name_index; + std::map push_constants; + AssetPack* include_asset_pack = 0; + ShaderTopology topology; + VkRenderPass renderPass = VK_NULL_HANDLE; + std::unordered_map sampler_key_image_override_map; + std::unordered_map keyed_set_binding_index_map; + }; + + struct BufferGroup { + std::string group_name; + std::unordered_map buffers; + std::unordered_map images; + std::unordered_map> runtime_images; + std::unordered_map shaders; + std::unordered_map restricted_to_keys; + }; +} \ No newline at end of file diff --git a/src/Window.cpp b/src/Window.cpp index ffa5819b..c2244b9f 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -1,3 +1,5 @@ +#include "Directz.cpp.hpp" + namespace dz { WindowReflectableGroup::WindowReflectableGroup(WINDOW* window_ptr): diff --git a/src/env.cpp b/src/env.cpp index d3a88875..beb18736 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -1,3 +1,5 @@ +#include "Directz.cpp.hpp" + namespace dz { void set_env(const std::string& key, const std::string& value) { diff --git a/src/path.cpp b/src/path.cpp index 5df2a54d..0727cc73 100644 --- a/src/path.cpp +++ b/src/path.cpp @@ -1,3 +1,5 @@ + + namespace dz { std::filesystem::path getUserDirectoryPath() { return std::filesystem::path(getenv("HOME")); } #if !defined(MACOS) && !defined(IOS) diff --git a/tests/ECS.cpp b/tests/ECS.cpp index 15da4b13..192be711 100644 --- a/tests/ECS.cpp +++ b/tests/ECS.cpp @@ -613,196 +613,212 @@ int main() { ImGui::TextDisabled("GID: 0x%08X", SelectedReflectableID); ImGui::Spacing(); - auto& reflectables = reflectable_group.GetReflectables(); - - auto reflect_begin = reflectables.begin(); - auto reflect_it = reflect_begin; - auto reflect_end = reflectables.end(); - size_t reflect_dist = 0; - - auto update_iterators = [&]() { - reflect_begin = reflectables.begin(); - reflect_it = reflect_begin + reflect_dist; - reflect_end = reflectables.end(); - }; - - for (; reflect_it != reflect_end; reflect_it++) { - reflect_dist = std::distance(reflect_begin, reflect_it); - auto& reflectable = **reflect_it; - ImGui::PushID(&reflectable); - const auto& reflectable_name = reflectable.GetName(); - - if (ImGui::CollapsingHeader(reflectable_name.c_str(), ImGuiTreeNodeFlags_DefaultOpen)) - { - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6, 4)); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(12, 8)); + std::function render_reflectables; + render_reflectables = [&](auto& what_reflectable_group) { + auto& reflectables = what_reflectable_group.GetReflectables(); + + auto reflect_begin = reflectables.begin(); + auto reflect_it = reflect_begin; + auto reflect_end = reflectables.end(); + size_t reflect_dist = 0; + + auto update_iterators = [&]() { + reflect_begin = reflectables.begin(); + reflect_it = reflect_begin + reflect_dist; + reflect_end = reflectables.end(); + }; + + for (; reflect_it != reflect_end; reflect_it++) { + reflect_dist = std::distance(reflect_begin, reflect_it); + auto& reflectable = **reflect_it; + ImGui::PushID(&reflectable); + const auto& reflectable_name = reflectable.GetName(); + + if (ImGui::CollapsingHeader(reflectable_name.c_str(), ImGuiTreeNodeFlags_DefaultOpen)) + { + bool popped_style_var = false; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6, 4)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(12, 8)); - auto reflectable_type_hint = reflectable.GetTypeHint(); + auto reflectable_type_hint = reflectable.GetTypeHint(); - switch (reflectable_type_hint) { - case ReflectableTypeHint::VEC2: - { - auto data_ptr = reflectable.GetVoidPropertyByIndex(0); - if (ImGui::DragFloat2("##vec2", static_cast(data_ptr), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { - reflectable.NotifyChange(0); - update_iterators(); - } - break; - } - case ReflectableTypeHint::VEC3: - { - auto data_ptr = reflectable.GetVoidPropertyByIndex(0); - if (ImGui::DragFloat3("##vec3", static_cast(data_ptr), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { - reflectable.NotifyChange(0); - update_iterators(); + switch (reflectable_type_hint) { + case ReflectableTypeHint::VEC2: + { + auto data_ptr = reflectable.GetVoidPropertyByIndex(0); + if (ImGui::DragFloat2("##vec2", static_cast(data_ptr), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { + reflectable.NotifyChange(0); + update_iterators(); + } + break; } - break; - } - case ReflectableTypeHint::VEC3_RGB: - { - auto data_ptr = reflectable.GetVoidPropertyByIndex(0); - if (ImGui::ColorEdit3("##rgb", static_cast(data_ptr), ImGuiColorEditFlags_Float)) { - reflectable.NotifyChange(0); - update_iterators(); + case ReflectableTypeHint::VEC3: + { + auto data_ptr = reflectable.GetVoidPropertyByIndex(0); + if (ImGui::DragFloat3("##vec3", static_cast(data_ptr), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { + reflectable.NotifyChange(0); + update_iterators(); + } + break; } - break; - } - case ReflectableTypeHint::VEC4: - { - auto data_ptr = reflectable.GetVoidPropertyByIndex(0); - if (ImGui::DragFloat4("##vec4", static_cast(data_ptr), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { - reflectable.NotifyChange(0); - update_iterators(); + case ReflectableTypeHint::VEC3_RGB: + { + auto data_ptr = reflectable.GetVoidPropertyByIndex(0); + if (ImGui::ColorEdit3("##rgb", static_cast(data_ptr), ImGuiColorEditFlags_Float)) { + reflectable.NotifyChange(0); + update_iterators(); + } + break; } - break; - } - case ReflectableTypeHint::VEC4_RGBA: - { - auto data_ptr = reflectable.GetVoidPropertyByIndex(0); - if (ImGui::ColorEdit4("##rgba", static_cast(data_ptr), ImGuiColorEditFlags_Float)) { - reflectable.NotifyChange(0); - update_iterators(); + case ReflectableTypeHint::VEC4: + { + auto data_ptr = reflectable.GetVoidPropertyByIndex(0); + if (ImGui::DragFloat4("##vec4", static_cast(data_ptr), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { + reflectable.NotifyChange(0); + update_iterators(); + } + break; } - break; - } - default: - case ReflectableTypeHint::STRUCT: { - const auto& reflectable_typeinfos = reflectable.GetPropertyTypeinfos(); - const auto& reflectable_prop_names = reflectable.GetPropertyNames(); - const auto& disabled_properties = reflectable.GetDisabledProperties(); - size_t index = 0; - for (auto& prop_name : reflectable_prop_names) + case ReflectableTypeHint::VEC4_RGBA: { - ImGui::PushID(prop_name.c_str()); - auto prop_index = reflectable.GetPropertyIndexByName(prop_name); - auto type_info = reflectable_typeinfos[prop_index]; - bool is_disabled = (prop_index < disabled_properties.size()) ? disabled_properties[prop_index] : false; - - ImGui::BeginDisabled(is_disabled); - ImGui::Text("%s", prop_name.c_str()); - ImGui::SameLine(); - - if (*type_info == typeid(float)) + auto data_ptr = reflectable.GetVoidPropertyByIndex(0); + if (ImGui::ColorEdit4("##rgba", static_cast(data_ptr), ImGuiColorEditFlags_Float)) { + reflectable.NotifyChange(0); + update_iterators(); + } + break; + } + default: + case ReflectableTypeHint::STRUCT: { + const auto& reflectable_typeinfos = reflectable.GetPropertyTypeinfos(); + const auto& reflectable_prop_names = reflectable.GetPropertyNames(); + const auto& disabled_properties = reflectable.GetDisabledProperties(); + size_t index = 0; + for (auto& prop_name : reflectable_prop_names) { - auto& value = reflectable.GetPropertyByIndex(prop_index); - ImGui::PushID(prop_index); - if (ImGui::InputFloat("##input", &value, 0.1f, 1.0f, "%.3f")) { - reflectable.NotifyChange(prop_index); - update_iterators(); + ImGui::PushID(prop_name.c_str()); + auto prop_index = reflectable.GetPropertyIndexByName(prop_name); + auto type_info = reflectable_typeinfos[prop_index]; + bool is_disabled = (prop_index < disabled_properties.size()) ? disabled_properties[prop_index] : false; + + ImGui::BeginDisabled(is_disabled); + ImGui::Text("%s", prop_name.c_str()); + ImGui::SameLine(); + + if (*type_info == typeid(float)) + { + auto& value = reflectable.GetPropertyByIndex(prop_index); + ImGui::PushID(prop_index); + if (ImGui::InputFloat("##input", &value, 0.1f, 1.0f, "%.3f")) { + reflectable.NotifyChange(prop_index); + update_iterators(); + } + ImGui::PopID(); } - ImGui::PopID(); - } - else if (*type_info == typeid(int)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); - ImGui::PushID(prop_index); - if (ImGui::InputInt("##input", &value)) { - reflectable.NotifyChange(prop_index); - update_iterators(); + else if (*type_info == typeid(int)) { + auto& value = reflectable.GetPropertyByIndex(prop_index); + ImGui::PushID(prop_index); + if (ImGui::InputInt("##input", &value)) { + reflectable.NotifyChange(prop_index); + update_iterators(); + } + ImGui::PopID(); } - ImGui::PopID(); - } - else if (*type_info == typeid(Light::LightType)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); - static const char* projection_types[] = { "Directional", "Spot", "Point" }; - int current_index = static_cast(value); - if (ImGui::Combo("##lightType", ¤t_index, projection_types, IM_ARRAYSIZE(projection_types))) { - value = static_cast(current_index); - reflectable.NotifyChange(prop_index); - update_iterators(); + else if (*type_info == typeid(Light::LightType)) { + auto& value = reflectable.GetPropertyByIndex(prop_index); + static const char* projection_types[] = { "Directional", "Spot", "Point" }; + int current_index = static_cast(value); + if (ImGui::Combo("##lightType", ¤t_index, projection_types, IM_ARRAYSIZE(projection_types))) { + value = static_cast(current_index); + reflectable.NotifyChange(prop_index); + update_iterators(); + } } - } - else if (*type_info == typeid(Camera::ProjectionType)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); - static const char* projection_types[] = { "Perspective", "Orthographic" }; - int current_index = static_cast(value); - if (ImGui::Combo("##proj", ¤t_index, projection_types, IM_ARRAYSIZE(projection_types))) { - value = static_cast(current_index); - reflectable.NotifyChange(prop_index); - update_iterators(); + else if (*type_info == typeid(Camera::ProjectionType)) { + auto& value = reflectable.GetPropertyByIndex(prop_index); + static const char* projection_types[] = { "Perspective", "Orthographic" }; + int current_index = static_cast(value); + if (ImGui::Combo("##proj", ¤t_index, projection_types, IM_ARRAYSIZE(projection_types))) { + value = static_cast(current_index); + reflectable.NotifyChange(prop_index); + update_iterators(); + } } - } - else if (*type_info == typeid(std::string)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); - if (value.capacity() < 128) value.reserve(128); - ImGui::PushID(prop_index); - if (ImGui::InputText("##s", value.data(), value.capacity() + 1)) { - reflectable.NotifyChange(prop_index); - update_iterators(); + else if (*type_info == typeid(std::string)) { + auto& value = reflectable.GetPropertyByIndex(prop_index); + if (value.capacity() < 128) value.reserve(128); + ImGui::PushID(prop_index); + if (ImGui::InputText("##s", value.data(), value.capacity() + 1)) { + reflectable.NotifyChange(prop_index); + update_iterators(); + } + ImGui::PopID(); } - ImGui::PopID(); - } - else if (*type_info == typeid(vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); - if (ImGui::DragFloat2("##vec2", static_cast(&value[0]), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { - reflectable.NotifyChange(prop_index); - update_iterators(); + else if (*type_info == typeid(vec)) { + auto& value = reflectable.GetPropertyByIndex>(prop_index); + if (ImGui::DragFloat2("##vec2", static_cast(&value[0]), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { + reflectable.NotifyChange(prop_index); + update_iterators(); + } } - } - else if (*type_info == typeid(vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); - if (ImGui::DragFloat3("##vec3", static_cast(&value[0]), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { - reflectable.NotifyChange(prop_index); - update_iterators(); + else if (*type_info == typeid(vec)) { + auto& value = reflectable.GetPropertyByIndex>(prop_index); + if (ImGui::DragFloat3("##vec3", static_cast(&value[0]), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { + reflectable.NotifyChange(prop_index); + update_iterators(); + } } - } - else if (*type_info == typeid(vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); - if (ImGui::DragFloat4("##vec4", static_cast(&value[0]), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { - reflectable.NotifyChange(prop_index); - update_iterators(); + else if (*type_info == typeid(vec)) { + auto& value = reflectable.GetPropertyByIndex>(prop_index); + if (ImGui::DragFloat4("##vec4", static_cast(&value[0]), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { + reflectable.NotifyChange(prop_index); + update_iterators(); + } } - } - else if (*type_info == typeid(color_vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); - if (ImGui::ColorEdit3("##rgb", static_cast(&value[0]), ImGuiColorEditFlags_Float)) { - reflectable.NotifyChange(0); - update_iterators(); + else if (*type_info == typeid(color_vec)) { + auto& value = reflectable.GetPropertyByIndex>(prop_index); + if (ImGui::ColorEdit3("##rgb", static_cast(&value[0]), ImGuiColorEditFlags_Float)) { + reflectable.NotifyChange(0); + update_iterators(); + } } - } - else if (*type_info == typeid(color_vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); - if (ImGui::ColorEdit4("##rgba", static_cast(&value[0]), ImGuiColorEditFlags_Float)) { - reflectable.NotifyChange(0); - update_iterators(); + else if (*type_info == typeid(color_vec)) { + auto& value = reflectable.GetPropertyByIndex>(prop_index); + if (ImGui::ColorEdit4("##rgba", static_cast(&value[0]), ImGuiColorEditFlags_Float)) { + reflectable.NotifyChange(0); + update_iterators(); + } + } + else if (*type_info == typeid(MaterialIndexReflectable)) { + auto& value = reflectable.GetPropertyByIndex(prop_index); + auto& material_group = ecs.GetGroupByIndex(value.material_index); + ImGui::EndDisabled(); + ImGui::PopID(); + ImGui::PopStyleVar(2); + popped_style_var = true; + render_reflectables(material_group); + break; + } + else { + ImGui::TextDisabled(""); } - } - else { - ImGui::TextDisabled(""); - } - ImGui::EndDisabled(); - ImGui::PopID(); + ImGui::EndDisabled(); + ImGui::PopID(); + } + break; + } } - break; - } - } - ImGui::PopStyleVar(2); + if (!popped_style_var) + ImGui::PopStyleVar(2); + } + + ImGui::PopID(); } - - ImGui::PopID(); - } + }; + render_reflectables(reflectable_group); ImGui::PopID(); } From d4335aed90c3ccfc2d125cf79c680b2d818c19c4 Mon Sep 17 00:00:00 2001 From: Steven French Date: Sun, 3 Aug 2025 08:17:29 +1200 Subject: [PATCH 2/5] fix a variety of LSP issues Change-Id: Ibf5b416af9470e713c6a3e23e2f90f274ea251e8 --- include/dz/Shader.hpp | 2 +- include/dz/Util.hpp | 7 + src/Directz.cpp.hpp | 50 ++++- src/Reflectable.cpp | 2 + src/Renderer.cpp | 35 +--- src/RendererImpl.hpp | 84 +++++---- src/Shader.cpp | 2 + src/State.cpp | 1 + src/Window.cpp | 21 +-- src/Window.mm | 4 +- src/WindowImpl.hpp | 424 +++++++++++++++++++++--------------------- src/runtime.cpp | 3 +- 12 files changed, 329 insertions(+), 306 deletions(-) diff --git a/include/dz/Shader.hpp b/include/dz/Shader.hpp index bab127fc..61626ab7 100644 --- a/include/dz/Shader.hpp +++ b/include/dz/Shader.hpp @@ -11,6 +11,7 @@ namespace dz { + struct Renderer; enum class ShaderModuleType { Vertex = 1, /**< Vertex shader module. */ @@ -28,7 +29,6 @@ namespace dz TriangleFan = 5 }; - struct Renderer; struct Shader; struct Framebuffer; diff --git a/include/dz/Util.hpp b/include/dz/Util.hpp index 1ed10a2f..dd971ca0 100644 --- a/include/dz/Util.hpp +++ b/include/dz/Util.hpp @@ -1,6 +1,8 @@ #pragma once #include #include +#include + namespace dz { inline static std::string to_lower(const std::string& str) { std::string nstr(str.size(), 0); @@ -10,4 +12,9 @@ namespace dz { } return nstr; } + + inline static std::wstring string_to_wstring(const std::string& str) { + static std::wstring_convert> converter = {}; + return converter.from_bytes(str); + } } \ No newline at end of file diff --git a/src/Directz.cpp.hpp b/src/Directz.cpp.hpp index 987ee38e..187a04b0 100644 --- a/src/Directz.cpp.hpp +++ b/src/Directz.cpp.hpp @@ -1,6 +1,5 @@ #pragma once -#include -using namespace dz; +#include #include #include #include @@ -40,14 +39,17 @@ using namespace dz; #endif #undef min #undef max +#include "WindowImpl.hpp" +#include "RendererImpl.hpp" namespace dz { - #include "WindowImpl.hpp" - #include "RendererImpl.hpp" /** * @brief Creates a Window given a Serial interface */ WINDOW* window_create_from_serial(Serial& serial); + DirectRegistry* make_direct_registry(); + void free_direct_registry(); + void set_env(const std::string& key, const std::string& value); std::string get_env(const std::string& key); void append_vk_icd_filename(const std::string& swiftshader_icd_path); @@ -144,11 +146,47 @@ namespace dz void buffer_group_make_gpu_buffer(const std::string& name, ShaderBuffer& buffer); std::vector::iterator dr_get_windows_begin(); std::vector::iterator dr_get_windows_end(); - std::vector::iterator dr_get_window_reflectable_entries_begin(); - std::vector::iterator dr_get_window_reflectable_entries_end(); bool vk_check(const char* fn, VkResult result); void vk_log(const char* fn, VkResult result); bool recreate_swap_chain(Renderer* renderer); + + struct QueueFamilyIndices + { + int32_t graphicsAndComputeFamily = -1; + int32_t presentFamily = -1; + bool isComplete() { return graphicsAndComputeFamily > -1 && presentFamily > -1; }; + }; + struct SwapChainSupportDetails + { + VkSurfaceCapabilitiesKHR capabilities; + std::vector formats; + std::vector presentModes; + }; + + VkSampleCountFlagBits get_max_usable_sample_count(DirectRegistry* direct_registry, Renderer* renderer); + void direct_registry_ensure_physical_device(DirectRegistry* direct_registry, Renderer* renderer); + uint32_t rate_device_suitability(DirectRegistry* direct_registry, Renderer* renderer, VkPhysicalDevice device); + bool is_device_suitable(DirectRegistry* direct_registry, Renderer* renderer, VkPhysicalDevice device); + QueueFamilyIndices find_queue_families(DirectRegistry* direct_registry, Renderer* renderer, VkPhysicalDevice device); + void direct_registry_ensure_logical_device(DirectRegistry* direct_registry, Renderer* renderer); + SwapChainSupportDetails query_swap_chain_support(Renderer* renderer, VkPhysicalDevice device); + VkSurfaceFormatKHR choose_swap_surface_format(const std::vector& availableFormats); + VkPresentModeKHR choose_swap_present_mode(Renderer* renderer, const std::vector& availablePresentModes); + VkExtent2D choose_swap_extent(Renderer* renderer, VkSurfaceCapabilitiesKHR capabilities); + void ensure_command_pool(Renderer* renderer); + void ensure_command_buffers(Renderer* renderer); + void ensure_render_pass(Renderer* renderer); + void create_sync_objects(Renderer* renderer); + void pre_begin_render_pass(Renderer* renderer); + void begin_render_pass(Renderer* renderer); + void post_render_pass(Renderer* renderer); + bool swap_buffers(Renderer* renderer); + void renderer_draw_commands(Renderer* renderer, Shader* shader, const std::vector& commands); + void renderer_destroy(Renderer* renderer); + void destroy_swap_chain(Renderer* renderer); + void createBuffer(Renderer* renderer, + VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, + VkBuffer& buffer, VkDeviceMemory& bufferMemory); } extern "C" DirectRegistry* dr_ptr; extern "C" DirectRegistry& dr; \ No newline at end of file diff --git a/src/Reflectable.cpp b/src/Reflectable.cpp index bcf7a80e..557c46f6 100644 --- a/src/Reflectable.cpp +++ b/src/Reflectable.cpp @@ -1,4 +1,6 @@ #include +#include +#include bool BackupGroupVector(Serial& serial, const std::vector>& group_vector) { auto group_vector_size = group_vector.size(); diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 62e21318..70d3dbfa 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -1,18 +1,7 @@ #include "RendererImpl.hpp" +#include "Directz.cpp.hpp" namespace dz { - struct QueueFamilyIndices - { - int32_t graphicsAndComputeFamily = -1; - int32_t presentFamily = -1; - bool isComplete() { return graphicsAndComputeFamily > -1 && presentFamily > -1; }; - }; - struct SwapChainSupportDetails - { - VkSurfaceCapabilitiesKHR capabilities; - std::vector formats; - std::vector presentModes; - }; #ifndef NDEBUG bool check_validation_layers_support(); VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback( @@ -23,27 +12,6 @@ namespace dz { ); void populate_debug_messenger_create_info(VkDebugUtilsMessengerCreateInfoEXT& createInfo); #endif - VkSampleCountFlagBits get_max_usable_sample_count(DirectRegistry* direct_registry, Renderer* renderer); - void direct_registry_ensure_physical_device(DirectRegistry* direct_registry, Renderer* renderer); - uint32_t rate_device_suitability(DirectRegistry* direct_registry, Renderer* renderer, VkPhysicalDevice device); - bool is_device_suitable(DirectRegistry* direct_registry, Renderer* renderer, VkPhysicalDevice device); - QueueFamilyIndices find_queue_families(DirectRegistry* direct_registry, Renderer* renderer, VkPhysicalDevice device); - void direct_registry_ensure_logical_device(DirectRegistry* direct_registry, Renderer* renderer); - SwapChainSupportDetails query_swap_chain_support(Renderer* renderer, VkPhysicalDevice device); - VkSurfaceFormatKHR choose_swap_surface_format(const std::vector& availableFormats); - VkPresentModeKHR choose_swap_present_mode(Renderer* renderer, const std::vector& availablePresentModes); - VkExtent2D choose_swap_extent(Renderer* renderer, VkSurfaceCapabilitiesKHR capabilities); - void ensure_command_pool(Renderer* renderer); - void ensure_command_buffers(Renderer* renderer); - void ensure_render_pass(Renderer* renderer); - void create_sync_objects(Renderer* renderer); - void pre_begin_render_pass(Renderer* renderer); - void begin_render_pass(Renderer* renderer); - void post_render_pass(Renderer* renderer); - bool swap_buffers(Renderer* renderer); - void renderer_draw_commands(Renderer* renderer, Shader* shader, const std::vector& commands); - void renderer_destroy(Renderer* renderer); - void destroy_swap_chain(Renderer* renderer); Renderer* renderer_init(WINDOW* window) { auto renderer = new Renderer{ @@ -1085,7 +1053,6 @@ namespace dz { throw std::runtime_error("failed to find suitable memory type!"); } - void createBuffer(Renderer* renderer, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) diff --git a/src/RendererImpl.hpp b/src/RendererImpl.hpp index c2868f91..7e77215a 100644 --- a/src/RendererImpl.hpp +++ b/src/RendererImpl.hpp @@ -1,42 +1,48 @@ #pragma once + +#include "Directz.cpp.hpp" + #define MAX_FRAMES_IN_FLIGHT 4 -struct Renderer -{ - WINDOW* window = 0; - VkDebugUtilsMessengerEXT debugMessenger; - VkSurfaceKHR surface; - VkRenderPass renderPass = VK_NULL_HANDLE; - VkSwapchainKHR swapChain; - VkSwapchainKHR swapChains[1]; - int imageCount = MAX_FRAMES_IN_FLIGHT; - std::vector swapChainImages; - std::vector swapChainImageViews; - std::vector swapChainFramebuffers; - VkExtent2D swapChainExtent; - std::vector imageAvailableSemaphores; - std::vector renderFinishedSemaphores; - std::vector inFlightFences; - std::vector commandBuffers; - uint32_t currentFrame = 0; - uint32_t imageIndex = 0; - VkCommandBufferBeginInfo beginInfo; - VkSubmitInfo submitInfo; - VkPresentInfoKHR presentInfo; - VkPipelineStageFlags waitStages[1]; - VkSemaphore signalSemaphores[1]; - std::map> drawBuffers; - std::map> countBuffers; - VkSurfaceTransformFlagBitsKHR currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - std::vector vec_draw_information; - std::vector>> screen_draw_lists; - std::vector>> fb_draw_lists; -#ifdef __ANDROID__ - bool supportsIndirectCount = false; -#else - bool supportsIndirectCount = true; -#endif - // PFN_vkCreateDebugUtilsMessengerEXT _vkCreateDebugUtilsMessengerEXT; - void destroy_surface(); - void cleanup_swapchain(); -}; \ No newline at end of file +namespace dz { + struct Renderer + { + WINDOW* window = 0; + VkDebugUtilsMessengerEXT debugMessenger; + VkSurfaceKHR surface; + VkRenderPass renderPass = VK_NULL_HANDLE; + VkSwapchainKHR swapChain; + VkSwapchainKHR swapChains[1]; + int imageCount = MAX_FRAMES_IN_FLIGHT; + std::vector swapChainImages; + std::vector swapChainImageViews; + std::vector swapChainFramebuffers; + VkExtent2D swapChainExtent; + std::vector imageAvailableSemaphores; + std::vector renderFinishedSemaphores; + std::vector inFlightFences; + std::vector commandBuffers; + uint32_t currentFrame = 0; + uint32_t imageIndex = 0; + VkCommandBufferBeginInfo beginInfo; + VkSubmitInfo submitInfo; + VkPresentInfoKHR presentInfo; + VkPipelineStageFlags waitStages[1]; + VkSemaphore signalSemaphores[1]; + std::map> drawBuffers; + std::map> countBuffers; + VkSurfaceTransformFlagBitsKHR currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + + std::vector vec_draw_information; + std::vector>> screen_draw_lists; + std::vector>> fb_draw_lists; + #ifdef __ANDROID__ + bool supportsIndirectCount = false; + #else + bool supportsIndirectCount = true; + #endif + // PFN_vkCreateDebugUtilsMessengerEXT _vkCreateDebugUtilsMessengerEXT; + void destroy_surface(); + void cleanup_swapchain(); + }; +} \ No newline at end of file diff --git a/src/Shader.cpp b/src/Shader.cpp index 3600f059..38c83839 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -12,6 +12,8 @@ #include "Directz.cpp.hpp" #include "Shader.cpp.hpp" #include "Framebuffer.cpp.hpp" +#include "Image.cpp.hpp" +#include namespace dz { diff --git a/src/State.cpp b/src/State.cpp index 50ca53eb..3102d8ba 100644 --- a/src/State.cpp +++ b/src/State.cpp @@ -1,5 +1,6 @@ #include #include +#include "Directz.cpp.hpp" void dz::track_static_state( int sid, diff --git a/src/Window.cpp b/src/Window.cpp index c2244b9f..915b36f9 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -125,13 +125,12 @@ namespace dz { if (dr.window_ptrs.size() == 1) { ImGuiViewport* main_viewport = ImGui::GetMainViewport(); - main_viewport->PlatformUserData = main_viewport->PlatformHandleRaw = window_get_native_handle(window); + main_viewport->PlatformHandleRaw = window_get_native_handle(window); main_viewport->PlatformHandle = window; main_viewport->Pos.x = window->x; main_viewport->Pos.y = window->y; main_viewport->Size.x = width; main_viewport->Size.y = height; - main_viewport->PlatformWindowCreated = false; window->imguiViewport = main_viewport; #ifdef _WIN32 dr.hwnd_root = window->hwnd; @@ -188,9 +187,6 @@ namespace dz { auto& vp = *window->imguiViewport; vp.PlatformHandle = nullptr; vp.PlatformHandleRaw = nullptr; - if (!destroy_remaining) - vp.RendererUserData = nullptr; - vp.PlatformUserData = nullptr; } window->destroy_platform(); auto& event_interface = *window->event_interface; @@ -435,15 +431,16 @@ namespace dz { setDPIAware = true; } hInstance = GetModuleHandle(NULL); - WNDCLASSEX wc = {0}; + WNDCLASSEXW wc = {0}; // wc.cbSize = sizeof(WNDCLASS); - wc.cbSize = sizeof(WNDCLASSEX); + wc.cbSize = sizeof(WNDCLASSEXW); wc.style = CS_VREDRAW | CS_HREDRAW; wc.lpfnWndProc = wndproc; wc.hInstance = hInstance; - wc.lpszClassName = title.c_str(); + auto wtitle = string_to_wstring(title); + wc.lpszClassName = wtitle.c_str(); wc.hCursor = LoadCursor(NULL, IDC_ARROW); - RegisterClassEx(&wc); + RegisterClassExW(&wc); dpiScale = 1.0f; HDC screen = GetDC(NULL); int32_t dpi = GetDeviceCaps(screen, LOGPIXELSX); @@ -456,10 +453,10 @@ namespace dz { AdjustWindowRectEx(&desiredRect, wsStyle, FALSE, exStyle); adjustedWidth = desiredRect.right - desiredRect.left; adjustedHeight = desiredRect.bottom - desiredRect.top; - hwnd = CreateWindowEx( + hwnd = CreateWindowExW( exStyle, - title.c_str(), - title.c_str(), + wtitle.c_str(), + wtitle.c_str(), wsStyle, x == -1 ? CW_USEDEFAULT : x, y == -1 ? CW_USEDEFAULT : y, diff --git a/src/Window.mm b/src/Window.mm index 35e9149a..6c137af0 100644 --- a/src/Window.mm +++ b/src/Window.mm @@ -16,10 +16,10 @@ #import #import #endif +#include "WindowImpl.hpp" +#include "RendererImpl.hpp" namespace dz { - #include "WindowImpl.hpp" - #include "RendererImpl.hpp" void create_surface(Renderer* renderer) { auto& window = *renderer->window; diff --git a/src/WindowImpl.hpp b/src/WindowImpl.hpp index 0a223f0c..fcbfbffd 100644 --- a/src/WindowImpl.hpp +++ b/src/WindowImpl.hpp @@ -1,227 +1,229 @@ #pragma once #include #include -struct WINDOW : Restorable -{ - std::string title; - float x; - float y; - bool borderless; - bool vsync; - WINDOW( - const std::string& title, - float x, float y, - bool borderless, bool vsync, - float _width, float _height -#ifdef ANDROID - , ANativeWindow* android_window, AAssetManager* android_asset_manager -#endif - ): - title(title), - x(x), - y(y), - borderless(borderless), - vsync(vsync), - width(std::shared_ptr(zmalloc(1, _width), [](float* fp) { zfree(fp, 1); })), - height(std::shared_ptr(zmalloc(1, _height), [](float* fp) { zfree(fp, 1); })) -#ifdef ANDROID - , android_window(android_window), android_asset_manager(android_asset_manager) -#endif - {}; +namespace dz { + struct WINDOW : Restorable + { + std::string title; + float x; + float y; + bool borderless; + bool vsync; + WINDOW( + const std::string& title, + float x, float y, + bool borderless, bool vsync, + float _width, float _height + #ifdef ANDROID + , ANativeWindow* android_window, AAssetManager* android_asset_manager + #endif + ): + title(title), + x(x), + y(y), + borderless(borderless), + vsync(vsync), + width(std::shared_ptr(zmalloc(1, _width), [](float* fp) { zfree(fp, 1); })), + height(std::shared_ptr(zmalloc(1, _height), [](float* fp) { zfree(fp, 1); })) + #ifdef ANDROID + , android_window(android_window), android_asset_manager(android_asset_manager) + #endif + {}; - WINDOW(Serial& serial) { - restore(serial); - } + WINDOW(Serial& serial) { + restore(serial); + } - inline static int CID = CID_WINDOW; - int getCID() override { return CID; } + inline static int CID = CID_WINDOW; + int getCID() override { return CID; } - bool backup(Serial& serial) override { - serial << title << x << y << borderless << vsync << *width << *height; - return true; - } + bool backup(Serial& serial) override { + serial << title << x << y << borderless << vsync << *width << *height; + return true; + } - bool restore(Serial& serial) override { - serial >> title >> x >> y >> borderless >> vsync; - float _width, _height; - serial >> _width >> _height; - width = std::shared_ptr(zmalloc(1, _width), [](float* fp) { zfree(fp, 1); }); - height = std::shared_ptr(zmalloc(1, _height), [](float* fp) { zfree(fp, 1); }); - return true; - } + bool restore(Serial& serial) override { + serial >> title >> x >> y >> borderless >> vsync; + float _width, _height; + serial >> _width >> _height; + width = std::shared_ptr(zmalloc(1, _width), [](float* fp) { zfree(fp, 1); }); + height = std::shared_ptr(zmalloc(1, _height), [](float* fp) { zfree(fp, 1); }); + return true; + } - std::shared_ptr width; - std::shared_ptr height; - std::chrono::time_point lastFrame; - std::shared_ptr float_frametime; - std::shared_ptr double_frametime; - std::shared_ptr keys; - std::shared_ptr buttons; - std::shared_ptr cursor; - std::shared_ptr mod; - std::shared_ptr focused; - bool minimized = false; - bool closed = false; - bool close_requested = false; - VkViewport viewport = {}; - VkRect2D scissor = {}; - Renderer* renderer = 0; - std::map> draw_list_managers; - EventInterface* event_interface = 0; - bool capture = false; - bool drag_in_progress = false; - ImGuiViewport* imguiViewport = 0; - std::map>> priority_shader_dispatches; -#ifdef _WIN32 - HINSTANCE hInstance; - HWND hwnd; - // HDC hDeviceContext; - HGLRC hRenderingContext; - bool setDPIAware = false; - float dpiScale; -#elif defined(__linux__) && !defined(__ANDROID__) - Display* display = nullptr; - Window window = 0; - Window root = 0; - Atom wm_protocols = 0; - Atom wm_delete_window = 0; - Atom atom_net_wm_state = 0; - Atom atom_net_wm_state_hidden = 0; - Atom atom_net_wm_state_maximized_horz = 0; - Atom atom_net_wm_state_maximized_vert = 0; - int screenNumber = 0; - uint32_t originalDelay = 0; - uint32_t originalInterval = 0; - void initAtoms(); -#elif defined(__ANDROID__) - ANativeWindow* android_window = 0; - AAssetManager* android_asset_manager = 0; -#elif defined(MACOS) || defined(IOS) - void *nsWindow = 0; - void *nsView; - void *metalView = 0; -#endif - void create_platform(); - void post_init_platform(); - bool poll_events_platform(); - void destroy_platform(); -#ifdef __ANDROID__ - void recreate_android(ANativeWindow* android_window, float width, float height); -#endif + std::shared_ptr width; + std::shared_ptr height; + std::chrono::time_point lastFrame; + std::shared_ptr float_frametime; + std::shared_ptr double_frametime; + std::shared_ptr keys; + std::shared_ptr buttons; + std::shared_ptr cursor; + std::shared_ptr mod; + std::shared_ptr focused; + bool minimized = false; + bool closed = false; + bool close_requested = false; + VkViewport viewport = {}; + VkRect2D scissor = {}; + Renderer* renderer = 0; + std::map> draw_list_managers; + EventInterface* event_interface = 0; + bool capture = false; + bool drag_in_progress = false; + ImGuiViewport* imguiViewport = 0; + std::map>> priority_shader_dispatches; + #ifdef _WIN32 + HINSTANCE hInstance; + HWND hwnd; + // HDC hDeviceContext; + HGLRC hRenderingContext; + bool setDPIAware = false; + float dpiScale; + #elif defined(__linux__) && !defined(__ANDROID__) + Display* display = nullptr; + Window window = 0; + Window root = 0; + Atom wm_protocols = 0; + Atom wm_delete_window = 0; + Atom atom_net_wm_state = 0; + Atom atom_net_wm_state_hidden = 0; + Atom atom_net_wm_state_maximized_horz = 0; + Atom atom_net_wm_state_maximized_vert = 0; + int screenNumber = 0; + uint32_t originalDelay = 0; + uint32_t originalInterval = 0; + void initAtoms(); + #elif defined(__ANDROID__) + ANativeWindow* android_window = 0; + AAssetManager* android_asset_manager = 0; + #elif defined(MACOS) || defined(IOS) + void *nsWindow = 0; + void *nsView; + void *metalView = 0; + #endif + void create_platform(); + void post_init_platform(); + bool poll_events_platform(); + void destroy_platform(); + #ifdef __ANDROID__ + void recreate_android(ANativeWindow* android_window, float width, float height); + #endif - size_t id = GlobalUID::GetNew("Window"); -}; -inline static constexpr uint8_t WINDOW_TYPE_WIN32 = 1; -inline static constexpr uint8_t WINDOW_TYPE_MACOS = 2; -inline static constexpr uint8_t WINDOW_TYPE_X11 = 4; -inline static constexpr uint8_t WINDOW_TYPE_XCB = 8; -inline static constexpr uint8_t WINDOW_TYPE_WAYLAND = 16; -inline static constexpr uint8_t WINDOW_TYPE_ANDROID = 32; -inline static constexpr uint8_t WINDOW_TYPE_IOS = 64; -static const KEYCODES WIN_MAP_KEYCODES[] = { - KEYCODES::NUL, - KEYCODES::ESCAPE, - KEYCODES::_1, KEYCODES::_2, KEYCODES::_3, - KEYCODES::_4, KEYCODES::_5, KEYCODES::_6, - KEYCODES::_7, KEYCODES::_8, KEYCODES::_9, - KEYCODES::_0, - KEYCODES::MINUS, KEYCODES::EQUAL, KEYCODES::BACKSPACE, - KEYCODES::TAB, - KEYCODES::Q, KEYCODES::W, KEYCODES::E, KEYCODES::R, KEYCODES::T, KEYCODES::Y, KEYCODES::U, KEYCODES::I, KEYCODES::O, KEYCODES::P, - KEYCODES::LEFTBRACKET, KEYCODES::RIGHTBRACKET, KEYCODES::ENTER, KEYCODES::CTRL, - KEYCODES::A, KEYCODES::S, KEYCODES::D, KEYCODES::F, KEYCODES::G, KEYCODES::H, KEYCODES::J, KEYCODES::K, KEYCODES::L, - KEYCODES::SEMICOLON, KEYCODES::SINGLEQUOTE, KEYCODES::GRAVEACCENT, KEYCODES::SHIFT, KEYCODES::BACKSLASH, - KEYCODES::Z, KEYCODES::X, KEYCODES::C, KEYCODES::V, KEYCODES::B, KEYCODES::N, KEYCODES::M, KEYCODES::COMMA, KEYCODES::PERIOD, KEYCODES::SLASH, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::SPACE, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::HOME, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::END, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::UP, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::LEFT, KEYCODES::NUL, KEYCODES::RIGHT, KEYCODES::NUL, KEYCODES::NUL, - KEYCODES::DOWN, KEYCODES::NUL, KEYCODES::CTRL, KEYCODES::Delete}; + size_t id = GlobalUID::GetNew("Window"); + }; + inline static constexpr uint8_t WINDOW_TYPE_WIN32 = 1; + inline static constexpr uint8_t WINDOW_TYPE_MACOS = 2; + inline static constexpr uint8_t WINDOW_TYPE_X11 = 4; + inline static constexpr uint8_t WINDOW_TYPE_XCB = 8; + inline static constexpr uint8_t WINDOW_TYPE_WAYLAND = 16; + inline static constexpr uint8_t WINDOW_TYPE_ANDROID = 32; + inline static constexpr uint8_t WINDOW_TYPE_IOS = 64; + static const KEYCODES WIN_MAP_KEYCODES[] = { + KEYCODES::NUL, + KEYCODES::ESCAPE, + KEYCODES::_1, KEYCODES::_2, KEYCODES::_3, + KEYCODES::_4, KEYCODES::_5, KEYCODES::_6, + KEYCODES::_7, KEYCODES::_8, KEYCODES::_9, + KEYCODES::_0, + KEYCODES::MINUS, KEYCODES::EQUAL, KEYCODES::BACKSPACE, + KEYCODES::TAB, + KEYCODES::Q, KEYCODES::W, KEYCODES::E, KEYCODES::R, KEYCODES::T, KEYCODES::Y, KEYCODES::U, KEYCODES::I, KEYCODES::O, KEYCODES::P, + KEYCODES::LEFTBRACKET, KEYCODES::RIGHTBRACKET, KEYCODES::ENTER, KEYCODES::CTRL, + KEYCODES::A, KEYCODES::S, KEYCODES::D, KEYCODES::F, KEYCODES::G, KEYCODES::H, KEYCODES::J, KEYCODES::K, KEYCODES::L, + KEYCODES::SEMICOLON, KEYCODES::SINGLEQUOTE, KEYCODES::GRAVEACCENT, KEYCODES::SHIFT, KEYCODES::BACKSLASH, + KEYCODES::Z, KEYCODES::X, KEYCODES::C, KEYCODES::V, KEYCODES::B, KEYCODES::N, KEYCODES::M, KEYCODES::COMMA, KEYCODES::PERIOD, KEYCODES::SLASH, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::SPACE, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::HOME, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::END, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::UP, KEYCODES::NUL, KEYCODES::NUL, KEYCODES::LEFT, KEYCODES::NUL, KEYCODES::RIGHT, KEYCODES::NUL, KEYCODES::NUL, + KEYCODES::DOWN, KEYCODES::NUL, KEYCODES::CTRL, KEYCODES::Delete}; -struct WindowMetaReflectable : Reflectable { + struct WindowMetaReflectable : Reflectable { -private: - WINDOW* window_ptr; - int uid; - std::string name; - inline static std::unordered_map> prop_name_indexes = { - {"title", {0, 0}} - }; - inline static std::unordered_map prop_index_names = { - {0, "title"} - }; - inline static std::vector prop_names = { - "title" - }; - inline static const std::vector typeinfos = { - &typeid(std::string) + private: + WINDOW* window_ptr; + int uid; + std::string name; + inline static std::unordered_map> prop_name_indexes = { + {"title", {0, 0}} + }; + inline static std::unordered_map prop_index_names = { + {0, "title"} + }; + inline static std::vector prop_names = { + "title" + }; + inline static const std::vector typeinfos = { + &typeid(std::string) + }; + + public: + WindowMetaReflectable(WINDOW* window_ptr); + int GetID() override; + std::string& GetName() override; + DEF_GET_PROPERTY_INDEX_BY_NAME(prop_name_indexes); + DEF_GET_PROPERTY_NAMES(prop_names); + void* GetVoidPropertyByIndex(int prop_index) override; + DEF_GET_VOID_PROPERTY_BY_NAME; + DEF_GET_PROPERTY_TYPEINFOS(typeinfos); + void NotifyChange(int prop_index) override; }; -public: - WindowMetaReflectable(WINDOW* window_ptr); - int GetID() override; - std::string& GetName() override; - DEF_GET_PROPERTY_INDEX_BY_NAME(prop_name_indexes); - DEF_GET_PROPERTY_NAMES(prop_names); - void* GetVoidPropertyByIndex(int prop_index) override; - DEF_GET_VOID_PROPERTY_BY_NAME; - DEF_GET_PROPERTY_TYPEINFOS(typeinfos); - void NotifyChange(int prop_index) override; -}; + struct WindowViewportReflectable : Reflectable { -struct WindowViewportReflectable : Reflectable { + private: + WINDOW* window_ptr; + int uid; + std::string name; + inline static std::unordered_map> prop_name_indexes = { + {"x", {0, 0}}, + {"y", {1, 0}}, + {"width", {2, 0}}, + {"height", {3, 0}} + }; + inline static std::unordered_map prop_index_names = { + {0, "x"}, + {1, "y"}, + {2, "width"}, + {3, "height"} + }; + inline static std::vector prop_names = { + "x", + "y", + "width", + "height" + }; + inline static const std::vector typeinfos = { + &typeid(float), + &typeid(float), + &typeid(float), + &typeid(float) + }; + inline static const std::vector& disabled_properties = { + true, + true, + true, + true + }; -private: - WINDOW* window_ptr; - int uid; - std::string name; - inline static std::unordered_map> prop_name_indexes = { - {"x", {0, 0}}, - {"y", {1, 0}}, - {"width", {2, 0}}, - {"height", {3, 0}} + public: + WindowViewportReflectable(WINDOW* window_ptr); + int GetID() override; + std::string& GetName() override; + DEF_GET_PROPERTY_INDEX_BY_NAME(prop_name_indexes); + DEF_GET_PROPERTY_NAMES(prop_names); + void* GetVoidPropertyByIndex(int prop_index) override; + DEF_GET_VOID_PROPERTY_BY_NAME; + DEF_GET_PROPERTY_TYPEINFOS(typeinfos); + DEF_GET_DISABLED_PROPERTIES(disabled_properties); }; - inline static std::unordered_map prop_index_names = { - {0, "x"}, - {1, "y"}, - {2, "width"}, - {3, "height"} - }; - inline static std::vector prop_names = { - "x", - "y", - "width", - "height" - }; - inline static const std::vector typeinfos = { - &typeid(float), - &typeid(float), - &typeid(float), - &typeid(float) - }; - inline static const std::vector& disabled_properties = { - true, - true, - true, - true - }; - -public: - WindowViewportReflectable(WINDOW* window_ptr); - int GetID() override; - std::string& GetName() override; - DEF_GET_PROPERTY_INDEX_BY_NAME(prop_name_indexes); - DEF_GET_PROPERTY_NAMES(prop_names); - void* GetVoidPropertyByIndex(int prop_index) override; - DEF_GET_VOID_PROPERTY_BY_NAME; - DEF_GET_PROPERTY_TYPEINFOS(typeinfos); - DEF_GET_DISABLED_PROPERTIES(disabled_properties); -}; \ No newline at end of file +} \ No newline at end of file diff --git a/src/runtime.cpp b/src/runtime.cpp index a3d320ef..0a03acb2 100644 --- a/src/runtime.cpp +++ b/src/runtime.cpp @@ -1,3 +1,4 @@ #include -DirectRegistry* dr_ptr = make_direct_registry(); +#include "Directz.cpp.hpp" +DirectRegistry* dr_ptr = dz::make_direct_registry(); DirectRegistry& dr = *dr_ptr; From 583825a65292d1194266fb7b1104766225065184 Mon Sep 17 00:00:00 2001 From: Steven French Date: Sun, 3 Aug 2025 08:19:34 +1200 Subject: [PATCH 3/5] [ECS-Test] fix template errors Change-Id: Iec2f5f7165d0c63ce1d10c6a36954e2ddc568ba3 --- tests/ECS.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/ECS.cpp b/tests/ECS.cpp index 192be711..f06455cb 100644 --- a/tests/ECS.cpp +++ b/tests/ECS.cpp @@ -707,7 +707,7 @@ int main() { if (*type_info == typeid(float)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); + auto& value = reflectable.template GetPropertyByIndex(prop_index); ImGui::PushID(prop_index); if (ImGui::InputFloat("##input", &value, 0.1f, 1.0f, "%.3f")) { reflectable.NotifyChange(prop_index); @@ -716,7 +716,7 @@ int main() { ImGui::PopID(); } else if (*type_info == typeid(int)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); + auto& value = reflectable.template GetPropertyByIndex(prop_index); ImGui::PushID(prop_index); if (ImGui::InputInt("##input", &value)) { reflectable.NotifyChange(prop_index); @@ -725,7 +725,7 @@ int main() { ImGui::PopID(); } else if (*type_info == typeid(Light::LightType)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); + auto& value = reflectable.template GetPropertyByIndex(prop_index); static const char* projection_types[] = { "Directional", "Spot", "Point" }; int current_index = static_cast(value); if (ImGui::Combo("##lightType", ¤t_index, projection_types, IM_ARRAYSIZE(projection_types))) { @@ -735,7 +735,7 @@ int main() { } } else if (*type_info == typeid(Camera::ProjectionType)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); + auto& value = reflectable.template GetPropertyByIndex(prop_index); static const char* projection_types[] = { "Perspective", "Orthographic" }; int current_index = static_cast(value); if (ImGui::Combo("##proj", ¤t_index, projection_types, IM_ARRAYSIZE(projection_types))) { @@ -745,7 +745,7 @@ int main() { } } else if (*type_info == typeid(std::string)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); + auto& value = reflectable.template GetPropertyByIndex(prop_index); if (value.capacity() < 128) value.reserve(128); ImGui::PushID(prop_index); if (ImGui::InputText("##s", value.data(), value.capacity() + 1)) { @@ -755,42 +755,42 @@ int main() { ImGui::PopID(); } else if (*type_info == typeid(vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); + auto& value = reflectable.template GetPropertyByIndex>(prop_index); if (ImGui::DragFloat2("##vec2", static_cast(&value[0]), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { reflectable.NotifyChange(prop_index); update_iterators(); } } else if (*type_info == typeid(vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); + auto& value = reflectable.template GetPropertyByIndex>(prop_index); if (ImGui::DragFloat3("##vec3", static_cast(&value[0]), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { reflectable.NotifyChange(prop_index); update_iterators(); } } else if (*type_info == typeid(vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); + auto& value = reflectable.template GetPropertyByIndex>(prop_index); if (ImGui::DragFloat4("##vec4", static_cast(&value[0]), 0.01f, -1000.0f, 1000.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp)) { reflectable.NotifyChange(prop_index); update_iterators(); } } else if (*type_info == typeid(color_vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); + auto& value = reflectable.template GetPropertyByIndex>(prop_index); if (ImGui::ColorEdit3("##rgb", static_cast(&value[0]), ImGuiColorEditFlags_Float)) { reflectable.NotifyChange(0); update_iterators(); } } else if (*type_info == typeid(color_vec)) { - auto& value = reflectable.GetPropertyByIndex>(prop_index); + auto& value = reflectable.template GetPropertyByIndex>(prop_index); if (ImGui::ColorEdit4("##rgba", static_cast(&value[0]), ImGuiColorEditFlags_Float)) { reflectable.NotifyChange(0); update_iterators(); } } else if (*type_info == typeid(MaterialIndexReflectable)) { - auto& value = reflectable.GetPropertyByIndex(prop_index); + auto& value = reflectable.template GetPropertyByIndex(prop_index); auto& material_group = ecs.GetGroupByIndex(value.material_index); ImGui::EndDisabled(); ImGui::PopID(); From 689aa50c0644b533295a81b9095415c2d3d4378c Mon Sep 17 00:00:00 2001 From: Steven French Date: Sun, 3 Aug 2025 08:25:54 +1200 Subject: [PATCH 4/5] revert to WNDCLASSEXA instead of wstring (was broken) Change-Id: I04e6d541ed0c4d7c28dc75456a651f06e955afa3 --- src/Window.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Window.cpp b/src/Window.cpp index 915b36f9..88499876 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -431,16 +431,15 @@ namespace dz { setDPIAware = true; } hInstance = GetModuleHandle(NULL); - WNDCLASSEXW wc = {0}; + WNDCLASSEXA wc = {0}; // wc.cbSize = sizeof(WNDCLASS); - wc.cbSize = sizeof(WNDCLASSEXW); + wc.cbSize = sizeof(WNDCLASSEXA); wc.style = CS_VREDRAW | CS_HREDRAW; wc.lpfnWndProc = wndproc; wc.hInstance = hInstance; - auto wtitle = string_to_wstring(title); - wc.lpszClassName = wtitle.c_str(); + wc.lpszClassName = title.c_str(); wc.hCursor = LoadCursor(NULL, IDC_ARROW); - RegisterClassExW(&wc); + RegisterClassExA(&wc); dpiScale = 1.0f; HDC screen = GetDC(NULL); int32_t dpi = GetDeviceCaps(screen, LOGPIXELSX); @@ -453,10 +452,10 @@ namespace dz { AdjustWindowRectEx(&desiredRect, wsStyle, FALSE, exStyle); adjustedWidth = desiredRect.right - desiredRect.left; adjustedHeight = desiredRect.bottom - desiredRect.top; - hwnd = CreateWindowExW( + hwnd = CreateWindowExA( exStyle, - wtitle.c_str(), - wtitle.c_str(), + title.c_str(), + title.c_str(), wsStyle, x == -1 ? CW_USEDEFAULT : x, y == -1 ? CW_USEDEFAULT : y, From 42002c5a80901cad29b81fb7f95d63bf6591af58 Mon Sep 17 00:00:00 2001 From: Steven French Date: Sun, 3 Aug 2025 10:16:04 +1200 Subject: [PATCH 5/5] Scene Transform, transform_dirty, Camera is_active Change-Id: I804ebfac65b53feec41997e519a48a7cf30d4d1e --- include/dz/DrawList.hpp | 3 +- include/dz/DrawListManager.hpp | 23 ++++--- include/dz/ECS.hpp | 15 ++++- include/dz/ECS/Camera.hpp | 40 ++++++++---- include/dz/ECS/Entity.hpp | 13 +++- include/dz/ECS/Scene.hpp | 111 ++++++++++++++++++++++++++++++++- src/DirectZ.cpp | 1 + src/ECS/Camera.cpp | 17 ++--- src/ECS/Entity.cpp | 13 +++- src/ECS/Scene.cpp | 41 ++++++++++++ src/ImGuiLayer.cpp | 3 + src/Window.cpp | 3 + tests/ECS.cpp | 10 +++ 13 files changed, 259 insertions(+), 34 deletions(-) create mode 100644 src/ECS/Scene.cpp diff --git a/include/dz/DrawList.hpp b/include/dz/DrawList.hpp index 88236574..9886452a 100644 --- a/include/dz/DrawList.hpp +++ b/include/dz/DrawList.hpp @@ -55,7 +55,7 @@ namespace dz /** * @brief A CameraTuple is the information required to draw from a cameras perspective */ - using CameraTuple = std::tuple>; + using CameraTuple = std::tuple, bool>; /** * @brief Information for a single Camera draw @@ -65,6 +65,7 @@ namespace dz Framebuffer* framebuffer; std::function pre_render_fn; ShaderDrawList shaderDrawList; + bool inactive = false; }; /** diff --git a/include/dz/DrawListManager.hpp b/include/dz/DrawListManager.hpp index 2e994c8b..ac3d1b1e 100644 --- a/include/dz/DrawListManager.hpp +++ b/include/dz/DrawListManager.hpp @@ -48,6 +48,8 @@ namespace dz DrawInformation drawInformation; bool draw_list_dirty = true; public: + bool enable_global_camera_if_cameras_empty; + /** * @brief Constructs a DrawListManager with a draw key and logic function. * @@ -57,12 +59,14 @@ namespace dz DrawListManager( const std::string& draw_key, const Determine_DrawT_DrawTuples_Function& fn_determine_DrawT_DrawTuples, const std::string& camera_key = "", const Determine_CameraTuple_Function& fn_determine_CameraTuple = {}, - const Determine_VisibleDraws_Function& fn_get_visible_draws = {} + const Determine_VisibleDraws_Function& fn_get_visible_draws = {}, + bool enable_global_camera_if_cameras_empty = true ): fn_determine_DrawT_DrawTuples(fn_determine_DrawT_DrawTuples), fn_determine_CameraTuple(fn_determine_CameraTuple), draw_key(draw_key), - camera_key(camera_key) + camera_key(camera_key), + enable_global_camera_if_cameras_empty(enable_global_camera_if_cameras_empty) { if (fn_get_visible_draws) { this->fn_get_visible_draws = fn_get_visible_draws; @@ -99,19 +103,22 @@ namespace dz { const size_t camera_elements = buffer_group_get_buffer_element_count(buffer_group, camera_key); + drawInformation.cameraDrawInfos.resize(camera_elements); + auto cameraDrawInfos_data = drawInformation.cameraDrawInfos.data(); + for (size_t i = 0; i < camera_elements; ++i) { - auto [camera_index, framebuffer, camera_pre_render_fn] = fn_determine_CameraTuple(buffer_group, i); - CameraDrawInformation cameraDrawInfo{ + auto [camera_index, framebuffer, camera_pre_render_fn, inactive] = fn_determine_CameraTuple(buffer_group, i); + cameraDrawInfos_data[i] = CameraDrawInformation{ .camera_index = camera_index, .framebuffer = framebuffer, - .pre_render_fn = camera_pre_render_fn + .pre_render_fn = camera_pre_render_fn, + .inactive = inactive }; - drawInformation.cameraDrawInfos.push_back(cameraDrawInfo); } } - if (drawInformation.cameraDrawInfos.empty()) + if (enable_global_camera_if_cameras_empty && drawInformation.cameraDrawInfos.empty()) { CameraDrawInformation cameraDrawInfo{ .camera_index = -1, @@ -134,6 +141,8 @@ namespace dz }; for (auto& cameraDrawInfo : drawInformation.cameraDrawInfos) { + if (cameraDrawInfo.inactive) + continue; auto camera_index = cameraDrawInfo.camera_index; auto visible_entity_indices = fn_get_visible_draws(buffer_group, camera_index); auto visible_entity_indices_data = visible_entity_indices.data(); diff --git a/include/dz/ECS.hpp b/include/dz/ECS.hpp index 777ce328..cdb5454e 100644 --- a/include/dz/ECS.hpp +++ b/include/dz/ECS.hpp @@ -137,9 +137,10 @@ namespace dz { auto GenerateCamerasDrawFunction() { return [&](auto buffer_group, auto camera_index) -> CameraTuple { auto& camera_group = GetGroupByIndex(camera_index); + auto& camera = GetCamera(camera_group.id); return {camera_index, camera_group.framebuffer, [&, camera_index]() { shader_update_push_constant(main_shader, 0, (void*)&camera_index, sizeof(uint32_t)); - }}; + }, !camera.is_active}; }; } @@ -216,7 +217,8 @@ namespace dz { draw_mg( buffer_name, GenerateEntitysDrawFunction(), Cameras_Str, GenerateCamerasDrawFunction(), - GenerateCameraVisibilityFunction() + GenerateCameraVisibilityFunction(), + false ) { RegisterProviders(); @@ -236,7 +238,8 @@ namespace dz { draw_mg( buffer_name, GenerateEntitysDrawFunction(), Cameras_Str, GenerateCamerasDrawFunction(), - GenerateCameraVisibilityFunction() + GenerateCameraVisibilityFunction(), + false ) { RegisterProviders(); @@ -376,6 +379,9 @@ namespace dz { auto cam_ptr = dynamic_cast(ptr); assert(cam_ptr); cam_ptr->InitFramebuffer(main_shader, width, height); + cam_ptr->update_draw_list_fn = [&]() { + draw_mg.MarkDirty(); + }; } } } @@ -838,6 +844,9 @@ namespace dz { auto& camera = GetCamera(camera_id); auto& camera_group = GetGroupByID(camera_id); + camera_group.update_draw_list_fn = [&]() { + draw_mg.MarkDirty(); + }; auto& width = *window_get_width_ref(window_ptr); auto& height = *window_get_height_ref(window_ptr); diff --git a/include/dz/ECS/Camera.hpp b/include/dz/ECS/Camera.hpp index 03f529b8..99950661 100644 --- a/include/dz/ECS/Camera.hpp +++ b/include/dz/ECS/Camera.hpp @@ -26,8 +26,8 @@ namespace dz::ecs { float orthoHeight; int parent_index = -1; int parent_cid = 0; - int padding1 = 0; - int padding2 = 0; + int transform_dirty = 1; + int is_active = 1; inline static constexpr bool IsCameraProvider = true; inline static constexpr size_t PID = 5; inline static float Priority = 0.5f; @@ -49,8 +49,8 @@ struct Camera { float orthoHeight; int parent_index; int parent_cid; - int padding1; - int padding2; + int transform_dirty; + int is_active; }; )"; @@ -72,6 +72,13 @@ struct Camera { void GetCameraModel(int camera_index, out mat4 out_model, out int parent_index, out int parent_cid) { Camera camera = GetCameraData(camera_index); + if (camera.transform_dirty == 0) { + out_model = inverse(camera.view); + parent_index = camera.parent_index; + parent_cid = camera.parent_cid; + return; + } + vec3 eye = camera.position; vec3 center = camera.center; vec3 up = camera.up; @@ -112,12 +119,14 @@ void GetCameraModel(int camera_index, out mat4 out_model, out int parent_index, parent_index = camera.parent_index; parent_cid = camera.parent_cid; + + camera.transform_dirty = 0; } )"} }; - struct CameraTypeReflectable : Reflectable { + struct CameraMetaReflectable : Reflectable { private: std::function get_camera_function; @@ -125,20 +134,24 @@ void GetCameraModel(int camera_index, out mat4 out_model, out int parent_index, int uid; std::string name; inline static std::unordered_map> prop_name_indexes = { - {"type", {0, 0}} + {"type", {0, 0}}, + {"is_active", {1, 0}} }; inline static std::unordered_map prop_index_names = { - {0, "type"} + {0, "type"}, + {1, "is_active"} }; inline static std::vector prop_names = { - "type" + "type", + "is_active" }; inline static const std::vector typeinfos = { - &typeid(Camera::ProjectionType) + &typeid(Camera::ProjectionType), + &typeid(bool) }; public: - CameraTypeReflectable( + CameraMetaReflectable( const std::function& get_camera_function, const std::function& reset_reflectables_function ); @@ -281,6 +294,8 @@ void GetCameraModel(int camera_index, out mat4 out_model, out int parent_index, VkDescriptorSet frame_image_ds = VK_NULL_HANDLE; bool open_in_editor = true; + std::function update_draw_list_fn; + CameraReflectableGroup(BufferGroup* buffer_group): buffer_group(buffer_group), name("Camera") @@ -316,14 +331,16 @@ void GetCameraModel(int camera_index, out mat4 out_model, out int parent_index, delete reflectable; reflectables.clear(); } + void UpdateChildren() override { if (reflectables.size() == 0) { - reflectables.push_back(new CameraTypeReflectable([&]() mutable { + reflectables.push_back(new CameraMetaReflectable([&]() mutable { auto camera_buff = buffer_group_get_buffer_data_ptr(buffer_group, CamerasBufferName); auto cameras_ptr = (struct Camera*)(camera_buff.get()); return &cameras_ptr[index]; }, [&]() mutable { UpdateChildren(); + update_draw_list_fn(); })); reflectables.push_back(new CameraViewReflectable([&]() mutable { auto camera_buff = buffer_group_get_buffer_data_ptr(buffer_group, CamerasBufferName); @@ -362,6 +379,7 @@ void GetCameraModel(int camera_index, out mat4 out_model, out int parent_index, default: break; } } + void InitFramebuffer(Shader* shader, float width, float height) { // Initialize camera framebuffer fb_color_image = image_create({ diff --git a/include/dz/ECS/Entity.hpp b/include/dz/ECS/Entity.hpp index 0b5ade5c..05896388 100644 --- a/include/dz/ECS/Entity.hpp +++ b/include/dz/ECS/Entity.hpp @@ -8,7 +8,7 @@ namespace dz::ecs { int parent_index = -1; int parent_cid = 0; int enabled_components = 0; - int padding = 0; + int transform_dirty = 1; vec position = vec(0.0f, 0.0f, 0.0f, 1.0f); vec rotation = vec(0.0f, 0.0f, 0.0f, 1.0f);; vec scale = vec(1.0f, 1.0f, 1.0f, 1.0f);; @@ -24,7 +24,7 @@ struct Entity { int parent_index; int parent_cid; int enabled_components; - int padding; + int transform_dirty; vec4 position; vec4 rotation; vec4 scale; @@ -39,6 +39,13 @@ struct Entity { void GetEntityModel(int entity_index, out mat4 out_model, out int parent_index, out int parent_cid) { Entity entity = GetEntityData(entity_index); + if (entity.transform_dirty == 0) { + out_model = entity.model; + parent_index = entity.parent_index; + parent_cid = entity.parent_cid; + return; + } + mat4 model = mat4(1.0); model[3] = vec4(entity.position.xyz, 1.0); @@ -71,6 +78,8 @@ void GetEntityModel(int entity_index, out mat4 out_model, out int parent_index, parent_index = entity.parent_index; parent_cid = entity.parent_cid; + + entity.transform_dirty = 0; } )"} }; diff --git a/include/dz/ECS/Scene.hpp b/include/dz/ECS/Scene.hpp index b0ba5681..3f07ec90 100644 --- a/include/dz/ECS/Scene.hpp +++ b/include/dz/ECS/Scene.hpp @@ -5,6 +5,12 @@ namespace dz::ecs { struct Scene : Provider { int parent_index = -1; int parent_cid = 0; + int transform_dirty = 1; + int padding2 = 0; + vec position = vec(0.0f, 0.0f, 0.0f, 1.0f); + vec rotation = vec(0.0f, 0.0f, 0.0f, 1.0f);; + vec scale = vec(1.0f, 1.0f, 1.0f, 1.0f);; + mat model = mat(1.0f); inline static constexpr size_t PID = 1; inline static float Priority = 0.5f; @@ -15,6 +21,12 @@ namespace dz::ecs { struct Scene { int parent_index; int parent_cid; + int transform_dirty; + int padding2; + vec4 position; + vec4 rotation; + vec4 scale; + mat4 model; }; )"; @@ -23,18 +35,94 @@ struct Scene { void GetSceneModel(int scene_index, out mat4 out_model, out int parent_index, out int parent_cid) { Scene scene = GetSceneData(scene_index); - out_model = mat4(1.0); + if (scene.transform_dirty == 0) { + out_model = scene.model; + parent_index = scene.parent_index; + parent_cid = scene.parent_cid; + return; + } + + mat4 model = mat4(1.0); + model[3] = vec4(scene.position.xyz, 1.0); + + mat4 scale = mat4(1.0); + scale[0].xyz *= scene.scale.x; + scale[1].xyz *= scene.scale.y; + scale[2].xyz *= scene.scale.z; + + mat4 rotX = mat4(1.0); + rotX[1][1] = cos(scene.rotation.x); + rotX[1][2] = -sin(scene.rotation.x); + rotX[2][1] = sin(scene.rotation.x); + rotX[2][2] = cos(scene.rotation.x); + + mat4 rotY = mat4(1.0); + rotY[0][0] = cos(scene.rotation.y); + rotY[0][2] = sin(scene.rotation.y); + rotY[2][0] = -sin(scene.rotation.y); + rotY[2][2] = cos(scene.rotation.y); + + mat4 rotZ = mat4(1.0); + rotZ[0][0] = cos(scene.rotation.z); + rotZ[0][1] = -sin(scene.rotation.z); + rotZ[1][0] = sin(scene.rotation.z); + rotZ[1][1] = cos(scene.rotation.z); + + mat4 rot = rotZ * rotY * rotX; + + out_model = model * rot * scale; parent_index = scene.parent_index; parent_cid = scene.parent_cid; + + scene.transform_dirty = 0; } )"} }; + struct SceneTransformReflectable : Reflectable { + private: + std::function get_scene_function; + int uid; + std::string name; + inline static std::unordered_map> prop_name_indexes = { + {"position", {0, 0}}, + {"rotation", {1, 0}}, + {"scale", {2, 0}} + }; + inline static std::unordered_map prop_index_names = { + {0, "position"}, + {1, "rotation"}, + {2, "scale"} + }; + inline static std::vector prop_names = { + "position", + "rotation", + "scale" + }; + inline static const std::vector typeinfos = { + &typeid(vec), + &typeid(vec), + &typeid(vec) + }; + + public: + SceneTransformReflectable(const std::function& get_scene_function); + int GetID() override; + std::string& GetName() override; + DEF_GET_PROPERTY_INDEX_BY_NAME(prop_name_indexes); + DEF_GET_PROPERTY_NAMES(prop_names); + void* GetVoidPropertyByIndex(int prop_index) override; + DEF_GET_VOID_PROPERTY_BY_NAME; + DEF_GET_PROPERTY_TYPEINFOS(typeinfos); + void NotifyChange(int prop_index) override; + }; + struct SceneReflectableGroup : ReflectableGroup { BufferGroup* buffer_group = nullptr; std::string name; std::vector> reflectable_children; + std::vector reflectables; SceneReflectableGroup(BufferGroup* buffer_group): buffer_group(buffer_group), name("Scene") @@ -44,15 +132,36 @@ void GetSceneModel(int scene_index, out mat4 out_model, out int parent_index, ou { restore(serial); } + ~SceneReflectableGroup() { + ClearReflectables(); + } GroupType GetGroupType() override { return ReflectableGroup::Scene; } std::string& GetName() override { return name; } + const std::vector& GetReflectables() override { + return reflectables; + } std::vector>& GetChildren() override { return reflectable_children; } + void ClearReflectables() { + if (reflectables.empty()) { + return; + } + delete reflectables[0]; + reflectables.clear(); + } + void UpdateChildren() override { + if (reflectables.empty()) { + reflectables.push_back(new SceneTransformReflectable([&]() { + auto buffer = buffer_group_get_buffer_data_ptr(buffer_group, "Scenes"); + return ((struct Scene*)(buffer.get())) + index; + })); + } + } bool backup(Serial& serial) const override { if (!backup_internal(serial)) return false; diff --git a/src/DirectZ.cpp b/src/DirectZ.cpp index 156e4384..cb824565 100644 --- a/src/DirectZ.cpp +++ b/src/DirectZ.cpp @@ -74,6 +74,7 @@ namespace dz #include "ImGuiLayer.cpp" #include "Displays.cpp" +#include "ECS/Scene.cpp" #include "ECS/Entity.cpp" #include "ECS/Mesh.cpp" #include "ECS/SubMesh.cpp" diff --git a/src/ECS/Camera.cpp b/src/ECS/Camera.cpp index f31dcfc6..a8c9b64f 100644 --- a/src/ECS/Camera.cpp +++ b/src/ECS/Camera.cpp @@ -64,37 +64,37 @@ void dz::ecs::CameraInit(Camera& camera) { } } -dz::ecs::Camera::CameraTypeReflectable::CameraTypeReflectable( +dz::ecs::Camera::CameraMetaReflectable::CameraMetaReflectable( const std::function& get_camera_function, const std::function& reset_reflectables_function ): get_camera_function(get_camera_function), reset_reflectables_function(reset_reflectables_function), uid(int(GlobalUID::GetNew("Reflectable"))), - name("Camera Type") + name("Camera Meta") {} -int dz::ecs::Camera::CameraTypeReflectable::GetID() { +int dz::ecs::Camera::CameraMetaReflectable::GetID() { return uid; } -std::string& dz::ecs::Camera::CameraTypeReflectable::GetName() { +std::string& dz::ecs::Camera::CameraMetaReflectable::GetName() { return name; } -void* dz::ecs::Camera::CameraTypeReflectable::GetVoidPropertyByIndex(int prop_index) { +void* dz::ecs::Camera::CameraMetaReflectable::GetVoidPropertyByIndex(int prop_index) { auto camera_ptr = get_camera_function(); if (!camera_ptr) return nullptr; auto& camera = *camera_ptr; switch (prop_index) { - case 0: - return &camera.type; + case 0: return &camera.type; + case 1: return &camera.is_active; default: return nullptr; } } -void dz::ecs::Camera::CameraTypeReflectable::NotifyChange(int prop_index) { +void dz::ecs::Camera::CameraMetaReflectable::NotifyChange(int prop_index) { auto camera_ptr = get_camera_function(); if (!camera_ptr) return; @@ -149,6 +149,7 @@ void dz::ecs::Camera::CameraViewReflectable::NotifyChange(int prop_index) { switch (prop_index) { default: CameraInit(camera); + camera.transform_dirty = 1; break; } } diff --git a/src/ECS/Entity.cpp b/src/ECS/Entity.cpp index db4018e3..67ab2d41 100644 --- a/src/ECS/Entity.cpp +++ b/src/ECS/Entity.cpp @@ -1,5 +1,6 @@ #include #include +#include dz::ecs::Entity::EntityTransformReflectable::EntityTransformReflectable(const std::function& get_entity_function): get_entity_function(get_entity_function), @@ -27,4 +28,14 @@ void* dz::ecs::Entity::EntityTransformReflectable::GetVoidPropertyByIndex(int pr } } -void dz::ecs::Entity::EntityTransformReflectable::NotifyChange(int prop_index) {} \ No newline at end of file +void dz::ecs::Entity::EntityTransformReflectable::NotifyChange(int prop_index) { + auto entity_ptr = get_entity_function(); + if (!entity_ptr) + return; + auto& entity = *entity_ptr; + switch (prop_index) { + default: + entity.transform_dirty = 1; + break; + } +} \ No newline at end of file diff --git a/src/ECS/Scene.cpp b/src/ECS/Scene.cpp new file mode 100644 index 00000000..26150cec --- /dev/null +++ b/src/ECS/Scene.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +dz::ecs::Scene::SceneTransformReflectable::SceneTransformReflectable(const std::function& get_scene_function): + get_scene_function(get_scene_function), + uid(int(GlobalUID::GetNew("Reflectable"))), + name("Transform") +{} + +int dz::ecs::Scene::SceneTransformReflectable::GetID() { + return uid; +} + +std::string& dz::ecs::Scene::SceneTransformReflectable::GetName() { + return name; +} + +void* dz::ecs::Scene::SceneTransformReflectable::GetVoidPropertyByIndex(int prop_index) { + auto scene_ptr = get_scene_function(); + assert(scene_ptr); + auto& scene = *scene_ptr; + switch (prop_index) { + case 0: return &scene.position; + case 1: return &scene.rotation; + case 2: return &scene.scale; + default: return nullptr; + } +} + +void dz::ecs::Scene::SceneTransformReflectable::NotifyChange(int prop_index) { + auto scene_ptr = get_scene_function(); + if (!scene_ptr) + return; + auto& scene = *scene_ptr; + switch (prop_index) { + default: + scene.transform_dirty = 1; + break; + } +} \ No newline at end of file diff --git a/src/ImGuiLayer.cpp b/src/ImGuiLayer.cpp index 7ee8a7cd..d2f00413 100644 --- a/src/ImGuiLayer.cpp +++ b/src/ImGuiLayer.cpp @@ -1,5 +1,8 @@ #include #include "fa-solid-900-ttf.c" +#include "WindowImpl.hpp" +#include "RendererImpl.hpp" + namespace dz { VkDescriptorPool CreateImGuiDescriptorPool(VkDevice device) { diff --git a/src/Window.cpp b/src/Window.cpp index 88499876..32088fd3 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -187,6 +187,9 @@ namespace dz { auto& vp = *window->imguiViewport; vp.PlatformHandle = nullptr; vp.PlatformHandleRaw = nullptr; + if (!destroy_remaining) + vp.RendererUserData = nullptr; + vp.PlatformUserData = nullptr; } window->destroy_platform(); auto& event_interface = *window->event_interface; diff --git a/tests/ECS.cpp b/tests/ECS.cpp index f06455cb..b10ea1d9 100644 --- a/tests/ECS.cpp +++ b/tests/ECS.cpp @@ -724,6 +724,16 @@ int main() { } ImGui::PopID(); } + else if (*type_info == typeid(bool)) { + auto& value = reflectable.template GetPropertyByIndex(prop_index); + ImGui::PushID(prop_index); + if (ImGui::Checkbox("##checkbox", &value)) + { + reflectable.NotifyChange(prop_index); + update_iterators(); + } + ImGui::PopID(); + } else if (*type_info == typeid(Light::LightType)) { auto& value = reflectable.template GetPropertyByIndex(prop_index); static const char* projection_types[] = { "Directional", "Spot", "Point" };