From 7247faee739acdb8f1d2832ad63f2656b83bfd2e Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Mon, 26 Sep 2022 21:08:59 +0800 Subject: [PATCH 01/24] Serialization [WIP] --- .../Inspector/SHEditorComponentView.hpp | 2 +- .../src/Serialization/SHSerialization.cpp | 79 +++++++++++++++ .../src/Serialization/SHSerialization.h | 28 ++++++ .../Serialization/SHSerializationHelper.hpp | 97 +++++++++++++++++++ 4 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 SHADE_Engine/src/Serialization/SHSerialization.cpp create mode 100644 SHADE_Engine/src/Serialization/SHSerialization.h create mode 100644 SHADE_Engine/src/Serialization/SHSerializationHelper.hpp diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 080cbf2c..889abc79 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -44,7 +44,7 @@ namespace SHADE { if (!component) return; - auto componentType = rttr::type::get(*component); + auto componentType = rttr::type::get(); CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); ImGui::SameLine(); if (ImGui::CollapsingHeader(componentType.get_name().data())) diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp new file mode 100644 index 00000000..ee681a85 --- /dev/null +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -0,0 +1,79 @@ +#include "SHpch.h" +#include "SHSerialization.h" + +#include + +#include "Scene/SHSceneManager.h" +#include "Tools/SHException.h" + +#include "SHSerializationHelper.hpp" +#include "Math/Transform/SHTransformComponent.h" + +namespace SHADE +{ + namespace SHSerialization + { + void SerializeSceneToFile(std::filesystem::path const& path) + { + + } + + std::string SerializeSceneToString() + { + YAML::Emitter out; + SerializeSceneToEmitter(out); + return std::string(out.c_str()); + } + + void SerializeSceneToEmitter(YAML::Emitter& out) + { + auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + auto root = sceneGraph.GetRoot(); + + SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node."); + + auto const& children = root->GetChildren(); + out << YAML::BeginDoc; + for (auto child : children) + { + out << YAML::BeginSeq; + out << SerializeEntityToNode(child); + out << YAML::EndSeq; + } + out << YAML::EndDoc; + } + + std::string SerializeEntityToString() + { + return std::string(); + } + + void SerializeEntityToFile(std::filesystem::path const& path) + { + } + + YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode) + { + YAML::Node node; + if(!sceneNode) + { + node = YAML::Null; + return node; + } + auto eid = sceneNode->GetEntityID(); + node["EID"] = eid; + node["isActive"] = sceneNode->IsActive(); + auto const& children = sceneNode->GetChildren(); + node["NumberOfChildren"] = children.size(); + + YAML::Node components; + + if(const auto transform = SHComponentManager::GetComponent_s(eid)) + { + components[rttr::type::get().get_name().data()] = SerializeComponentToNode(transform); + } + node["Components"] = components; + return node; + } + } +} diff --git a/SHADE_Engine/src/Serialization/SHSerialization.h b/SHADE_Engine/src/Serialization/SHSerialization.h new file mode 100644 index 00000000..aaccd065 --- /dev/null +++ b/SHADE_Engine/src/Serialization/SHSerialization.h @@ -0,0 +1,28 @@ +#pragma once + +#include "SH_API.h" +#include +#include + +#include + +namespace YAML +{ + class Emitter; + class Node; +} + +namespace SHADE +{ + class SHSceneNode; + namespace SHSerialization + { + static void SerializeSceneToFile(std::filesystem::path const& path); + static std::string SerializeSceneToString(); + static void SerializeSceneToEmitter(YAML::Emitter& out); + + static std::string SerializeEntityToString(); + static void SerializeEntityToFile(std::filesystem::path const& path); + static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode); + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp new file mode 100644 index 00000000..560c58dd --- /dev/null +++ b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp @@ -0,0 +1,97 @@ +#pragma once + +#include "ECS_Base/Components/SHComponent.h" +#include + +#include + +namespace SHADE +{ + namespace SHSerialization + { + template , bool> = true> + static std::string SerializeComponentToString(ComponentType* component) + { + return std::string(); + } + + template , bool> = true> + static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path) + { + } + + static YAML::Node RTTRToNode(const rttr::variant& var) + { + YAML::Node node; + auto varType = var.get_type(); + if(varType.is_arithmetic()) + { + bool ok = false; + if (varType == rttr::type::get()) + node = var.to_bool(); + else if (varType == rttr::type::get()) + node = var.to_int8(&ok); + else if (varType == rttr::type::get()) + node = var.to_int16(&ok); + else if (varType == rttr::type::get()) + node = var.to_int32(&ok); + else if (varType == rttr::type::get()) + node = var.to_int64(&ok); + else if (varType == rttr::type::get()) + node = var.to_uint8(&ok); + else if (varType == rttr::type::get()) + node = var.to_uint16(&ok); + else if (varType == rttr::type::get()) + node = var.to_uint32(&ok); + else if (varType == rttr::type::get()) + node = var.to_uint64(&ok); + else if (varType == rttr::type::get()) + node = var.to_float(&ok); + else if (varType == rttr::type::get()) + node = var.to_double(&ok); + //else if (varType == rttr::type::get()) //same as uint8_t + // node = var.to_uint8(); + } + else if (varType.is_enumeration()) + { + bool ok = false; + auto result = var.to_string(&ok); + if (ok) + { + node = var.to_string(); + } + else + { + ok = false; + auto value = var.to_uint64(&ok); + if (ok) + node = value; + else + node = YAML::Null; + } + } + else + { + auto properties = var.get_type().get_properties(); + for(auto property : properties) + { + node[property.get_name().data()] = RTTRToNode(property.get_value(var)); + } + } + return node; + } + + template , bool> = true> + static YAML::Node SerializeComponentToNode(ComponentType* component) + { + YAML::Node node{}; + if(!component) + return node; + + auto componentType = rttr::type::get(); + node[componentType.get_name().data()] = RTTRToNode(*component); + + return node; + } + } +} \ No newline at end of file From 233e7a0e8fcb783311d52d5f77837a57e9650889 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Mon, 26 Sep 2022 23:51:20 +0800 Subject: [PATCH 02/24] Serialization fix --- .../src/Serialization/SHSerialization.cpp | 113 +++++++++--------- .../src/Serialization/SHSerialization.h | 6 +- .../Serialization/SHSerializationHelper.hpp | 6 +- 3 files changed, 61 insertions(+), 64 deletions(-) diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index ee681a85..25358805 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -1,4 +1,5 @@ #include "SHpch.h" +#include "SHSerializationHelper.hpp" #include "SHSerialization.h" #include @@ -6,74 +7,70 @@ #include "Scene/SHSceneManager.h" #include "Tools/SHException.h" -#include "SHSerializationHelper.hpp" #include "Math/Transform/SHTransformComponent.h" namespace SHADE { - namespace SHSerialization + void SHSerialization::SerializeSceneToFile(std::filesystem::path const& path) { - void SerializeSceneToFile(std::filesystem::path const& path) - { + } + + std::string SHSerialization::SerializeSceneToString() + { + YAML::Emitter out; + SerializeSceneToEmitter(out); + return std::string(out.c_str()); + } + + void SHSerialization::SerializeSceneToEmitter(YAML::Emitter& out) + { + auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + auto root = sceneGraph.GetRoot(); + + SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node."); + + auto const& children = root->GetChildren(); + out << YAML::BeginDoc; + for (auto child : children) + { + out << YAML::BeginSeq; + out << SerializeEntityToNode(child); + out << YAML::EndSeq; } + out << YAML::EndDoc; + } - std::string SerializeSceneToString() + std::string SHSerialization::SerializeEntityToString() + { + return std::string(); + } + + void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path) + { + } + + YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode) + { + YAML::Node node; + if (!sceneNode) { - YAML::Emitter out; - SerializeSceneToEmitter(out); - return std::string(out.c_str()); - } - - void SerializeSceneToEmitter(YAML::Emitter& out) - { - auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); - auto root = sceneGraph.GetRoot(); - - SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node."); - - auto const& children = root->GetChildren(); - out << YAML::BeginDoc; - for (auto child : children) - { - out << YAML::BeginSeq; - out << SerializeEntityToNode(child); - out << YAML::EndSeq; - } - out << YAML::EndDoc; - } - - std::string SerializeEntityToString() - { - return std::string(); - } - - void SerializeEntityToFile(std::filesystem::path const& path) - { - } - - YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode) - { - YAML::Node node; - if(!sceneNode) - { - node = YAML::Null; - return node; - } - auto eid = sceneNode->GetEntityID(); - node["EID"] = eid; - node["isActive"] = sceneNode->IsActive(); - auto const& children = sceneNode->GetChildren(); - node["NumberOfChildren"] = children.size(); - - YAML::Node components; - - if(const auto transform = SHComponentManager::GetComponent_s(eid)) - { - components[rttr::type::get().get_name().data()] = SerializeComponentToNode(transform); - } - node["Components"] = components; + node = YAML::Null; return node; } + auto eid = sceneNode->GetEntityID(); + node["EID"] = eid; + node["isActive"] = sceneNode->IsActive(); + auto const& children = sceneNode->GetChildren(); + node["NumberOfChildren"] = children.size(); + + YAML::Node components; + + if (const auto transform = SHComponentManager::GetComponent_s(eid)) + { + components[rttr::type::get().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(transform); + } + node["Components"] = components; + return node; } } diff --git a/SHADE_Engine/src/Serialization/SHSerialization.h b/SHADE_Engine/src/Serialization/SHSerialization.h index aaccd065..0611e4d2 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.h +++ b/SHADE_Engine/src/Serialization/SHSerialization.h @@ -5,7 +5,7 @@ #include #include - +#include "SH_API.h" namespace YAML { class Emitter; @@ -15,7 +15,7 @@ namespace YAML namespace SHADE { class SHSceneNode; - namespace SHSerialization + struct SH_API SHSerialization { static void SerializeSceneToFile(std::filesystem::path const& path); static std::string SerializeSceneToString(); @@ -24,5 +24,5 @@ namespace SHADE static std::string SerializeEntityToString(); static void SerializeEntityToFile(std::filesystem::path const& path); static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode); - } + }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp index 560c58dd..bfc29e7a 100644 --- a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp +++ b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp @@ -7,7 +7,7 @@ namespace SHADE { - namespace SHSerialization + struct SHSerializationHelper { template , bool> = true> static std::string SerializeComponentToString(ComponentType* component) @@ -89,9 +89,9 @@ namespace SHADE return node; auto componentType = rttr::type::get(); - node[componentType.get_name().data()] = RTTRToNode(*component); + node = RTTRToNode(*component); return node; } - } + }; } \ No newline at end of file From c4ed1991650638cb514b461c2ecc0d9ced294026 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 27 Sep 2022 07:03:31 +0800 Subject: [PATCH 03/24] Serialize Vec 2/3/4 --- .../Serialization/SHSerializationHelper.hpp | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp index bfc29e7a..e702dd24 100644 --- a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp +++ b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp @@ -5,6 +5,10 @@ #include +#include "Math/Vector/SHVec2.h" +#include "Math/Vector/SHVec3.h" +#include "Math/Vector/SHVec4.h" + namespace SHADE { struct SHSerializationHelper @@ -24,7 +28,28 @@ namespace SHADE { YAML::Node node; auto varType = var.get_type(); - if(varType.is_arithmetic()) + if(varType == rttr::type::get()) + { + node.SetStyle(YAML::EmitterStyle::Flow); + node["X"] = var.convert().x; + node["Y"] = var.convert().y; + node["Z"] = var.convert().z; + node["W"] = var.convert().w; + } + else if(varType == rttr::type::get()) + { + node.SetStyle(YAML::EmitterStyle::Flow); + node["X"] = var.convert().x; + node["Y"] = var.convert().y; + node["Z"] = var.convert().z; + } + else if(varType == rttr::type::get()) + { + node.SetStyle(YAML::EmitterStyle::Flow); + node["X"] = var.convert().x; + node["Y"] = var.convert().y; + } + else if(varType.is_arithmetic()) { bool ok = false; if (varType == rttr::type::get()) @@ -94,4 +119,4 @@ namespace SHADE return node; } }; -} \ No newline at end of file +} From cebb1a2cf85aa2c779b0ceb4a9372a23cde095f6 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 27 Sep 2022 21:06:25 +0800 Subject: [PATCH 04/24] Deserialization WIP --- .../src/Serialization/SHSerialization.cpp | 92 ++++++++++++++++--- .../src/Serialization/SHSerialization.h | 17 +++- 2 files changed, 94 insertions(+), 15 deletions(-) diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index 25358805..926e4ff5 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -4,6 +4,7 @@ #include +#include "ECS_Base/Managers/SHEntityManager.h" #include "Scene/SHSceneManager.h" #include "Tools/SHException.h" @@ -29,18 +30,60 @@ namespace SHADE auto root = sceneGraph.GetRoot(); SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node."); - + auto const& children = root->GetChildren(); out << YAML::BeginDoc; - for (auto child : children) - { - out << YAML::BeginSeq; - out << SerializeEntityToNode(child); - out << YAML::EndSeq; - } + + auto pred = [&out](SHSceneNode* node){out << SerializeEntityToNode(node);}; + sceneGraph.Traverse(pred); + //out << SerializeEntityToNode(child); + out << YAML::EndDoc; } + static void DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector& createdEntities, EntityID parentEID = MAX_EID) + { + if(!node[EIDNode]) + return; + EntityID eid = node[EIDNode].as(); + std::string name = "Default"; + if(node[EntityNameNode]) + name = node[EntityNameNode].as(); + //Compile component IDs + const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]); + eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID); + createdEntities.push_back(eid); + if(node[NumberOfChildrenNode]) + { int numOfChildren = node[NumberOfChildrenNode].as(); + for(int i = 0; i < numOfChildren; ++i) + { + DeserializeEntity(it, *it, createdEntities, eid); + ++it; + } + } + } + + void SHSerialization::DeserializeSceneFromFile(std::string const& fileData) + { + YAML::Node entities = YAML::Load(fileData.c_str()); + std::vector createdEntities{}; + + //Create Entities + for(auto it = entities.begin(); it != entities.end(); ++it) + { + DeserializeEntity(it, (*it), createdEntities); + } + + //Initialize Entity + for(auto it = entities.begin(); it != entities.end(); ++it) + { + //For each node, Deserialize component + //Recurse through properties + } + } + + + std::string SHSerialization::SerializeEntityToString() { return std::string(); @@ -53,16 +96,19 @@ namespace SHADE YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode) { YAML::Node node; - if (!sceneNode) + auto eid = sceneNode->GetEntityID(); + auto entity = SHEntityManager::GetEntityByID(eid); + if (!sceneNode || !entity) { node = YAML::Null; return node; } - auto eid = sceneNode->GetEntityID(); - node["EID"] = eid; - node["isActive"] = sceneNode->IsActive(); + + node[EIDNode] = eid; + node[EntityNameNode] = entity->name; + node[IsActiveNode] = sceneNode->IsActive(); auto const& children = sceneNode->GetChildren(); - node["NumberOfChildren"] = children.size(); + node[NumberOfChildrenNode] = children.size(); YAML::Node components; @@ -70,7 +116,27 @@ namespace SHADE { components[rttr::type::get().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(transform); } - node["Components"] = components; + node[ComponentsNode] = components; return node; } + + template, bool> = true> + std::optional GetComponentID(YAML::Node const & componentNode) + { + if(componentNode[rttr::type::get().get_name().data()]) + return {SHFamilyID::GetID()}; + else + return std::nullopt; + } + + std::vector SHSerialization::GetComponentIDList(YAML::Node const& componentsNode) + { + std::vector componentIDList; + + auto id = GetComponentID(componentsNode); + if(id.has_value()) + componentIDList.push_back(id.value()); + + return componentIDList; + } } diff --git a/SHADE_Engine/src/Serialization/SHSerialization.h b/SHADE_Engine/src/Serialization/SHSerialization.h index 0611e4d2..022a01c4 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.h +++ b/SHADE_Engine/src/Serialization/SHSerialization.h @@ -5,7 +5,7 @@ #include #include -#include "SH_API.h" + namespace YAML { class Emitter; @@ -15,14 +15,27 @@ namespace YAML namespace SHADE { class SHSceneNode; + + constexpr const char* ComponentsNode = "Components"; + constexpr const char* EntityNameNode = "Name"; + constexpr const char* EIDNode = "EID"; + constexpr const char* IsActiveNode = "IsActive"; + constexpr const char* NumberOfChildrenNode = "NumberOfChildren"; + struct SH_API SHSerialization { + //TODO: change paths to resource ID static void SerializeSceneToFile(std::filesystem::path const& path); static std::string SerializeSceneToString(); static void SerializeSceneToEmitter(YAML::Emitter& out); - + static void DeserializeSceneFromFile(std::string const& fileData); + + static std::string SerializeEntityToString(); static void SerializeEntityToFile(std::filesystem::path const& path); static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode); + + static std::vector GetComponentIDList(YAML::Node const& componentsNode); + private: }; } \ No newline at end of file From 01f648ceb626ba8b6bec50c87198e380ac277b24 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sat, 1 Oct 2022 23:43:00 +0800 Subject: [PATCH 05/24] Serialize/Deserialize [WIP] --- .../src/Serialization/SHSerialization.cpp | 100 +++++++++---- .../src/Serialization/SHSerialization.h | 3 +- .../Serialization/SHSerializationHelper.hpp | 136 ++++++++++++++---- 3 files changed, 185 insertions(+), 54 deletions(-) diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index 926e4ff5..ee189f2c 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -7,21 +7,31 @@ #include "ECS_Base/Managers/SHEntityManager.h" #include "Scene/SHSceneManager.h" #include "Tools/SHException.h" +#include "Assets/SHAssetManager.h" +#include +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Math/Transform/SHTransformComponent.h" namespace SHADE { void SHSerialization::SerializeSceneToFile(std::filesystem::path const& path) { - + YAML::Emitter out; + SerializeSceneToEmitter(out); + std::ofstream file(path.c_str()); + if (file.good()) + { + file << out.c_str(); + file.close(); + } } std::string SHSerialization::SerializeSceneToString() { YAML::Emitter out; SerializeSceneToEmitter(out); - return std::string(out.c_str()); + return std::basic_string(out.c_str()); } void SHSerialization::SerializeSceneToEmitter(YAML::Emitter& out) @@ -30,55 +40,82 @@ namespace SHADE auto root = sceneGraph.GetRoot(); SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node."); - - auto const& children = root->GetChildren(); - out << YAML::BeginDoc; - auto pred = [&out](SHSceneNode* node){out << SerializeEntityToNode(node);}; + auto const& children = root->GetChildren(); + out << YAML::BeginSeq; + + auto pred = [&out](SHSceneNode* node) {out << SerializeEntityToNode(node); }; sceneGraph.Traverse(pred); - //out << SerializeEntityToNode(child); - - out << YAML::EndDoc; + //out << SerializeEntityToNode(child); + + out << YAML::EndSeq; } static void DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector& createdEntities, EntityID parentEID = MAX_EID) { - if(!node[EIDNode]) + if (!node[EIDNode]) return; EntityID eid = node[EIDNode].as(); std::string name = "Default"; - if(node[EntityNameNode]) + if (node[EntityNameNode]) name = node[EntityNameNode].as(); //Compile component IDs const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]); eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID); createdEntities.push_back(eid); - if(node[NumberOfChildrenNode]) - { int numOfChildren = node[NumberOfChildrenNode].as(); - for(int i = 0; i < numOfChildren; ++i) + if (node[NumberOfChildrenNode]) + { + if(const int numOfChildren = node[NumberOfChildrenNode].as(); numOfChildren > 0) { - DeserializeEntity(it, *it, createdEntities, eid); ++it; + for (int i = 0; i < numOfChildren; ++i) + { + DeserializeEntity(it, (*it), createdEntities, eid); + if((i + 1) < numOfChildren) + ++it; + } } } } - void SHSerialization::DeserializeSceneFromFile(std::string const& fileData) + void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path) { - YAML::Node entities = YAML::Load(fileData.c_str()); + //TODO:Shift to using XQ's FileIO + std::ifstream iFile; + iFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); + std::string fileContent = ""; + + try + { + // Open file + // Read file's buffer contents into streams + iFile.open(path); + std::stringstream fileStream; + fileStream << iFile.rdbuf(); + + fileContent = fileStream.str(); + + // Close file handler + iFile.close(); + } + catch (std::ifstream::failure e) + { + SHLOG_ERROR("Could not read file"); + } + YAML::Node entities = YAML::Load(fileContent); std::vector createdEntities{}; //Create Entities - for(auto it = entities.begin(); it != entities.end(); ++it) + for (auto it = entities.begin(); it != entities.end(); ++it) { DeserializeEntity(it, (*it), createdEntities); } //Initialize Entity - for(auto it = entities.begin(); it != entities.end(); ++it) + auto entityVecIt = createdEntities.begin(); + for (auto it = entities.begin(); it != entities.end(); ++it) { - //For each node, Deserialize component - //Recurse through properties + InitializeEntity(*it, *entityVecIt++); } } @@ -103,7 +140,7 @@ namespace SHADE node = YAML::Null; return node; } - + node.SetStyle(YAML::EmitterStyle::Block); node[EIDNode] = eid; node[EntityNameNode] = entity->name; node[IsActiveNode] = sceneNode->IsActive(); @@ -121,10 +158,10 @@ namespace SHADE } template, bool> = true> - std::optional GetComponentID(YAML::Node const & componentNode) + std::optional GetComponentID(YAML::Node const& componentNode) { - if(componentNode[rttr::type::get().get_name().data()]) - return {SHFamilyID::GetID()}; + if (componentNode[rttr::type::get().get_name().data()]) + return { SHFamilyID::GetID() }; else return std::nullopt; } @@ -134,9 +171,20 @@ namespace SHADE std::vector componentIDList; auto id = GetComponentID(componentsNode); - if(id.has_value()) + if (id.has_value()) + componentIDList.push_back(id.value()); + id = GetComponentID(componentsNode); + if (id.has_value()) componentIDList.push_back(id.value()); return componentIDList; } + + void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid) + { + auto componentsNode = entityNode[ComponentsNode]; + if(!componentsNode) + return; + SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); + } } diff --git a/SHADE_Engine/src/Serialization/SHSerialization.h b/SHADE_Engine/src/Serialization/SHSerialization.h index 022a01c4..8a57f036 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.h +++ b/SHADE_Engine/src/Serialization/SHSerialization.h @@ -28,7 +28,7 @@ namespace SHADE static void SerializeSceneToFile(std::filesystem::path const& path); static std::string SerializeSceneToString(); static void SerializeSceneToEmitter(YAML::Emitter& out); - static void DeserializeSceneFromFile(std::string const& fileData); + static void DeserializeSceneFromFile(std::filesystem::path const& path); static std::string SerializeEntityToString(); @@ -37,5 +37,6 @@ namespace SHADE static std::vector GetComponentIDList(YAML::Node const& componentsNode); private: + static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid); }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp index e702dd24..da98c885 100644 --- a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp +++ b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp @@ -5,6 +5,7 @@ #include +#include "ECS_Base/Managers/SHComponentManager.h" #include "Math/Vector/SHVec2.h" #include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec4.h" @@ -13,13 +14,13 @@ namespace SHADE { struct SHSerializationHelper { - template , bool> = true> + template , bool> = true> static std::string SerializeComponentToString(ComponentType* component) { return std::string(); } - template , bool> = true> + template , bool> = true> static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path) { } @@ -28,7 +29,7 @@ namespace SHADE { YAML::Node node; auto varType = var.get_type(); - if(varType == rttr::type::get()) + if (varType == rttr::type::get()) { node.SetStyle(YAML::EmitterStyle::Flow); node["X"] = var.convert().x; @@ -36,44 +37,44 @@ namespace SHADE node["Z"] = var.convert().z; node["W"] = var.convert().w; } - else if(varType == rttr::type::get()) + else if (varType == rttr::type::get()) { node.SetStyle(YAML::EmitterStyle::Flow); node["X"] = var.convert().x; node["Y"] = var.convert().y; node["Z"] = var.convert().z; } - else if(varType == rttr::type::get()) + else if (varType == rttr::type::get()) { node.SetStyle(YAML::EmitterStyle::Flow); node["X"] = var.convert().x; node["Y"] = var.convert().y; } - else if(varType.is_arithmetic()) + else if (varType.is_arithmetic()) { bool ok = false; if (varType == rttr::type::get()) - node = var.to_bool(); + node = var.to_bool(); else if (varType == rttr::type::get()) - node = var.to_int8(&ok); + node = var.to_int8(&ok); else if (varType == rttr::type::get()) - node = var.to_int16(&ok); + node = var.to_int16(&ok); else if (varType == rttr::type::get()) - node = var.to_int32(&ok); + node = var.to_int32(&ok); else if (varType == rttr::type::get()) - node = var.to_int64(&ok); + node = var.to_int64(&ok); else if (varType == rttr::type::get()) - node = var.to_uint8(&ok); + node = var.to_uint8(&ok); else if (varType == rttr::type::get()) - node = var.to_uint16(&ok); + node = var.to_uint16(&ok); else if (varType == rttr::type::get()) - node = var.to_uint32(&ok); + node = var.to_uint32(&ok); else if (varType == rttr::type::get()) - node = var.to_uint64(&ok); + node = var.to_uint64(&ok); else if (varType == rttr::type::get()) - node = var.to_float(&ok); + node = var.to_float(&ok); else if (varType == rttr::type::get()) - node = var.to_double(&ok); + node = var.to_double(&ok); //else if (varType == rttr::type::get()) //same as uint8_t // node = var.to_uint8(); } @@ -87,18 +88,18 @@ namespace SHADE } else { - ok = false; - auto value = var.to_uint64(&ok); - if (ok) - node = value; - else - node = YAML::Null; + ok = false; + auto value = var.to_uint64(&ok); + if (ok) + node = value; + else + node = YAML::Null; } } else { auto properties = var.get_type().get_properties(); - for(auto property : properties) + for (auto property : properties) { node[property.get_name().data()] = RTTRToNode(property.get_value(var)); } @@ -106,17 +107,98 @@ namespace SHADE return node; } - template , bool> = true> + template , bool> = true> static YAML::Node SerializeComponentToNode(ComponentType* component) { YAML::Node node{}; - if(!component) - return node; + if (!component) + return node; auto componentType = rttr::type::get(); node = RTTRToNode(*component); return node; } + + template , bool> = true> + static void InitializeProperty(ComponentType* component, rttr::property const& prop, YAML::Node const& propertyNode) + { + auto propType = prop.get_type(); + if (propType == rttr::type::get()) + { + SHVec4 vec{ propertyNode["X"].as(), propertyNode["Y"].as(), propertyNode["Z"].as(), propertyNode["W"].as() }; + prop.set_value(component, vec); + } + else if (propType == rttr::type::get()) + { + SHVec3 vec{ propertyNode["X"].as(), propertyNode["Y"].as(), propertyNode["Z"].as() }; + prop.set_value(component, vec); + } + else if (propType == rttr::type::get()) + { + SHVec2 vec{ propertyNode["X"].as(), propertyNode["Y"].as() }; + prop.set_value(component, vec); + } + else if (propType.is_arithmetic()) + { + bool ok = false; + if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + else if (propType == rttr::type::get()) + prop.set_value(component, propertyNode.as()); + } + else if (propType.is_enumeration()) + { + auto enumAlign = prop.get_enumeration(); + prop.set_value(component, enumAlign.name_to_value(propertyNode.as())); + } + else + { + auto properties = propType.get_properties(); + for (auto property : properties) + { + InitializeProperty(component, property, propertyNode[property.get_name().data()]); + } + } + } + + template , bool> = true> + static void InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid) + { + auto component = SHComponentManager::GetComponent_s(eid); + if (componentsNode.IsNull() && !component) + return; + auto rttrType = rttr::type::get(); + auto componentNode = componentsNode[rttrType.get_name().data()]; + if (componentsNode.IsNull()) + return; + auto properties = rttrType.get_properties(); + for (auto const& prop : properties) + { + if (componentNode[prop.get_name().data()]) + { + InitializeProperty(component, prop, componentNode[prop.get_name().data()]); + } + } + } + }; } From 3b3492843fe743c28dd1c5961977e449e8e4c638 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sun, 16 Oct 2022 03:25:33 +0800 Subject: [PATCH 06/24] Added input class --- SHADE_Managed/src/Input/Input.cxx | 102 ++++++++++ SHADE_Managed/src/Input/Input.hxx | 325 ++++++++++++++++++++++++++++++ 2 files changed, 427 insertions(+) create mode 100644 SHADE_Managed/src/Input/Input.cxx create mode 100644 SHADE_Managed/src/Input/Input.hxx diff --git a/SHADE_Managed/src/Input/Input.cxx b/SHADE_Managed/src/Input/Input.cxx new file mode 100644 index 00000000..0a386f3a --- /dev/null +++ b/SHADE_Managed/src/Input/Input.cxx @@ -0,0 +1,102 @@ +/************************************************************************************//*! +\file Input.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 16, 2022 +\brief Contains the definition of the managed Input static class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#include "SHpch.h" +#include "Input.hxx" +#include "Utility/Convert.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + Vector3 Input::MousePosition::get() + { + int x, y; + SHInputManager::GetMouseWindowPosition(&x, &y); + return Vector3(static_cast(x), static_cast(y), 0.0f); + } + int Input::MouseScrollDelta::get() + { + return SHInputManager::GetMouseWheelVerticalDelta(); + } + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + bool Input::GetKey(KeyCode key) + { + return SHInputManager::GetKey(static_cast(key)); + } + + bool Input::GetKeyDown(KeyCode key) + { + return SHInputManager::GetKeyDown(static_cast(key)); + } + + bool Input::GetKeyUp(KeyCode key) + { + return SHInputManager::GetKeyUp(static_cast(key)); + } + + bool Input::GetMouseButton(MouseCode mouseButton) + { + return SHInputManager::GetKey(static_cast(mouseButton)); + } + + bool Input::GetMouseButtonDown(MouseCode mouseButton) + { + return SHInputManager::GetKeyDown(static_cast(mouseButton)); + } + + bool Input::GetMouseButtonUp(MouseCode mouseButton) + { + return SHInputManager::GetKeyUp(static_cast(mouseButton)); + } + + /*---------------------------------------------------------------------------------*/ + /* Cursor Functions */ + /*---------------------------------------------------------------------------------*/ + void Input::SetMousePosition(Vector2 pos) + { + SHInputManager::SetMouseWindowPosition + ( + static_cast(pos.x), + static_cast(pos.y) + ); + } + + /*---------------------------------------------------------------------------------*/ + /* Time Functions */ + /*---------------------------------------------------------------------------------*/ + double Input::GetKeyHeldTime(KeyCode key) + { + return SHInputManager::GetKeyHeldTime(static_cast(key)); + } + + double Input::GetKeyReleasedTime(KeyCode key) + { + return SHInputManager::GetKeyReleasedTime(static_cast(key)); + } + + double Input::GetMouseHeldTime(MouseCode key) + { + return SHInputManager::GetKeyHeldTime(static_cast(key)); + } + + double Input::GetMouseReleasedTime(MouseCode key) + { + return SHInputManager::GetKeyReleasedTime(static_cast(key)); + } + +} \ No newline at end of file diff --git a/SHADE_Managed/src/Input/Input.hxx b/SHADE_Managed/src/Input/Input.hxx new file mode 100644 index 00000000..f281e4c8 --- /dev/null +++ b/SHADE_Managed/src/Input/Input.hxx @@ -0,0 +1,325 @@ +/************************************************************************************//*! +\file Input.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 16, 2022 +\brief Contains the definition of the managed Input static class. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +#include "Input/SHInputManager.h" +#include "Math/Vector2.hxx" +#include "Math/Vector3.hxx" + +namespace SHADE +{ + /// + /// Static class responsible for providing access to Input-related functionality. + /// + public ref class Input abstract sealed + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Represents the available supported keycodes that can be passed into the + /// key-based Input functions. + /// + enum class KeyCode : int + { + Space = static_cast(SHInputManager::SH_KEYCODE::SPACE), + //Apostrophe = static_cast(SHInputManager::SH_KEYCODE::APOSTROPHE), + Comma = static_cast(SHInputManager::SH_KEYCODE::OEM_COMMA), + Minus = static_cast(SHInputManager::SH_KEYCODE::OEM_MINUS), + Period = static_cast(SHInputManager::SH_KEYCODE::OEM_PERIOD), + //Slash = static_cast(SHInputManager::SH_KEYCODE::SLASH), + Key0 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_0), + Key1 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_1), + Key2 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_2), + Key3 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_3), + Key4 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_4), + Key5 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_5), + Key6 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_6), + Key7 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_7), + Key8 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_8), + Key9 = static_cast(SHInputManager::SH_KEYCODE::NUMBER_9), + + //Semicolon = static_cast(SHInputManager::SH_KEYCODE::SEMICOLON), + //Equal = static_cast(SHInputManager::SH_KEYCODE::EQUAL), + + A = static_cast(SHInputManager::SH_KEYCODE::A), + B = static_cast(SHInputManager::SH_KEYCODE::B), + C = static_cast(SHInputManager::SH_KEYCODE::C), + D = static_cast(SHInputManager::SH_KEYCODE::D), + E = static_cast(SHInputManager::SH_KEYCODE::E), + F = static_cast(SHInputManager::SH_KEYCODE::F), + G = static_cast(SHInputManager::SH_KEYCODE::G), + H = static_cast(SHInputManager::SH_KEYCODE::H), + I = static_cast(SHInputManager::SH_KEYCODE::I), + J = static_cast(SHInputManager::SH_KEYCODE::J), + K = static_cast(SHInputManager::SH_KEYCODE::K), + L = static_cast(SHInputManager::SH_KEYCODE::L), + M = static_cast(SHInputManager::SH_KEYCODE::M), + N = static_cast(SHInputManager::SH_KEYCODE::N), + O = static_cast(SHInputManager::SH_KEYCODE::O), + P = static_cast(SHInputManager::SH_KEYCODE::P), + Q = static_cast(SHInputManager::SH_KEYCODE::Q), + R = static_cast(SHInputManager::SH_KEYCODE::R), + S = static_cast(SHInputManager::SH_KEYCODE::S), + T = static_cast(SHInputManager::SH_KEYCODE::T), + U = static_cast(SHInputManager::SH_KEYCODE::U), + V = static_cast(SHInputManager::SH_KEYCODE::V), + W = static_cast(SHInputManager::SH_KEYCODE::W), + X = static_cast(SHInputManager::SH_KEYCODE::X), + Y = static_cast(SHInputManager::SH_KEYCODE::Y), + Z = static_cast(SHInputManager::SH_KEYCODE::Z), + + //LeftBracket = static_cast(SHInputManager::SH_KEYCODE::LEFTBRACKET), + //BackSlash = static_cast(SHInputManager::SH_KEYCODE::BACKSLASH), + //RightBracket = static_cast(SHInputManager::SH_KEYCODE::RIGHTBRACKET), + //GraveAccent = static_cast(SHInputManager::SH_KEYCODE::GRAVEACCENT), + + //WORLD1 = static_cast(SHInputManager::SH_KEYCODE::WORLD1), + //WORLD2 = static_cast(SHInputManager::SH_KEYCODE::WORLD2), + + /* Function keys */ + Escape = static_cast(SHInputManager::SH_KEYCODE::ESCAPE), + Enter = static_cast(SHInputManager::SH_KEYCODE::ENTER), + Tab = static_cast(SHInputManager::SH_KEYCODE::TAB), + Backspace = static_cast(SHInputManager::SH_KEYCODE::BACKSPACE), + Insert = static_cast(SHInputManager::SH_KEYCODE::INSERT), + Delete = static_cast(SHInputManager::SH_KEYCODE::DEL), + Right = static_cast(SHInputManager::SH_KEYCODE::RIGHT_ARROW), + Left = static_cast(SHInputManager::SH_KEYCODE::LEFT_ARROW), + Down = static_cast(SHInputManager::SH_KEYCODE::DOWN_ARROW), + Up = static_cast(SHInputManager::SH_KEYCODE::UP_ARROW), + PageUp = static_cast(SHInputManager::SH_KEYCODE::PAGE_UP), + PageDown = static_cast(SHInputManager::SH_KEYCODE::PAGE_DOWN), + Home = static_cast(SHInputManager::SH_KEYCODE::HOME), + End = static_cast(SHInputManager::SH_KEYCODE::END), + CapsLock = static_cast(SHInputManager::SH_KEYCODE::CAPS_LOCK), + ScrollLock = static_cast(SHInputManager::SH_KEYCODE::SCROLL_LOCK), + NumLock = static_cast(SHInputManager::SH_KEYCODE::NUM_LOCK), + PrintScreen = static_cast(SHInputManager::SH_KEYCODE::PRINT_SCREEN), + Pause = static_cast(SHInputManager::SH_KEYCODE::PAUSE), + F1 = static_cast(SHInputManager::SH_KEYCODE::F1), + F2 = static_cast(SHInputManager::SH_KEYCODE::F2), + F3 = static_cast(SHInputManager::SH_KEYCODE::F3), + F4 = static_cast(SHInputManager::SH_KEYCODE::F4), + F5 = static_cast(SHInputManager::SH_KEYCODE::F5), + F6 = static_cast(SHInputManager::SH_KEYCODE::F6), + F7 = static_cast(SHInputManager::SH_KEYCODE::F7), + F8 = static_cast(SHInputManager::SH_KEYCODE::F8), + F9 = static_cast(SHInputManager::SH_KEYCODE::F9), + F10 = static_cast(SHInputManager::SH_KEYCODE::F10), + F11 = static_cast(SHInputManager::SH_KEYCODE::F11), + F12 = static_cast(SHInputManager::SH_KEYCODE::F12), + F13 = static_cast(SHInputManager::SH_KEYCODE::F13), + F14 = static_cast(SHInputManager::SH_KEYCODE::F14), + F15 = static_cast(SHInputManager::SH_KEYCODE::F15), + F16 = static_cast(SHInputManager::SH_KEYCODE::F16), + F17 = static_cast(SHInputManager::SH_KEYCODE::F17), + F18 = static_cast(SHInputManager::SH_KEYCODE::F18), + F19 = static_cast(SHInputManager::SH_KEYCODE::F19), + F20 = static_cast(SHInputManager::SH_KEYCODE::F20), + F21 = static_cast(SHInputManager::SH_KEYCODE::F21), + F22 = static_cast(SHInputManager::SH_KEYCODE::F22), + F23 = static_cast(SHInputManager::SH_KEYCODE::F23), + F24 = static_cast(SHInputManager::SH_KEYCODE::F24), + + /* Keypad */ + KeyPad0 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_0), + KeyPad1 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_1), + KeyPad2 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_2), + KeyPad3 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_3), + KeyPad4 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_4), + KeyPad5 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_5), + KeyPad6 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_6), + KeyPad7 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_7), + KeyPad8 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_8), + KeyPad9 = static_cast(SHInputManager::SH_KEYCODE::NUMPAD_9), + //KeyPadDecimal = static_cast(SHInputManager::SH_KEYCODE::KPDECIMAL), + //KeyPadDivide = static_cast(SHInputManager::SH_KEYCODE::KPDIVIDE), + //KeyPadMultiply = static_cast(SHInputManager::SH_KEYCODE::KPMULTIPLY), + //KeyPadSubtract = static_cast(SHInputManager::SH_KEYCODE::KPSUBTRACT), + //KeyPadAdd = static_cast(SHInputManager::SH_KEYCODE::KPADD), + //KeyPadEnter = static_cast(SHInputManager::SH_KEYCODE::KPENTER), + //KeyPadEqual = static_cast(SHInputManager::SH_KEYCODE::KEYPAD), + + Shift = static_cast(SHInputManager::SH_KEYCODE::SHIFT), + LeftControl = static_cast(SHInputManager::SH_KEYCODE::LEFT_CTRL), + LeftAlt = static_cast(SHInputManager::SH_KEYCODE::LEFT_ALT), + LeftSuper = static_cast(SHInputManager::SH_KEYCODE::LEFT_WINDOWS), + RightShift = static_cast(SHInputManager::SH_KEYCODE::RIGHT_SHIFT), + RightControl = static_cast(SHInputManager::SH_KEYCODE::RIGHT_CTRL), + RightAlt = static_cast(SHInputManager::SH_KEYCODE::RIGHT_ALT), + RightSuper = static_cast(SHInputManager::SH_KEYCODE::RIGHT_WINDOWS), + + /* Gamepad */ + JoystickA = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_A), + JoystickB = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_B), + JoystickX = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_X), + JoystickY = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_Y), + JoystickLeftBumper = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTSHOULDER), + JoystickRightBumper = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTSHOULDER), + JoystickLeftTrigger = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTTRIGGER), + JoystickRightTrigger = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTTRIGGER), + JoystickDPadUp = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_UP), + JoystickDPadDown = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_DOWN), + JoystickDPadLeft = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_LEFT), + JoystickDPadRight = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_RIGHT), + JoystickMenu = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_MENU), + JoystickView = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_VIEW), + JoystickLeftStick = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_LEFT_THUMBSTICK_BUTTON), + JoystickRightStick = static_cast(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHT_THUMBSTICK_BUTTON), + + /* Unity Gamepad Mappings */ + JoystickButton0 = JoystickA, + JoystickButton1 = JoystickB, + JoystickButton2 = JoystickX, + JoystickButton3 = JoystickY, + JoystickButton4 = JoystickLeftBumper, + JoystickButton5 = JoystickRightBumper, + JoystickButton6 = JoystickView, + JoystickButton7 = JoystickMenu, + JoystickButton8 = JoystickLeftStick, + JoystickButton9 = JoystickRightStick + + }; + /// + /// Represents the available supported mouse keycodes that can be passed into the + /// mouse-button-based Input functions. + /// + enum class MouseCode : int + { + LeftButton = static_cast(SHInputManager::SH_KEYCODE::LMB), + RightButton = static_cast(SHInputManager::SH_KEYCODE::RMB), + MiddleButton = static_cast(SHInputManager::SH_KEYCODE::MMB), + Button3 = static_cast(SHInputManager::SH_KEYCODE::XMB1), + Button4 = static_cast(SHInputManager::SH_KEYCODE::XMB2) + }; + + /*-----------------------------------------------------------------------------*/ + /* Properites */ + /*-----------------------------------------------------------------------------*/ + /// + /// Mouse position in screen coordinates relative to the top left of the window. + /// This value is a Vector3 for compatibility with functions that have Vector3 + /// arguments. The z component of the Vector3 is always 0 + /// + static property Vector3 MousePosition + { + Vector3 get(); + } + /// + /// Amnount of vertical mouse scroll in this frame. + /// + static property int MouseScrollDelta + { + int get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Checks if a specified key is being held down. + /// This will also be true if GetKeyDown() is true. + /// + /// KeyCode of the key to check. + /// True while the user holds down the key specified. + static bool GetKey(KeyCode key); + /// + /// Checks if a specified key is pressed and was not pressed before. + /// + /// KeyCode of the key to check. + /// + /// True during the frame the user starts pressing down the key specified. + /// + static bool GetKeyDown(KeyCode key); + /// + /// Checks if a specified key is no longer pressed pressed and was pressed + /// before. + /// + /// KeyCode of the key to check. + /// + /// True during the frame the user releases the key identified by name. + /// + static bool GetKeyUp(KeyCode key); + /// + /// Checks if a specified mouse button is being held down. + /// This will also be true if GetMouseButtonDown() is true. + /// + /// MouseCode of the mouse button to check. + /// True while the user holds down the mouse button specified. + static bool GetMouseButton(MouseCode mouseButton); + /// + /// Checks if a specified mouse button is pressed and was not pressed before. + /// + /// MouseCode of the mouse button to check. + /// + /// True during the frame the user pressed the given mouse button. + /// + static bool GetMouseButtonDown(MouseCode mouseButton); + /// + /// Checks if a specified mouse button is no longer pressed and was pressed + /// before. + /// + /// MouseCode of the mouse button to check. + /// + /// True during the frame the user releases the given mouse button. + /// + static bool GetMouseButtonUp(MouseCode mouseButton); + + /*-----------------------------------------------------------------------------*/ + /* Cursor Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Sets the position of the mouse cursor relative to the top left corner of the + /// window. + /// + /// + /// Position of the mouse in window pixel coordinates to set. + /// + static void SetMousePosition(Vector2 pos); + + /*-----------------------------------------------------------------------------*/ + /* Timing Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Retrieves the duration that the specified key has been held or was last held + /// for. + /// + /// The key to check. + /// Time in seconds that the key was held. + static double GetKeyHeldTime(KeyCode key); + /// + /// Retrieves the duration that the specified key has not been held or was last + /// not been held for. + /// + /// The key to check. + /// Time in seconds that the key was held. + static double GetKeyReleasedTime(KeyCode key); + /// + /// Retrieves the duration that the specified key has been held or was last held + /// for. + /// + /// The key to check. + /// Time in seconds that the key was held. + static double GetMouseHeldTime(MouseCode mouseButton); + /// + /// Retrieves the duration that the specified key has not been held or was last + /// not been held for. + /// + /// The key to check. + /// Time in seconds that the key was held. + static double GetMouseReleasedTime(MouseCode mouseButton); + }; +} \ No newline at end of file From 808274fce08c6f1ebf72f6b4308440b79b63e9e7 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 14:16:14 +0800 Subject: [PATCH 07/24] Lots of changes - World renderer graph add new resource for scene - G-Buffer Write subpass now renders offscreen to a color attachment - Added a new subpass "Scene layout transition" to get vulkan to help transition our scene image layout to shader read - Added back SHEDITOR check - Created a post offscreen render system to create the necessary objects - SH_ATT_DESC_TYPE is now SH_ATT_DESC_TYPE_FLAGS. Render graph resources also now store a bit field instead of a single type. - Render graph nodes now have more customization when it comes to registering resources. They now have the option to not clear resources on begin. --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 23 +++- .../MiddleEnd/Interface/SHGraphicsSystem.h | 20 +-- .../Interface/SHPostOffscreenRenderSystem.cpp | 79 ++++++++++++ .../Interface/SHPostOffscreenRenderSystem.h | 29 +++++ .../SHAttachmentDescInitParams.cpp | 7 + .../RenderGraph/SHAttachmentDescInitParams.h | 14 ++ .../RenderGraph/SHAttachmentDescriptionType.h | 13 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 50 +++++-- .../src/Graphics/RenderGraph/SHRenderGraph.h | 23 +++- .../RenderGraph/SHRenderGraphNode.cpp | 16 ++- .../Graphics/RenderGraph/SHRenderGraphNode.h | 3 +- .../RenderGraph/SHRenderGraphResource.cpp | 122 +++++++++++------- .../RenderGraph/SHRenderGraphResource.h | 13 +- .../src/Graphics/RenderGraph/SHSubpass.cpp | 8 +- .../src/Graphics/RenderGraph/SHSubpass.h | 2 +- SHADE_Engine/src/Graphics/SHVulkanDefines.h | 1 + 16 files changed, 317 insertions(+), 106 deletions(-) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp create mode 100644 SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 09f1c93e..14ddf7be 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -144,27 +144,32 @@ namespace SHADE // Initialize world render graph worldRenderGraph->Init(device, swapchain); - worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second); - worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + worldRenderGraph->AddResource("Present", {SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT}, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene", {SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT}, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Depth Buffer", {SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL}, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + worldRenderGraph->AddResource("Entity ID", {SH_ATT_DESC_TYPE_FLAGS::COLOR}, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); //worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); //worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm); - auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Present"}, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); - gBufferWriteSubpass->AddColorOutput("Present"); + gBufferWriteSubpass->AddColorOutput("Scene"); gBufferWriteSubpass->AddColorOutput("Entity ID"); - gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL); + gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); + // We do this to just transition our scene layout to shader read + auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); + sceneLayoutTransitionSubpass->AddInput("Scene"); - // TODO: Use macro to add this node when SH_EDITOR is enabled +#ifdef SHEDITOR auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"}); auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); imguiSubpass->AddColorOutput("Present"); +#endif worldRenderGraph->Generate(); @@ -207,6 +212,10 @@ namespace SHADE cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); + + // Register the post offscreen render to the system + postOffscreenRender = resourceManager.Create(); + postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 3160cd57..517b5999 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -31,6 +31,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h" #include "../Textures/SHTextureLibrary.h" #include "../Textures/SHVkSamplerCache.h" +#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h" namespace SHADE { @@ -262,14 +263,15 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Getters (Temporary) */ /*-----------------------------------------------------------------------------*/ - Handle GetDevice() const { return device; } - Handle GetSwapchain() const { return swapchain; } - Handle GetSurface() const { return surface; } - Handle GetPhysicalDevice() const { return physicalDevice; } - Handle GetQueue() const { return graphicsQueue; } - Handle GetDescriptorPool() const { return descPool; } - Handle GetDefaultViewport() const {return defaultViewport;} - Handle GetMousePickSystem(void) const noexcept {return mousePickSystem;}; + Handle GetDevice() const { return device; } + Handle GetSwapchain() const { return swapchain; } + Handle GetSurface() const { return surface; } + Handle GetPhysicalDevice() const { return physicalDevice; } + Handle GetQueue() const { return graphicsQueue; } + Handle GetDescriptorPool() const { return descPool; } + Handle GetDefaultViewport() const {return defaultViewport;} + Handle GetMousePickSystem(void) const noexcept {return mousePickSystem;}; + Handle GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; //SHRenderGraph const& GetRenderGraph(void) const noexcept; //Handle GetRenderPass() const { return renderPass; } @@ -327,5 +329,7 @@ namespace SHADE // Sub systems Handle mousePickSystem; + Handle postOffscreenRender; + }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp new file mode 100644 index 00000000..7d40d9bd --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -0,0 +1,79 @@ +#include "SHpch.h" +#include "SHPostOffscreenRenderSystem.h" +#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/Descriptors/SHVkDescriptorPool.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Images/SHVkSampler.h" +#include "Graphics/RenderGraph/SHRenderGraphResource.h" + +namespace SHADE +{ + /***************************************************************************/ + /*! + + \brief + This function basically creates the entities required for offscreen + rendering. It takes in a render graph resource. Side note: it creates + a descriptor set layout that is similar to the one created in imgui. This + is so that the descriptor set passed to imGui won't be invalid. + + \param logicalDevice + For vulkan object creation + + \param renderGraphResource + The resource in which has been + + \param descriptorPool + + \return + + */ + /***************************************************************************/ + void SHPostOffscreenRenderSystem::Init(Handle logicalDevice, Handle renderGraphResource, Handle descriptorPool) noexcept + { + offscreenRender = renderGraphResource; + + // Create sampler + offscreenRenderSampler = logicalDevice->CreateSampler( + { + .minFilter = vk::Filter::eLinear, + .magFilter = vk::Filter::eLinear, + .addressMode = vk::SamplerAddressMode::eRepeat, + .mipmapMode = vk::SamplerMipmapMode::eLinear, + .minLod = -1000, + .maxLod = 1000 + } + ); + + // Create descriptor set layout binding + SHVkDescriptorSetLayout::Binding imageBinding + { + .Type = vk::DescriptorType::eCombinedImageSampler, + .Stage = vk::ShaderStageFlagBits::eFragment, + .BindPoint = 0, + .DescriptorCount = 1, + }; + + // Create descriptor set layout + offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }); + + // Create descriptor set + offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 }); + + std::vector combinedImageSampler + { + std::make_tuple(renderGraphResource->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal), + }; + + // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change + offscreenRenderDescSet->ModifyWriteDescImage(0, 0, combinedImageSampler); + offscreenRenderDescSet->UpdateDescriptorSetImages(0, 0); + } + + Handle SHPostOffscreenRenderSystem::GetDescriptorSetGroup(void) const noexcept + { + return offscreenRenderDescSet; + } + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h new file mode 100644 index 00000000..90767bc2 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h @@ -0,0 +1,29 @@ +#pragma once + +#include "Resource/Handle.h" + +namespace SHADE +{ + class SHVkLogicalDevice; + class SHVkDescriptorSetLayout; + class SHVkDescriptorSetGroup; + class SHVkDescriptorPool; + class SHVkSampler; + class SHRenderGraphResource; + + class SHPostOffscreenRenderSystem + { + private: + Handle offscreenRender; + + Handle offscreenRenderDescSetLayout; + Handle offscreenRenderDescSet; + Handle offscreenRenderSampler; + + public: + void Init (Handle logicalDevice, Handle renderGraphResource, Handle descriptorPool) noexcept; + //void Run () + + Handle GetDescriptorSetGroup (void) const noexcept; + }; +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp new file mode 100644 index 00000000..6e01269e --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp @@ -0,0 +1,7 @@ +#include "SHpch.h" +#include "SHAttachmentDescInitParams.h" + +namespace SHADE +{ + +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h new file mode 100644 index 00000000..20e924cb --- /dev/null +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Resource/Handle.h" + +namespace SHADE +{ + class SHRenderGraphResource; + + struct SHAttachmentDescInitParams + { + Handle resourceHdl; + bool dontClearOnLoad{false}; + }; +} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h index dc21fa37..241292d4 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h @@ -3,12 +3,13 @@ namespace SHADE { // Used for attachment description creation for renderpass node - enum class SH_ATT_DESC_TYPE + enum class SH_ATT_DESC_TYPE_FLAGS { - COLOR, - COLOR_PRESENT, - DEPTH, - STENCIL, - DEPTH_STENCIL, + COLOR = 0x01, + COLOR_PRESENT = 0x02, + DEPTH = 0x04, + STENCIL = 0x08, + DEPTH_STENCIL = 0x10, + INPUT = 0x20 }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 1861f6d2..51584300 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -8,10 +8,17 @@ #include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Tools/SHLogger.h" +#include "SHAttachmentDescInitParams.h" namespace SHADE { - + + SHRenderGraph::ResourceInstruction::ResourceInstruction(char const* resourceName, bool dontClearOnLoad /*= false*/) noexcept + : resourceName{ resourceName } + , dontClearOnLoad{ dontClearOnLoad } + { + + } /***************************************************************************/ /*! @@ -40,7 +47,7 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast(-1)*/, uint32_t h /*= static_cast(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/) + void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w /*= static_cast(-1)*/, uint32_t h /*= static_cast(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/) { // If we set to if (w == static_cast(-1) && h == static_cast(-1)) @@ -50,7 +57,7 @@ namespace SHADE format = swapchainHdl->GetSurfaceFormatKHR().format; } - graphResources.try_emplace(resourceName, resourceManager.Create(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, usageFlags, createFlags)); + graphResources.try_emplace(resourceName, resourceManager.Create(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); } /***************************************************************************/ @@ -82,7 +89,7 @@ namespace SHADE { for (auto& color : subpass->colorReferences) { - if (i == nodes.size() - 1 && node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) + if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))) resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR; else resourceAttLayouts[color.attachment] = color.layout; @@ -210,10 +217,18 @@ namespace SHADE for (auto& inputAtt : subpass->inputReferences) { auto resource = node->attResources[inputAtt.attachment]; - if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR || resource->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) - colorRead |= (1 << i); - else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL) - depthRead |= (1 << i); + if (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::INPUT)) + { + if (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR) || + resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) + colorRead |= (1 << i); + else if (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL)) + depthRead |= (1 << i); + } + else + { + SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. "); + } } ++i; @@ -400,7 +415,7 @@ namespace SHADE */ /***************************************************************************/ - Handle SHRenderGraph::AddNode(std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept + SHADE::Handle SHRenderGraph::AddNode(std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept { if (nodeIndexing.contains(nodeName)) { @@ -408,12 +423,19 @@ namespace SHADE return {}; } - std::vector> resources; - for (auto const& name : resourceNames) + std::vector descInitParams; + for (auto const& instruction : resourceInstruction) { // If the resource that the new node is requesting for exists, allow the graph to reference it - if (graphResources.contains(name)) - resources.push_back(graphResources.at(name)); + if (graphResources.contains(instruction.resourceName)) + { + descInitParams.push_back( + { + .resourceHdl = graphResources.at(instruction.resourceName), + .dontClearOnLoad = false, + } + ); + } else { SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node."); @@ -435,7 +457,7 @@ namespace SHADE } } - nodes.emplace_back(resourceManager.Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources)); + nodes.emplace_back(resourceManager.Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources)); nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u); return nodes.at(nodeIndexing[nodeName]); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index cfc29bc2..8eb458aa 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -33,7 +33,17 @@ namespace SHADE class SH_API SHRenderGraph { + public: + struct ResourceInstruction + { + std::string resourceName; + bool dontClearOnLoad; + + ResourceInstruction (char const* resourceName, bool dontClearOnLoad = false) noexcept; + }; + private: + /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ @@ -74,13 +84,14 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle const& logicalDevice, Handle const& swapchain) noexcept; - void AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); - Handle AddNode (std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept; + void Init (Handle const& logicalDevice, Handle const& swapchain) noexcept; + void AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); + Handle AddNode (std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept; + void Generate (void) noexcept; - void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; - void FinaliseBatch(uint32_t frameIndex, Handle descPool); - void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; + void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; + void FinaliseBatch(uint32_t frameIndex, Handle descPool); + void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index ea09dd47..0ff8fe96 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -42,7 +42,7 @@ namespace SHADE for (uint32_t j = 0; j < attResources.size(); ++j) { - uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0; + uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; imageViews[j] = attResources[j]->imageViews[imageViewIndex]; // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's @@ -69,7 +69,7 @@ namespace SHADE for (uint32_t j = 0; j < attResources.size(); ++j) { - uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0; + uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0; imageViews[j] = attResources[j]->imageViews[imageViewIndex]; // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's @@ -104,14 +104,14 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector> attRes, std::vector> predecessors, std::unordered_map> const* resources) noexcept + SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept : logicalDeviceHdl{ logicalDevice } , renderpass{} , framebuffers{} , prereqNodes{ std::move(predecessors) } , attachmentDescriptions{} , resourceAttachmentMapping{} - , attResources{ std::move(attRes) } + , attResources{ } , subpasses{} , executed{ false } , configured{ false } @@ -121,6 +121,12 @@ namespace SHADE // pipeline library initialization pipelineLibrary.Init(logicalDeviceHdl); + // Store all the handles to resources + attResources.reserve (attDescInitParams.size()); + for (auto& param : attDescInitParams) + attResources.push_back(param.resourceHdl); + + // We have as many descriptions as we have resources attachmentDescriptions.resize(attResources.size()); bool containsSwapchainImage = false; @@ -140,7 +146,7 @@ namespace SHADE newDesc.format = attResources[i]->resourceFormat; - if (attResources[i]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) + if (attResources[i]->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) containsSwapchainImage = true; resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 28527a92..f36e7622 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -9,6 +9,7 @@ #include "SH_API.h" #include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h" #include "Graphics/MiddleEnd/Batching/SHBatcher.h" +#include "SHAttachmentDescInitParams.h" namespace SHADE { @@ -87,7 +88,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector> attRes, std::vector> predecessors, std::unordered_map> const* resources) noexcept; + SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index bcd1dc9f..adf3b6cd 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -45,10 +45,10 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphResource::SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept + SHRenderGraphResource::SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept : logicalDevice {logicalDevice} , swapchain{ swapchain } - , resourceType{ type } + , resourceTypeFlags{ } , resourceFormat{ format } , images{} , imageViews{} @@ -58,52 +58,10 @@ namespace SHADE , resourceName{ name } { // If the resource type is an arbitrary image and not swapchain image - if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) + if (typeFlags.size() == 1 && *typeFlags.begin() == SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT) { - imageAspectFlags = vk::ImageAspectFlags{}; - usage = usageFlags; + resourceTypeFlags |= static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT); - // Check the resource type and set image usage flags and image aspect flags accordingly - switch (resourceType) - { - case SH_ATT_DESC_TYPE::COLOR: - usage |= vk::ImageUsageFlagBits::eColorAttachment; - imageAspectFlags |= vk::ImageAspectFlagBits::eColor; - break; - case SH_ATT_DESC_TYPE::DEPTH: - usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; - imageAspectFlags |= vk::ImageAspectFlagBits::eDepth; - break; - case SH_ATT_DESC_TYPE::STENCIL: - usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; - imageAspectFlags |= vk::ImageAspectFlagBits::eStencil; - break; - case SH_ATT_DESC_TYPE::DEPTH_STENCIL: - usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; - imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth; - break; - } - - // The resource is not a swapchain image, just use the first slot of the vector - images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); - - // prepare image view details - SHImageViewDetails viewDetails - { - .viewType = vk::ImageViewType::e2D, - .format = images[0]->GetImageFormat(), - .imageAspectFlags = imageAspectFlags, - .baseMipLevel = 0, - .mipLevelCount = mipLevels, - .baseArrayLayer = 0, - .layerCount = 1, - }; - - // just 1 image view created - imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails)); - } - else // if swapchain image resource - { // Prepare image view details SHImageViewDetails viewDetails { @@ -126,6 +84,65 @@ namespace SHADE imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails); } } + else // if swapchain image resource + { + imageAspectFlags = vk::ImageAspectFlags{}; + usage = usageFlags; + + for (auto& type : typeFlags) + { + // store the flags + resourceTypeFlags |= static_cast(type); + + // Check the resource type and set image usage flags and image aspect flags accordingly + switch (type) + { + case SH_ATT_DESC_TYPE_FLAGS::COLOR: + usage |= vk::ImageUsageFlagBits::eColorAttachment; + imageAspectFlags |= vk::ImageAspectFlagBits::eColor; + break; + case SH_ATT_DESC_TYPE_FLAGS::DEPTH: + usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; + imageAspectFlags |= vk::ImageAspectFlagBits::eDepth; + break; + case SH_ATT_DESC_TYPE_FLAGS::STENCIL: + usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; + imageAspectFlags |= vk::ImageAspectFlagBits::eStencil; + break; + case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL: + usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; + imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth; + break; + case SH_ATT_DESC_TYPE_FLAGS::INPUT: + usage |= vk::ImageUsageFlagBits::eInputAttachment; + usage |= vk::ImageUsageFlagBits::eSampled; + break; + case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT: + { + SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. "); + return; + } + } + } + + // The resource is not a swapchain image, just use the first slot of the vector + images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); + + // prepare image view details + SHImageViewDetails viewDetails + { + .viewType = vk::ImageViewType::e2D, + .format = images[0]->GetImageFormat(), + .imageAspectFlags = imageAspectFlags, + .baseMipLevel = 0, + .mipLevelCount = mipLevels, + .baseArrayLayer = 0, + .layerCount = 1, + }; + + // just 1 image view created + imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails)); + } } /***************************************************************************/ @@ -141,7 +158,7 @@ namespace SHADE /***************************************************************************/ SHRenderGraphResource::SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept : resourceName{ std::move(rhs.resourceName) } - , resourceType{ std::move(rhs.resourceType) } + , resourceTypeFlags{ std::move(rhs.resourceTypeFlags) } , images{ std::move(rhs.images) } , imageViews{ std::move(rhs.imageViews) } , resourceFormat{ std::move(rhs.resourceFormat) } @@ -149,6 +166,7 @@ namespace SHADE , height{ rhs.height } , mipLevels{ rhs.mipLevels } , imageAspectFlags{ rhs.imageAspectFlags } + , swapchain {rhs.swapchain} { } @@ -172,7 +190,7 @@ namespace SHADE return *this; resourceName = std::move(rhs.resourceName); - resourceType = std::move(rhs.resourceType); + resourceTypeFlags = std::move(rhs.resourceTypeFlags); images = std::move(rhs.images); imageViews = std::move(rhs.imageViews); resourceFormat = std::move(rhs.resourceFormat); @@ -180,6 +198,7 @@ namespace SHADE height = rhs.height; mipLevels = rhs.mipLevels; imageAspectFlags = rhs.imageAspectFlags; + swapchain = rhs.swapchain; return *this; } @@ -202,7 +221,7 @@ namespace SHADE width = newWidth; height = newHeight; - if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) + if ((resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) == 0) { // prepare image view details SHImageViewDetails viewDetails @@ -299,4 +318,9 @@ namespace SHADE return height; } + Handle SHRenderGraphResource::GetImageView(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept + { + return imageViews [index]; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h index 66f0677b..efaf9bf5 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h @@ -16,6 +16,8 @@ namespace SHADE class SHVkCommandBuffer; class SHVkBuffer; + static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0; + class SH_API SHRenderGraphResource { private: @@ -32,7 +34,7 @@ namespace SHADE std::string resourceName; //! Used for initializing image layouts - SH_ATT_DESC_TYPE resourceType; + SHRenderGraphResourceFlags resourceTypeFlags; //! The resource itself (this is a vector because if the resource happens //! to be a swapchain image, then we need however many frames in flight). @@ -67,7 +69,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; + SHRenderGraphResource(Handle const& logicalDevice, Handle const& swapchain, std::string const& name, std::initializer_list typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; ~SHRenderGraphResource(void) noexcept; @@ -82,9 +84,10 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - vk::Format GetResourceFormat (void) const noexcept; - uint32_t GetWidth (void) const noexcept; - uint32_t GetHeight (void) const noexcept; + vk::Format GetResourceFormat (void) const noexcept; + uint32_t GetWidth (void) const noexcept; + uint32_t GetHeight (void) const noexcept; + Handle GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept; friend class SHRenderGraphNode; friend class SHRenderGraph; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index abd3a7be..6afbfb09 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -120,18 +120,18 @@ namespace SHADE */ /***************************************************************************/ - void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept + void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType) noexcept { vk::ImageLayout imageLayout; switch (attachmentDescriptionType) { - case SH_ATT_DESC_TYPE::DEPTH: + case SH_ATT_DESC_TYPE_FLAGS::DEPTH: imageLayout = vk::ImageLayout::eDepthAttachmentOptimal; break; - case SH_ATT_DESC_TYPE::STENCIL: + case SH_ATT_DESC_TYPE_FLAGS::STENCIL: imageLayout = vk::ImageLayout::eStencilAttachmentOptimal; break; - case SH_ATT_DESC_TYPE::DEPTH_STENCIL: + case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL: imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal; break; default: diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index aba282b9..2e883ebc 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -71,7 +71,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ // Preparation functions void AddColorOutput(std::string resourceToReference) noexcept; - void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept; + void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept; void AddInput(std::string resourceToReference) noexcept; // Runtime functions diff --git a/SHADE_Engine/src/Graphics/SHVulkanDefines.h b/SHADE_Engine/src/Graphics/SHVulkanDefines.h index 1cbcae0f..a0a6d57c 100644 --- a/SHADE_Engine/src/Graphics/SHVulkanDefines.h +++ b/SHADE_Engine/src/Graphics/SHVulkanDefines.h @@ -12,6 +12,7 @@ namespace SHADE using BindingAndSetHash = uint64_t; using SetIndex = uint32_t; using SHSubPassIndex = uint32_t; + using SHRenderGraphResourceFlags = uint32_t; } From 2830dad8e3f9d810d71d4dbeaaf80f704857e5c0 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 15:35:32 +0800 Subject: [PATCH 08/24] Fixed Kai Wei's issues (sampler move ctor never move device :D) --- SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp | 4 +++- .../src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp index f12b834d..30bcde79 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp @@ -39,7 +39,8 @@ namespace SHADE } SHVkSampler::SHVkSampler(SHVkSampler&& rhs) noexcept - : vkSampler { rhs.vkSampler } + : vkSampler{ rhs.vkSampler } + , device{ rhs.device } { rhs.vkSampler = nullptr; } @@ -56,6 +57,7 @@ namespace SHADE SHADE::SHVkSampler& SHVkSampler::operator=(SHVkSampler&& rhs) noexcept { vkSampler = rhs.vkSampler; + device = rhs.device; rhs.vkSampler = nullptr; return *this; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 14ddf7be..247c58fd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -189,7 +189,6 @@ namespace SHADE worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); - // TODO: This is VERY temporarily here until a more solid resource management system is implemented shaderSourceLibrary.Init("../../TempShaderFolder/"); From 0d02ece4c1f88272bb5b135a7cafccceaeacb38c Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 16:28:29 +0800 Subject: [PATCH 09/24] Wrote handle resize for mouse picking objects --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 2 ++ .../MiddleEnd/Interface/SHMousePickSystem.cpp | 29 ++++++++++++++----- .../MiddleEnd/Interface/SHMousePickSystem.h | 5 +++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 247c58fd..cd99648c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -559,6 +559,8 @@ namespace SHADE worldRenderGraph->HandleResize(windowDims.first, windowDims.second); + mousePickSystem->HandleResize(); + defaultViewport->SetWidth(static_cast(windowDims.first)); defaultViewport->SetHeight(static_cast(windowDims.second)); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index ee8665d5..e4ac92e5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -9,8 +9,10 @@ namespace SHADE { - void SHMousePickSystem::Init(Handle logicalDevice, std::span> cmdPools, Handle eidAttachment) noexcept + void SHMousePickSystem::Init(Handle device, std::span> cmdPools, Handle eidAttachment) noexcept { + logicalDevice = device; + pickedEID = 0; // Create command buffers @@ -22,13 +24,7 @@ namespace SHADE // assign the attachment entityIDAttachment = eidAttachment; - // Create the fence - afterCopyFence = logicalDevice->CreateFence(); - - uint32_t bufferSize = entityIDAttachment->GetWidth() * eidAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat()); - - // Create the buffer - imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + HandleResize(); } void SHMousePickSystem::Run(Handle queue, uint32_t frameIndex) noexcept @@ -63,6 +59,23 @@ namespace SHADE } } + void SHMousePickSystem::HandleResize(void) noexcept + { + if (afterCopyFence) + afterCopyFence.Free(); + + if (imageDataDstBuffer) + imageDataDstBuffer.Free(); + + // Create the fence + afterCopyFence = logicalDevice->CreateFence(); + + uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat()); + + // Create the buffer + imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + } + EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept { return pickedEID; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h index 080a192c..4b84c1df 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h @@ -17,6 +17,8 @@ namespace SHADE class SHMousePickSystem { private: + Handle logicalDevice; + //! Handle to the render graph resource that will contain the entity IDs Handle entityIDAttachment; @@ -35,8 +37,9 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init(Handle logicalDevice, std::span> cmdPools, Handle eidAttachment) noexcept; + void Init(Handle device, std::span> cmdPools, Handle eidAttachment) noexcept; void Run (Handle queue, uint32_t frameIndex) noexcept; + void HandleResize (void) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ From 1117ecc5ef9556061681b7f50b20450ba93270da Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 17:31:53 +0800 Subject: [PATCH 10/24] WIP --- .../src/Graphics/Devices/SHVkLogicalDevice.cpp | 5 ++--- .../src/Graphics/Devices/SHVkLogicalDevice.h | 2 +- .../src/Graphics/Images/SHVkSampler.cpp | 17 +++++++++-------- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 1 + .../Interface/SHPostOffscreenRenderSystem.cpp | 4 ++-- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 4f4f94a4..7c7acfc5 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -550,10 +550,9 @@ namespace SHADE } - Handle SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector const& bindings) noexcept + Handle SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector const& bindings, bool genImmutableSamplers/* = false*/) noexcept { - return SHVkInstance::GetResourceManager().Create (GetHandle(), setIndex, bindings); - + return SHVkInstance::GetResourceManager().Create (GetHandle(), setIndex, bindings, genImmutableSamplers); } Handle SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 5c400e02..6f7048b8 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -186,7 +186,7 @@ namespace SHADE Handle CreateRenderpass (std::span const vkDescriptions, std::vector const& subpasses) noexcept; Handle CreateRenderpass (std::span const vkDescriptions, std::span const spDescs, std::span const spDeps) noexcept; Handle CreateFramebuffer (Handle const& renderpassHdl, std::vector> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept; - Handle CreateDescriptorSetLayout (SetIndex setIndex, std::vector const& bindings) noexcept; + Handle CreateDescriptorSetLayout (SetIndex setIndex, std::vector const& bindings, bool genImmutableSamplers = false) noexcept; Handle CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept; Handle CreateDescriptorSetGroup(Handle pool, std::vector> const& layouts, diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp index 30bcde79..4300f2bd 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp @@ -24,14 +24,15 @@ namespace SHADE { const vk::SamplerCreateInfo SAMPLER_CREATE_INFO { - .magFilter = params.magFilter, - .minFilter = params.minFilter, - .mipmapMode = params.mipmapMode, - .addressModeU = params.addressMode, - .addressModeV = params.addressMode, - .addressModeW = params.addressMode, - .minLod = params.minLod, - .maxLod = params.maxLod + .magFilter = params.magFilter, + .minFilter = params.minFilter, + .mipmapMode = params.mipmapMode, + .addressModeU = params.addressMode, + .addressModeV = params.addressMode, + .addressModeW = params.addressMode, + .maxAnisotropy = 1.0f, + .minLod = params.minLod, + .maxLod = params.maxLod, }; // Create the sampler diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index cd99648c..6d9a84aa 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -560,6 +560,7 @@ namespace SHADE worldRenderGraph->HandleResize(windowDims.first, windowDims.second); mousePickSystem->HandleResize(); + //postOffscreenRender->HandleResize(); defaultViewport->SetWidth(static_cast(windowDims.first)); defaultViewport->SetHeight(static_cast(windowDims.second)); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp index 7d40d9bd..bbc7c021 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -56,14 +56,14 @@ namespace SHADE }; // Create descriptor set layout - offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }); + offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, true); // Create descriptor set offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 }); std::vector combinedImageSampler { - std::make_tuple(renderGraphResource->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal), + std::make_tuple(renderGraphResource->GetImageView(), Handle{}, vk::ImageLayout::eShaderReadOnlyOptimal), }; // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change From c16bea2d39fb0e86d6820ee0eb166e2b1d3ca852 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 17:35:15 +0800 Subject: [PATCH 11/24] WIP --- .../Descriptors/SHVkDescriptorSetGroup.cpp | 2 +- .../Descriptors/SHVkDescriptorSetLayout.cpp | 29 +++++++++++++++++-- .../Descriptors/SHVkDescriptorSetLayout.h | 4 ++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index e842df47..ea859718 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -172,7 +172,7 @@ namespace SHADE // write sampler and image view auto& [view, sampler, layout] = imageViewsAndSamplers[i]; writeInfo.descImageInfos[i].imageView = view->GetImageView(); - writeInfo.descImageInfos[i].sampler = sampler->GetVkSampler(); + writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr; writeInfo.descImageInfos[i].imageLayout = layout; } } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp index 002aa29d..0943c489 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp @@ -1,16 +1,18 @@ #include "SHPch.h" #include "SHVkDescriptorSetLayout.h" #include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Images/SHVkSampler.h" namespace SHADE { /*---------------------------------------------------------------------------------*/ /* Constructor/Destructor */ /*---------------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, SetIndex set, const std::vector& bindings) + SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, SetIndex set, const std::vector& bindings, bool genImmutableSamplers/* = false*/) : device { device } , layoutDesc { bindings } , setIndex {set} + , immutableSampler{} { // Check if auto-binding point calculation configuration is valid bool autoCalc = false; @@ -26,6 +28,25 @@ namespace SHADE } } + vk::Sampler tempVkSampler = nullptr; + if (genImmutableSamplers) + { + // Create sampler + immutableSampler = device->CreateSampler( + { + .minFilter = vk::Filter::eLinear, + .magFilter = vk::Filter::eLinear, + .addressMode = vk::SamplerAddressMode::eRepeat, + .mipmapMode = vk::SamplerMipmapMode::eLinear, + .minLod = -1000, + .maxLod = 1000 + } + ); + + tempVkSampler = immutableSampler->GetVkSampler(); + } + + // Fill up VK bindings with auto calculated bind points if needed std::vector layoutBindings; layoutBindings.reserve(bindings.size()); @@ -39,7 +60,7 @@ namespace SHADE .descriptorType = binding.Type, .descriptorCount = binding.DescriptorCount, .stageFlags = binding.Stage, - .pImmutableSamplers = nullptr // We will create our own samplers + .pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr, }; layoutBindings.emplace_back(VK_BINDING); @@ -75,7 +96,8 @@ namespace SHADE : device {rhs.device} , setLayout {rhs.setLayout} , layoutDesc{std::move (rhs.layoutDesc)} - , setIndex {rhs.setIndex} + , setIndex{ rhs.setIndex } + , immutableSampler{ rhs.immutableSampler } { rhs.setLayout = VK_NULL_HANDLE; } @@ -106,6 +128,7 @@ namespace SHADE setLayout = rhs.setLayout; layoutDesc = std::move(rhs.layoutDesc); setIndex = rhs.setIndex; + immutableSampler = rhs.immutableSampler; rhs.setLayout = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h index 9b436026..4fffbc96 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h @@ -10,6 +10,7 @@ namespace SHADE /* Forward Declarations */ /*---------------------------------------------------------------------------------*/ class SHVkLogicalDevice; + class SHVkSampler; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -74,7 +75,7 @@ namespace SHADE /// /// /// - SHVkDescriptorSetLayout(Handle device, SetIndex setIndex, const std::vector& bindings); + SHVkDescriptorSetLayout(Handle device, SetIndex setIndex, const std::vector& bindings, bool genImmutableSamplers = false); SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete; SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept; /// @@ -107,5 +108,6 @@ namespace SHADE vk::DescriptorSetLayout setLayout; std::vector layoutDesc; // Stores description of the layout SetIndex setIndex; // Index of the set + Handle immutableSampler; }; } \ No newline at end of file From 95ee4b7b550c090bd982a3f59615243ffc297a12 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Sun, 16 Oct 2022 19:42:44 +0800 Subject: [PATCH 12/24] Resize half working --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 20 +++++++++++++------ .../MiddleEnd/Interface/SHGraphicsSystem.h | 3 +++ .../Interface/SHPostOffscreenRenderSystem.cpp | 9 +++++++-- .../Interface/SHPostOffscreenRenderSystem.h | 2 ++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 6d9a84aa..21d7569e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -71,7 +71,7 @@ namespace SHADE if (width == 0 || height == 0) return; - renderContext.SetIsResized(true); + PrepareResize(resizeWidth, resizeHeight); }); window->RegisterWindowCloseCallback([&](void) @@ -545,6 +545,14 @@ namespace SHADE ); } + void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept + { + resizeWidth = newWidth; + resizeHeight = newHeight; + + renderContext.SetIsResized(true); + } + void SHGraphicsSystem::HandleResize(void) noexcept { if (window->IsMinimized() || renderContext.GetWindowIsDead()) @@ -557,15 +565,15 @@ namespace SHADE renderContext.HandleResize(); - worldRenderGraph->HandleResize(windowDims.first, windowDims.second); + worldRenderGraph->HandleResize(resizeWidth, resizeHeight); mousePickSystem->HandleResize(); - //postOffscreenRender->HandleResize(); + postOffscreenRender->HandleResize(); - defaultViewport->SetWidth(static_cast(windowDims.first)); - defaultViewport->SetHeight(static_cast(windowDims.second)); + defaultViewport->SetWidth(static_cast(resizeWidth)); + defaultViewport->SetHeight(static_cast(resizeHeight)); - worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); + worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); } void SHGraphicsSystem::AwaitGraphicsExecution() diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 517b5999..c3b39514 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -252,6 +252,7 @@ namespace SHADE /***************************************************************************/ void BuildTextures(); + void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept; void HandleResize(void) noexcept; void AwaitGraphicsExecution(); @@ -331,5 +332,7 @@ namespace SHADE Handle mousePickSystem; Handle postOffscreenRender; + uint32_t resizeWidth; + uint32_t resizeHeight; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp index bbc7c021..8b41a979 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -56,14 +56,19 @@ namespace SHADE }; // Create descriptor set layout - offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, true); + offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, false); // Create descriptor set offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 }); + HandleResize(); + } + + void SHPostOffscreenRenderSystem::HandleResize(void) noexcept + { std::vector combinedImageSampler { - std::make_tuple(renderGraphResource->GetImageView(), Handle{}, vk::ImageLayout::eShaderReadOnlyOptimal), + std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal), }; // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h index 90767bc2..d3360b87 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h @@ -24,6 +24,8 @@ namespace SHADE void Init (Handle logicalDevice, Handle renderGraphResource, Handle descriptorPool) noexcept; //void Run () + void HandleResize (void) noexcept; + Handle GetDescriptorSetGroup (void) const noexcept; }; } From b10f490e45381422cdd81ef68d99aaca2d67215b Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Sun, 16 Oct 2022 23:15:11 +0800 Subject: [PATCH 13/24] SP3-102 SP3-248 Saving of SHMETA files with asset IDs, retrieval of asset data under works, currently all assets are loaded into memory automatically --- Assets/Cube.003.shmesh.shmeta | 3 + Assets/Cube.012.shmesh.shmeta | 3 + .../RaccoonPreTexturedVer1_Base9.shtex.shmeta | 3 + .../src/Application/SBApplication.cpp | 7 +- .../src/Assets/Asset Types/SHTextureAsset.h | 1 + .../src/Assets/Libraries/SHMeshCompiler.cpp | 4 +- .../src/Assets/Libraries/SHMeshCompiler.h | 2 +- .../src/Assets/Libraries/SHMeshLoader.cpp | 3 +- .../src/Assets/Libraries/SHMeshLoader.h | 2 +- .../Assets/Libraries/SHTextureCompiler.cpp | 4 +- .../src/Assets/Libraries/SHTextureCompiler.h | 2 +- .../src/Assets/Libraries/SHTextureLoader.cpp | 1 + .../src/Assets/Libraries/SHTextureLoader.h | 2 +- SHADE_Engine/src/Assets/SHAssetMacros.h | 9 +- SHADE_Engine/src/Assets/SHAssetManager.cpp | 112 ++++++++++++------ .../src/Assets/SHAssetMetaHandler.cpp | 29 +++-- 16 files changed, 132 insertions(+), 55 deletions(-) create mode 100644 Assets/Cube.003.shmesh.shmeta create mode 100644 Assets/Cube.012.shmesh.shmeta create mode 100644 Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta diff --git a/Assets/Cube.003.shmesh.shmeta b/Assets/Cube.003.shmesh.shmeta new file mode 100644 index 00000000..d41be546 --- /dev/null +++ b/Assets/Cube.003.shmesh.shmeta @@ -0,0 +1,3 @@ +Name: Cube.003 +ID: 110152941 +Type:  diff --git a/Assets/Cube.012.shmesh.shmeta b/Assets/Cube.012.shmesh.shmeta new file mode 100644 index 00000000..d5cd1090 --- /dev/null +++ b/Assets/Cube.012.shmesh.shmeta @@ -0,0 +1,3 @@ +Name: Cube.012 +ID: 107348815 +Type:  diff --git a/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta new file mode 100644 index 00000000..f8c267d9 --- /dev/null +++ b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta @@ -0,0 +1,3 @@ +Name: RaccoonPreTexturedVer1_Base9 +ID: 91918845 +Type:  diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 202a3852..5a265d39 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -104,10 +104,10 @@ namespace Sandbox //TODO: REMOVE AFTER PRESENTATION //SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); - SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh"); + //SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh"); //SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds"); //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds"); - SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex"); + //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex"); //TODO: REMOVE AFTER PRESENTATION @@ -125,6 +125,8 @@ namespace Sandbox SHSceneManager::InitSceneManager("TestScene"); SHFrameRateController::UpdateFRC(); + + SHAssetManager::Load(); } void SBApplication::Update(void) @@ -154,6 +156,7 @@ namespace Sandbox SHSceneManager::Exit(); SHSystemManager::Exit(); + SHAssetManager::Unload(); } } diff --git a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h index 07cebea9..d24b6c02 100644 --- a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h +++ b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h @@ -9,6 +9,7 @@ namespace SHADE { bool compiled; + std::string name; uint32_t numBytes; uint32_t width; uint32_t height; diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp index 12b2517e..8026f0e1 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp @@ -16,7 +16,7 @@ #include -void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept +std::string SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept { std::string newPath{ path.string() }; newPath = newPath.substr(0, newPath.find_last_of('/') + 1); @@ -67,4 +67,6 @@ void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPat ); file.close(); + + return newPath; } diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h index 6da00525..a8ce67be 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h @@ -21,6 +21,6 @@ namespace SHADE { private: public: - static void CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept; + static std::string CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp index 3a5fb9ec..4bfa2d9b 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp @@ -142,8 +142,7 @@ namespace SHADE SHLOG_ERROR("Unable to open SHMesh File: {}", path.string()); } - std::string name{ path.filename().string() }; - name = name.substr(0, name.find_last_of('.')); + const std::string name{ path.stem().string() }; file.seekg(0); diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h index 3e430aca..a27d63ea 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h @@ -29,8 +29,8 @@ namespace SHADE static void LoadExternal(std::vector& meshes, AssetPath path) noexcept; - static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept; public: static void LoadMesh(std::vector& meshes, AssetPath path) noexcept; + static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp index 62af4da6..49de6b5c 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp @@ -17,7 +17,7 @@ namespace SHADE { - void SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path) + std::string SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path) { std::string newPath{ path.string() }; newPath = newPath.substr(0, newPath.find_last_of('.')); @@ -69,5 +69,7 @@ namespace SHADE ); file.close(); + + return newPath; } } diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h index d8685795..52980084 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h @@ -19,6 +19,6 @@ namespace SHADE { struct SHTextureCompiler { - static void CompileTextureBinary(SHTextureAsset const& asset, AssetPath path); + static std::string CompileTextureBinary(SHTextureAsset const& asset, AssetPath path); }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp index 47501d42..5147562a 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp @@ -93,6 +93,7 @@ namespace SHADE std::memcpy(pixel, file.GetImageData()->m_mem, totalBytes); //pixel = std::move(reinterpret_cast(file.GetDDSData())); + asset.name = path.stem().string(); asset.compiled = false; asset.numBytes = static_cast(totalBytes); asset.width = file.GetWidth(); diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h index e84fe5cf..eb61ea91 100644 --- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h +++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h @@ -26,8 +26,8 @@ namespace SHADE static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept; - static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; public: static void LoadImageAsset(AssetPath paths, SHTextureAsset& image); + static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept; }; } diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h index 8c462af7..61c5879d 100644 --- a/SHADE_Engine/src/Assets/SHAssetMacros.h +++ b/SHADE_Engine/src/Assets/SHAssetMacros.h @@ -40,7 +40,7 @@ typedef FMOD::Sound* SHSound; #define ASSET_META_VER "1.0" // Asset type enum -enum class AssetType : uint8_t +enum class AssetType : AssetTypeMeta { INVALID = 0, AUDIO = 1, @@ -57,7 +57,12 @@ enum class AssetType : uint8_t }; //Directory -#define ASSET_ROOT "./Assets/" +#ifdef _PUBLISH +#define ASSET_ROOT "Assets" +#else +#define ASSET_ROOT "../../Assets" +#endif + // ASSET EXTENSIONS #define META_EXTENSION ".shmeta" diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index 430b8c79..e3578f92 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -307,12 +307,22 @@ namespace SHADE for (auto const& mesh : meshes) { - meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh); + auto id{ GenerateAssetID(AssetType::MESH) }; + meshCollection.emplace(id, mesh); + AssetPath path; if (!mesh.compiled) { - SHMeshCompiler::CompileMeshBinary(mesh, asset.path); + path = SHMeshCompiler::CompileMeshBinary(mesh, asset.path); } + + assetCollection.emplace_back( + mesh.header.meshName, + id, + AssetType::MESH, + path, + 0 + ); } } @@ -322,11 +332,20 @@ namespace SHADE SHTextureLoader::LoadImageAsset(asset.path, image); - textureCollection.emplace(GenerateAssetID(AssetType::DDS), image); - if (!image.compiled) { - SHTextureCompiler::CompileTextureBinary(image, asset.path); + auto id{ GenerateAssetID(AssetType::TEXTURE) }; + textureCollection.emplace(id, image); + + auto path{ SHTextureCompiler::CompileTextureBinary(image, asset.path) }; + + assetCollection.emplace_back( + image.name, + id, + AssetType::TEXTURE, + path, + 0 + ); } } @@ -344,8 +363,24 @@ namespace SHADE ****************************************************************************/ void SHAssetManager::LoadAllData() noexcept { + //TODO Remove when on demand loading is done for (auto const& asset : assetCollection) { + switch (asset.type) + { + case AssetType::MESH: + meshCollection.emplace(asset.id, SHMeshAsset()); + SHMeshLoader::LoadSHMesh(meshCollection[asset.id], asset.path); + break; + + case AssetType::TEXTURE: + textureCollection.emplace(asset.id, SHTextureAsset()); + SHTextureLoader::LoadSHTexture(asset.path, textureCollection[asset.id]); + break; + + default: + void; + } } } @@ -362,40 +397,51 @@ namespace SHADE std::vector metaFiles; std::vector AssetFiles; - //TODO: Write new function for file manager to loop through all files - SHFileSystem::StartupFillDirectories(ASSET_ROOT); - FolderPointer rootFolder = SHFileSystem::GetRoot(); - - for (auto const& meta : metaFiles) + for (auto const dir : std::filesystem::recursive_directory_iterator(ASSET_ROOT)) { - for (std::vector::const_iterator it{ AssetFiles.cbegin() }; - it != AssetFiles.cend(); - ++it) + if (dir.path().extension().string() == META_EXTENSION) { - // Asset exists for meta file - std::string fileExtCheck{ it->filename().string() }; - fileExtCheck += META_EXTENSION; - if (meta.filename().string() == fileExtCheck) - { - RegisterAsset(meta, *it); - AssetFiles.erase(it); - break; - } + auto meta{ SHAssetMetaHandler::RetrieveMetaData(dir.path()) }; + + assetCollection.push_back(meta); + assetRegistry.emplace(meta.id, meta); } } + //TODO: Write new function for file manager to loop through all files + //SHFileSystem::StartupFillDirectories(ASSET_ROOT); + //FolderPointer rootFolder = SHFileSystem::GetRoot(); + + //for (auto const& meta : metaFiles) + //{ + // for (std::vector::const_iterator it{ AssetFiles.cbegin() }; + // it != AssetFiles.cend(); + // ++it) + // { + // // Asset exists for meta file + // std::string fileExtCheck{ it->filename().string() }; + // fileExtCheck += META_EXTENSION; + // if (meta.filename().string() == fileExtCheck) + // { + // RegisterAsset(meta, *it); + // AssetFiles.erase(it); + // break; + // } + // } + //} + //TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa) - for (auto const& file : AssetFiles) - { - if (IsRecognised(file.extension().string().c_str())) - { - SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file)); - } - else - { - std::cout << "Unsupported File Format: " << file.filename() << "\n"; - } - } + //for (auto const& file : AssetFiles) + //{ + // if (IsRecognised(file.extension().string().c_str())) + // { + // SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file)); + // } + // else + // { + // std::cout << "Unsupported File Format: " << file.filename() << "\n"; + // } + //} } AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp index 6554a3e4..442c3d96 100644 --- a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp +++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp @@ -72,6 +72,13 @@ namespace SHADE std::string line; SHAsset meta; + // Get resource name + GetFieldValue(metaFile, line); + std::stringstream nameStream{ line }; + AssetName name; + nameStream >> name; + meta.name = name; + // Get resource id GetFieldValue(metaFile, line); std::stringstream idStream{ line }; @@ -88,6 +95,8 @@ namespace SHADE metaFile.close(); + meta.path = path.parent_path().string() + "/" + path.stem().string(); + return meta; } @@ -103,7 +112,7 @@ namespace SHADE std::string path{ meta.path.string() }; path.append(META_EXTENSION); - std::ofstream metaFile{ path, std::ios_base::out }; + std::ofstream metaFile{ path, std::ios_base::out | std::ios_base::trunc }; if (!metaFile.is_open()) { @@ -113,17 +122,17 @@ namespace SHADE metaFile << "Name: " << meta.name << "\n"; metaFile << "ID: " << meta.id << "\n"; - metaFile << "Type: " << static_cast(meta.type) << std::endl; + metaFile << "Type: " << static_cast(meta.type) << std::endl; - //TODO Add in information that is specific to types like mesh - switch(meta.type) - { - case AssetType::MESH: - break; + ////TODO Add in information that is specific to types like mesh + //switch(meta.type) + //{ + //case AssetType::MESH: + // break; - default: - break; - } + //default: + // break; + //} metaFile.close(); } From 013bb713258fafbe46917380763ec0beaf76b05b Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Mon, 17 Oct 2022 15:04:38 +0800 Subject: [PATCH 14/24] Functions to retrieve mesh and texture data --- SHADE_Engine/src/Assets/SHAssetManager.cpp | 20 ++++++++++++++++++++ SHADE_Engine/src/Assets/SHAssetManager.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp index e3578f92..aa9772dd 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.cpp +++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp @@ -255,6 +255,26 @@ namespace SHADE return result; } + SHMeshAsset const* SHAssetManager::GetMesh(AssetID id) noexcept + { + if (meshCollection.find(id) == meshCollection.end()) + { + return nullptr; + } + + return &meshCollection[id]; + } + + SHTextureAsset const* SHAssetManager::GetTexture(AssetID id) noexcept + { + if (textureCollection.find(id) == textureCollection.end()) + { + return nullptr; + } + + return &textureCollection[id]; + } + /**************************************************************************** * \param Path for meta data file * \param Path for asset file diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h index 7064d63d..50549e01 100644 --- a/SHADE_Engine/src/Assets/SHAssetManager.h +++ b/SHADE_Engine/src/Assets/SHAssetManager.h @@ -75,6 +75,8 @@ namespace SHADE static std::vector GetAllMeshes() noexcept; static std::vector GetAllTextures() noexcept; + static SHMeshAsset const* GetMesh(AssetID id) noexcept; + static SHTextureAsset const* GetTexture(AssetID id) noexcept; private: /**************************************************************************** * \brief Load resource data into memory From 17b71393f34974c64a55285518c0044a1889033f Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Mon, 17 Oct 2022 16:50:53 +0800 Subject: [PATCH 15/24] Restructured abit --- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 207 ++++++++++-------- .../MiddleEnd/Interface/SHGraphicsSystem.h | 15 +- 2 files changed, 132 insertions(+), 90 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 21d7569e..d5a45cf7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -36,11 +36,9 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { +#pragma region INIT_EXIT - /*---------------------------------------------------------------------------------*/ - /* Constructor/Destructors */ - /*---------------------------------------------------------------------------------*/ - void SHGraphicsSystem::Init(void) + void SHGraphicsSystem::InitBoilerplate(void) noexcept { /*-----------------------------------------------------------------------*/ /* BACKEND BOILERPLATE */ @@ -51,7 +49,7 @@ namespace SHADE // Get Physical Device and Construct Logical Device physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST); device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice); - + // Construct surface surface = device->CreateSurface(window->GetHWND()); @@ -106,11 +104,12 @@ namespace SHADE graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + } - - + void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept + { /*-----------------------------------------------------------------------*/ - /* MIDDLE END SETUP + /* MIDDLE END SETUP - Viewports - Renderer - Render graph in renderers @@ -118,6 +117,7 @@ namespace SHADE - Default vertex input state - Global data /*-----------------------------------------------------------------------*/ + auto windowDims = window->GetWindowSize(); SHGraphicsGlobalData::Init(device); @@ -132,63 +132,49 @@ namespace SHADE // Create Default Viewport defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); - + // Get render graph from default viewport world renderer - worldRenderGraph = resourceManager.Create(); - - std::vector> renderContextCmdPools{swapchain->GetNumImages()}; + sceneRenderGraph = resourceManager.Create(); + + std::vector> renderContextCmdPools{ swapchain->GetNumImages() }; for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) { renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; } // Initialize world render graph - worldRenderGraph->Init(device, swapchain); - worldRenderGraph->AddResource("Present", {SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT}, windowDims.first, windowDims.second); - worldRenderGraph->AddResource("Scene", {SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT}, windowDims.first, windowDims.second); - worldRenderGraph->AddResource("Depth Buffer", {SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL}, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - worldRenderGraph->AddResource("Entity ID", {SH_ATT_DESC_TYPE_FLAGS::COLOR}, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + sceneRenderGraph->Init(device, swapchain); + sceneRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); + sceneRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); + sceneRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + sceneRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - //worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - //worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - //worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); - //worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm); - auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors + auto node = sceneRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene" }, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); gBufferWriteSubpass->AddColorOutput("Scene"); gBufferWriteSubpass->AddColorOutput("Entity ID"); - gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); + gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); // We do this to just transition our scene layout to shader read auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); sceneLayoutTransitionSubpass->AddInput("Scene"); #ifdef SHEDITOR - auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"}); + auto imguiNode = sceneRenderGraph->AddNode("ImGui Node", { "Present" }, { "G-Buffer" }); auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); imguiSubpass->AddColorOutput("Present"); #endif - worldRenderGraph->Generate(); - - // Create Semaphore - for (auto& semaHandle : graphSemaphores) - { - semaHandle = device->CreateSemaphore(); - } - - // Create Debug Renderers - /*debugScreenRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph); - debugScreenRenderer->SetCamera(screenCamera); - debugWorldRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph); - debugWorldRenderer->SetCamera(worldCamera);*/ + // Generate world render graph + sceneRenderGraph->Generate(); // Add world renderer to default viewport - worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); + worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], sceneRenderGraph); worldRenderer->SetCamera(worldCamera); + // TODO: This is VERY temporarily here until a more solid resource management system is implemented shaderSourceLibrary.Init("../../TempShaderFolder/"); @@ -202,21 +188,59 @@ namespace SHADE cubeFS->Reflect(); defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass); + } + + void SHGraphicsSystem::InitMiddleEnd(void) noexcept + { + InitSceneRenderGraph(); + + // Create Semaphore + for (auto& semaHandle : graphSemaphores) + { + semaHandle = device->CreateSemaphore(); + } + } + + void SHGraphicsSystem::InitSubsystems(void) noexcept + { mousePickSystem = resourceManager.Create(); std::vector> cmdPools; cmdPools.reserve(swapchain->GetNumImages()); for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) - cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); + cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); - mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); + mousePickSystem->Init(device, cmdPools, sceneRenderGraph->GetRenderGraphResource("Entity ID")); // Register the post offscreen render to the system postOffscreenRender = resourceManager.Create(); - postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); + postOffscreenRender->Init(device, sceneRenderGraph->GetRenderGraphResource("Scene"), descPool); } + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*---------------------------------------------------------------------------------*/ + void SHGraphicsSystem::Init(void) + { + InitBoilerplate(); + InitMiddleEnd(); + InitSubsystems(); + + + } + + void SHGraphicsSystem::Exit(void) + { + } + +#pragma endregion INIT_EXIT + +#pragma region LIFECYCLE + + /*---------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*---------------------------------------------------------------------------------*/ /***************************************************************************/ /*! @@ -336,14 +360,7 @@ namespace SHADE } } } - - void SHGraphicsSystem::Exit(void) - { - } - - /*---------------------------------------------------------------------------------*/ - /* Lifecycle Functions */ - /*---------------------------------------------------------------------------------*/ + /***************************************************************************/ /*! @@ -435,6 +452,10 @@ namespace SHADE renderContext.AdvanceFrame(); } +#pragma endregion LIFECYCLE + +#pragma region ADD_REMOVE_BUILD + Handle SHGraphicsSystem::AddViewport(const vk::Viewport& viewport) { // Create the viewport @@ -545,47 +566,9 @@ namespace SHADE ); } - void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept - { - resizeWidth = newWidth; - resizeHeight = newHeight; - - renderContext.SetIsResized(true); - } - - void SHGraphicsSystem::HandleResize(void) noexcept - { - if (window->IsMinimized() || renderContext.GetWindowIsDead()) - return; - - auto windowDims = window->GetWindowSize(); - - // Resize the swapchain - swapchain->Resize(surface, windowDims.first, windowDims.second); - - renderContext.HandleResize(); - - worldRenderGraph->HandleResize(resizeWidth, resizeHeight); - - mousePickSystem->HandleResize(); - postOffscreenRender->HandleResize(); - - defaultViewport->SetWidth(static_cast(resizeWidth)); - defaultViewport->SetHeight(static_cast(resizeHeight)); - - worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); - } - - void SHGraphicsSystem::AwaitGraphicsExecution() - { - device->WaitIdle(); - } - - void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept - { - window = wind; - } +#pragma endregion ADD_REMOVE +#pragma region ROUTINES /*-----------------------------------------------------------------------------------*/ /* System Routine Functions - BeginRoutine */ /*-----------------------------------------------------------------------------------*/ @@ -657,5 +640,51 @@ namespace SHADE renderable.ResetChangedFlag(); } } +#pragma endregion ROUTINES +#pragma region MISC + + void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept + { + resizeWidth = newWidth; + resizeHeight = newHeight; + + renderContext.SetIsResized(true); + } + + void SHGraphicsSystem::HandleResize(void) noexcept + { + if (window->IsMinimized() || renderContext.GetWindowIsDead()) + return; + + auto windowDims = window->GetWindowSize(); + + // Resize the swapchain + swapchain->Resize(surface, windowDims.first, windowDims.second); + + renderContext.HandleResize(); + + sceneRenderGraph->HandleResize(resizeWidth, resizeHeight); + + mousePickSystem->HandleResize(); + postOffscreenRender->HandleResize(); + + defaultViewport->SetWidth(static_cast(resizeWidth)); + defaultViewport->SetHeight(static_cast(resizeHeight)); + + worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); + } + + void SHGraphicsSystem::AwaitGraphicsExecution() + { + device->WaitIdle(); + } + + void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept + { + window = wind; + } + + +#pragma endregion MISC } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index c3b39514..e6739715 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -67,6 +67,12 @@ namespace SHADE /***********************************************************************************/ class SH_API SHGraphicsSystem : public SHSystem { + private: + void InitBoilerplate (void) noexcept; + void InitSceneRenderGraph(void) noexcept; + void InitMiddleEnd (void) noexcept; + void InitSubsystems (void) noexcept; + public: class SH_API BeginRoutine final : public SHSystemRoutine { @@ -279,6 +285,7 @@ namespace SHADE private: + /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ @@ -305,6 +312,12 @@ namespace SHADE SHSamplerCache samplerCache; SHMaterialInstanceCache materialInstanceCache; // Viewports +#ifdef SHEDITOR + Handle editorViewport; + Handle editorRenderer; + Handle editorRenderGraph; +#endif + Handle defaultViewport; // Whole screen std::vector> viewports; // Additional viewports @@ -326,7 +339,7 @@ namespace SHADE // Temp Materials Handle defaultMaterial; - Handle worldRenderGraph; + Handle sceneRenderGraph; // Sub systems Handle mousePickSystem; From 7b7533420eca64a859209f782e3ef2689afb3a23 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 18 Oct 2022 01:12:03 +0800 Subject: [PATCH 16/24] WIP --- .../MiddleEnd/Interface/SHGraphicsConstants.h | 6 ++ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 75 ++++++++++++++----- .../MiddleEnd/Interface/SHGraphicsSystem.h | 19 +++-- .../MiddleEnd/Interface/SHMousePickSystem.cpp | 3 + .../MiddleEnd/Interface/SHRenderer.cpp | 11 ++- .../Graphics/RenderGraph/SHRenderGraph.cpp | 15 ++-- .../src/Graphics/RenderGraph/SHRenderGraph.h | 3 +- .../RenderGraph/SHRenderGraphNode.cpp | 15 ++-- .../Graphics/RenderGraph/SHRenderGraphNode.h | 4 +- .../src/Graphics/RenderGraph/SHSubpass.cpp | 6 +- .../src/Graphics/RenderGraph/SHSubpass.h | 2 +- .../Graphics/Renderpass/SHVkRenderpass.cpp | 3 +- SHADE_Engine/src/Resource/SparseSet.h | 6 +- 13 files changed, 118 insertions(+), 50 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index ac2f1f8c..67cbc001 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -25,6 +25,12 @@ namespace SHADE struct SHGraphicsConstants { public: + struct RenderGraphIndices + { + static constexpr uint32_t WORLD = 0; + static constexpr uint32_t EDITOR = 0; + }; + struct DescriptorSetIndex { /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index d5a45cf7..929e5d54 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -119,7 +119,6 @@ namespace SHADE /*-----------------------------------------------------------------------*/ auto windowDims = window->GetWindowSize(); - SHGraphicsGlobalData::Init(device); // Set Up Cameras screenCamera = resourceManager.Create(); @@ -134,7 +133,7 @@ namespace SHADE defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); // Get render graph from default viewport world renderer - sceneRenderGraph = resourceManager.Create(); + worldRenderGraph = resourceManager.Create(); std::vector> renderContextCmdPools{ swapchain->GetNumImages() }; for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) @@ -143,35 +142,36 @@ namespace SHADE } // Initialize world render graph - sceneRenderGraph->Init(device, swapchain); - sceneRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); - sceneRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); - sceneRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - sceneRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); + worldRenderGraph->Init(device, swapchain); + //worldRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); + worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); + worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - auto node = sceneRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene" }, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Present", */"Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); gBufferWriteSubpass->AddColorOutput("Scene"); gBufferWriteSubpass->AddColorOutput("Entity ID"); + //gBufferWriteSubpass->AddColorOutput("Present"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); // We do this to just transition our scene layout to shader read auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); sceneLayoutTransitionSubpass->AddInput("Scene"); -#ifdef SHEDITOR - auto imguiNode = sceneRenderGraph->AddNode("ImGui Node", { "Present" }, { "G-Buffer" }); - auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); - imguiSubpass->AddColorOutput("Present"); -#endif +//#ifdef SHEDITOR +// auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, { "G-Buffer" }); +// auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); +// imguiSubpass->AddColorOutput("Present"); +//#endif // Generate world render graph - sceneRenderGraph->Generate(); + worldRenderGraph->Generate(); // Add world renderer to default viewport - worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], sceneRenderGraph); + worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); @@ -192,8 +192,14 @@ namespace SHADE void SHGraphicsSystem::InitMiddleEnd(void) noexcept { + SHGraphicsGlobalData::Init(device); + InitSceneRenderGraph(); +#ifdef SHEDITOR + InitEditorRenderGraph(); +#endif + // Create Semaphore for (auto& semaHandle : graphSemaphores) { @@ -211,13 +217,45 @@ namespace SHADE for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); - mousePickSystem->Init(device, cmdPools, sceneRenderGraph->GetRenderGraphResource("Entity ID")); + mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); // Register the post offscreen render to the system postOffscreenRender = resourceManager.Create(); - postOffscreenRender->Init(device, sceneRenderGraph->GetRenderGraphResource("Scene"), descPool); + postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); } +#ifdef SHEDITOR + void SHGraphicsSystem::InitEditorRenderGraph(void) noexcept + { + auto windowDims = window->GetWindowSize(); + + // Create Default Viewport + editorViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 1.0f)); + + // Get render graph from viewport editor renderer + editorRenderGraph = resourceManager.Create(); + + std::vector> renderContextCmdPools{ swapchain->GetNumImages() }; + for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) + renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; + + editorRenderGraph->Init(device, swapchain); + editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); + + + auto imguiNode = editorRenderGraph->AddNode("ImGui Node", { "Present"}, {}); + auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); + imguiSubpass->AddColorOutput("Present"); + + // Generate world render graph + editorRenderGraph->Generate(); + + // Add world renderer to default viewport + editorRenderer = editorViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], editorRenderGraph); + editorRenderer->SetCamera(worldCamera); + } +#endif + /*---------------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*---------------------------------------------------------------------------------*/ @@ -664,7 +702,8 @@ namespace SHADE renderContext.HandleResize(); - sceneRenderGraph->HandleResize(resizeWidth, resizeHeight); + worldRenderGraph->HandleResize(resizeWidth, resizeHeight); + editorRenderGraph->HandleResize(windowDims.first, windowDims.second); mousePickSystem->HandleResize(); postOffscreenRender->HandleResize(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index e6739715..0e1e2f78 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -68,10 +68,14 @@ namespace SHADE class SH_API SHGraphicsSystem : public SHSystem { private: - void InitBoilerplate (void) noexcept; - void InitSceneRenderGraph(void) noexcept; - void InitMiddleEnd (void) noexcept; - void InitSubsystems (void) noexcept; + void InitBoilerplate (void) noexcept; + void InitSceneRenderGraph (void) noexcept; + void InitMiddleEnd (void) noexcept; + void InitSubsystems (void) noexcept; + +#ifdef SHEDITOR + void InitEditorRenderGraph (void) noexcept; +#endif public: class SH_API BeginRoutine final : public SHSystemRoutine @@ -277,6 +281,9 @@ namespace SHADE Handle GetQueue() const { return graphicsQueue; } Handle GetDescriptorPool() const { return descPool; } Handle GetDefaultViewport() const {return defaultViewport;} +#ifdef SHEDITOR + Handle GetEditorViewport () const {return editorViewport;}; +#endif Handle GetMousePickSystem(void) const noexcept {return mousePickSystem;}; Handle GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; //SHRenderGraph const& GetRenderGraph(void) const noexcept; @@ -306,7 +313,7 @@ namespace SHADE SHWindow* window = nullptr; // Middle End Resources - ResourceManager resourceManager; + ResourceManager resourceManager; SHMeshLibrary meshLibrary; SHTextureLibrary texLibrary; SHSamplerCache samplerCache; @@ -339,7 +346,7 @@ namespace SHADE // Temp Materials Handle defaultMaterial; - Handle sceneRenderGraph; + Handle worldRenderGraph; // Sub systems Handle mousePickSystem; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index e4ac92e5..1dd8212d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -62,7 +62,10 @@ namespace SHADE void SHMousePickSystem::HandleResize(void) noexcept { if (afterCopyFence) + { + afterCopyFence->Reset(); afterCopyFence.Free(); + } if (imageDataDstBuffer) imageDataDstBuffer.Free(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 14af56ee..425e9c81 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -75,12 +75,15 @@ namespace SHADE void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept { - cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); - cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); + if (camera) + { + cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); + cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); - std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; + std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; - cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + } } void SHRenderer::UpdateCameraDataToBuffer(void) noexcept diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 51584300..98cb6709 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -57,7 +57,7 @@ namespace SHADE format = swapchainHdl->GetSurfaceFormatKHR().format; } - graphResources.try_emplace(resourceName, resourceManager.Create(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); + graphResources.try_emplace(resourceName, resourceManager->Create(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); } /***************************************************************************/ @@ -102,11 +102,11 @@ namespace SHADE resourceAttLayouts[input.attachment] = input.layout; } - for (uint32_t i = 0; i < node->attachmentDescriptions.size(); ++i) + for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j) { - auto& att = node->attachmentDescriptions[i]; + auto& att = node->attachmentDescriptions[j]; att.initialLayout = vk::ImageLayout::eUndefined; - att.finalLayout = resourceAttLayouts[i]; + att.finalLayout = resourceAttLayouts[j]; } ++i; } @@ -365,10 +365,9 @@ namespace SHADE , swapchainHdl{ } , nodes{} , graphResources{} - , resourceManager{} - + , resourceManager{nullptr} { - + resourceManager = std::make_shared(); } SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept @@ -457,7 +456,7 @@ namespace SHADE } } - nodes.emplace_back(resourceManager.Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources)); + nodes.emplace_back(resourceManager->Create(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources)); nodeIndexing.emplace(nodeName, static_cast(nodes.size()) - 1u); return nodes.at(nodeIndexing[nodeName]); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 8eb458aa..952c6d8f 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -16,6 +16,7 @@ #include #include +#include namespace SHADE { @@ -70,7 +71,7 @@ namespace SHADE std::unordered_map> graphResources; //! Resource library for graph handles - ResourceManager resourceManager; + std::shared_ptr resourceManager; public: /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 0ff8fe96..ec184386 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -104,7 +104,7 @@ namespace SHADE */ /***************************************************************************/ - SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept + SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept : logicalDeviceHdl{ logicalDevice } , renderpass{} , framebuffers{} @@ -162,7 +162,7 @@ namespace SHADE } SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept - : resourceManager{ rhs.resourceManager } + : resourceManager{ std::move (rhs.resourceManager) } , logicalDeviceHdl{ rhs.logicalDeviceHdl } , renderpass{ rhs.renderpass } , framebuffers{ std::move(rhs.framebuffers) } @@ -177,6 +177,8 @@ namespace SHADE , ptrToResources{ rhs.ptrToResources } , pipelineLibrary{ std::move(rhs.pipelineLibrary) } , batcher{ std::move(rhs.batcher) } + , spDescs{ std::move(rhs.spDescs) } + , spDeps{ std::move(rhs.spDeps) } { rhs.renderpass = {}; @@ -187,7 +189,7 @@ namespace SHADE if (&rhs == this) return *this; - resourceManager = rhs.resourceManager; + resourceManager = std::move(rhs.resourceManager); logicalDeviceHdl = rhs.logicalDeviceHdl; renderpass = rhs.renderpass; framebuffers = std::move(rhs.framebuffers); @@ -200,6 +202,9 @@ namespace SHADE ptrToResources = std::move(rhs.ptrToResources); pipelineLibrary = std::move(rhs.pipelineLibrary); batcher = std::move(rhs.batcher); + spDescs = std::move(rhs.spDescs); + spDeps = std::move(rhs.spDeps); + rhs.renderpass = {}; @@ -230,10 +235,10 @@ namespace SHADE } // Add subpass to container and create mapping for it - subpasses.emplace_back(resourceManager.Create(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); + subpasses.emplace_back(resourceManager->Create(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); subpassIndexing.try_emplace(subpassName, static_cast(subpasses.size()) - 1u); Handle subpass = subpasses.back(); - subpass->Init(resourceManager); + subpass->Init(*resourceManager); // Register the SuperBatch batcher.RegisterSuperBatch(subpass->GetSuperBatch()); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index f36e7622..77861108 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -26,7 +26,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*-----------------------------------------------------------------------*/ - ResourceManager& resourceManager; + std::shared_ptr resourceManager; //! For Vulkan object creation Handle logicalDeviceHdl; @@ -88,7 +88,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHRenderGraphNode(ResourceManager& rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; + SHRenderGraphNode(std::shared_ptr rm, Handle const& logicalDevice, Handle const& swapchain, std::vector attDescInitParams, std::vector> predecessors, std::unordered_map> const* resources) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index 6afbfb09..ffbe4ff0 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -23,7 +23,7 @@ namespace SHADE */ /***************************************************************************/ - SHSubpass::SHSubpass(ResourceManager& rm, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept + SHSubpass::SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* resources) noexcept : resourceAttachmentMapping{ mapping } , ptrToResources{ resources } , parentNode{ parent } @@ -55,6 +55,8 @@ namespace SHADE , inputReferences{ std::move(rhs.inputReferences) } , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } , ptrToResources{ rhs.ptrToResources } + , descriptorSetLayout{ rhs.descriptorSetLayout } + , exteriorDrawCalls{ std::move (rhs.exteriorDrawCalls) } { } @@ -83,6 +85,8 @@ namespace SHADE inputReferences = std::move(rhs.inputReferences); resourceAttachmentMapping = rhs.resourceAttachmentMapping; ptrToResources = rhs.ptrToResources; + descriptorSetLayout = rhs.descriptorSetLayout; + exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); return *this; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 2e883ebc..c567a897 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -62,7 +62,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHSubpass(ResourceManager& rm, Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; + SHSubpass(Handle const& parent, uint32_t index, std::unordered_map const* mapping, std::unordered_map> const* ptrToResources) noexcept; SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept; diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp index fee23f13..74128ec8 100644 --- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp +++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp @@ -253,7 +253,8 @@ namespace SHADE SHVkRenderpass::~SHVkRenderpass(void) noexcept { - logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr); + if (vkRenderpass) + logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr); } diff --git a/SHADE_Engine/src/Resource/SparseSet.h b/SHADE_Engine/src/Resource/SparseSet.h index 8a3f9c6e..fb4a8311 100644 --- a/SHADE_Engine/src/Resource/SparseSet.h +++ b/SHADE_Engine/src/Resource/SparseSet.h @@ -59,9 +59,9 @@ namespace SHADE SparseSet(); ~SparseSet() = default; - // Disallow moving or copying - SparseSet(const SparseSet&) = delete; - SparseSet(SparseSet&&) = delete; + //// Disallow moving or copying + //SparseSet(const SparseSet&) = delete; + //SparseSet(SparseSet&&) = delete; /*-----------------------------------------------------------------------------*/ /* Usage Functions */ From e76bc6ef58985f524c65cede1f1e8f82923a8b70 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 18 Oct 2022 02:41:27 +0800 Subject: [PATCH 17/24] World render graph now doesn't render to swapchain image. world render graph now only renders to "Scene" resource. Editor render graph renders to "Present" swapchain image. Removed some unnecessary if statements slowing down the resizing Printing for success also disabled for now --- .../Graphics/Debugging/SHVulkanDebugUtil.cpp | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 34 ++++++------------- .../MiddleEnd/PerFrame/SHRenderContext.cpp | 1 - 3 files changed, 12 insertions(+), 25 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp index c8a1fe1a..fd39da24 100644 --- a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp +++ b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp @@ -99,7 +99,7 @@ namespace SHADE void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message) noexcept { - SHLOGV_INFO(message); + //SHLOGV_INFO(message); } /***************************************************************************/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 929e5d54..c78cc58f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -143,30 +143,22 @@ namespace SHADE // Initialize world render graph worldRenderGraph->Init(device, swapchain); - //worldRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); - auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Present", */"Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors + auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors //First subpass to write to G-Buffer auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); gBufferWriteSubpass->AddColorOutput("Scene"); gBufferWriteSubpass->AddColorOutput("Entity ID"); - //gBufferWriteSubpass->AddColorOutput("Present"); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); // We do this to just transition our scene layout to shader read auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); sceneLayoutTransitionSubpass->AddInput("Scene"); -//#ifdef SHEDITOR -// auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, { "G-Buffer" }); -// auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); -// imguiSubpass->AddColorOutput("Present"); -//#endif - // Generate world render graph worldRenderGraph->Generate(); @@ -297,12 +289,6 @@ namespace SHADE if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; - if (renderContext.GetResized()) - { - return; - } - - // Frame data for the current frame auto const& frameData = renderContext.GetCurrentFrameData(); uint32_t frameIndex = renderContext.GetCurrentFrame(); @@ -463,12 +449,6 @@ namespace SHADE if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; - if (renderContext.GetResized()) - { - return; - } - - const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); auto& currFrameData = renderContext.GetCurrentFrameData(); @@ -480,9 +460,7 @@ namespace SHADE // If swapchain is incompatible/outdated if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR) { - HandleResize(); - } } @@ -692,9 +670,14 @@ namespace SHADE void SHGraphicsSystem::HandleResize(void) noexcept { + device->WaitIdle(); + if (window->IsMinimized() || renderContext.GetWindowIsDead()) return; + graphSemaphores[0].Free(); + graphSemaphores[1].Free(); + auto windowDims = window->GetWindowSize(); // Resize the swapchain @@ -712,6 +695,11 @@ namespace SHADE defaultViewport->SetHeight(static_cast(resizeHeight)); worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); + + for (auto& semaHandle : graphSemaphores) + semaHandle = device->CreateSemaphore(); + + } void SHGraphicsSystem::AwaitGraphicsExecution() diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp index 0ac7013a..8041adfd 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp @@ -52,7 +52,6 @@ namespace SHADE { frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient)); } - } // Initialize all the info. From 033ba48304bd51152fcb1e32312796b354808f3c Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 18 Oct 2022 15:04:25 +0800 Subject: [PATCH 18/24] Editor changes to support viewport integration --- Assets/Editor/Layouts/Default.ini | 48 ++++ Assets/Editor/Layouts/UserLayout.ini | 48 ++++ .../HierarchyPanel/SHHierarchyPanel.cpp | 31 ++- .../HierarchyPanel/SHHierarchyPanel.h | 2 + .../Inspector/SHEditorComponentView.hpp | 9 +- .../Inspector/SHEditorInspector.cpp | 2 +- .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 88 +++++-- .../EditorWindow/MenuBar/SHEditorMenuBar.h | 1 + .../Profiling/SHEditorProfiler.cpp | 2 +- .../Editor/EditorWindow/SHEditorWindow.cpp | 26 +- .../src/Editor/EditorWindow/SHEditorWindow.h | 9 +- .../EditorWindow/SHEditorWindowIncludes.h | 3 +- .../ViewportWindow/SHEditorViewport.cpp | 60 +++++ .../ViewportWindow/SHEditorViewport.h | 29 +++ SHADE_Engine/src/Editor/SHEditor.cpp | 244 +++++++++++------- SHADE_Engine/src/Editor/SHEditor.hpp | 21 +- 16 files changed, 492 insertions(+), 131 deletions(-) create mode 100644 Assets/Editor/Layouts/Default.ini create mode 100644 Assets/Editor/Layouts/UserLayout.ini create mode 100644 SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp create mode 100644 SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h diff --git a/Assets/Editor/Layouts/Default.ini b/Assets/Editor/Layouts/Default.ini new file mode 100644 index 00000000..4ddc46c2 --- /dev/null +++ b/Assets/Editor/Layouts/Default.ini @@ -0,0 +1,48 @@ +[Window][MainStatusBar] +Pos=0,1060 +Size=1920,20 +Collapsed=0 + +[Window][SHEditorMenuBar] +Pos=0,24 +Size=1920,1036 +Collapsed=0 + +[Window][Hierarchy Panel] +Pos=0,120 +Size=225,940 +Collapsed=0 +DockId=0x00000004,0 + +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Inspector] +Pos=1686,24 +Size=234,1036 +Collapsed=0 +DockId=0x00000006,0 + +[Window][Profiler] +Pos=0,24 +Size=225,94 +Collapsed=0 +DockId=0x00000003,0 + +[Window][Viewport] +Pos=227,24 +Size=1457,1036 +Collapsed=0 +DockId=0x00000002,0 + +[Docking][Data] +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,55 Size=1920,1036 Split=X + DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1684,1036 Split=X + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=225,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 + DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1293,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=234,1036 Selected=0xE7039252 + diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini new file mode 100644 index 00000000..869da91a --- /dev/null +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -0,0 +1,48 @@ +[Window][MainStatusBar] +Pos=0,1167 +Size=2314,20 +Collapsed=0 + +[Window][SHEditorMenuBar] +Pos=0,48 +Size=2314,1119 +Collapsed=0 + +[Window][Hierarchy Panel] +Pos=0,152 +Size=208,1015 +Collapsed=0 +DockId=0x00000004,0 + +[Window][Debug##Default] +Pos=60,60 +Size=400,400 +Collapsed=0 + +[Window][Inspector] +Pos=2044,48 +Size=270,1119 +Collapsed=0 +DockId=0x00000006,0 + +[Window][Profiler] +Pos=0,48 +Size=208,102 +Collapsed=0 +DockId=0x00000003,0 + +[Window][Viewport] +Pos=210,48 +Size=1832,1119 +Collapsed=0 +DockId=0x00000002,0 + +[Docking][Data] +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=-7,358 Size=2314,1119 Split=X + DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=2042,1036 Split=X + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=208,1036 Split=Y Selected=0x1E6EB881 + DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 + DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1832,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=270,1036 Selected=0xE7039252 + diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 0f25175f..42c9da66 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -66,8 +66,8 @@ namespace SHADE editor->selectedEntities.clear(); } ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal); - ImGui::End(); } + ImGui::End(); } void SHHierarchyPanel::Exit() @@ -75,6 +75,11 @@ namespace SHADE SHEditorWindow::Exit(); } + void SHHierarchyPanel::SetScrollTo(EntityID eid) + { + scrollTo = eid; + } + //#==============================================================# //|| Private Member Functions || //#==============================================================# @@ -82,7 +87,20 @@ namespace SHADE { if (ImGui::BeginMenuBar()) { - if (ImGui::SmallButton(ICON_MD_ADD)) + + ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x - 35.0f); + if(ImGui::SmallButton(ICON_MD_DESELECT)) + { + auto editor = SHSystemManager::GetSystem(); + editor->selectedEntities.clear(); + } + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text("Clear Selections"); + ImGui::EndTooltip(); + } + if (ImGui::SmallButton(ICON_MD_ADD_CIRCLE)) { SHEntityManager::CreateEntity(); } @@ -103,6 +121,13 @@ namespace SHADE //Get node data (Children, eid, selected) auto& children = currentNode->GetChildren(); EntityID eid = currentNode->GetEntityID(); + + if(scrollTo != MAX_EID && eid == scrollTo) + { + ImGui::SetScrollHereY(); + scrollTo = MAX_EID; + } + auto editor = SHSystemManager::GetSystem(); const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end()); @@ -157,7 +182,7 @@ namespace SHADE } ImGui::EndPopup(); } - + //Handle node selection if (ImGui::IsItemHovered()) { diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h index 78e445fd..88983ca9 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h @@ -23,11 +23,13 @@ namespace SHADE void Init() override; void Update() override; void Exit() override; + void SetScrollTo(EntityID eid); private: void DrawMenuBar() const noexcept; ImRect RecursivelyDrawEntityNode(SHSceneNode*); void CreateChildEntity(EntityID parentEID) const noexcept; std::string filter; bool isAnyNodeSelected = false; + EntityID scrollTo = MAX_EID; };//class SHHierarchyPanel }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 93f6984e..47fec730 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -207,8 +207,10 @@ namespace SHADE auto& colliders = component->GetColliders(); int const size = static_cast(colliders.size()); ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true); + std::optional colliderToDelete{std::nullopt}; for (int i{}; i < size; ++i) { + ImGui::PushID(i); SHCollider& collider = component->GetCollider(i); auto cursorPos = ImGui::GetCursorPos(); @@ -235,9 +237,14 @@ namespace SHADE } if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data())) { - component->RemoveCollider(i); + colliderToDelete = i; } SHEditorWidgets::EndPanel(); + ImGui::PopID(); + } + if(colliderToDelete.has_value()) + { + component->RemoveCollider(colliderToDelete.value()); } ImGui::EndChild(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index a9b1c724..da09f345 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -99,8 +99,8 @@ namespace SHADE } } - ImGui::End(); } + ImGui::End(); } void SHEditorInspector::Exit() diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index a49af994..3cb6561d 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -36,6 +36,11 @@ namespace SHADE void SHEditorMenuBar::Init() { SHEditorWindow::Init(); + constexpr std::string_view path = "../../Assets/Editor/Layouts"; + for(auto const& entry : std::filesystem::directory_iterator(path)) + { + layoutPaths.push_back(entry.path()); + } } void SHEditorMenuBar::Update() @@ -87,20 +92,6 @@ namespace SHADE ImGui::EndDisabled(); ImGui::EndMenu(); } - if(ImGui::BeginMenu("Theme")) - { - auto styles = rttr::type::get().get_enumeration(); - auto values = styles.get_values(); - for (auto style : values) - { - if(ImGui::Selectable(style.to_string().c_str())) - { - if(auto editor = SHSystemManager::GetSystem()) - editor->SetStyle(style.convert()); - } - } - ImGui::EndMenu(); - } if (ImGui::BeginMenu("Scripts")) { if (ImGui::Selectable("Generate Visual Studio Project")) @@ -120,18 +111,79 @@ namespace SHADE } ImGui::EndMenu(); } + + if (ImGui::BeginMenu("Window")) + { + for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) + { + if (window.get() != this) + ImGui::Checkbox(window->windowName.data(), &window->isOpen); + } + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Theme")) + { + const auto styles = rttr::type::get().get_enumeration(); + auto values = styles.get_values(); + for (auto style : values) + { + if (ImGui::Selectable(style.to_string().c_str())) + { + if (auto editor = SHSystemManager::GetSystem()) + editor->SetStyle(style.convert()); + } + } + ImGui::EndMenu(); + } + if(ImGui::BeginMenu("Layout")) + { + for(auto const& entry : layoutPaths) + { + if(ImGui::Selectable(entry.stem().string().c_str())) + { + ImGui::LoadIniSettingsFromDisk(entry.string().c_str()); + } + } + ImGui::EndMenu(); + } ImGui::EndMainMenuBar(); } - const ImGuiID dockspace_id = ImGui::GetID("DockSpace"); - ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspaceFlags); + const ImGuiID dockspaceId = ImGui::GetID("DockSpace"); + ImGui::DockSpace(dockspaceId, ImVec2(0.0f, 0.0f), dockspaceFlags); ImGui::End(); } } void SHEditorMenuBar::DrawSecondaryBar() const noexcept { - + ImGuiViewport* viewport = ImGui::GetMainViewport(); + if(ImGui::BeginViewportSideBar("##SecondaryMenuBar", viewport, ImGuiDir_Up, ImGui::GetFrameHeight(), ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_MenuBar)) + { + ImGui::BeginMenuBar(); + ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.5f - 80.f); + const auto editor = SHSystemManager::GetSystem(); + ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY); + if(ImGui::SmallButton(ICON_MD_PLAY_ARROW)) + { + editor->editorState = SHEditor::State::PLAY; + } + ImGui::EndDisabled(); + ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE); + if(ImGui::SmallButton(ICON_MD_PAUSE)) + { + editor->editorState = SHEditor::State::PAUSE; + } + ImGui::EndDisabled(); + ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP); + if(ImGui::SmallButton(ICON_MD_STOP)) + { + editor->editorState = SHEditor::State::STOP; + } + ImGui::EndDisabled(); + ImGui::EndMenuBar(); + } + ImGui::End(); } void SHEditorMenuBar::DrawStatusBar() const noexcept @@ -142,8 +194,8 @@ namespace SHADE if (ImGui::BeginViewportSideBar("MainStatusBar", ImGui::GetMainViewport(), ImGuiDir_Down, menuBarHeight, editorMenuBarFlags)) { ImGui::Text("Entity count: "); - ImGui::End(); } + ImGui::End(); ImGui::PopStyleVar(3); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h index 616ba43e..7cbcd696 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h @@ -18,5 +18,6 @@ namespace SHADE void DrawSecondaryBar() const noexcept; void DrawStatusBar() const noexcept; float menuBarHeight = 20.0f; + std::vector layoutPaths; };//class SHEditorMenuBar }//namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp index 4b36fe5d..ef2ff8c0 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp @@ -37,8 +37,8 @@ namespace SHADE if(Begin()) { ImGui::PlotLines("DT", frames.data(), static_cast(frames.size()), 0, nullptr, 0.0f, 16.0f); - ImGui::End(); } + ImGui::End(); } void SHEditorProfiler::Exit() diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp index 2e2c820c..491c1bc2 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp @@ -19,7 +19,7 @@ namespace SHADE //|| Public Member Functions || //#==============================================================# SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags) - : isOpen(true), windowName(name), windowFlags(inFlags), io(ImGui::GetIO()) + : windowName(name), windowFlags(inFlags), io(ImGui::GetIO()) { } @@ -40,7 +40,29 @@ namespace SHADE //#==============================================================# bool SHEditorWindow::Begin() { - return ImGui::Begin(windowName.data(), &isOpen, windowFlags); + bool result = ImGui::Begin(windowName.data(), &isOpen, windowFlags); + + auto wndSize = ImGui::GetWindowSize(); + if(windowSize.x != wndSize.x || windowSize.y != wndSize.y) + { + windowSize = {wndSize.x, wndSize.y}; + OnResize(); + } + auto wndPos = ImGui::GetWindowPos(); + if(windowPos.x != wndPos.x || windowPos.y != wndPos.y) + { + windowPos = {wndPos.x, wndPos.y}; + OnPosChange(); + } + return result; + } + + void SHEditorWindow::OnResize() + { + } + + void SHEditorWindow::OnPosChange() + { } }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h index 244ef677..3e7a2a5c 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h @@ -5,6 +5,8 @@ //#==============================================================# #include +#include "Math/Vector/SHVec2.h" + //#==============================================================# //|| Forward Declarations || //#==============================================================# @@ -21,11 +23,16 @@ namespace SHADE virtual void Init(); virtual void Update(); virtual void Exit(); - bool isOpen = false; + bool isOpen; std::string_view windowName; protected: virtual bool Begin(); + virtual void OnResize(); + virtual void OnPosChange(); + ImGuiWindowFlags windowFlags = 0; ImGuiIO& io; + SHVec2 windowSize; + SHVec2 windowPos; };//class SHEditorWindow }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h index d1ebfbf4..f0267b06 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h @@ -2,4 +2,5 @@ #include "MenuBar/SHEditorMenuBar.h" //Menu Bar #include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel #include "Inspector/SHEditorInspector.h" //Inspector -#include "Profiling/SHEditorProfiler.h" //Profiler \ No newline at end of file +#include "Profiling/SHEditorProfiler.h" //Profiler +#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp new file mode 100644 index 00000000..c903a80f --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -0,0 +1,60 @@ +#include "SHpch.h" +#include "SHEditorViewport.h" + +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" + +namespace SHADE +{ + SHEditorViewport::SHEditorViewport() + :SHEditorWindow("Viewport", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar) + { + } + + void SHEditorViewport::Init() + { + SHEditorWindow::Init(); + + } + + void SHEditorViewport::Update() + { + SHEditorWindow::Update(); + if(Begin()) + { + DrawMenuBar(); + auto gfxSystem = SHSystemManager::GetSystem(); + auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0]; + ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize()); + } + ImGui::End(); + } + + void SHEditorViewport::Exit() + { + SHEditorWindow::Exit(); + } + + void SHEditorViewport::OnResize() + { + SHEditorWindow::OnResize(); + //Get graphics system to resize swapchain image + auto gfxSystem = SHSystemManager::GetSystem(); + + gfxSystem->PrepareResize(static_cast(windowSize.x), static_cast(windowSize.y)); + } + + void SHEditorViewport::OnPosChange() + { + SHEditorWindow::OnPosChange(); + } + + void SHEditorViewport::DrawMenuBar() const noexcept + { + if(ImGui::BeginMenuBar()) + { + ImGui::EndMenuBar(); + } + } +}//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h new file mode 100644 index 00000000..5f4a5919 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h @@ -0,0 +1,29 @@ +#pragma once +//#==============================================================# +//|| Library Includes || +//#==============================================================# +#include + +//#==============================================================# +//|| SHADE Includes || +//#==============================================================# +#include "imgui_internal.h" +#include "ECS_Base/SHECSMacros.h" +#include "Editor/EditorWindow/SHEditorWindow.h" + +namespace SHADE +{ + class SHEditorViewport final : public SHEditorWindow + { + public: + SHEditorViewport(); + void Init() override; + void Update() override; + void Exit() override; + protected: + void OnResize() override; + void OnPosChange() override; + private: + void DrawMenuBar() const noexcept; + };//class SHEditorViewport +}//namespace SHADE diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index d9fc8373..4c6caff0 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -43,6 +43,8 @@ #include #include +#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" + RTTR_REGISTRATION { using namespace SHADE; @@ -73,6 +75,7 @@ namespace SHADE //#==============================================================# void SHEditor::Init() { + IMGUI_CHECKVERSION(); if(auto context = ImGui::CreateContext()) { @@ -82,11 +85,21 @@ namespace SHADE } } - ImGuiIO& io = ImGui::GetIO(); (void)io; + //Add editor windows + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports - io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking + io = &ImGui::GetIO(); + + io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports + io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking + io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini"; + + InitLayout(); InitFonts(); @@ -98,11 +111,11 @@ namespace SHADE SetStyle(Style::SHADE); - //Add editor windows - SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); + + for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) + { + window->Init(); + } SHLOG_INFO("Successfully initialised SHADE Engine Editor") } @@ -116,7 +129,7 @@ namespace SHADE if(window->isOpen) window->Update(); } - + if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z)) { SHCommandManager::RedoCommand(); @@ -125,36 +138,46 @@ namespace SHADE { SHCommandManager::UndoCommand(); } - - + Render(); } void SHEditor::Render() { ImGui::Render(); - ImGuiIO& io = ImGui::GetIO(); - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + if (io->ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { ImGui::UpdatePlatformWindows(); ImGui::RenderPlatformWindowsDefault(); } } + void SHEditor::InitLayout() noexcept + { + if(!std::filesystem::exists(io->IniFilename)) + { + std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename); + } + //eventually load preferred layout here + } + void SHEditor::InitFonts() noexcept { - ImGuiIO& io = ImGui::GetIO(); - ImFont* mainFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path + ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path - static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; + constexpr ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; - ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path + ImFont* UIFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path - io.Fonts->Build(); + io->Fonts->Build(); } void SHEditor::Exit() { + for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) + { + window->Init(); + } ImGui_ImplVulkan_Shutdown(); ImGui_ImplSDL2_Shutdown(); ImGui::DestroyContext(); @@ -167,86 +190,86 @@ namespace SHADE default: case Style::SHADE: { - ImGuiStyle& imStyle = ImGui::GetStyle(); - ImVec4* colors = imStyle.Colors; - colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f); - colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f); - colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f); - colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); - colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f); - colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); - colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); - colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); - colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); - colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); - colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f); - colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f); - colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg]; - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); - colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); - colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f); - colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg]; - colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); - colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f); - colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); - colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); - colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); - colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); - colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f); - colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f); + ImGuiStyle& imStyle = ImGui::GetStyle(); + ImVec4* colors = imStyle.Colors; + colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f); + colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f); + colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); + colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f); + colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); + colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); + colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f); + colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg]; + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); + colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); + colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f); + colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg]; + colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); + colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); + colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); + colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); + colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); + colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f); + colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.141f, 0.141f, 0.141f, 0.70f); - colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight]; - colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f); + colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight]; + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f); - imStyle.WindowPadding = ImVec2(8.00f, 8.00f); - imStyle.FramePadding = ImVec2(5.00f, 2.00f); - imStyle.CellPadding = ImVec2(6.00f, 8.00f); - imStyle.ItemSpacing = ImVec2(6.00f, 6.00f); - imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f); - imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f); - imStyle.IndentSpacing = 25; - imStyle.ScrollbarSize = 15; - imStyle.GrabMinSize = 10; - imStyle.WindowBorderSize = 0.6f; - imStyle.ChildBorderSize = 1; - imStyle.PopupBorderSize = 1; - imStyle.FrameBorderSize = 1; - imStyle.TabBorderSize = 1; - imStyle.WindowRounding = 7; - imStyle.ChildRounding = 4; - imStyle.FrameRounding = 3; - imStyle.PopupRounding = 4; - imStyle.ScrollbarRounding = 9; - imStyle.GrabRounding = 3; - imStyle.LogSliderDeadzone = 4; - imStyle.TabRounding = 4; + imStyle.WindowPadding = ImVec2(8.00f, 8.00f); + imStyle.FramePadding = ImVec2(5.00f, 2.00f); + imStyle.CellPadding = ImVec2(6.00f, 8.00f); + imStyle.ItemSpacing = ImVec2(6.00f, 6.00f); + imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f); + imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f); + imStyle.IndentSpacing = 25; + imStyle.ScrollbarSize = 15; + imStyle.GrabMinSize = 10; + imStyle.WindowBorderSize = 0.6f; + imStyle.ChildBorderSize = 1; + imStyle.PopupBorderSize = 1; + imStyle.FrameBorderSize = 1; + imStyle.TabBorderSize = 1; + imStyle.WindowRounding = 7; + imStyle.ChildRounding = 4; + imStyle.FrameRounding = 3; + imStyle.PopupRounding = 4; + imStyle.ScrollbarRounding = 9; + imStyle.GrabRounding = 3; + imStyle.LogSliderDeadzone = 4; + imStyle.TabRounding = 4; imStyle.WindowMenuButtonPosition = ImGuiDir_None; } break; @@ -281,10 +304,11 @@ namespace SHADE imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers(); + //auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers(); + auto const& renderers = gfxSystem->GetEditorViewport()->GetRenderers(); SHASSERT(!renderers.empty(), "No Renderers available") - auto renderGraph = renderers[0]->GetRenderGraph(); + auto renderGraph = renderers[SHGraphicsConstants::RenderGraphIndices::EDITOR]->GetRenderGraph(); auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass(); if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false) @@ -309,6 +333,28 @@ namespace SHADE }); } + void SHEditor::PollPicking() + { + if (auto gfxSystem = SHSystemManager::GetSystem()) + { + if (!ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity(); + if(pickedEID == MAX_EID) + return; + if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) + { + if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow()) + { + hierarchyPanel->SetScrollTo(pickedEID); + } + selectedEntities.clear(); + } + selectedEntities.push_back(pickedEID); + } + } + } + void SHEditor::NewFrame() { SDL_Event event; diff --git a/SHADE_Engine/src/Editor/SHEditor.hpp b/SHADE_Engine/src/Editor/SHEditor.hpp index d579a9b5..baa6324e 100644 --- a/SHADE_Engine/src/Editor/SHEditor.hpp +++ b/SHADE_Engine/src/Editor/SHEditor.hpp @@ -90,11 +90,11 @@ namespace SHADE return reinterpret_cast(editorWindows[GetEditorWindowID()].get()); } + static EditorWindowMap editorWindows; private: // Number of windows; used for Editor Window ID Generation static EditorWindowID windowCount; // Map of Editor Windows - static EditorWindowMap editorWindows; friend class SHEditor; }; @@ -110,10 +110,17 @@ namespace SHADE class SH_API EditorRoutine final : public SHSystemRoutine { public: - EditorRoutine() = default; + EditorRoutine():SHSystemRoutine("Editor routine", true) {}; void Execute(double dt) noexcept override final; }; + enum class State : uint8_t + { + PLAY, + PAUSE, + STOP + }; + /** * @brief Style options * @@ -162,9 +169,13 @@ namespace SHADE void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;}; + void PollPicking(); + // List of selected entities std::vector selectedEntities; + State editorState = State::STOP; + private: /** * @brief Start new frame for editor @@ -177,7 +188,7 @@ namespace SHADE */ void Render(); - + void InitLayout() noexcept; void InitFonts() noexcept; @@ -186,6 +197,8 @@ namespace SHADE // Handle to command buffer used for ImGui Vulkan Backend Handle imguiCommandBuffer; - SDL_Window* sdlWindow; + SDL_Window* sdlWindow {nullptr}; + + ImGuiIO* io{nullptr}; };//class SHEditor }//namespace SHADE From a221cfc1cde720a123ae2c959ff2e1bcc11c131e Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 18 Oct 2022 17:25:45 +0800 Subject: [PATCH 19/24] Modified SHScriptEngine's serialization functions to take in EntityID instead of SHEntity --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 8 ++++---- SHADE_Engine/src/Scripting/SHScriptEngine.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 65f445a6..d7a090a4 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -115,7 +115,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Script Serialisation Functions */ /*---------------------------------------------------------------------------------*/ - std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity) const + std::string SHScriptEngine::SerialiseScripts(EntityID entity) const { // Create buffer needed to store serialised script data constexpr int BUFFER_SIZE = 10240; @@ -124,7 +124,7 @@ namespace SHADE // Attempt to serialise the script std::string result; - if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE)) + if (csScriptsSerialise(entity, buffer.get(), BUFFER_SIZE)) { result = std::string(buffer.get()); } @@ -140,9 +140,9 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Script Serialisation Functions */ /*-----------------------------------------------------------------------------------*/ - void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml) const + void SHScriptEngine::DeserialiseScript(EntityID entity, const std::string& yaml) const { - csScriptDeserialise(entity.GetEID(), yaml.c_str()); + csScriptDeserialise(entity, yaml.c_str()); } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 239d6b90..60723425 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -148,7 +148,7 @@ namespace SHADE /// /// String that represents the set of scripts attached to the specified Entity. /// - std::string SerialiseScripts(const SHEntity& entity) const; + std::string SerialiseScripts(EntityID entity) const; /// /// Loads the specified JSON string and creates a Script for the specified Entity /// based on the specified JSON string. @@ -157,7 +157,7 @@ namespace SHADE /// /// The YAML string that represents the Script to load into the Entity. /// - void DeserialiseScript(const SHEntity& entity, const std::string& yaml) const; + void DeserialiseScript(EntityID entity, const std::string& yaml) const; /*-----------------------------------------------------------------------------*/ /* Script Editor Functions */ From 9ce5a4a47bb6031d75db0e7f19241b2797d47ff0 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Tue, 18 Oct 2022 17:41:14 +0800 Subject: [PATCH 20/24] Mouse picking system now uses cursor returned from editor - This new cursor position is relative to where the viewport is rendering - Window resize callback in Graphics system now checks if editor is enabled before signaling for resize. This is because editor will handle the signaling for resizing when its enabled. When its disabled, the graphics system will signal itself to resize when the window resize callback is called. --- Assets/Editor/Layouts/UserLayout.ini | 30 +++++++++---------- .../src/Editor/EditorWindow/SHEditorWindow.h | 1 + .../ViewportWindow/SHEditorViewport.cpp | 11 +++++++ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 18 +++++++---- .../MiddleEnd/Interface/SHGraphicsSystem.h | 4 +-- .../MiddleEnd/Interface/SHMousePickSystem.cpp | 14 +++++---- .../MiddleEnd/Interface/SHMousePickSystem.h | 7 +++++ .../MiddleEnd/Interface/SHViewport.cpp | 10 +++++++ .../Graphics/MiddleEnd/Interface/SHViewport.h | 2 ++ 9 files changed, 70 insertions(+), 27 deletions(-) diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini index 869da91a..e55aeb81 100644 --- a/Assets/Editor/Layouts/UserLayout.ini +++ b/Assets/Editor/Layouts/UserLayout.ini @@ -1,16 +1,16 @@ [Window][MainStatusBar] -Pos=0,1167 -Size=2314,20 +Pos=0,1060 +Size=1920,20 Collapsed=0 [Window][SHEditorMenuBar] Pos=0,48 -Size=2314,1119 +Size=1920,1012 Collapsed=0 [Window][Hierarchy Panel] -Pos=0,152 -Size=208,1015 +Pos=0,142 +Size=321,918 Collapsed=0 DockId=0x00000004,0 @@ -20,29 +20,29 @@ Size=400,400 Collapsed=0 [Window][Inspector] -Pos=2044,48 -Size=270,1119 +Pos=1649,48 +Size=271,1012 Collapsed=0 DockId=0x00000006,0 [Window][Profiler] Pos=0,48 -Size=208,102 +Size=321,92 Collapsed=0 DockId=0x00000003,0 [Window][Viewport] -Pos=210,48 -Size=1832,1119 +Pos=323,48 +Size=1324,1012 Collapsed=0 DockId=0x00000002,0 [Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=-7,358 Size=2314,1119 Split=X - DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=2042,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=208,1036 Split=Y Selected=0x1E6EB881 +DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=617,298 Size=1920,1012 Split=X + DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X + DockNode ID=0x00000001 Parent=0x00000005 SizeRef=321,1036 Split=Y Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1832,1036 CentralNode=1 Selected=0x13926F0B - DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=270,1036 Selected=0xE7039252 + DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1324,1036 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h index 3e7a2a5c..dca02399 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h @@ -34,5 +34,6 @@ namespace SHADE ImGuiIO& io; SHVec2 windowSize; SHVec2 windowPos; + SHVec2 viewportMousePos; };//class SHEditorWindow }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index c903a80f..f6e6dcff 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -4,6 +4,7 @@ #include "ECS_Base/Managers/SHSystemManager.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" namespace SHADE { @@ -26,6 +27,14 @@ namespace SHADE DrawMenuBar(); auto gfxSystem = SHSystemManager::GetSystem(); auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0]; + + if (ImGui::IsWindowHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + { + auto mousePos = ImGui::GetMousePos(); + auto cursorPos = ImGui::GetCursorScreenPos(); + viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y}; + gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos); + } ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize()); } ImGui::End(); @@ -42,6 +51,8 @@ namespace SHADE //Get graphics system to resize swapchain image auto gfxSystem = SHSystemManager::GetSystem(); + //auto pos = ImGui::GetCursorPos(); + //windowCursorPos = {} gfxSystem->PrepareResize(static_cast(windowSize.x), static_cast(windowSize.y)); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index c78cc58f..b160d863 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -69,7 +69,15 @@ namespace SHADE if (width == 0 || height == 0) return; - PrepareResize(resizeWidth, resizeHeight); +#ifdef SHEDITOR + + //PrepareResize(1, 1, SHVec2(0, 0)); + +#else + + PrepareResize(resizeWidth, resizeHeight, SHVec2(0, 0)); + +#endif }); window->RegisterWindowCloseCallback([&](void) @@ -130,7 +138,7 @@ namespace SHADE worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); // Create Default Viewport - defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); + worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); // Get render graph from default viewport world renderer worldRenderGraph = resourceManager.Create(); @@ -163,7 +171,7 @@ namespace SHADE worldRenderGraph->Generate(); // Add world renderer to default viewport - worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); + worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); @@ -691,8 +699,8 @@ namespace SHADE mousePickSystem->HandleResize(); postOffscreenRender->HandleResize(); - defaultViewport->SetWidth(static_cast(resizeWidth)); - defaultViewport->SetHeight(static_cast(resizeHeight)); + worldViewport->SetWidth(static_cast(resizeWidth)); + worldViewport->SetHeight(static_cast(resizeHeight)); worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 0e1e2f78..7d0fa3ab 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -280,7 +280,7 @@ namespace SHADE Handle GetPhysicalDevice() const { return physicalDevice; } Handle GetQueue() const { return graphicsQueue; } Handle GetDescriptorPool() const { return descPool; } - Handle GetDefaultViewport() const {return defaultViewport;} + Handle GetDefaultViewport() const {return worldViewport;} #ifdef SHEDITOR Handle GetEditorViewport () const {return editorViewport;}; #endif @@ -325,7 +325,7 @@ namespace SHADE Handle editorRenderGraph; #endif - Handle defaultViewport; // Whole screen + Handle worldViewport; // Whole screen std::vector> viewports; // Additional viewports // Debug Renderers diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp index 1dd8212d..57a08d47 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp @@ -6,6 +6,7 @@ #include "Graphics/Synchronization/SHVkFence.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/SHVkUtil.h" +#include "Graphics/MiddleEnd/Interface/SHViewport.h" namespace SHADE { @@ -13,7 +14,7 @@ namespace SHADE { logicalDevice = device; - pickedEID = 0; + pickedEID = MAX_EID; // Create command buffers for (auto& pool : cmdPools) @@ -30,7 +31,7 @@ namespace SHADE void SHMousePickSystem::Run(Handle queue, uint32_t frameIndex) noexcept { // if input detected - if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::LEFT_CTRL) && SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB)) + if (SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB)) { afterCopyFence->Reset(); @@ -52,10 +53,8 @@ namespace SHADE // wait for the copy to be done afterCopyFence->Wait(true, std::numeric_limits::max()); - int mouseX = 0, mouseY = 0; - SHInputManager::GetMouseWindowPosition(&mouseX, &mouseY); + pickedEID = imageDataDstBuffer->GetDataFromMappedPointer(static_cast(viewportMousePos.y) * entityIDAttachment->GetWidth() + static_cast(viewportMousePos.x)); - pickedEID = imageDataDstBuffer->GetDataFromMappedPointer(mouseY * entityIDAttachment->GetWidth() + mouseX); } } @@ -79,6 +78,11 @@ namespace SHADE imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); } + void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept + { + viewportMousePos = vpMousePos; + } + EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept { return pickedEID; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h index 4b84c1df..85e86969 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h @@ -13,6 +13,7 @@ namespace SHADE class SHVkFence; class SHVkQueue; class SHVkBuffer; + class SHViewport; class SHMousePickSystem { @@ -33,6 +34,10 @@ namespace SHADE //! eid picked from screen EntityID pickedEID; + + //! mouse position relative to the viewport window displaying the world + SHVec2 viewportMousePos; + public: /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ @@ -44,6 +49,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ + void SetViewportMousePos (SHVec2 vpMousePos) noexcept; + EntityID GetPickedEntity (void) const noexcept; }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index dc534a49..f47920e0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -85,4 +85,14 @@ namespace SHADE } + void SHViewport::SetX(float x) noexcept + { + viewport.x = x; + } + + void SHViewport::SetY(float y) noexcept + { + viewport.y = y; + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index 221dbe7e..04b39f00 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -67,6 +67,8 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ void SetWidth(float w) noexcept; void SetHeight (float h) noexcept; + void SetX (float x) noexcept; + void SetY (float y) noexcept; /*-----------------------------------------------------------------------------*/ /* Getters */ From 15a17deaf0d0592261904fd7bee3e764815ff71f Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 18 Oct 2022 19:08:31 +0800 Subject: [PATCH 21/24] select picked entity in hierarchy panel --- .gitignore | 2 ++ .../src/Application/SBApplication.cpp | 9 +++++-- .../Editor/EditorWindow/SHEditorWindow.cpp | 1 + .../src/Editor/EditorWindow/SHEditorWindow.h | 1 + .../ViewportWindow/SHEditorViewport.cpp | 27 ++++++++++++++----- SHADE_Engine/src/Editor/SHEditor.cpp | 3 ++- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 8 +++--- 7 files changed, 37 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 1110510c..5d998cfd 100644 --- a/.gitignore +++ b/.gitignore @@ -362,3 +362,5 @@ MigrationBackup/ *.csproj *.filters + +Assets/Editor/Layouts/UserLayout.ini diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 202a3852..23943940 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -130,14 +130,19 @@ namespace Sandbox void SBApplication::Update(void) { SHGraphicsSystem* graphicsSystem = SHADE::SHSystemManager::GetSystem(); + SHEditor* editor = SHADE::SHSystemManager::GetSystem(); //TODO: Change true to window is open while (!window.WindowShouldClose()) { SHFrameRateController::UpdateFRC(); SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime()); SHSceneManager::UpdateSceneManager(); - SHSceneManager::SceneUpdate(0.016f); - SHSystemManager::RunRoutines(false, 0.016f); +#ifdef SHEDITOR + if(editor->editorState == SHEditor::State::PLAY) + SHSceneManager::SceneUpdate(0.016f); +#endif + SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f); + editor->PollPicking(); } // Finish all graphics jobs first diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp index 491c1bc2..edbe0faa 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp @@ -54,6 +54,7 @@ namespace SHADE windowPos = {wndPos.x, wndPos.y}; OnPosChange(); } + isWindowHovered = ImGui::IsWindowHovered(); return result; } diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h index dca02399..f46cd880 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h @@ -24,6 +24,7 @@ namespace SHADE virtual void Update(); virtual void Exit(); bool isOpen; + bool isWindowHovered; std::string_view windowName; protected: virtual bool Begin(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index f6e6dcff..420443ae 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -2,6 +2,8 @@ #include "SHEditorViewport.h" #include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/SHEditor.hpp" +#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h" @@ -27,14 +29,25 @@ namespace SHADE DrawMenuBar(); auto gfxSystem = SHSystemManager::GetSystem(); auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0]; + auto mousePos = ImGui::GetMousePos(); + auto cursorPos = ImGui::GetCursorScreenPos(); + viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y}; + gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos); + //if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + //{ + // auto eid = gfxSystem->GetMousePickSystem ()->GetPickedEntity(); + // if(eid != MAX_EID) + // { + // auto editor = SHSystemManager::GetSystem(); + // editor->selectedEntities.clear(); + // editor->selectedEntities.push_back(eid); + // if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow()) + // { + // hierarchyPanel->SetScrollTo(eid); + // } + // } + //} - if (ImGui::IsWindowHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) - { - auto mousePos = ImGui::GetMousePos(); - auto cursorPos = ImGui::GetCursorScreenPos(); - viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y}; - gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos); - } ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize()); } ImGui::End(); diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 4c6caff0..6b3c3a93 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -337,7 +337,8 @@ namespace SHADE { if (auto gfxSystem = SHSystemManager::GetSystem()) { - if (!ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) + auto viewportWindow = SHEditorWindowManager::GetEditorWindow(); + if (viewportWindow->isWindowHovered && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity(); if(pickedEID == MAX_EID) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index b160d863..143f3bf5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -597,7 +597,7 @@ namespace SHADE /* System Routine Functions - BeginRoutine */ /*-----------------------------------------------------------------------------------*/ SHGraphicsSystem::BeginRoutine::BeginRoutine() - : SHSystemRoutine("Graphics System Frame Set Up", false) + : SHSystemRoutine("Graphics System Frame Set Up", true) {} void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept @@ -609,7 +609,7 @@ namespace SHADE /* System Routine Functions - RenderRoutine */ /*-----------------------------------------------------------------------------------*/ SHGraphicsSystem::RenderRoutine::RenderRoutine() - : SHSystemRoutine("Graphics System Render", false) + : SHSystemRoutine("Graphics System Render", true) {} void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept @@ -621,7 +621,7 @@ namespace SHADE /* System Routine Functions - EndRoutine */ /*-----------------------------------------------------------------------------------*/ SHGraphicsSystem::EndRoutine::EndRoutine() - : SHSystemRoutine("Graphics System Frame Clean Up", false) + : SHSystemRoutine("Graphics System Frame Clean Up", true) {} void SHGraphicsSystem::EndRoutine::Execute(double) noexcept @@ -633,7 +633,7 @@ namespace SHADE /* System Routine Functions - BatcherDispatcherRoutine */ /*-----------------------------------------------------------------------------------*/ SHGraphicsSystem::BatcherDispatcherRoutine::BatcherDispatcherRoutine() - : SHSystemRoutine("Graphics System Batcher Dispatcher", false) + : SHSystemRoutine("Graphics System Batcher Dispatcher", true) {} void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept From 82637b620d953b01adb8201168031b13fcaeefd4 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Tue, 18 Oct 2022 19:36:49 +0800 Subject: [PATCH 22/24] Delete UserLayout.ini --- Assets/Editor/Layouts/UserLayout.ini | 48 ---------------------------- 1 file changed, 48 deletions(-) delete mode 100644 Assets/Editor/Layouts/UserLayout.ini diff --git a/Assets/Editor/Layouts/UserLayout.ini b/Assets/Editor/Layouts/UserLayout.ini deleted file mode 100644 index e55aeb81..00000000 --- a/Assets/Editor/Layouts/UserLayout.ini +++ /dev/null @@ -1,48 +0,0 @@ -[Window][MainStatusBar] -Pos=0,1060 -Size=1920,20 -Collapsed=0 - -[Window][SHEditorMenuBar] -Pos=0,48 -Size=1920,1012 -Collapsed=0 - -[Window][Hierarchy Panel] -Pos=0,142 -Size=321,918 -Collapsed=0 -DockId=0x00000004,0 - -[Window][Debug##Default] -Pos=60,60 -Size=400,400 -Collapsed=0 - -[Window][Inspector] -Pos=1649,48 -Size=271,1012 -Collapsed=0 -DockId=0x00000006,0 - -[Window][Profiler] -Pos=0,48 -Size=321,92 -Collapsed=0 -DockId=0x00000003,0 - -[Window][Viewport] -Pos=323,48 -Size=1324,1012 -Collapsed=0 -DockId=0x00000002,0 - -[Docking][Data] -DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=617,298 Size=1920,1012 Split=X - DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X - DockNode ID=0x00000001 Parent=0x00000005 SizeRef=321,1036 Split=Y Selected=0x1E6EB881 - DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881 - DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE - DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1324,1036 CentralNode=1 Selected=0x13926F0B - DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252 - From 87cf3ffa6176b9cacb97259fa52b9fd0ce361202 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 18 Oct 2022 20:09:50 +0800 Subject: [PATCH 23/24] Added script inspector tooltips support via Tooltip attribute --- SHADE_Engine/src/Editor/SHEditorUI.cpp | 59 +++++++++++++++---- SHADE_Engine/src/Editor/SHEditorUI.h | 45 ++++++++++---- SHADE_Engine/src/Editor/SHEditorUI.hpp | 7 ++- SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 4 +- SHADE_Managed/src/Editor/Editor.cxx | 56 ++++++++++++++---- SHADE_Managed/src/Editor/Editor.hxx | 10 +++- .../TooltipAttribute.cxx} | 29 +++++---- SHADE_Managed/src/Editor/TooltipAttribute.hxx | 53 +++++++++++++++++ .../Serialisation/SerializeFieldAttribute.hxx | 11 +--- TempScriptsFolder/RaccoonShowcase.cs | 8 ++- TempScriptsFolder/RaccoonSpin.cs | 4 +- 11 files changed, 221 insertions(+), 65 deletions(-) rename SHADE_Managed/src/{Serialisation/SerialiseFieldAttribute.cxx => Editor/TooltipAttribute.cxx} (54%) create mode 100644 SHADE_Managed/src/Editor/TooltipAttribute.hxx diff --git a/SHADE_Engine/src/Editor/SHEditorUI.cpp b/SHADE_Engine/src/Editor/SHEditorUI.cpp index 65b65827..76f7bac6 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.cpp +++ b/SHADE_Engine/src/Editor/SHEditorUI.cpp @@ -67,6 +67,11 @@ namespace SHADE ImGui::Separator(); } + bool SHEditorUI::IsItemHovered() + { + return ImGui::IsItemHovered(); + } + bool SHEditorUI::BeginMenu(const std::string& label) { return ImGui::BeginMenu(label.data()); @@ -82,6 +87,16 @@ namespace SHADE ImGui::EndMenu(); } + void SHEditorUI::BeginTooltip() + { + ImGui::BeginTooltip(); + } + + void SHEditorUI::EndTooltip() + { + ImGui::EndTooltip(); + } + /*-----------------------------------------------------------------------------------*/ /* ImGui Wrapper Functions - Pop Ups */ /*-----------------------------------------------------------------------------------*/ @@ -135,24 +150,30 @@ namespace SHADE return ImGui::Selectable(std::format("{} {}", icon, label).data()); } - bool SHEditorUI::InputCheckbox(const std::string& label, bool& value) + bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered) { ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); return ImGui::Checkbox("#", &value); } - bool SHEditorUI::InputInt(const std::string& label, int& value) + bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered) { ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); return ImGui::InputInt("#", &value, 1, 10, ImGuiInputTextFlags_EnterReturnsTrue); } - bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value) + bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered) { int signedVal = static_cast(value); ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); const bool CHANGED = InputInt("#", signedVal); if (CHANGED) @@ -162,35 +183,43 @@ namespace SHADE } return CHANGED; } - bool SHEditorUI::InputFloat(const std::string& label, float& value) + bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered) { ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); return ImGui::InputFloat("#", &value, 0.1f, 1.0f, "%.3f", ImGuiInputTextFlags_EnterReturnsTrue); } - bool SHEditorUI::InputDouble(const std::string& label, double& value) + bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered) { ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); return ImGui::InputDouble("#", &value, 0.1, 1.0, "%.3f", ImGuiInputTextFlags_EnterReturnsTrue); } - bool SHEditorUI::InputAngle(const std::string& label, double& value) + bool SHEditorUI::InputAngle(const std::string& label, double& value, bool* isHovered) { ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); return ImGui::InputDouble("#", &value, 1.0, 45.0, "%.3f", ImGuiInputTextFlags_EnterReturnsTrue); } - bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value) + bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered) { float val = static_cast(value); ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); const bool CHANGED = ImGui::SliderFloat("#", &val, static_cast(min), static_cast(max), "%.3f", @@ -204,22 +233,24 @@ namespace SHADE return CHANGED; } - bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value) + bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered) { static const std::vector COMPONENT_LABELS = { "X", "Y" }; - return SHEditorWidgets::DragN(label, COMPONENT_LABELS, { &value.x, &value.y }); + return SHEditorWidgets::DragN(label, COMPONENT_LABELS, { &value.x, &value.y }, 0.1f, "%.3f", float{}, float{}, 0, isHovered); } - bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, float speed) + bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered, float speed) { static const std::vector COMPONENT_LABELS = { "X", "Y", "Z"}; - return SHEditorWidgets::DragN(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f"); + return SHEditorWidgets::DragN(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f", float{}, float{}, 0, isHovered); } - bool SHEditorUI::InputTextField(const std::string& label, std::string& value) + bool SHEditorUI::InputTextField(const std::string& label, std::string& value, bool* isHovered) { std::array buffer = { '\0' }; strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str()); ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH); if (CHANGED) @@ -229,13 +260,15 @@ namespace SHADE return CHANGED; } - bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector& enumNames) + bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector& enumNames, bool* isHovered) { // Clamp input value const std::string& INITIAL_NAME = v >= static_cast(enumNames.size()) ? "Unknown" : enumNames[v]; bool b = false; ImGui::Text(label.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::SameLine(); if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None)) { diff --git a/SHADE_Engine/src/Editor/SHEditorUI.h b/SHADE_Engine/src/Editor/SHEditorUI.h index 13468215..b8451765 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.h +++ b/SHADE_Engine/src/Editor/SHEditorUI.h @@ -90,12 +90,19 @@ namespace SHADE static void SameLine(); static void Separator(); - /*-----------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------*/ + /* ImGui Wrapper Functions - Queries */ + /*-----------------------------------------------------------------------------*/ + static bool IsItemHovered(); + + /*-----------------------------------------------------------------------------*/ /* ImGui Wrapper Functions - Menu */ /*-----------------------------------------------------------------------------*/ static bool BeginMenu(const std::string& label); static bool BeginMenu(const std::string& label, const char* icon); static void EndMenu(); + static void BeginTooltip(); + static void EndTooltip(); /*-----------------------------------------------------------------------------*/ /* ImGui Wrapper Functions - Pop Ups */ @@ -165,8 +172,9 @@ namespace SHADE /// /// Label used to identify this widget. /// Reference to the variable to store the result. + /// Label used to identify this widget. /// Reference to the variable to store the result. + /// Label used to identify this widget. /// Reference to the variable to store the result. + /// Label used to identify this widget. /// Reference to the variable to store the result. + /// Label used to identify this widget. /// Reference to the variable to store the result. + /// Label used to identify this widget. /// Reference to the variable to store the result. + /// Minimum value of the slider. /// Maximum value of the slider. /// Reference to the variable to store the result. + /// Label used to identify this widget. /// Reference to the variable to store the result. + /// Label used to identify this widget. /// Reference to the variable to store the result. + /// Label used to identify this widget. /// Reference to the variable to store the result. + /// /// Conversion function from the type of enum to C-style string. /// + /// The name of the input. /// The reference to the value to modify. /// Vector of names for each enumeration value. + /// SkipItems) @@ -174,6 +174,8 @@ namespace SHADE ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize); ImGui::SetColumnWidth(-1, 80.0f); ImGui::Text(fieldLabel.c_str()); + if (isHovered) + *isHovered = ImGui::IsItemHovered(); ImGui::NextColumn(); for (std::size_t i = 0; i < N; ++i) { diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index 735f8c2c..8d105fce 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -29,6 +29,7 @@ of DigiPen Institute of Technology is prohibited. #include "Editor/IconsMaterialDesign.h" #include "Editor/Command/SHCommandManager.h" #include "Editor/Command/SHCommand.hpp" +#include "TooltipAttribute.hxx" // Using Directives using namespace System; @@ -48,17 +49,17 @@ using namespace System::Collections::Generic; /// The managed type of the object to edit. /// The native type of the object to edit. /// The SHEditorUI:: function to use for editing. -#define RENDER_FIELD(MANAGED_TYPE, NATIVE_TYPE, FUNC) \ -(field->FieldType == MANAGED_TYPE::typeid) \ -{ \ - NATIVE_TYPE val = safe_cast(field->GetValue(object)); \ - NATIVE_TYPE oldVal = val; \ - if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \ - { \ - field->SetValue(object, val); \ - registerUndoAction(object, field, val, oldVal); \ - } \ -} \ +#define RENDER_FIELD(MANAGED_TYPE, NATIVE_TYPE, FUNC) \ +(field->FieldType == MANAGED_TYPE::typeid) \ +{ \ + NATIVE_TYPE val = safe_cast(field->GetValue(object)); \ + NATIVE_TYPE oldVal = val; \ + if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered))\ + { \ + field->SetValue(object, val); \ + registerUndoAction(object, field, val, oldVal); \ + } \ +} \ /// /// Macro expansion that is used in renderFieldInInspector() to check the type of a field /// named "field" against the specified type and if it matches, retrieves the value of @@ -76,7 +77,7 @@ using namespace System::Collections::Generic; { \ NATIVE_TYPE val = Convert::ToNative(safe_cast(field->GetValue(object))); \ NATIVE_TYPE oldVal = val; \ - if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \ + if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered)) \ { \ field->SetValue(object, Convert::ToCLI(val)); \ registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \ @@ -196,6 +197,8 @@ namespace SHADE } void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object) { + bool isHovered = false; + if RENDER_FIELD (Int16, int, InputInt) else if RENDER_FIELD (Int32, int, InputInt) else if RENDER_FIELD (Int64, int, InputInt) @@ -244,6 +247,15 @@ namespace SHADE registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); } } + + // Check if the field has a specific attribute + TooltipAttribute^ toolTip = hasAttribute(field); + if (toolTip && isHovered) + { + SHEditorUI::BeginTooltip(); + SHEditorUI::Text(Convert::ToNative(toolTip->Description)); + SHEditorUI::EndTooltip(); + } } void Editor::renderScriptContextMenu(Entity entity, Script^ script) @@ -274,4 +286,24 @@ namespace SHADE SHCommandManager::RegisterCommand(std::reinterpret_pointer_cast(std::make_shared())); } + generic + Attribute Editor::hasAttribute(System::Reflection::FieldInfo^ field) + { + array^ attributes = field->GetCustomAttributes(true); + for each (System::Object^ attrib in attributes) + { + try + { + Attribute attribute = safe_cast(attrib); + if (attribute != nullptr) + return attribute; + } + catch (System::InvalidCastException^) + { + continue; + } + } + // Failed to find + return Attribute{}; + } } diff --git a/SHADE_Managed/src/Editor/Editor.hxx b/SHADE_Managed/src/Editor/Editor.hxx index c4800645..6b59589a 100644 --- a/SHADE_Managed/src/Editor/Editor.hxx +++ b/SHADE_Managed/src/Editor/Editor.hxx @@ -23,7 +23,7 @@ namespace SHADE /// /// Static class for Editor-related functions /// - public ref class Editor abstract sealed + private ref class Editor abstract sealed { public: /*-----------------------------------------------------------------------------*/ @@ -48,7 +48,13 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* UndoRedoStack Functions */ /*-----------------------------------------------------------------------------*/ + /// + /// Undoes the last script inspector change if there is any. + /// static void Undo(); + /// + /// Redoes the last script inspector change if there is any. + /// static void Redo(); private: @@ -86,5 +92,7 @@ namespace SHADE /// The Script to render the inspector for. static void renderScriptContextMenu(Entity entity, Script^ script); static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData); + generic where Attribute : System::Attribute + static Attribute hasAttribute(System::Reflection::FieldInfo^ field); }; } diff --git a/SHADE_Managed/src/Serialisation/SerialiseFieldAttribute.cxx b/SHADE_Managed/src/Editor/TooltipAttribute.cxx similarity index 54% rename from SHADE_Managed/src/Serialisation/SerialiseFieldAttribute.cxx rename to SHADE_Managed/src/Editor/TooltipAttribute.cxx index c371d200..8d5a5d55 100644 --- a/SHADE_Managed/src/Serialisation/SerialiseFieldAttribute.cxx +++ b/SHADE_Managed/src/Editor/TooltipAttribute.cxx @@ -1,27 +1,34 @@ /************************************************************************************//*! -\file SerializeFieldAttribute.cxx +\file TooltipAttribute.cxx \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu -\date Nov 5, 2021 -\brief Contains the definition of the functions of the managed SerializeField - Attribute class. +\date Oct 18, 2022 +\brief Contains the definition of the functions of the managed Tooltip Attribute + class. Note: This file is written in C++17/CLI. - -Copyright (C) 2021 DigiPen Institute of Technology. -Reproduction or disclosure of this file or its contents without the prior written consent + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ -// Precompiled Headers #include "SHpch.h" -// Primary Header -#include "SerializeFieldAttribute.hxx" +#include "TooltipAttribute.hxx" namespace SHADE { + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + System::String^ TooltipAttribute::Description::get() + { + return desc; + } + /*---------------------------------------------------------------------------------*/ /* Constructors */ /*---------------------------------------------------------------------------------*/ - SerializeField::SerializeField() + TooltipAttribute::TooltipAttribute(System::String^ description) + : desc { description } {} } diff --git a/SHADE_Managed/src/Editor/TooltipAttribute.hxx b/SHADE_Managed/src/Editor/TooltipAttribute.hxx new file mode 100644 index 00000000..e7cd168c --- /dev/null +++ b/SHADE_Managed/src/Editor/TooltipAttribute.hxx @@ -0,0 +1,53 @@ +/************************************************************************************//*! +\file TooltipAttribute.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 18, 2022 +\brief Contains the definition of the managed Tooltip Attribute class with + the declaration of functions for working with it. + + Note: This file is written in C++17/CLI. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +namespace SHADE +{ + /// + /// Simple attribute to mark that a field in a Script should be serialised. + /// + [System::AttributeUsage(System::AttributeTargets::Field)] + public ref class TooltipAttribute : public System::Attribute + { + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Description that is to be shown in the Tooltip. + /// + property System::String^ Description + { + System::String^ get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructor for a Tooltip attribute that fills in the description. + /// + /// Text to be shown when a field is hovered. + TooltipAttribute(System::String^ description); + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + System::String^ desc; + }; +} + diff --git a/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx b/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx index 533ded2a..7a7bb83c 100644 --- a/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx +++ b/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx @@ -21,15 +21,6 @@ namespace SHADE /// [System::AttributeUsage(System::AttributeTargets::Field)] public ref class SerializeField : public System::Attribute - { - public: - /*-----------------------------------------------------------------------------*/ - /* Constructors */ - /*-----------------------------------------------------------------------------*/ - /// - /// Default Constructor - /// - SerializeField(); - }; + {}; } diff --git a/TempScriptsFolder/RaccoonShowcase.cs b/TempScriptsFolder/RaccoonShowcase.cs index e2d6454d..93ea53eb 100644 --- a/TempScriptsFolder/RaccoonShowcase.cs +++ b/TempScriptsFolder/RaccoonShowcase.cs @@ -3,8 +3,12 @@ using System; public class RaccoonShowcase : Script { - public double RotateSpeed = 1.0; - public Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0); + [SerializeField] + [Tooltip("Speed of the rotation in radians per second.")] + private double RotateSpeed = 1.0; + [SerializeField] + [Tooltip("Speed of the scaling in radians per second around each axis.")] + private Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0); private Transform Transform; private double rotation = 0.0; private Vector3 scale = Vector3.Zero; diff --git a/TempScriptsFolder/RaccoonSpin.cs b/TempScriptsFolder/RaccoonSpin.cs index 7785cfd5..d6ee1c9f 100644 --- a/TempScriptsFolder/RaccoonSpin.cs +++ b/TempScriptsFolder/RaccoonSpin.cs @@ -3,7 +3,9 @@ using System; public class RaccoonSpin : Script { - public double RotateSpeed = 1.0; + [SerializeField] + [Tooltip("Speed of the rotation in radians per second.")] + private double RotateSpeed = 1.0; private double rotation = 0.0; private Transform Transform; public RaccoonSpin(GameObject gameObj) : base(gameObj) { } From 96f5b29418eba41c360e2386350b64946ab036a2 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Wed, 19 Oct 2022 01:03:32 +0800 Subject: [PATCH 24/24] Serialization/Deserialization --- .../HierarchyPanel/SHHierarchyPanel.cpp | 6 +++ .../EditorWindow/MenuBar/SHEditorMenuBar.cpp | 11 ++++- .../src/Serialization/SHSerialization.cpp | 42 ++++++++++++++++--- .../src/Serialization/SHSerialization.h | 3 +- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 42c9da66..30af228b 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -21,6 +21,8 @@ //#==============================================================# #include +#include "Serialization/SHSerialization.h" + namespace SHADE { @@ -171,6 +173,10 @@ namespace SHADE editor->selectedEntities.clear(); editor->selectedEntities.push_back(eid); } + if(ImGui::Selectable("Copy")) + { + SHLOG_INFO(SHSerialization::SerializeEntitiesToString(editor->selectedEntities)) + } if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data())) { SHEntityManager::DestroyEntity(eid); diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index 3cb6561d..c33f4fb6 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -17,6 +17,8 @@ #include #include +#include "Serialization/SHSerialization.h" + namespace SHADE { constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | @@ -73,7 +75,14 @@ namespace SHADE { if (ImGui::BeginMenu("File")) { - + if(ImGui::Selectable("Save")) + { + SHSerialization::SerializeSceneToFile("../../Assets/Scenes/Test.SHADE"); + } + if(ImGui::Selectable("Load")) + { + SHSerialization::DeserializeSceneFromFile("../../Assets/Scenes/Test.SHADE"); + } ImGui::EndMenu(); } if(ImGui::BeginMenu("Edit")) diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index ee189f2c..e259fbbc 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -12,6 +12,7 @@ #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Math/Transform/SHTransformComponent.h" +#include "Physics/Components/SHRigidBodyComponent.h" namespace SHADE { @@ -119,11 +120,27 @@ namespace SHADE } } - - - std::string SHSerialization::SerializeEntityToString() + void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out) { - return std::string(); + out << SerializeEntityToNode(entityNode); + auto const& children = entityNode->GetChildren(); + for(auto const& child : children) + { + EmitEntity(child, out); + } + } + + std::string SHSerialization::SerializeEntitiesToString(std::vector const& entities) + { + YAML::Emitter out; + YAML::Node node; + auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + for (auto const& eid : entities) + { + auto entityNode = sceneGraph.GetNode(eid); + EmitEntity(entityNode, out); + } + return std::basic_string(out.c_str()); } void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path) @@ -153,6 +170,14 @@ namespace SHADE { components[rttr::type::get().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(transform); } + if (const auto renderable = SHComponentManager::GetComponent_s(eid)) + { + components[rttr::type::get().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(renderable); + } + if (const auto rigidbody = SHComponentManager::GetComponent_s(eid)) + { + components[rttr::type::get().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody); + } node[ComponentsNode] = components; return node; } @@ -173,17 +198,22 @@ namespace SHADE auto id = GetComponentID(componentsNode); if (id.has_value()) componentIDList.push_back(id.value()); + id = GetComponentID(componentsNode); if (id.has_value()) componentIDList.push_back(id.value()); + id = GetComponentID(componentsNode); + if (id.has_value()) + componentIDList.push_back(id.value()); + return componentIDList; } void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid) { - auto componentsNode = entityNode[ComponentsNode]; - if(!componentsNode) + auto const componentsNode = entityNode[ComponentsNode]; + if (!componentsNode) return; SHSerializationHelper::InitializeComponentFromNode(componentsNode, eid); } diff --git a/SHADE_Engine/src/Serialization/SHSerialization.h b/SHADE_Engine/src/Serialization/SHSerialization.h index 8a57f036..d247de7a 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.h +++ b/SHADE_Engine/src/Serialization/SHSerialization.h @@ -31,7 +31,8 @@ namespace SHADE static void DeserializeSceneFromFile(std::filesystem::path const& path); - static std::string SerializeEntityToString(); + static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out); + static std::string SerializeEntitiesToString(std::vector const& entities); static void SerializeEntityToFile(std::filesystem::path const& path); static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode);