From b933b0f7fc06f82f27e776a8da58a1bd90259831 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 16 Sep 2022 13:13:38 +0800 Subject: [PATCH 01/37] Added SerializeField attribute --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 4 +-- .../Serialisation/SerializeFieldAttribute.hxx | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 47c722dd..3116d680 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -483,8 +483,8 @@ namespace SHADE DWORD status; while (true) { - const auto SUCCESS = GetExitCodeProcess(procInfo.hProcess, &status); - if (!SUCCESS) + const auto EXEC_SUCCESS = GetExitCodeProcess(procInfo.hProcess, &status); + if (!EXEC_SUCCESS) { auto err = GetLastError(); std::ostringstream oss; diff --git a/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx b/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx new file mode 100644 index 00000000..6036a7f5 --- /dev/null +++ b/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx @@ -0,0 +1,35 @@ +/************************************************************************************//*! +\file SerializeFieldAttribute.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 5, 2021 +\brief Contains the definition of the managed SerializeField Attribute class with + the declaration of functions for working with it. + + 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 +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(AttributeTargets::Field)] + public ref class SerializeField : public System::Attribute + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + /// + /// Default Constructor + /// + SerializeField() = default; + }; +} + From da582e0f1d74c9255483b17944b0e96d9a9b340a Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 16 Sep 2022 13:58:08 +0800 Subject: [PATCH 02/37] added serial --- .../src/Serialisation/ReflectionUtilities.cxx | 429 ++++++++++++++++++ .../src/Serialisation/ReflectionUtilities.hxx | 73 +++ .../Serialisation/SerialiseFieldAttribute.cxx | 27 ++ .../Serialisation/SerializeFieldAttribute.hxx | 4 +- 4 files changed, 531 insertions(+), 2 deletions(-) create mode 100644 SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx create mode 100644 SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx create mode 100644 SHADE_Managed/src/Serialisation/SerialiseFieldAttribute.cxx diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx new file mode 100644 index 00000000..8ea4a44e --- /dev/null +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx @@ -0,0 +1,429 @@ +/************************************************************************************//*! +\file ReflectionUtilities.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 6, 2021 +\brief Contains the definition of the functions for the ReflectionUtilities + managed static 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 +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "Serialisation/ReflectionUtilities.hxx" +// External Dependencies + +// Project Includes +#include "SerializeFieldAttribute.hxx" +#include "Utility/Convert.hxx" + +/*-------------------------------------------------------------------------------------*/ +/* Macro Functions */ +/*-------------------------------------------------------------------------------------*/ +/// +/// Macro expansion that is used in FieldToRapidJsonValue() to check the type of a field +/// named "fieldInfo" against the specified type and if it matches, store said field +/// of an object named "object" it into rapidjson::Value called "jsonValue" as that +/// specified type. +/// +/// The type to check. +#define PRIMITIVE_FIELD_CAST(T) \ +(fieldInfo->FieldType == T::typeid) \ +{ \ + jsonValue = safe_cast(fieldInfo->GetValue(object)); \ +} \ +/// +/// Macro expansion that is used in RapidJsonValueToField() to check the type of a field +/// named "fieldInfo" against the specified type and if it matches, retrieves the value +/// using the function FUNC provided from a rapidjson::Value called "jsonValue" and sets +/// the value of the field to the retrieved value. +/// +/// The type to check. +/// Member function of jsonValue to use to retrieve the data. +#define PRIMITIVE_FIELD_ASSIGN(T, FUNC) \ +(fieldInfo->FieldType == T::typeid) \ +{ \ + fieldInfo->SetValue(object, jsonValue.FUNC()); \ +} \ +/// +/// Macro expansion that is used in RapidJsonValueToField() to retrieve the specified +/// member of a Vector type that is stored into a Vector named "vec". +/// +/// The name of the member to retrieve. +#define PRIMITIVE_VECTOR_FIELD_ASSIGN(MEMBER) \ +iter = jsonValue.FindMember(#MEMBER); \ +if (iter != jsonValue.MemberEnd()) \ +{ \ + vec.MEMBER = iter->value.GetDouble(); \ +} \ +/// +/// Macro expansion that is used in RapidJsonValueToField() to retrieve the specified +/// member of a Color type that is stored into a Color named "col". +/// +/// The name of the member to retrieve. +#define PRIMITIVE_COLOR_FIELD_ASSIGN(MEMBER) \ +iter = jsonValue.FindMember(#MEMBER); \ +if (iter != jsonValue.MemberEnd()) \ +{ \ + col.MEMBER = iter->value.GetFloat(); \ +} \ +/// +/// Macro expansion that is used to write the name of a field named fieldInfo into a +/// rapidjson writer called writer. +/// +#define PRIMITIVE_WRITE_FIELD_NAME writer.String(Convert::ToNative(fieldInfo->Name).c_str()); +/// +/// Macro expansion that is used in serialiseFieldJson() to check the type of a field +/// named "fieldInfo" against the specified type and if it matches, writes the value +/// using the function FUNC in to a rapidjson writer object named "writer". +/// +/// The type to check. +/// +/// Member function of the rapidjson writer object to use to write the data. +/// +#define PRIMITIVE_FIELD_SERIALISE_JSON(T, FUNC) \ +(fieldInfo->FieldType == T::typeid) \ +{ \ + PRIMITIVE_WRITE_FIELD_NAME \ + writer.FUNC(safe_cast(fieldInfo->GetValue(object))); \ +} \ +/// +/// Macro expansion that is used in serialiseFieldJson() to write the specified +/// member of a Vector named "vec" using the rapidjson writer named "writer". +/// +/// The name of the member to write. +#define PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(MEMBER) \ +writer.String(#MEMBER); \ +writer.Double(vec.MEMBER); \ +/*-------------------------------------------------------------------------------------*/ +/* Function Definitions */ +/*-------------------------------------------------------------------------------------*/ +namespace SHADE +{ + System::Collections::Generic::IEnumerable^ ReflectionUtilities::GetInstanceFields(System::Object^ object) + { + using namespace System::Reflection; + + return object->GetType()->GetFields + ( + BindingFlags::Public | BindingFlags::NonPublic | BindingFlags::Instance + ); + } + + bool ReflectionUtilities::FieldIsSerialisable(System::Reflection::FieldInfo^ fieldInfo) + { + return fieldInfo->IsPublic || fieldInfo->GetCustomAttributes(SerializeField::typeid, true)->Length > 0; + } + + /*---------------------------------------------------------------------------------*/ + /* Serialisation Functions */ + /*---------------------------------------------------------------------------------*/ + //void ReflectionUtilities::Serialise(System::Object^ object, YAML::Emitter& yaml) + //{ + // // Create YAML object + // yaml << YAML::Key << Convert::ToNative(object->GetType().FullName); + // yaml << YAML::BeginMap; + + // // Get all fields + // IEnumerable^ fields = GetInstanceFields(object); + // for each (FieldInfo^ field in fields) + // { + // // Ignore private and non-SerialiseField + // if (!FieldIsSerialisable(field)) + // continue; + + // // Serialise + // rapidjson::Value jsonValue = FieldToRapidJsonValue(field, object, allocator); + // rapidjson::Value key(Convert::ToNative(field->Name).c_str(), allocator); + // scriptRoot.AddMember(key.Move(), jsonValue, allocator); + // } + + // /* Add the Script JSON Object to the JSON root node*/ + // rapidjson::Value key(Convert::ToNative(object->GetType()->FullName).c_str(), allocator); + // json.AddMember(key.Move(), scriptRoot, allocator); + + // /* Prepare to send to the caller */ + // // Convert to string + // rapidjson::StringBuffer buffer; + // rapidjson::PrettyWriter writer(buffer); + // json.Accept(writer); + + // // Return the result + // return Convert::ToCLI(std::string(buffer.GetString())); + //} + //void ReflectionUtilities::Deserialise(System::String^ jsonString, Object^ object) + //{ + // // Load the JSON + // rapidjson::Document json; + // auto& allocator = json.GetAllocator(); + // json.Parse(Convert::ToNative(jsonString).c_str()); + + // // Get the root object + // auto scriptRoot = json.MemberBegin(); + // if (scriptRoot == json.MemberEnd()) + // { + // Pls::Debug::LogError("[ReflectionUtilities] Attempted read of corrupted serialised object."); + // return; + // } + // + // // Get all fields + // IEnumerable^ fields = GetInstanceFields(object); + // for each (FieldInfo^ field in fields) + // { + // // Ignore private and non-SerialiseField + // if (!FieldIsSerialisable(field)) + // continue; + + // // Deserialise + // auto iter = scriptRoot->value.FindMember(Convert::ToNative(field->Name).c_str()); + // if (iter != scriptRoot->value.MemberEnd()) + // { + // // Get the data and set it in + // RapidJsonValueToField(iter->value, field, object); + + // } + // } + //} + //void ReflectionUtilities::Serialise(Object^ object, JsonWriter& writer) + //{ + // /* Script Name */ + // writer.String(Convert::ToNative(object->GetType()->FullName).c_str()); + + // /* Script Contents */ + // writer.StartObject(); + // IEnumerable^ fields = GetInstanceFields(object); + // for each (FieldInfo^ field in fields) + // { + // // Ignore private and non-SerialiseField + // if (!FieldIsSerialisable(field)) + // continue; + + // // Serialise + // serialiseFieldJson(field, object, writer); + // } + // writer.EndObject(); + //} + + ///*---------------------------------------------------------------------------------*/ + ///* Serialisation Helper Functions */ + ///*---------------------------------------------------------------------------------*/ + //rapidjson::Value ReflectionUtilities::FieldToRapidJsonValue(FieldInfo^ fieldInfo, Object^ object, JsonAllocator& allocator) + //{ + // rapidjson::Value jsonValue; + + // // Check each type of value and convert it into a rapidjson::Value + // if PRIMITIVE_FIELD_CAST(Int16) + // else if PRIMITIVE_FIELD_CAST(Int32) + // else if PRIMITIVE_FIELD_CAST(Int64) + // else if PRIMITIVE_FIELD_CAST(UInt16) + // else if PRIMITIVE_FIELD_CAST(UInt32) + // else if PRIMITIVE_FIELD_CAST(UInt64) + // else if PRIMITIVE_FIELD_CAST(Byte) + // else if PRIMITIVE_FIELD_CAST(bool) + // else if PRIMITIVE_FIELD_CAST(float) + // else if PRIMITIVE_FIELD_CAST(double) + // else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid)) + // { + // jsonValue = safe_cast(fieldInfo->GetValue(object)); + // } + // else if (fieldInfo->FieldType == String::typeid) + // { + // String^ str = safe_cast(fieldInfo->GetValue(object)); + // jsonValue.SetString(Convert::ToNative(str).c_str(), str->Length, allocator); + // } + // else if (fieldInfo->FieldType == Vector2::typeid) + // { + // jsonValue.SetObject(); + // Vector2 vec = safe_cast(fieldInfo->GetValue(object)); + // jsonValue.AddMember(rapidjson::Value("x"), rapidjson::Value(vec.x), allocator); + // jsonValue.AddMember(rapidjson::Value("y"), rapidjson::Value(vec.y), allocator); + // } + // else if (fieldInfo->FieldType == Vector3::typeid) + // { + // jsonValue.SetObject(); + // Vector3 vec = safe_cast(fieldInfo->GetValue(object)); + // jsonValue.AddMember(rapidjson::Value("x"), rapidjson::Value(vec.x), allocator); + // jsonValue.AddMember(rapidjson::Value("y"), rapidjson::Value(vec.y), allocator); + // jsonValue.AddMember(rapidjson::Value("z"), rapidjson::Value(vec.z), allocator); + // } + // else if (fieldInfo->FieldType == Color::typeid) + // { + // jsonValue.SetObject(); + // Color col = safe_cast(fieldInfo->GetValue(object)); + // jsonValue.AddMember(rapidjson::Value("r"), rapidjson::Value(col.r), allocator); + // jsonValue.AddMember(rapidjson::Value("g"), rapidjson::Value(col.g), allocator); + // jsonValue.AddMember(rapidjson::Value("b"), rapidjson::Value(col.b), allocator); + // jsonValue.AddMember(rapidjson::Value("a"), rapidjson::Value(col.a), allocator); + // } + // else if (IResourceID::typeid->IsAssignableFrom(fieldInfo->FieldType)) + // { + // IResourceID^ rscId = safe_cast(fieldInfo->GetValue(object)); + // jsonValue = rscId->Id; + // } + // else // Not any of the supported types + // { + // Pls::Debug::LogWarning(Convert::ToNative(String::Format + // ( + // "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialisation.", + // fieldInfo->Name, fieldInfo->FieldType) + // )); + // } + // return jsonValue; + //} + //void ReflectionUtilities::RapidJsonValueToField(const rapidjson::Value& jsonValue, FieldInfo^ fieldInfo, Object^ object) + //{ + // if PRIMITIVE_FIELD_ASSIGN(Int16, GetInt) + // else if PRIMITIVE_FIELD_ASSIGN(Int32, GetInt) + // else if PRIMITIVE_FIELD_ASSIGN(Int64, GetInt64) + // else if PRIMITIVE_FIELD_ASSIGN(UInt16, GetUint) + // else if PRIMITIVE_FIELD_ASSIGN(UInt32, GetUint) + // else if PRIMITIVE_FIELD_ASSIGN(UInt64, GetUint64) + // else if PRIMITIVE_FIELD_ASSIGN(Byte, GetInt) + // else if PRIMITIVE_FIELD_ASSIGN(bool, GetBool) + // else if PRIMITIVE_FIELD_ASSIGN(float, GetFloat) + // else if PRIMITIVE_FIELD_ASSIGN(double, GetDouble) + // else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid)) + // { + // fieldInfo->SetValue(object, jsonValue.GetInt()); + // } + // else if (fieldInfo->FieldType == String::typeid) + // { + // fieldInfo->SetValue(object, Convert::ToCLI(jsonValue.GetString())); + // } + // else if (fieldInfo->FieldType == Vector2::typeid) + // { + // Vector2 vec; + // auto iter = jsonValue.MemberEnd(); + // PRIMITIVE_VECTOR_FIELD_ASSIGN(x) + // PRIMITIVE_VECTOR_FIELD_ASSIGN(y) + // fieldInfo->SetValue(object, vec); + // } + // else if (fieldInfo->FieldType == Vector3::typeid) + // { + // Vector3 vec; + // auto iter = jsonValue.MemberEnd(); + // PRIMITIVE_VECTOR_FIELD_ASSIGN(x) + // PRIMITIVE_VECTOR_FIELD_ASSIGN(y) + // PRIMITIVE_VECTOR_FIELD_ASSIGN(z) + // fieldInfo->SetValue(object, vec); + // } + // else if (fieldInfo->FieldType == Color::typeid) + // { + // Color col; + // auto iter = jsonValue.MemberEnd(); + // PRIMITIVE_COLOR_FIELD_ASSIGN(r) + // PRIMITIVE_COLOR_FIELD_ASSIGN(g) + // PRIMITIVE_COLOR_FIELD_ASSIGN(b) + // PRIMITIVE_COLOR_FIELD_ASSIGN(a) + // fieldInfo->SetValue(object, col); + // } + // else if (IResourceIDInternal::typeid->IsAssignableFrom(fieldInfo->FieldType)) + // { + // IResourceIDInternal^ rsc = safe_cast(Activator::CreateInstance(fieldInfo->FieldType)); + // rsc->Id = jsonValue.GetInt64(); + // fieldInfo->SetValue(object, rsc); + // } + // else // Not any of the supported types + // { + // Pls::Debug::LogWarning(Convert::ToNative(String::Format + // ( + // "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for deserialisation.", + // fieldInfo->Name, fieldInfo->FieldType) + // )); + // } + //} + + ///*---------------------------------------------------------------------------------*/ + ///* Internal Serialisation Helper Functions */ + ///*---------------------------------------------------------------------------------*/ + //void ReflectionUtilities::serialiseFieldJson(FieldInfo^ fieldInfo, Object^ object, JsonWriter& writer) + //{ + // if PRIMITIVE_FIELD_SERIALISE_JSON(Int16, Int) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(Int32, Int) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(Int64, Int64) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(UInt16, Uint) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(UInt32, Uint) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(UInt64, Uint64) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(Byte, Int) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(bool, Bool) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(float, Double) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(double, Double) + // else if PRIMITIVE_FIELD_SERIALISE_JSON(double, Double) + // else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid)) + // { + // PRIMITIVE_WRITE_FIELD_NAME + // writer.Int(safe_cast(fieldInfo->GetValue(object))); + + // } + // else if (fieldInfo->FieldType == String::typeid) + // { + // PRIMITIVE_WRITE_FIELD_NAME + // writer.String(Convert::ToNative(safe_cast(fieldInfo->GetValue(object))).c_str()); + + // } + // else if (fieldInfo->FieldType == Vector2::typeid) + // { + // // Get handle to the Vector to edit + // Vector2 vec = safe_cast(fieldInfo->GetValue(object)); + + // // Write the vector data + // PRIMITIVE_WRITE_FIELD_NAME + // writer.StartObject(); + // { + // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(x) + // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(y) + // } + // writer.EndObject(); + // } + // else if (fieldInfo->FieldType == Vector3::typeid) + // { + // // Get handle to the Vector to edit + // Vector3 vec = safe_cast(fieldInfo->GetValue(object)); + + // // Write the vector data + // PRIMITIVE_WRITE_FIELD_NAME + // writer.StartObject(); + // { + // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(x) + // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(y) + // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(z) + // } + // writer.EndObject(); + // } + // else if (fieldInfo->FieldType == Color::typeid) + // { + // // Get handle to the Vector to edit + // Color vec = safe_cast(fieldInfo->GetValue(object)); + + // // Write the vector data + // PRIMITIVE_WRITE_FIELD_NAME + // writer.StartObject(); + // { + // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(r) + // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(g) + // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(b) + // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(a) + // } + // writer.EndObject(); + // } + // else if (IResourceID::typeid->IsAssignableFrom(fieldInfo->FieldType)) + // { + // PRIMITIVE_WRITE_FIELD_NAME + // IResourceID^ rsc = safe_cast(fieldInfo->GetValue(object)); + // writer.Int64(rsc->Id); + // } + // else // Not any of the supported types + // { + // Pls::Debug::LogWarning(Convert::ToNative(String::Format + // ( + // "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialisation.", + // fieldInfo->Name, fieldInfo->FieldType) + // )); + // } + //} +} diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx new file mode 100644 index 00000000..f312ec05 --- /dev/null +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx @@ -0,0 +1,73 @@ +/************************************************************************************//*! +\file ReflectionUtilities.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Nov 6, 2021 +\brief Contains the definition of the managed ReflectionUtilities static 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 +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +#pragma once + +// External Dependencies +#include +#include + + +namespace SHADE +{ + /// + /// Contains useful static functions for working with Reflection. + /// + private ref class ReflectionUtilities abstract sealed + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + + /*-----------------------------------------------------------------------------*/ + /* Utility Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Retrieves a set of all non-static (instance) fields from a specified object. + /// + /// The object to get non-static fields from. + /// Immutable list of non-static fields. + static System::Collections::Generic::IEnumerable^ GetInstanceFields(System::Object^ object); + /// + /// Checks if a specified field is a candidate for serialisation. This means that + /// the field is public or private with the [SerialiseField] attribute. + /// + /// The field to check. + /// + /// True if the specified field is a candidate for serialisation. + /// + static bool FieldIsSerialisable(System::Reflection::FieldInfo^ fieldInfo); + + /*-----------------------------------------------------------------------------*/ + /* Serialisation Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Creates a JSON node that represents the specified object and its associated + /// serialisable fields. Public fields and fields marked with the SerialiseField + /// attribute will be serialised. + /// + /// The object to serialise. + //static void Serialise(Object^ object, YAML::Emitter& yaml); + /// + /// Deserialises a JSON string and copies the deserialised data into the + /// specified object if there are matching fields. + /// + /// + /// The JSON string that contains the data to copy into this PlushieScript + /// object. + /// + /// The object to copy deserialised data into. + //static void Deserialise(System::String^ jsonString, Object^ object); + }; +} \ No newline at end of file diff --git a/SHADE_Managed/src/Serialisation/SerialiseFieldAttribute.cxx b/SHADE_Managed/src/Serialisation/SerialiseFieldAttribute.cxx new file mode 100644 index 00000000..c371d200 --- /dev/null +++ b/SHADE_Managed/src/Serialisation/SerialiseFieldAttribute.cxx @@ -0,0 +1,27 @@ +/************************************************************************************//*! +\file SerializeFieldAttribute.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. + + 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 +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "SerializeFieldAttribute.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + SerializeField::SerializeField() + {} +} diff --git a/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx b/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx index 6036a7f5..533ded2a 100644 --- a/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx +++ b/SHADE_Managed/src/Serialisation/SerializeFieldAttribute.hxx @@ -19,7 +19,7 @@ namespace SHADE /// /// Simple attribute to mark that a field in a Script should be serialised. /// - [System::AttributeUsage(AttributeTargets::Field)] + [System::AttributeUsage(System::AttributeTargets::Field)] public ref class SerializeField : public System::Attribute { public: @@ -29,7 +29,7 @@ namespace SHADE /// /// Default Constructor /// - SerializeField() = default; + SerializeField(); }; } From 4546b84c061464fa26f76afecd995d527d8b2e2c Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 16 Sep 2022 15:37:22 +0800 Subject: [PATCH 03/37] Added YAML serialization of scripts --- .../src/Serialisation/ReflectionUtilities.cxx | 535 ++++++------------ .../src/Serialisation/ReflectionUtilities.h++ | 54 ++ .../src/Serialisation/ReflectionUtilities.hxx | 34 +- 3 files changed, 249 insertions(+), 374 deletions(-) create mode 100644 SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx index 8ea4a44e..2a9cc57c 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.cxx @@ -16,41 +16,17 @@ of DigiPen Institute of Technology is prohibited. #include "SHpch.h" // Primary Header #include "Serialisation/ReflectionUtilities.hxx" -// External Dependencies - // Project Includes #include "SerializeFieldAttribute.hxx" #include "Utility/Convert.hxx" +#include "Math/Vector2.hxx" +#include "Math/Vector3.hxx" +#include "Utility/Debug.hxx" /*-------------------------------------------------------------------------------------*/ /* Macro Functions */ /*-------------------------------------------------------------------------------------*/ /// -/// Macro expansion that is used in FieldToRapidJsonValue() to check the type of a field -/// named "fieldInfo" against the specified type and if it matches, store said field -/// of an object named "object" it into rapidjson::Value called "jsonValue" as that -/// specified type. -/// -/// The type to check. -#define PRIMITIVE_FIELD_CAST(T) \ -(fieldInfo->FieldType == T::typeid) \ -{ \ - jsonValue = safe_cast(fieldInfo->GetValue(object)); \ -} \ -/// -/// Macro expansion that is used in RapidJsonValueToField() to check the type of a field -/// named "fieldInfo" against the specified type and if it matches, retrieves the value -/// using the function FUNC provided from a rapidjson::Value called "jsonValue" and sets -/// the value of the field to the retrieved value. -/// -/// The type to check. -/// Member function of jsonValue to use to retrieve the data. -#define PRIMITIVE_FIELD_ASSIGN(T, FUNC) \ -(fieldInfo->FieldType == T::typeid) \ -{ \ - fieldInfo->SetValue(object, jsonValue.FUNC()); \ -} \ -/// /// Macro expansion that is used in RapidJsonValueToField() to retrieve the specified /// member of a Vector type that is stored into a Vector named "vec". /// @@ -61,45 +37,7 @@ if (iter != jsonValue.MemberEnd()) \ { \ vec.MEMBER = iter->value.GetDouble(); \ } \ -/// -/// Macro expansion that is used in RapidJsonValueToField() to retrieve the specified -/// member of a Color type that is stored into a Color named "col". -/// -/// The name of the member to retrieve. -#define PRIMITIVE_COLOR_FIELD_ASSIGN(MEMBER) \ -iter = jsonValue.FindMember(#MEMBER); \ -if (iter != jsonValue.MemberEnd()) \ -{ \ - col.MEMBER = iter->value.GetFloat(); \ -} \ -/// -/// Macro expansion that is used to write the name of a field named fieldInfo into a -/// rapidjson writer called writer. -/// -#define PRIMITIVE_WRITE_FIELD_NAME writer.String(Convert::ToNative(fieldInfo->Name).c_str()); -/// -/// Macro expansion that is used in serialiseFieldJson() to check the type of a field -/// named "fieldInfo" against the specified type and if it matches, writes the value -/// using the function FUNC in to a rapidjson writer object named "writer". -/// -/// The type to check. -/// -/// Member function of the rapidjson writer object to use to write the data. -/// -#define PRIMITIVE_FIELD_SERIALISE_JSON(T, FUNC) \ -(fieldInfo->FieldType == T::typeid) \ -{ \ - PRIMITIVE_WRITE_FIELD_NAME \ - writer.FUNC(safe_cast(fieldInfo->GetValue(object))); \ -} \ -/// -/// Macro expansion that is used in serialiseFieldJson() to write the specified -/// member of a Vector named "vec" using the rapidjson writer named "writer". -/// -/// The name of the member to write. -#define PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(MEMBER) \ -writer.String(#MEMBER); \ -writer.Double(vec.MEMBER); \ + /*-------------------------------------------------------------------------------------*/ /* Function Definitions */ /*-------------------------------------------------------------------------------------*/ @@ -123,307 +61,182 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Serialisation Functions */ /*---------------------------------------------------------------------------------*/ - //void ReflectionUtilities::Serialise(System::Object^ object, YAML::Emitter& yaml) - //{ - // // Create YAML object - // yaml << YAML::Key << Convert::ToNative(object->GetType().FullName); - // yaml << YAML::BeginMap; + void ReflectionUtilities::Serialise(System::Object^ object, YAML::Emitter& yaml) + { + using namespace System::Reflection; - // // Get all fields - // IEnumerable^ fields = GetInstanceFields(object); - // for each (FieldInfo^ field in fields) - // { - // // Ignore private and non-SerialiseField - // if (!FieldIsSerialisable(field)) - // continue; + // Create YAML object + yaml << YAML::Key << Convert::ToNative(object->GetType()->FullName); + yaml << YAML::BeginMap; - // // Serialise - // rapidjson::Value jsonValue = FieldToRapidJsonValue(field, object, allocator); - // rapidjson::Value key(Convert::ToNative(field->Name).c_str(), allocator); - // scriptRoot.AddMember(key.Move(), jsonValue, allocator); - // } + // Get all fields + System::Collections::Generic::IEnumerable^ fields = GetInstanceFields(object); + for each (FieldInfo^ field in fields) + { + // Ignore private and non-SerialiseField + if (!FieldIsSerialisable(field)) + continue; - // /* Add the Script JSON Object to the JSON root node*/ - // rapidjson::Value key(Convert::ToNative(object->GetType()->FullName).c_str(), allocator); - // json.AddMember(key.Move(), scriptRoot, allocator); + // Serialise + writeFieldIntoYaml(field, object, yaml); + } - // /* Prepare to send to the caller */ - // // Convert to string - // rapidjson::StringBuffer buffer; - // rapidjson::PrettyWriter writer(buffer); - // json.Accept(writer); + yaml << YAML::EndMap; + } + void ReflectionUtilities::Deserialise(YAML::Node& yamlNode, Object^ object) + { + using namespace System::Reflection; - // // Return the result - // return Convert::ToCLI(std::string(buffer.GetString())); - //} - //void ReflectionUtilities::Deserialise(System::String^ jsonString, Object^ object) - //{ - // // Load the JSON - // rapidjson::Document json; - // auto& allocator = json.GetAllocator(); - // json.Parse(Convert::ToNative(jsonString).c_str()); + // Load the YAML + if (!yamlNode.IsMap()) + { + // Invalid + Debug::LogError + ( + System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of \"{0}\" script.", + object->GetType()->FullName) + ); + return; + } + // Get all fields + System::Collections::Generic::IEnumerable^ fields = GetInstanceFields(object); + for each (FieldInfo^ field in fields) + { + // Ignore private and non-SerialiseField + if (!FieldIsSerialisable(field)) + continue; - // // Get the root object - // auto scriptRoot = json.MemberBegin(); - // if (scriptRoot == json.MemberEnd()) - // { - // Pls::Debug::LogError("[ReflectionUtilities] Attempted read of corrupted serialised object."); - // return; - // } - // - // // Get all fields - // IEnumerable^ fields = GetInstanceFields(object); - // for each (FieldInfo^ field in fields) - // { - // // Ignore private and non-SerialiseField - // if (!FieldIsSerialisable(field)) - // continue; + // Deserialise + const std::string FIELD_NAME = Convert::ToNative(field->Name); + if (yamlNode[FIELD_NAME]) + { + writeYamlIntoField(field, object, yamlNode[FIELD_NAME]); + } + } + } + /*---------------------------------------------------------------------------------*/ + /* Serialization Helper Functions */ + /*---------------------------------------------------------------------------------*/ + void ReflectionUtilities::writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml) + { + // Field Name + yaml << YAML::Key << Convert::ToNative(fieldInfo->Name); - // // Deserialise - // auto iter = scriptRoot->value.FindMember(Convert::ToNative(field->Name).c_str()); - // if (iter != scriptRoot->value.MemberEnd()) - // { - // // Get the data and set it in - // RapidJsonValueToField(iter->value, field, object); + // Field Value + yaml << YAML::Value; + if (fieldInsertYaml (fieldInfo, object, yaml) || + fieldInsertYaml (fieldInfo, object, yaml) || + fieldInsertYaml (fieldInfo, object, yaml) || + fieldInsertYaml(fieldInfo, object, yaml) || + fieldInsertYaml(fieldInfo, object, yaml) || + fieldInsertYaml(fieldInfo, object, yaml) || + fieldInsertYaml (fieldInfo, object, yaml) || + fieldInsertYaml (fieldInfo, object, yaml) || + fieldInsertYaml (fieldInfo, object, yaml) || + fieldInsertYaml (fieldInfo, object, yaml)) + { + return; + } + else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid)) + { + yaml << safe_cast(fieldInfo->GetValue(object)); + } + else if (fieldInfo->FieldType == System::String::typeid) + { + System::String^ str = safe_cast(fieldInfo->GetValue(object)); + yaml << Convert::ToNative(str); + } + else if (fieldInfo->FieldType == Vector2::typeid) + { + Vector2 vec = safe_cast(fieldInfo->GetValue(object)); + yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << YAML::EndSeq; + } + else if (fieldInfo->FieldType == Vector3::typeid) + { + Vector3 vec = safe_cast(fieldInfo->GetValue(object)); + yaml << YAML::BeginSeq << YAML::Flow << vec.x << vec.y << vec.z << YAML::EndSeq; + } + else // Not any of the supported types + { + Debug::LogWarning(Convert::ToNative(System::String::Format + ( + "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialization.", + fieldInfo->Name, fieldInfo->FieldType) + )); + } + } - // } - // } - //} - //void ReflectionUtilities::Serialise(Object^ object, JsonWriter& writer) - //{ - // /* Script Name */ - // writer.String(Convert::ToNative(object->GetType()->FullName).c_str()); - - // /* Script Contents */ - // writer.StartObject(); - // IEnumerable^ fields = GetInstanceFields(object); - // for each (FieldInfo^ field in fields) - // { - // // Ignore private and non-SerialiseField - // if (!FieldIsSerialisable(field)) - // continue; - - // // Serialise - // serialiseFieldJson(field, object, writer); - // } - // writer.EndObject(); - //} - - ///*---------------------------------------------------------------------------------*/ - ///* Serialisation Helper Functions */ - ///*---------------------------------------------------------------------------------*/ - //rapidjson::Value ReflectionUtilities::FieldToRapidJsonValue(FieldInfo^ fieldInfo, Object^ object, JsonAllocator& allocator) - //{ - // rapidjson::Value jsonValue; - - // // Check each type of value and convert it into a rapidjson::Value - // if PRIMITIVE_FIELD_CAST(Int16) - // else if PRIMITIVE_FIELD_CAST(Int32) - // else if PRIMITIVE_FIELD_CAST(Int64) - // else if PRIMITIVE_FIELD_CAST(UInt16) - // else if PRIMITIVE_FIELD_CAST(UInt32) - // else if PRIMITIVE_FIELD_CAST(UInt64) - // else if PRIMITIVE_FIELD_CAST(Byte) - // else if PRIMITIVE_FIELD_CAST(bool) - // else if PRIMITIVE_FIELD_CAST(float) - // else if PRIMITIVE_FIELD_CAST(double) - // else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid)) - // { - // jsonValue = safe_cast(fieldInfo->GetValue(object)); - // } - // else if (fieldInfo->FieldType == String::typeid) - // { - // String^ str = safe_cast(fieldInfo->GetValue(object)); - // jsonValue.SetString(Convert::ToNative(str).c_str(), str->Length, allocator); - // } - // else if (fieldInfo->FieldType == Vector2::typeid) - // { - // jsonValue.SetObject(); - // Vector2 vec = safe_cast(fieldInfo->GetValue(object)); - // jsonValue.AddMember(rapidjson::Value("x"), rapidjson::Value(vec.x), allocator); - // jsonValue.AddMember(rapidjson::Value("y"), rapidjson::Value(vec.y), allocator); - // } - // else if (fieldInfo->FieldType == Vector3::typeid) - // { - // jsonValue.SetObject(); - // Vector3 vec = safe_cast(fieldInfo->GetValue(object)); - // jsonValue.AddMember(rapidjson::Value("x"), rapidjson::Value(vec.x), allocator); - // jsonValue.AddMember(rapidjson::Value("y"), rapidjson::Value(vec.y), allocator); - // jsonValue.AddMember(rapidjson::Value("z"), rapidjson::Value(vec.z), allocator); - // } - // else if (fieldInfo->FieldType == Color::typeid) - // { - // jsonValue.SetObject(); - // Color col = safe_cast(fieldInfo->GetValue(object)); - // jsonValue.AddMember(rapidjson::Value("r"), rapidjson::Value(col.r), allocator); - // jsonValue.AddMember(rapidjson::Value("g"), rapidjson::Value(col.g), allocator); - // jsonValue.AddMember(rapidjson::Value("b"), rapidjson::Value(col.b), allocator); - // jsonValue.AddMember(rapidjson::Value("a"), rapidjson::Value(col.a), allocator); - // } - // else if (IResourceID::typeid->IsAssignableFrom(fieldInfo->FieldType)) - // { - // IResourceID^ rscId = safe_cast(fieldInfo->GetValue(object)); - // jsonValue = rscId->Id; - // } - // else // Not any of the supported types - // { - // Pls::Debug::LogWarning(Convert::ToNative(String::Format - // ( - // "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialisation.", - // fieldInfo->Name, fieldInfo->FieldType) - // )); - // } - // return jsonValue; - //} - //void ReflectionUtilities::RapidJsonValueToField(const rapidjson::Value& jsonValue, FieldInfo^ fieldInfo, Object^ object) - //{ - // if PRIMITIVE_FIELD_ASSIGN(Int16, GetInt) - // else if PRIMITIVE_FIELD_ASSIGN(Int32, GetInt) - // else if PRIMITIVE_FIELD_ASSIGN(Int64, GetInt64) - // else if PRIMITIVE_FIELD_ASSIGN(UInt16, GetUint) - // else if PRIMITIVE_FIELD_ASSIGN(UInt32, GetUint) - // else if PRIMITIVE_FIELD_ASSIGN(UInt64, GetUint64) - // else if PRIMITIVE_FIELD_ASSIGN(Byte, GetInt) - // else if PRIMITIVE_FIELD_ASSIGN(bool, GetBool) - // else if PRIMITIVE_FIELD_ASSIGN(float, GetFloat) - // else if PRIMITIVE_FIELD_ASSIGN(double, GetDouble) - // else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid)) - // { - // fieldInfo->SetValue(object, jsonValue.GetInt()); - // } - // else if (fieldInfo->FieldType == String::typeid) - // { - // fieldInfo->SetValue(object, Convert::ToCLI(jsonValue.GetString())); - // } - // else if (fieldInfo->FieldType == Vector2::typeid) - // { - // Vector2 vec; - // auto iter = jsonValue.MemberEnd(); - // PRIMITIVE_VECTOR_FIELD_ASSIGN(x) - // PRIMITIVE_VECTOR_FIELD_ASSIGN(y) - // fieldInfo->SetValue(object, vec); - // } - // else if (fieldInfo->FieldType == Vector3::typeid) - // { - // Vector3 vec; - // auto iter = jsonValue.MemberEnd(); - // PRIMITIVE_VECTOR_FIELD_ASSIGN(x) - // PRIMITIVE_VECTOR_FIELD_ASSIGN(y) - // PRIMITIVE_VECTOR_FIELD_ASSIGN(z) - // fieldInfo->SetValue(object, vec); - // } - // else if (fieldInfo->FieldType == Color::typeid) - // { - // Color col; - // auto iter = jsonValue.MemberEnd(); - // PRIMITIVE_COLOR_FIELD_ASSIGN(r) - // PRIMITIVE_COLOR_FIELD_ASSIGN(g) - // PRIMITIVE_COLOR_FIELD_ASSIGN(b) - // PRIMITIVE_COLOR_FIELD_ASSIGN(a) - // fieldInfo->SetValue(object, col); - // } - // else if (IResourceIDInternal::typeid->IsAssignableFrom(fieldInfo->FieldType)) - // { - // IResourceIDInternal^ rsc = safe_cast(Activator::CreateInstance(fieldInfo->FieldType)); - // rsc->Id = jsonValue.GetInt64(); - // fieldInfo->SetValue(object, rsc); - // } - // else // Not any of the supported types - // { - // Pls::Debug::LogWarning(Convert::ToNative(String::Format - // ( - // "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for deserialisation.", - // fieldInfo->Name, fieldInfo->FieldType) - // )); - // } - //} - - ///*---------------------------------------------------------------------------------*/ - ///* Internal Serialisation Helper Functions */ - ///*---------------------------------------------------------------------------------*/ - //void ReflectionUtilities::serialiseFieldJson(FieldInfo^ fieldInfo, Object^ object, JsonWriter& writer) - //{ - // if PRIMITIVE_FIELD_SERIALISE_JSON(Int16, Int) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(Int32, Int) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(Int64, Int64) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(UInt16, Uint) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(UInt32, Uint) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(UInt64, Uint64) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(Byte, Int) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(bool, Bool) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(float, Double) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(double, Double) - // else if PRIMITIVE_FIELD_SERIALISE_JSON(double, Double) - // else if (fieldInfo->FieldType->IsSubclassOf(Enum::typeid)) - // { - // PRIMITIVE_WRITE_FIELD_NAME - // writer.Int(safe_cast(fieldInfo->GetValue(object))); - - // } - // else if (fieldInfo->FieldType == String::typeid) - // { - // PRIMITIVE_WRITE_FIELD_NAME - // writer.String(Convert::ToNative(safe_cast(fieldInfo->GetValue(object))).c_str()); - - // } - // else if (fieldInfo->FieldType == Vector2::typeid) - // { - // // Get handle to the Vector to edit - // Vector2 vec = safe_cast(fieldInfo->GetValue(object)); - - // // Write the vector data - // PRIMITIVE_WRITE_FIELD_NAME - // writer.StartObject(); - // { - // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(x) - // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(y) - // } - // writer.EndObject(); - // } - // else if (fieldInfo->FieldType == Vector3::typeid) - // { - // // Get handle to the Vector to edit - // Vector3 vec = safe_cast(fieldInfo->GetValue(object)); - - // // Write the vector data - // PRIMITIVE_WRITE_FIELD_NAME - // writer.StartObject(); - // { - // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(x) - // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(y) - // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(z) - // } - // writer.EndObject(); - // } - // else if (fieldInfo->FieldType == Color::typeid) - // { - // // Get handle to the Vector to edit - // Color vec = safe_cast(fieldInfo->GetValue(object)); - - // // Write the vector data - // PRIMITIVE_WRITE_FIELD_NAME - // writer.StartObject(); - // { - // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(r) - // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(g) - // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(b) - // PRIMITIVE_VECTOR_FIELD_SERIALISE_JSON(a) - // } - // writer.EndObject(); - // } - // else if (IResourceID::typeid->IsAssignableFrom(fieldInfo->FieldType)) - // { - // PRIMITIVE_WRITE_FIELD_NAME - // IResourceID^ rsc = safe_cast(fieldInfo->GetValue(object)); - // writer.Int64(rsc->Id); - // } - // else // Not any of the supported types - // { - // Pls::Debug::LogWarning(Convert::ToNative(String::Format - // ( - // "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for serialisation.", - // fieldInfo->Name, fieldInfo->FieldType) - // )); - // } - //} + void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) + { + if (fieldInfo->FieldType == System::Int16::typeid) + { + fieldInfo->SetValue(object, node.as()); + } + if (fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml(fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node) || + fieldAssignYaml (fieldInfo, object, node)) + { + return; + } + else if (fieldInfo->FieldType->IsSubclassOf(System::Enum::typeid)) + { + fieldInfo->SetValue(object, node.as()); + } + else if (fieldInfo->FieldType == System::String::typeid) + { + fieldInfo->SetValue(object, Convert::ToCLI(node.as())); + } + else if (fieldInfo->FieldType == Vector2::typeid) + { + if (node.IsSequence() && node.size() == 2) + { + Vector2 vec; + vec.x = node[0].as(); + vec.y = node[1].as(); + fieldInfo->SetValue(object, vec); + } + else + { + Debug::LogWarning + ( + System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of a Vector2 \"{0}\" field in \"{1}\" script.", + fieldInfo->Name, object->GetType()->FullName) + ); + } + } + else if (fieldInfo->FieldType == Vector3::typeid) + { + if (node.IsSequence() && node.size() == 3) + { + Vector3 vec; + vec.x = node[0].as(); + vec.y = node[1].as(); + vec.z = node[2].as(); + fieldInfo->SetValue(object, vec); + } + else + { + Debug::LogWarning + ( + System::String::Format("[ReflectionUtilities] Invalid YAML Node provided for deserialization of a Vector3 \"{0}\" field in \"{1}\" script.", + fieldInfo->Name, object->GetType()->FullName) + ); + } + } + else // Not any of the supported types + { + Debug::LogWarning(Convert::ToNative(System::String::Format + ( + "[ReflectionUtilities] Failed to parse \"{0}\" of \"{1}\" type for deserialisation.", + fieldInfo->Name, fieldInfo->FieldType) + )); + } + } } diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ new file mode 100644 index 00000000..88469b34 --- /dev/null +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.h++ @@ -0,0 +1,54 @@ +/************************************************************************************//*! +\file ReflectionUtilities.h++ +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 16, 2022 +\brief Contains the definition of the template functions of the managed + ReflectionUtilities 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 + +// Primary Header +#include "ReflectionUtilities.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Serialization Helper Functions */ + /*---------------------------------------------------------------------------------*/ + template + bool ReflectionUtilities::fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter) + { + if (fieldInfo->FieldType == FieldType::typeid) + { + emitter << safe_cast(fieldInfo->GetValue(object)); + return true; + } + + return false; + } + + template + bool ReflectionUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) + { + return fieldAssignYaml(fieldInfo, object, node); + } + + template + bool ReflectionUtilities::fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) + { + if (fieldInfo->FieldType == FieldType::typeid) + { + fieldInfo->SetValue(object, node.as()); + return true; + } + + return false; + } +} diff --git a/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx index f312ec05..53f8fa1d 100644 --- a/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx +++ b/SHADE_Managed/src/Serialisation/ReflectionUtilities.hxx @@ -14,9 +14,7 @@ of DigiPen Institute of Technology is prohibited. #pragma once // External Dependencies -#include -#include - +#include namespace SHADE { @@ -26,10 +24,6 @@ namespace SHADE private ref class ReflectionUtilities abstract sealed { public: - /*-----------------------------------------------------------------------------*/ - /* Type Definitions */ - /*-----------------------------------------------------------------------------*/ - /*-----------------------------------------------------------------------------*/ /* Utility Functions */ /*-----------------------------------------------------------------------------*/ @@ -58,16 +52,30 @@ namespace SHADE /// attribute will be serialised. /// /// The object to serialise. - //static void Serialise(Object^ object, YAML::Emitter& yaml); + static void Serialise(System::Object^ object, YAML::Emitter& yaml); /// - /// Deserialises a JSON string and copies the deserialised data into the - /// specified object if there are matching fields. + /// Deserialises a YAML node that contains a map of Scripts and copies the + /// deserialised data into the specified object if there are matching fields. /// - /// + /// /// The JSON string that contains the data to copy into this PlushieScript /// object. /// /// The object to copy deserialised data into. - //static void Deserialise(System::String^ jsonString, Object^ object); + static void Deserialise(YAML::Node& yamlNode, Object^ object); + + /*-----------------------------------------------------------------------------*/ + /* Serialization Helper Functions */ + /*-----------------------------------------------------------------------------*/ + static void writeFieldIntoYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Emitter& yaml); + template + static bool fieldInsertYaml(System::Reflection::FieldInfo^ fieldInfo, System::Object^ object, YAML::Emitter& emitter); + static void writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); + template + static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); + template + static bool fieldAssignYaml(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node); }; -} \ No newline at end of file +} + +#include "ReflectionUtilities.h++" \ No newline at end of file From 0f63ee10d07ce2d06816d070b5b19dbf3952c897 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 16 Sep 2022 16:37:50 +0800 Subject: [PATCH 04/37] Converted SHScriptEngine into a SHSystem --- .../src/Application/SBApplication.cpp | 6 +- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 29 ++------ SHADE_Engine/src/Scripting/SHScriptEngine.h | 73 ++++++++++--------- 3 files changed, 43 insertions(+), 65 deletions(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index f4c76db7..a89ea833 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -37,7 +37,7 @@ namespace Sandbox SHADE::SHSystemManager::CreateSystem(); SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); SHADE::SHSystemManager::RegisterRoutine(1); - + SHADE::SHSystemManager::CreateSystem(); graphicsSystem->SetWindow(&window); SDL_CreateWindowFrom(window.GetHWND()); @@ -47,9 +47,6 @@ namespace Sandbox //SHADE::SHEditor::Initialize(window.GetHWND()); #else #endif - - // Set up scripting - SHADE::SHScriptEngine::Init(); } void SBApplication::Update(void) @@ -76,7 +73,6 @@ namespace Sandbox void SBApplication::Exit(void) { - SHADE::SHScriptEngine::Exit(); SHADE::SHSystemManager::Exit(); SDL_DestroyWindow(sdlWindow); #ifdef SHEDITOR diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index b5a33c6d..c5490b1e 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -26,25 +26,6 @@ namespace SHADE /* Static Definitions */ /*--------------------------------------------------------------------------------*/ const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE"); - SHDotNetRuntime SHScriptEngine::dotNet { false }; - SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineInit = nullptr; - SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineLoadScripts = nullptr; - SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineUnloadScripts = nullptr; - SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineReloadScripts = nullptr; - SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineExit = nullptr; - SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameSetUp = nullptr; - SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteFixedUpdate = nullptr; - SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteUpdate = nullptr; - SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteLateUpdate = nullptr; - SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameCleanUp = nullptr; - SHScriptEngine::CsScriptManipFuncPtr SHScriptEngine::csScriptsAdd = nullptr; - SHScriptEngine::CsScriptBasicFuncPtr SHScriptEngine::csScriptsRemoveAll = nullptr; - SHScriptEngine::CsScriptOptionalFuncPtr SHScriptEngine::csScriptsRemoveAllImmediately = nullptr; - SHScriptEngine::CsScriptSerialiseFuncPtr SHScriptEngine::csScriptsSerialise = nullptr; - SHScriptEngine::CsScriptDeserialiseFuncPtr SHScriptEngine::csScriptDeserialise = nullptr; - SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptsSerialiseYaml = nullptr; - SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptDeserialiseYaml = nullptr; - SHScriptEngine::CsScriptEditorFuncPtr SHScriptEngine::csEditorRenderScripts = nullptr; /*---------------------------------------------------------------------------------*/ /* Lifecycle Functions */ @@ -137,7 +118,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Script Serialisation Functions */ /*---------------------------------------------------------------------------------*/ - std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity) + std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity) const { // Create buffer needed to store serialised script data constexpr int BUFFER_SIZE = 10240; @@ -162,7 +143,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Script Serialisation Functions */ /*---------------------------------------------------------------------------------*/ - void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml) + void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml) const { csScriptDeserialise(entity.GetEID(), yaml.c_str()); } @@ -170,7 +151,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Script Editor Functions */ /*---------------------------------------------------------------------------------*/ - void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity) + void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity) const { csEditorRenderScripts(entity.GetEID()); } @@ -178,7 +159,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Static Utility Functions */ /*---------------------------------------------------------------------------------*/ - bool SHScriptEngine::BuildScriptAssembly(bool debug) + bool SHScriptEngine::BuildScriptAssembly(bool debug) const { constexpr std::string_view BUILD_LOG_PATH = "../Build.log"; @@ -230,7 +211,7 @@ namespace SHADE return BUILD_SUCCESS; } - void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path) + void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path) const { // Sample static std::string_view FILE_CONTENTS = diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 442c0053..4988f594 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -18,6 +18,7 @@ of DigiPen Institute of Technology is prohibited. #include "SHDotNetRuntime.h" #include "ECS_Base/SHECSMacros.h" #include "ECS_Base/Entity/SHEntity.h" +#include "ECS_Base/System/SHSystem.h" #include "SH_API.h" namespace SHADE @@ -26,13 +27,13 @@ namespace SHADE /// Manages initialisation of the DotNetRuntime and interfacing with CLR code written /// and executed on .NET. /// - class SH_API SHScriptEngine + class SH_API SHScriptEngine : public SHSystem { public: /*-----------------------------------------------------------------------------*/ /* Constructor */ /*-----------------------------------------------------------------------------*/ - SHScriptEngine() = delete; + SHScriptEngine() = default; /*-----------------------------------------------------------------------------*/ /* Lifecycle Functions */ @@ -41,33 +42,33 @@ namespace SHADE /// Initialises the DotNetRuntime and retrieves function pointers to all /// functions on the CLR used to interface with the engine. /// - static void Init(); + void Init() override; /// /// Loads the managed script assembly. Ensure this is only called after /// UnloadScriptAssembly() has been called. /// - static void UnloadScriptAssembly(); + void UnloadScriptAssembly(); /// /// Unloads the managed script assembly. /// Take note that this will clear all existing scripts, ensure that the scene /// is saved before doing so. /// - static void LoadScriptAssembly(); + void LoadScriptAssembly(); /// /// Reloads the managed script assembly. /// Take note that this will clear all existing scripts, ensure that the scene /// is saved before doing so. /// - static void ReloadScriptAssembly(); + void ReloadScriptAssembly(); /// /// Executes the FixedUpdate()s of the Scripts that are attached to /// Entities. /// - static void ExecuteFixedUpdates(); + void ExecuteFixedUpdates(); /// /// Shuts down the DotNetRuntime. /// - static void Exit(); + void Exit() override; /*-----------------------------------------------------------------------------*/ /* Script Manipulation Functions */ @@ -84,14 +85,14 @@ namespace SHADE /// True if successfully added. False otherwise with the error logged to the /// console. /// - static bool AddScript(const SHEntity& entity, const std::string_view& scriptName); + bool AddScript(const SHEntity& entity, const std::string_view& scriptName); /// /// Removes all Scripts attached to the specified Entity. Does not do anything /// if the specified Entity is invalid or does not have any Scripts /// attached. /// /// The entity to remove the scripts from. - static void RemoveAllScripts(const SHEntity& entity); + void RemoveAllScripts(const SHEntity& entity); /// /// Removes all Scripts attached to the specified Entity. Unlike /// RemoveAllScripts(), this removes all the scripts immediately. @@ -103,7 +104,7 @@ namespace SHADE /// Whether or not to call OnDestroy on the scripts. This is ignored if not in /// play mode. /// - static void RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy); + void RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy); /*-----------------------------------------------------------------------------*/ /* Script Serialisation Functions */ @@ -116,7 +117,7 @@ namespace SHADE /// /// String that represents the set of scripts attached to the specified Entity. /// - static std::string SerialiseScripts(const SHEntity& entity); + std::string SerialiseScripts(const SHEntity& entity) const; /// /// Loads the specified JSON string and creates a Script for the specified Entity /// based on the specified JSON string. @@ -125,7 +126,7 @@ namespace SHADE /// /// The YAML string that represents the Script to load into the Entity. /// - static void DeserialiseScript(const SHEntity& entity, const std::string& yaml); + void DeserialiseScript(const SHEntity& entity, const std::string& yaml) const; /*-----------------------------------------------------------------------------*/ /* Script Editor Functions */ @@ -138,7 +139,7 @@ namespace SHADE /// rendering code. /// /// The Entity to render the Scripts of. - static void RenderScriptsInInspector(const SHEntity& entity); + void RenderScriptsInInspector(const SHEntity& entity) const; /*-----------------------------------------------------------------------------*/ /* Static Utility Functions */ @@ -153,12 +154,12 @@ namespace SHADE /// can be debugged. /// /// Whether or not the build succeeded. - static bool BuildScriptAssembly(bool debug = false); + bool BuildScriptAssembly(bool debug = false) const; /// /// Generates a .csproj file for editing and compiling the C# scripts. /// /// File path to the generated file. - static void GenerateScriptsCsProjFile(const std::filesystem::path& path); + void GenerateScriptsCsProjFile(const std::filesystem::path& path) const; private: /*-----------------------------------------------------------------------------*/ @@ -183,29 +184,29 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ - static SHDotNetRuntime dotNet; + SHDotNetRuntime dotNet { false }; // Function Pointers to CLR Code // - Engine Lifecycle - static CsFuncPtr csEngineInit; - static CsFuncPtr csEngineLoadScripts; - static CsFuncPtr csEngineUnloadScripts; - static CsFuncPtr csEngineReloadScripts; - static CsFuncPtr csEngineExit; + CsFuncPtr csEngineInit = nullptr; + CsFuncPtr csEngineLoadScripts = nullptr; + CsFuncPtr csEngineUnloadScripts = nullptr; + CsFuncPtr csEngineReloadScripts = nullptr; + CsFuncPtr csEngineExit = nullptr; // - Scripts Store - static CsFuncPtr csScriptsFrameSetUp; - static CsFuncPtr csScriptsExecuteFixedUpdate; - static CsFuncPtr csScriptsExecuteUpdate; - static CsFuncPtr csScriptsExecuteLateUpdate; - static CsFuncPtr csScriptsFrameCleanUp; - static CsScriptManipFuncPtr csScriptsAdd; - static CsScriptBasicFuncPtr csScriptsRemoveAll; - static CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately; - static CsScriptSerialiseFuncPtr csScriptsSerialise; - static CsScriptDeserialiseFuncPtr csScriptDeserialise; - static CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml; - static CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml; + CsFuncPtr csScriptsFrameSetUp = nullptr; + CsFuncPtr csScriptsExecuteFixedUpdate = nullptr; + CsFuncPtr csScriptsExecuteUpdate = nullptr; + CsFuncPtr csScriptsExecuteLateUpdate = nullptr; + CsFuncPtr csScriptsFrameCleanUp = nullptr; + CsScriptManipFuncPtr csScriptsAdd = nullptr; + CsScriptBasicFuncPtr csScriptsRemoveAll = nullptr; + CsScriptOptionalFuncPtr csScriptsRemoveAllImmediately = nullptr; + CsScriptSerialiseFuncPtr csScriptsSerialise = nullptr; + CsScriptDeserialiseFuncPtr csScriptDeserialise = nullptr; + CsScriptSerialiseYamlFuncPtr csScriptsSerialiseYaml = nullptr; + CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml = nullptr; // - Editor - static CsScriptEditorFuncPtr csEditorRenderScripts; + CsScriptEditorFuncPtr csEditorRenderScripts = nullptr; // Delegates /*ECS::EntityEvent::Delegate onEntityCreate; ECS::EntityEvent::Delegate onEntityDestroy;*/ @@ -216,7 +217,7 @@ namespace SHADE /// /// Loads all the function pointers to CLR code that we need to execute. /// - static void loadFunctions(); + void loadFunctions(); /// /// Reads the file via the specified path that represents a build log of error /// and warning messages. From c83a5a379e2a16d054ee7c9877478355476ab512 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 16 Sep 2022 17:02:36 +0800 Subject: [PATCH 05/37] Added Awake, Start, Update, LateUpdate, OnDestroy calls via SystemRoutines --- .../src/Application/SBApplication.cpp | 12 +++- SHADE_Engine/src/ECS_Base/System/SHSystem.h | 3 +- .../src/ECS_Base/System/SHSystemRoutine.h | 3 +- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 1 - SHADE_Engine/src/Scripting/SHScriptEngine.h | 31 ++++++++- .../src/Scripting/SHScriptEngineRoutines.cpp | 63 +++++++++++++++++++ 6 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index a89ea833..8f17863f 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -34,11 +34,19 @@ namespace Sandbox SDL_Init(SDL_INIT_VIDEO); window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow); + + // Create Systems SHADE::SHSystemManager::CreateSystem(); - SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); - SHADE::SHSystemManager::RegisterRoutine(1); SHADE::SHSystemManager::CreateSystem(); + // Create Routines + SHADE::SHSystemManager::RegisterRoutine(); + SHADE::SHSystemManager::RegisterRoutine(); + SHADE::SHSystemManager::RegisterRoutine(); + SHADE::SHSystemManager::RegisterRoutine(1); + SHADE::SHSystemManager::RegisterRoutine(); + + SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); graphicsSystem->SetWindow(&window); SDL_CreateWindowFrom(window.GetHWND()); diff --git a/SHADE_Engine/src/ECS_Base/System/SHSystem.h b/SHADE_Engine/src/ECS_Base/System/SHSystem.h index 19b16f72..93ea6a59 100644 --- a/SHADE_Engine/src/ECS_Base/System/SHSystem.h +++ b/SHADE_Engine/src/ECS_Base/System/SHSystem.h @@ -11,13 +11,14 @@ #pragma once #include "../SHECSMacros.h" +#include "SH_API.h" namespace SHADE { class SHSystemManager; - class SHSystem + class SH_API SHSystem { private: SystemID systemID; diff --git a/SHADE_Engine/src/ECS_Base/System/SHSystemRoutine.h b/SHADE_Engine/src/ECS_Base/System/SHSystemRoutine.h index cdb62438..2b6d8dc1 100644 --- a/SHADE_Engine/src/ECS_Base/System/SHSystemRoutine.h +++ b/SHADE_Engine/src/ECS_Base/System/SHSystemRoutine.h @@ -7,6 +7,7 @@ #include "SHRoutineStats.h" #include "SHSystem.h" #include +#include "SH_API.h" namespace SHADE @@ -15,7 +16,7 @@ namespace SHADE class SHSystemManager; - class SHSystemRoutine + class SH_API SHSystemRoutine { friend class SHSystemManager; protected: diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index c5490b1e..78b4d544 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -483,5 +483,4 @@ namespace SHADE } } } - } diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 4988f594..f3d69dd5 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -19,6 +19,7 @@ of DigiPen Institute of Technology is prohibited. #include "ECS_Base/SHECSMacros.h" #include "ECS_Base/Entity/SHEntity.h" #include "ECS_Base/System/SHSystem.h" +#include "ECS_Base/System/SHSystemRoutine.h" #include "SH_API.h" namespace SHADE @@ -27,9 +28,37 @@ namespace SHADE /// Manages initialisation of the DotNetRuntime and interfacing with CLR code written /// and executed on .NET. /// - class SH_API SHScriptEngine : public SHSystem + class SH_API SHScriptEngine final : public SHSystem { public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + class SH_API FrameSetUpRoutine final : public SHSystemRoutine + { + public: + FrameSetUpRoutine(); + void Execute(double dt) noexcept override final; + }; + class SH_API UpdateRoutine final : public SHSystemRoutine + { + public: + UpdateRoutine(); + void Execute(double dt) noexcept override final; + }; + class SH_API LateUpdateRoutine final : public SHSystemRoutine + { + public: + LateUpdateRoutine(); + void Execute(double dt) noexcept override final; + }; + class SH_API FrameCleanUpRoutine final : public SHSystemRoutine + { + public: + FrameCleanUpRoutine(); + void Execute(double dt) noexcept override final; + }; + /*-----------------------------------------------------------------------------*/ /* Constructor */ /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp b/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp new file mode 100644 index 00000000..5467fc56 --- /dev/null +++ b/SHADE_Engine/src/Scripting/SHScriptEngineRoutines.cpp @@ -0,0 +1,63 @@ +/************************************************************************************//*! +\file SHScriptEngineRoutines.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 17, 2021 +\brief Contains the implementation or functions of SystemRoutines in the + SHScriptEngine class. + +Copyright (C) 2021 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 +// Primary Header +#include "SHScriptEngine.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* System Routine Functions - FrameSetUpRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHScriptEngine::FrameSetUpRoutine::FrameSetUpRoutine() + : SHSystemRoutine("Script Engine Frame Set Up", false) + {} + void SHScriptEngine::FrameSetUpRoutine::Execute(double) noexcept + { + reinterpret_cast(system)->csScriptsFrameSetUp(); + } + + /*-----------------------------------------------------------------------------------*/ + /* System Routine Functions - UpdateRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHScriptEngine::UpdateRoutine::UpdateRoutine() + : SHSystemRoutine("Script Engine Update", false) + {} + void SHScriptEngine::UpdateRoutine::Execute(double) noexcept + { + reinterpret_cast(system)->csScriptsExecuteUpdate(); + } + + /*-----------------------------------------------------------------------------------*/ + /* System Routine Functions - LateUpdateRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHScriptEngine::LateUpdateRoutine::LateUpdateRoutine() + : SHSystemRoutine("Script Engine Late Update", false) + {} + void SHScriptEngine::LateUpdateRoutine::Execute(double) noexcept + { + reinterpret_cast(system)->csScriptsExecuteLateUpdate(); + } + + /*-----------------------------------------------------------------------------------*/ + /* System Routine Functions - FrameCleanUpRoutine */ + /*-----------------------------------------------------------------------------------*/ + SHScriptEngine::FrameCleanUpRoutine::FrameCleanUpRoutine() + : SHSystemRoutine("Script Engine Frame Clean Up", false) + {} + void SHScriptEngine::FrameCleanUpRoutine::Execute(double) noexcept + { + reinterpret_cast(system)->csScriptsFrameCleanUp(); + } +} From 5171ddd2bf2a2d6fcaddfb9c7ef848e246393f25 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 17 Sep 2022 03:20:24 +0800 Subject: [PATCH 06/37] Added SHLog class and changed Debug::Log to use SHLog --- SHADE_Engine/src/Tools/SHLog.cpp | 54 +++++++++++++++++++++++++++++ SHADE_Engine/src/Tools/SHLog.h | 48 +++++++++++++++++++++++++ SHADE_Managed/src/Utility/Debug.cxx | 30 ++++++++-------- 3 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 SHADE_Engine/src/Tools/SHLog.cpp create mode 100644 SHADE_Engine/src/Tools/SHLog.h diff --git a/SHADE_Engine/src/Tools/SHLog.cpp b/SHADE_Engine/src/Tools/SHLog.cpp new file mode 100644 index 00000000..2d0b7b58 --- /dev/null +++ b/SHADE_Engine/src/Tools/SHLog.cpp @@ -0,0 +1,54 @@ +/************************************************************************************//*! +\file SHLog.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 17, 2022 +\brief Contains the definition of functions of the SHLog static class. + +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 Header +#include "SHpch.h" +// Primary Header +#include "SHLog.h" +// Project Includes +#include "SHLogger.h" + +namespace SHADE +{ + void SHLog::Info(const std::string& msg) noexcept + { + SHLOG_INFO(msg) + } + + void SHLog::Warning(const std::string& msg) noexcept + { + SHLOG_WARNING(msg) + } + + + void SHLog::Error(const std::string& msg) noexcept + { + SHLOG_ERROR(msg) + } + + void SHLog::Critical(const std::string& msg) noexcept + { + SHLOG_CRITICAL(msg) + } + + void SHLog::Floor() noexcept + { + SHLOG_FLOOR() + } + +#ifdef _DEBUG + void SHLog::Trace(const std::string& msg) noexcept + { + SHLOG_TRACE(msg) + } +#endif + +} diff --git a/SHADE_Engine/src/Tools/SHLog.h b/SHADE_Engine/src/Tools/SHLog.h new file mode 100644 index 00000000..b77042db --- /dev/null +++ b/SHADE_Engine/src/Tools/SHLog.h @@ -0,0 +1,48 @@ +/************************************************************************************//*! +\file SHLog.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 17, 2022 +\brief Contains the SHLog static class. + +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. +*//*************************************************************************************/ + +// Standard Library +#include +// Project Headers +#include "SH_API.h" + +namespace SHADE +{ + /*!************************************************************************************ + + \class SHLog + + \brief + Static class that contains wrapper functions for SHLogger's macros. + + **************************************************************************************/ + class SH_API SHLog + { + public: + /*---------------------------------------------------------------------------------*/ + /* Constructor */ + /*---------------------------------------------------------------------------------*/ + SHLog() = delete; + + /*---------------------------------------------------------------------------------*/ + /* Logging Functions */ + /*---------------------------------------------------------------------------------*/ + static void Info(const std::string& msg) noexcept; + static void Warning(const std::string& msg) noexcept; + static void Error(const std::string& msg) noexcept; + static void Critical(const std::string& msg) noexcept; + static void Floor() noexcept; +#ifdef _DEBUG + static void Trace(const std::string& msg) noexcept; +#endif + }; +} diff --git a/SHADE_Managed/src/Utility/Debug.cxx b/SHADE_Managed/src/Utility/Debug.cxx index 330375b0..8a107ab3 100644 --- a/SHADE_Managed/src/Utility/Debug.cxx +++ b/SHADE_Managed/src/Utility/Debug.cxx @@ -18,6 +18,8 @@ of DigiPen Institute of Technology is prohibited. #include "Debug.hxx" // Standard Libraries #include +// External Libraries +#include "Tools/SHLog.h" // Project Headers #include "Convert.hxx" @@ -28,11 +30,11 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void Debug::Log(const std::string& str) { - std::cout << str << std::endl; + SHLog::Info(str); } void Debug::Log(System::String^ str) - { - System::Console::WriteLine(str); + { + SHLog::Info(Convert::ToNative(str)); } void Debug::Log(System::String^ str, Object^ owner) @@ -47,15 +49,15 @@ namespace SHADE { std::ostringstream oss; oss << "[" << throwerName << "] " << Convert::ToNative(str); - std::cout << oss.str() << std::endl; + Log(oss.str()); } void Debug::LogWarning(const std::string& str) { - std::cout << str << std::endl; + SHLog::Warning(str); } void Debug::LogWarning(System::String^ str) - { - System::Console::WriteLine(str); + { + SHLog::Warning(Convert::ToNative(str)); } void Debug::LogWarning(System::String^ str, Object^ thrower) { @@ -69,16 +71,16 @@ namespace SHADE void Debug::LogWarning(System::String^ str, const std::string& throwerName) { std::ostringstream oss; - oss << "[" << throwerName << "] " << Convert::ToNative(str); - std::cout << oss.str() << std::endl; + oss << "[" << throwerName << "] " << Convert::ToNative(str); + LogWarning(oss.str()); } void Debug::LogError(const std::string& str) { - std::cout << str << std::endl; + SHLog::Error(str); } void Debug::LogError(System::String^ str) { - System::Console::WriteLine(str); + SHLog::Error(Convert::ToNative(str)); } void Debug::LogError(System::String^ str, Object^ thrower) { @@ -88,7 +90,7 @@ namespace SHADE { std::ostringstream oss; oss << "[" << throwerName << "] -> " << Convert::ToNative(str); - std::cout << oss.str() << std::endl; + LogError(oss.str()); } void Debug::LogError(System::String^ str, System::String^ throwerName) { @@ -111,12 +113,12 @@ namespace SHADE { std::ostringstream oss; oss << "[" << throwerName << "] Unhandled exception: " << Convert::ToNative(exception->ToString()); - std::cout << oss.str() << std::endl; + LogError(oss.str()); } void Debug::LogExceptionNative(const std::exception& exception, const std::string& throwerName) { std::ostringstream oss; oss << "[" << throwerName << "] Unhandled exception: " << exception.what(); - std::cout << oss.str() << std::endl; + LogError(oss.str()); } } From 8772ce0ceac8421bd591850c900c68ae74db611d Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 20 Sep 2022 00:03:29 +0800 Subject: [PATCH 07/37] Fixed SHSceneManager not SH_API-ed --- SHADE_Engine/src/Scene/SHSceneManager.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Scene/SHSceneManager.h b/SHADE_Engine/src/Scene/SHSceneManager.h index bdd8f596..9682e4c2 100644 --- a/SHADE_Engine/src/Scene/SHSceneManager.h +++ b/SHADE_Engine/src/Scene/SHSceneManager.h @@ -16,11 +16,12 @@ #include "ECS_Base/General/SHFamily.h" #include "SHScene.h" #include +#include "SH_API.h" namespace SHADE { - class SHSceneManager + class SH_API SHSceneManager { private: //boolean to check if the scene has been changed From 9896c5c913e237188c7c417a5b272aa85b43547a Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 20 Sep 2022 16:23:03 +0800 Subject: [PATCH 08/37] Added CallbackAction and CallbackEvent --- SHADE_Managed/src/Events/CallbackAction.cxx | 48 ++++++++++++ SHADE_Managed/src/Events/CallbackAction.hxx | 57 ++++++++++++++ SHADE_Managed/src/Events/CallbackEvent.cxx | 71 +++++++++++++++++ SHADE_Managed/src/Events/CallbackEvent.hxx | 85 +++++++++++++++++++++ SHADE_Managed/src/Math/Vector2.hxx | 2 +- 5 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 SHADE_Managed/src/Events/CallbackAction.cxx create mode 100644 SHADE_Managed/src/Events/CallbackAction.hxx create mode 100644 SHADE_Managed/src/Events/CallbackEvent.cxx create mode 100644 SHADE_Managed/src/Events/CallbackEvent.hxx diff --git a/SHADE_Managed/src/Events/CallbackAction.cxx b/SHADE_Managed/src/Events/CallbackAction.cxx new file mode 100644 index 00000000..0ad356c1 --- /dev/null +++ b/SHADE_Managed/src/Events/CallbackAction.cxx @@ -0,0 +1,48 @@ +/************************************************************************************//*! +\file CallbackAction.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 20, 2022 +\brief Contains the definition of the functions for the CallbackAction managed + 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 +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "CallbackAction.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + generic + CallbackAction::CallbackAction(System::Reflection::MethodInfo^ method) + : CallbackAction(method, nullptr) + {} + generic + CallbackAction::CallbackAction(System::Reflection::MethodInfo^ method, System::Object^ obj) + : method { method } + , object { obj } + { + paramArray = gcnew cli::array(1); + } + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + generic + void CallbackAction::Invoke(T1 param1) + { + // Set parameters + paramArray[0] = safe_cast(param1); + // Invoke + method->Invoke(object, paramArray); + } +} diff --git a/SHADE_Managed/src/Events/CallbackAction.hxx b/SHADE_Managed/src/Events/CallbackAction.hxx new file mode 100644 index 00000000..f8b50266 --- /dev/null +++ b/SHADE_Managed/src/Events/CallbackAction.hxx @@ -0,0 +1,57 @@ +/************************************************************************************//*! +\file CallbackAction.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 20, 2021 +\brief Contains the definition of the managed CallbackAction 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 + +namespace SHADE +{ + /// + /// Holds a function and their associated object for invoking later. + /// + /// Type of the first parameter. + generic + public ref class CallbackAction + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructs a CallbackAction with the specified static method. + /// + /// MethodInfo representing the method to call. + /// Object to call the method on. Set null if static. + CallbackAction(System::Reflection::MethodInfo^ method); + /// + /// Constructs a CallbackAction with the specified instance method and object + /// which will invoke the method. + /// + /// MethodInfo representing the method to call. + /// Object to call the method on. + CallbackAction(System::Reflection::MethodInfo^ method, System::Object^ obj); + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Invokes this action with the specified parameters. + /// + /// + void Invoke(T1 param1); + + private: + System::Reflection::MethodInfo^ method; + cli::array^ paramArray; + System::Object^ object; + }; +} \ No newline at end of file diff --git a/SHADE_Managed/src/Events/CallbackEvent.cxx b/SHADE_Managed/src/Events/CallbackEvent.cxx new file mode 100644 index 00000000..9ba82ef2 --- /dev/null +++ b/SHADE_Managed/src/Events/CallbackEvent.cxx @@ -0,0 +1,71 @@ +/************************************************************************************//*! +\file CallbackEvent.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 20, 2022 +\brief Contains the definition of the functions for the CallbackEvent managed + 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 +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include "SHpch.h" +// Primary Header +#include "CallbackEvent.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + generic + CallbackEvent::CallbackEvent() + { + actions = gcnew System::Collections::Generic::List ^>(); + } + + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + generic + System::Collections::Generic::IEnumerable^>^ CallbackEvent::Actions::get() + { + return actions; + } + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + generic + void CallbackEvent::AddAction(CallbackAction^ action) + { + actions->Add(action); + } + generic + void CallbackEvent::AddAction(System::Reflection::MethodInfo^ method) + { + actions->Add(gcnew CallbackAction(method)); + } + generic + void CallbackEvent::AddAction(System::Reflection::MethodInfo^ method, System::Object^ object) + { + actions->Add(gcnew CallbackAction(method, object)); + } + generic + void CallbackEvent::RemoveAction(CallbackAction^ action) + { + actions->Remove(action); + } + generic + void CallbackEvent::Invoke(T1 param1) + { + for each (CallbackAction^ action in actions) + { + action->Invoke(param1); + } + } +} diff --git a/SHADE_Managed/src/Events/CallbackEvent.hxx b/SHADE_Managed/src/Events/CallbackEvent.hxx new file mode 100644 index 00000000..d0d6d2f1 --- /dev/null +++ b/SHADE_Managed/src/Events/CallbackEvent.hxx @@ -0,0 +1,85 @@ +/************************************************************************************//*! +\file CallbackEvent.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 20, 2021 +\brief Contains the definition of the managed CallbackEvent 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 "CallbackAction.hxx" + +namespace SHADE +{ + /// + /// Holds a set of CallbackActions that can be invoked together at a later time. + /// + /// Type of the first parameter. + generic + public ref class CallbackEvent + { + public: + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + /// + /// Default Constructor + /// + CallbackEvent(); + + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Read only access to the list of Actions + /// + property System::Collections::Generic::IEnumerable^>^ Actions + { + System::Collections::Generic::IEnumerable^>^ get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Adds the specified CallbackAction to the CallbackEvent. + /// + /// CallbackAction to add. + void AddAction(CallbackAction^ action); + /// + /// Adds a specified static method as a CallbackAction to the CallbackEvent. + /// + /// Method to add. + void AddAction(System::Reflection::MethodInfo^ method); + /// + /// Adds a specified instance method and associated object as a CallbackAction to + /// the CallbackEvent. + /// + /// Method to add. + /// Object that will call the specified method. + void AddAction(System::Reflection::MethodInfo^ method, System::Object^ object); + /// + /// Removes the specified CallbackAction from the CallbackEvent. + /// + /// CallbackAction to remove. + void RemoveAction(CallbackAction^ action); + /// + /// Invokes all CallbackActions registered with this CallbackEvent with the + /// specified parameters. + /// + /// + void Invoke(T1 param1); + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + System::Collections::Generic::List^>^ actions; + }; +} \ No newline at end of file diff --git a/SHADE_Managed/src/Math/Vector2.hxx b/SHADE_Managed/src/Math/Vector2.hxx index 69a6110f..9253a703 100644 --- a/SHADE_Managed/src/Math/Vector2.hxx +++ b/SHADE_Managed/src/Math/Vector2.hxx @@ -19,7 +19,7 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { /// - /// CLR version of the the PlushieEngine's Vector2 class that represents a + /// CLR version of the the SHADE Engine's Vector2 class that represents a /// 2-Dimensional Vector. Designed to closely match Unity's Vector2 struct. /// [System::Runtime::InteropServices::StructLayout(System::Runtime::InteropServices::LayoutKind::Sequential)] From 5f305f96090a8290ec3eaeed54e1f983c7296ca9 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 20 Sep 2022 18:13:13 +0800 Subject: [PATCH 09/37] Added SHTextureLibrary stub --- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 41 +++++ .../MiddleEnd/Textures/SHTextureLibrary.h | 142 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp create mode 100644 SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp new file mode 100644 index 00000000..97b72977 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -0,0 +1,41 @@ +/************************************************************************************//*! +\file SHTextureLibrary.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 20, 2022 +\brief Contains definitions for all of the functions of the classes that deal + with storage and management of buffers for textures. + +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 "SHTextureLibrary.h" + +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/Commands/SHVkCommandBuffer.h" +#include "Graphics/SHVkUtil.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData) + { + return {}; + } + + void SHTextureLibrary::Remove(Handle mesh) + { + + } + + void SHTextureLibrary::BuildBuffers(Handle device, Handle cmdBuffer) + { + + } + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h new file mode 100644 index 00000000..a0167cba --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -0,0 +1,142 @@ +/************************************************************************************//*! +\file SHTextureLibrary.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Sep 20, 2022 +\brief Contains definitions for all of the classes that deal with storage and + management of textures. + +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 + +// STL Includes +#include +// Project Includes +#include "Resource/Handle.h" +#include "Resource/ResourceLibrary.h" +#include "Math/SHMath.h" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkBuffer; + class SHVkLogicalDevice; + class SHVkCommandBuffer; + + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + class SHTexture + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ + using PixelChannel = uint8_t; + + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + }; + /***********************************************************************************/ + /*! + \brief + Manages storage for all textures in the Graphics System as a single set of + textures. + */ + /***********************************************************************************/ + class SHTextureLibrary + { + public: + /*-----------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------*/ + /*******************************************************************************/ + /*! + + \brief + Adds a texture to the Texture Library. But this does not mean that the + textures have been added yet. A call to "BuildBuffers()" is required to + transfer all textures into the GPU. + + \param pixelCount + Number of pixels in this Mesh. + \param positions + Pointer to the first in a contiguous array of SHMathVec3s that define vertex + positions. + + \return + Handle to the created Texture. This is not valid to be used until a call to + BuildBuffers(). + + */ + /*******************************************************************************/ + Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData); + /*******************************************************************************/ + /*! + + \brief + Removes a mesh from the Texture Library. But this does not mean that the + textures have been removed yet. A call to "BuildBuffers()" is required to + finalise all changes. + + \param mesh + Handle to the mesh to remove. + + */ + /*******************************************************************************/ + void Remove(Handle mesh); + /***************************************************************************/ + /*! + + \brief + Finalises all changes to the Texture Library into the GPU buffers. + + \param device + Device used to create and update the buffers. + \param cmdBuffer + Command buffer used to set up transfers of data in the GPU memory. This + call must be preceded by calls to cmdBuffer's BeginRecording() and ended + with EndRecording(). Do recall to also submit the cmdBuffer to a transfer + queue. + */ + /***************************************************************************/ + void BuildBuffers(Handle device, Handle cmdBuffer); + + /*-----------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------*/ + Handle GetTextureBuffer() const noexcept { return texStorageBuffer; } + + private: + /*-----------------------------------------------------------------------------*/ + /* Type Definition */ + /*-----------------------------------------------------------------------------*/ + struct AddJob + { + uint32_t PixelCount = 0; + const SHTexture::PixelChannel* PixelData = nullptr; + Handle Handle; + }; + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + // Manipulation Queues + std::vector addJobs; + std::vector> removeJobs; + // Tracking + ResourceLibrary textures{}; + std::vector> texOrder; + // CPU Storage + std::vector texStorage; + // GPU Storage + Handle texStorageBuffer{}; + // Flags + bool isDirty = true; + }; +} From 3d9abcf19ca550e3f850e9e232af76b5dd73ac07 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 09:19:18 +0800 Subject: [PATCH 10/37] Implemented image creation for textures in the texture bank --- SHADE_Engine/SHADE_Engine.vcxproj | 34 +++++ SHADE_Engine/SHADE_Engine.vcxproj.filters | 143 +++++++++++++++++- .../Graphics/Commands/SHVkCommandBuffer.cpp | 63 ++++---- .../src/Graphics/Commands/SHVkCommandBuffer.h | 6 +- .../src/Graphics/Images/SHVkImage.cpp | 33 +--- SHADE_Engine/src/Graphics/Images/SHVkImage.h | 4 +- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 115 +++++++++++++- .../MiddleEnd/Textures/SHTextureLibrary.h | 35 +++-- SHADE_Engine/src/Math/SHMath.h | 2 +- 9 files changed, 350 insertions(+), 85 deletions(-) diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj index 37ddf8f5..2aa3b608 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj +++ b/SHADE_Engine/SHADE_Engine.vcxproj @@ -138,6 +138,7 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + @@ -167,13 +168,31 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + + + + + + + + + + + + + + + + + + @@ -250,6 +269,7 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + @@ -273,12 +293,26 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters index f52aebb0..74be0df1 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj.filters +++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters @@ -28,6 +28,9 @@ {078AA1A3-F318-2B6D-9C37-3F6888A53B13} + + {8C1A20B0-78BC-4A86-6177-5EDA4DB8D1D6} + {DBC7D3B0-C769-FE86-B024-12DB9C6585D7} @@ -70,15 +73,30 @@ {4B204703-3704-0859-A064-02AC8C67F2DA} + + {7A02D7B0-E60F-0597-6FF6-0082DB02D14D} + + + {85EFB65D-F107-9E87-BAB4-2D21268C3221} + {EBA1D3FF-D75C-C3AB-8014-3CF66CAE0D3C} + + {1F603FFC-8B22-7386-D4D2-011340D44B64} + {8CDBA7C9-F8E8-D5AF-81CF-D19AEDDBA166} + + {D04C14FB-3C5A-42E1-C540-3ECC314D0E98} + {2460C057-1070-6C28-7929-D14665585BC1} + + {7E76F08B-EA83-1E72-736A-1A5DDF76EA28} + {FBD334F8-67EA-328E-B061-BEAF1CB70316} @@ -121,6 +139,9 @@ {EAD6C33D-5697-3F74-1FD2-88F18B518450} + + {3AB383AD-2681-77B3-0F15-E8D9FB815318} + {F1B75745-5D6D-D03A-E661-CA115216C73E} @@ -207,6 +228,9 @@ ECS_Base\UnitTesting + + Editor + Engine @@ -294,18 +318,69 @@ Graphics\Instance + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\GlobalData + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Meshes + + + Graphics\MiddleEnd\Meshes + Graphics\MiddleEnd\PerFrame Graphics\MiddleEnd\PerFrame + + Graphics\MiddleEnd\Pipeline + Graphics\MiddleEnd\Shaders @@ -315,6 +390,9 @@ Graphics\MiddleEnd\Shaders + + Graphics\MiddleEnd\Textures + Graphics\Pipeline @@ -421,7 +499,13 @@ Math - Math + Math\Transform + + + Math\Transform + + + Math\Transform Math\Vector @@ -498,8 +582,6 @@ Tools - - @@ -529,6 +611,9 @@ ECS_Base\UnitTesting + + Editor + Engine @@ -598,24 +683,66 @@ Graphics\Instance + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\GlobalData + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Meshes + Graphics\MiddleEnd\PerFrame Graphics\MiddleEnd\PerFrame + + Graphics\MiddleEnd\Pipeline + Graphics\MiddleEnd\Shaders Graphics\MiddleEnd\Shaders + + Graphics\MiddleEnd\Textures + Graphics\Pipeline @@ -698,7 +825,13 @@ Math - Math + Math\Transform + + + Math\Transform + + + Math\Transform Math\Vector @@ -740,7 +873,5 @@ Tools - - \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index 6898b7e0..cddb6cdb 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -8,6 +8,7 @@ #include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/Images/SHVkImage.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" @@ -421,9 +422,42 @@ namespace SHADE vkCommandBuffer.drawIndexed(indexCount, 1, firstIndex, vertexOffset, 0); } + + /***************************************************************************/ + /*! + \brief + Issues a multi indirect draw call. - void SHVkCommandBuffer::PipelineBarrier ( + \param indirectDrawData + SHVkBuffer containing the data for the multi indirect draw call. + \param drawCount + Number of multi indirect draw sub-calls stored in indirectDrawData. + + */ + /***************************************************************************/ + + void SHVkCommandBuffer::DrawMultiIndirect(Handle indirectDrawData, uint32_t drawCount) + { + if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING) + { + SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound."); + return; + } + + vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); + } + + void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo) + { + vkCommandBuffer.copyBufferToImage + ( + src, dst, vk::ImageLayout::eTransferDstOptimal, + static_cast(copyInfo.size()), copyInfo.data() + ); + } + + void SHVkCommandBuffer::PipelineBarrier( vk::PipelineStageFlags srcStage, vk::PipelineStageFlags dstStage, vk::DependencyFlags deps, @@ -457,33 +491,6 @@ namespace SHADE // //vkCommandBuffer.pipelineBarrier() //} - /***************************************************************************/ - /*! - - \brief - Issues a multi indirect draw call. - - \param indirectDrawData - SHVkBuffer containing the data for the multi indirect draw call. - \param drawCount - Number of multi indirect draw sub-calls stored in indirectDrawData. - - */ - /***************************************************************************/ - - void SHVkCommandBuffer::DrawMultiIndirect(Handle indirectDrawData, uint32_t drawCount) - { - if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING) - { - SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound."); - return; - } - - vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); - } - - - /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index d945fce8..f780638a 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -15,6 +15,7 @@ namespace SHADE class SHVkFramebuffer; class SHVkPipeline; class SHVkBuffer; + class SHVkImage; class SHVkDescriptorSetGroup; enum class SH_CMD_BUFFER_TYPE @@ -116,6 +117,10 @@ namespace SHADE // Draw Commands void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept; void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept; + void DrawMultiIndirect (Handle indirectDrawData, uint32_t drawCount); + + // Buffer Copy + void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector& copyInfo); // memory barriers void PipelineBarrier ( @@ -129,7 +134,6 @@ namespace SHADE bool IsReadyToSubmit (void) const noexcept; void HandlePostSubmit (void) noexcept; - void DrawMultiIndirect (Handle indirectDrawData, uint32_t drawCount); // Push Constant variable setting template diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp index 6ec1c9f2..b8bf273e 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.cpp @@ -234,7 +234,7 @@ namespace SHADE return SHVkInstance::GetResourceManager().Create(inLogicalDeviceHdl, parent, createParams); } - void SHVkImage::TransferToDeviceResource(void) noexcept + void SHVkImage::TransferToDeviceResource(Handle cmdBufferHdl) noexcept { // prepare copy regions std::vector copyRegions{mipOffsets.size()}; @@ -252,7 +252,7 @@ namespace SHADE copyRegions[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 }; } - //PrepareImageTransition(); + cmdBufferHdl->CopyBufferToImage(stagingBuffer, vkImage, copyRegions); } /***************************************************************************/ @@ -274,7 +274,7 @@ namespace SHADE */ /***************************************************************************/ - void SHVkImage::PrepareImageTransition(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept + void SHVkImage::PrepareImageTransitionInfo(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept { barrier.oldLayout = oldLayout; barrier.newLayout = newLayout; @@ -286,33 +286,6 @@ namespace SHADE barrier.subresourceRange.levelCount = mipLevelCount; barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.layerCount = layerCount; - - vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe; - vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe; - - if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal) - { - srcStage = vk::PipelineStageFlagBits::eTopOfPipe; - dstStage = vk::PipelineStageFlagBits::eTransfer; - - barrier.srcAccessMask = vk::AccessFlagBits::eNone; - barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite; - } - else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) - { - srcStage = vk::PipelineStageFlagBits::eTransfer; - - // TODO, what if we want to access in compute shader - dstStage = vk::PipelineStageFlagBits::eFragmentShader; - - barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite; - barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead; - } - else - { - SHLOG_ERROR("Image layouts are invalid. "); - } - } void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept diff --git a/SHADE_Engine/src/Graphics/Images/SHVkImage.h b/SHADE_Engine/src/Graphics/Images/SHVkImage.h index eec8dc7e..91d4f2d2 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkImage.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkImage.h @@ -135,8 +135,8 @@ namespace SHADE /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ Handle CreateImageView (Handle const& inLogicalDeviceHdl, Handle const& parent, SHImageViewDetails const& createParams) const noexcept; - void TransferToDeviceResource (void) noexcept; - void PrepareImageTransition (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; + void TransferToDeviceResource (Handle cmdBufferHdl) noexcept; + void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index 97b72977..3be4dd11 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -13,29 +13,130 @@ of DigiPen Institute of Technology is prohibited. #include "SHpch.h" #include "SHTextureLibrary.h" +#include "Graphics/SHVulkanIncludes.h" + #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Commands/SHVkCommandBuffer.h" #include "Graphics/SHVkUtil.h" +#include "Tools/SHLogger.h" namespace SHADE { - /*-----------------------------------------------------------------------------*/ - /* Usage Functions */ - /*-----------------------------------------------------------------------------*/ - Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData) + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels) { - return {}; + isDirty = true; + + auto handle = resourceManager.Create(); + addJobs.emplace_back(AddJob { pixelCount, pixelData, format, mipLevels }); + return handle; } - void SHTextureLibrary::Remove(Handle mesh) + void SHTextureLibrary::Remove(Handle texture) { + if (!texture) + throw std::invalid_argument("Attempted to remove a Texture that did not belong to the Texture Library!"); + removeJobs.emplace_back(texture); + isDirty = true; } - void SHTextureLibrary::BuildBuffers(Handle device, Handle cmdBuffer) + void SHTextureLibrary::BuildImages(Handle device, Handle cmdBuffer, Handle graphicsQueue, Handle descPool, Handle descLayout) { + /* Remove Textures */ + std::vector pipelineBarriers(addJobs.size()); + /* Add Textures */ + // Transition + for (int i = 0; auto& job : addJobs) + { + job.Image = resourceManager.Create(); + job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, pipelineBarriers[i]); + ++i; + } + vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe; + vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe; + preparePipelineBarriers(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, srcStage, dstStage, pipelineBarriers); + cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers); + + // Copy + for (auto& job : addJobs) + { + job.Image->TransferToDeviceResource(cmdBuffer); + } + + // Transition + for (int i = 0; auto & job : addJobs) + { + // Transition + job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, pipelineBarriers[i]); + } + preparePipelineBarriers(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, srcStage, dstStage, pipelineBarriers); + cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers); + + // Execute Commands + graphicsQueue->SubmitCommandBuffer({ cmdBuffer }); + device->WaitIdle(); + + // Create Image View + for (auto& job : addJobs) + { + const SHImageViewDetails DETAILS + { + .viewType = vk::ImageViewType::e2D, + .format = job.TextureFormat, + .imageAspectFlags = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0, + .mipLevelCount = job.MipLevels, + .baseArrayLayer = 0, + .layerCount = 0 + }; + job.Handle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS); + } + + // Build Descriptor + Handle descSetGroup = descPool->Allocate({ descLayout }, { 1 }).front(); + + + isDirty = false; + } + + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + void SHTextureLibrary::preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector& barriers) + { + if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal) + { + srcStage = vk::PipelineStageFlagBits::eTopOfPipe; + dstStage = vk::PipelineStageFlagBits::eTransfer; + + for (auto& barrier : barriers) + { + barrier.srcAccessMask = vk::AccessFlagBits::eNone; + barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite; + } + } + else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) + { + srcStage = vk::PipelineStageFlagBits::eTransfer; + + // TODO, what if we want to access in compute shader + dstStage = vk::PipelineStageFlagBits::eFragmentShader; + + for (auto& barrier : barriers) + { + barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite; + barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead; + } + } + else + { + SHLOG_ERROR("Image layouts are invalid. "); + } } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h index a0167cba..d30b02ed 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -37,11 +37,15 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------*/ - using PixelChannel = uint8_t; + using PixelChannel = void; + using TextureFormat = vk::Format; // TODO: Change + using Index = uint32_t; /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ + Handle ImageView; + Index TextureArrayIndex = std::numeric_limits::max(); }; /***********************************************************************************/ /*! @@ -61,7 +65,7 @@ namespace SHADE \brief Adds a texture to the Texture Library. But this does not mean that the - textures have been added yet. A call to "BuildBuffers()" is required to + textures have been added yet. A call to "BuildImages()" is required to transfer all textures into the GPU. \param pixelCount @@ -69,20 +73,22 @@ namespace SHADE \param positions Pointer to the first in a contiguous array of SHMathVec3s that define vertex positions. + \param format + Format of the texture loaded in. \return Handle to the created Texture. This is not valid to be used until a call to - BuildBuffers(). + BuildImages(). */ /*******************************************************************************/ - Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData); + Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels); /*******************************************************************************/ /*! \brief Removes a mesh from the Texture Library. But this does not mean that the - textures have been removed yet. A call to "BuildBuffers()" is required to + textures have been removed yet. A call to "BuildImages()" is required to finalise all changes. \param mesh @@ -106,7 +112,7 @@ namespace SHADE queue. */ /***************************************************************************/ - void BuildBuffers(Handle device, Handle cmdBuffer); + void BuildImages(Handle device, Handle cmdBuffer, Handle graphicsQueue); /*-----------------------------------------------------------------------------*/ /* Getter Functions */ @@ -119,10 +125,14 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ struct AddJob { - uint32_t PixelCount = 0; - const SHTexture::PixelChannel* PixelData = nullptr; - Handle Handle; + uint32_t PixelCount = 0; + const SHTexture::PixelChannel* PixelData = nullptr; + SHTexture::TextureFormat TextureFormat = {}; + int MipLevels = 0; + Handle Image; + Handle Handle; }; + /*-----------------------------------------------------------------------------*/ /* Data Members */ /*-----------------------------------------------------------------------------*/ @@ -130,7 +140,7 @@ namespace SHADE std::vector addJobs; std::vector> removeJobs; // Tracking - ResourceLibrary textures{}; + ResourceManager resourceManager; std::vector> texOrder; // CPU Storage std::vector texStorage; @@ -138,5 +148,10 @@ namespace SHADE Handle texStorageBuffer{}; // Flags bool isDirty = true; + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + void preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector& barriers); }; } diff --git a/SHADE_Engine/src/Math/SHMath.h b/SHADE_Engine/src/Math/SHMath.h index 55bf73a9..5fcea9fc 100644 --- a/SHADE_Engine/src/Math/SHMath.h +++ b/SHADE_Engine/src/Math/SHMath.h @@ -9,4 +9,4 @@ #include "SHQuaternion.h" #include "SHMatrix.h" -#include "SHTransform.h" \ No newline at end of file +#include "Transform/SHTransform.h" \ No newline at end of file From ba181eb9c908ec63cf55bdaf543f77479832d451 Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 22 Sep 2022 09:23:40 +0800 Subject: [PATCH 11/37] Shifted Command buffers outside of render graph Command buffers now exist in renderer instead Graphics system that calls the renderer, begins and ends the renderer recording in it's main loop as well --- SHADE_Engine/SHADE_Engine.vcxproj | 34 +++++ SHADE_Engine/SHADE_Engine.vcxproj.filters | 143 +++++++++++++++++- .../Descriptors/SHVkDescriptorPool.cpp | 5 +- .../Graphics/Descriptors/SHVkDescriptorPool.h | 2 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 36 ++++- .../MiddleEnd/Interface/SHRenderer.cpp | 21 ++- .../Graphics/MiddleEnd/Interface/SHRenderer.h | 12 +- .../MiddleEnd/Interface/SHViewport.cpp | 4 +- .../Graphics/MiddleEnd/Interface/SHViewport.h | 3 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 44 +----- .../src/Graphics/RenderGraph/SHRenderGraph.h | 12 +- SHADE_Engine/src/Math/SHMath.h | 2 +- 12 files changed, 239 insertions(+), 79 deletions(-) diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj index 37ddf8f5..2aa3b608 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj +++ b/SHADE_Engine/SHADE_Engine.vcxproj @@ -138,6 +138,7 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + @@ -167,13 +168,31 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + + + + + + + + + + + + + + + + + + @@ -250,6 +269,7 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + @@ -273,12 +293,26 @@ xcopy /s /r /y /q "$(SolutionDir)/Dependencies/dotnet/bin" "$(OutDir)" + + + + + + + + + + + + + + diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters index f52aebb0..74be0df1 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj.filters +++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters @@ -28,6 +28,9 @@ {078AA1A3-F318-2B6D-9C37-3F6888A53B13} + + {8C1A20B0-78BC-4A86-6177-5EDA4DB8D1D6} + {DBC7D3B0-C769-FE86-B024-12DB9C6585D7} @@ -70,15 +73,30 @@ {4B204703-3704-0859-A064-02AC8C67F2DA} + + {7A02D7B0-E60F-0597-6FF6-0082DB02D14D} + + + {85EFB65D-F107-9E87-BAB4-2D21268C3221} + {EBA1D3FF-D75C-C3AB-8014-3CF66CAE0D3C} + + {1F603FFC-8B22-7386-D4D2-011340D44B64} + {8CDBA7C9-F8E8-D5AF-81CF-D19AEDDBA166} + + {D04C14FB-3C5A-42E1-C540-3ECC314D0E98} + {2460C057-1070-6C28-7929-D14665585BC1} + + {7E76F08B-EA83-1E72-736A-1A5DDF76EA28} + {FBD334F8-67EA-328E-B061-BEAF1CB70316} @@ -121,6 +139,9 @@ {EAD6C33D-5697-3F74-1FD2-88F18B518450} + + {3AB383AD-2681-77B3-0F15-E8D9FB815318} + {F1B75745-5D6D-D03A-E661-CA115216C73E} @@ -207,6 +228,9 @@ ECS_Base\UnitTesting + + Editor + Engine @@ -294,18 +318,69 @@ Graphics\Instance + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\GlobalData + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Meshes + + + Graphics\MiddleEnd\Meshes + Graphics\MiddleEnd\PerFrame Graphics\MiddleEnd\PerFrame + + Graphics\MiddleEnd\Pipeline + Graphics\MiddleEnd\Shaders @@ -315,6 +390,9 @@ Graphics\MiddleEnd\Shaders + + Graphics\MiddleEnd\Textures + Graphics\Pipeline @@ -421,7 +499,13 @@ Math - Math + Math\Transform + + + Math\Transform + + + Math\Transform Math\Vector @@ -498,8 +582,6 @@ Tools - - @@ -529,6 +611,9 @@ ECS_Base\UnitTesting + + Editor + Engine @@ -598,24 +683,66 @@ Graphics\Instance + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\Batching + + + Graphics\MiddleEnd\GlobalData + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + Graphics\MiddleEnd\Interface + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Interface + + + Graphics\MiddleEnd\Meshes + Graphics\MiddleEnd\PerFrame Graphics\MiddleEnd\PerFrame + + Graphics\MiddleEnd\Pipeline + Graphics\MiddleEnd\Shaders Graphics\MiddleEnd\Shaders + + Graphics\MiddleEnd\Textures + Graphics\Pipeline @@ -698,7 +825,13 @@ Math - Math + Math\Transform + + + Math\Transform + + + Math\Transform Math\Vector @@ -740,7 +873,5 @@ Tools - - \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp index 77663ab8..6b770c3d 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.cpp @@ -50,9 +50,8 @@ namespace SHADE return *this; } - std::vector> SHVkDescriptorPool::Allocate(const std::vector>& layouts, std::vector const& variableDescCounts) + Handle SHVkDescriptorPool::Allocate(const std::vector>& layouts, std::vector const& variableDescCounts) { - SHVkInstance::GetResourceManager().Create(device, GetHandle(), layouts, variableDescCounts); - return {}; + return SHVkInstance::GetResourceManager().Create(device, GetHandle(), layouts, variableDescCounts); } } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h index 9314d940..b862ec09 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorPool.h @@ -101,7 +101,7 @@ namespace SHADE /// Handles to the created Descriptor Sets. If this DescriptorPool has run out of /// space, lesser number of Handles will be returned. /// - std::vector> Allocate(const std::vector>& layouts, std::vector const& variableDescCounts); + Handle Allocate(const std::vector>& layouts, std::vector const& variableDescCounts); private: /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 1130a02b..b38fa275 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -29,6 +29,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Batching/SHSuperBatch.h" #include "SHGraphicsConstants.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/Buffers/SHVkBuffer.h" namespace SHADE { @@ -129,7 +130,7 @@ namespace SHADE } // Initialize world render graph - worldRenderGraph->Init(device, swapchain, renderContextCmdPools, globalData); + worldRenderGraph->Init(device, swapchain, globalData); //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); @@ -167,7 +168,7 @@ namespace SHADE debugWorldRenderer->SetCamera(worldCamera);*/ // Add world renderer to default viewport - worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), descPool, globalData->GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); + worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, globalData->GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer->SetCamera(worldCamera); @@ -228,16 +229,37 @@ namespace SHADE // For every renderer for (int renIndex = 0; renIndex < static_cast(renderers.size()); ++renIndex) { - // Draw first - renderers[renIndex]->Draw(renderContext.GetCurrentFrame(), MESH_DATA); + /*-----------------------------------------------------------------------*/ + /* Renderer start */ + /*-----------------------------------------------------------------------*/ + // get command buffer of the renderer in the current frame + auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(renderContext.GetCurrentFrame()); - // get render graph - auto rg = renderers[renIndex]->GetRenderGraph(); + // Begin recording the command buffer + currentCmdBuffer->BeginRecording(); + + // Bind all the buffers required for meshes + for (auto& [buffer, bindingPoint] : MESH_DATA) + { + if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer) + currentCmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0); + else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer) + currentCmdBuffer->BindIndexBuffer(buffer, 0); + } + + // Draw first + renderers[renIndex]->Draw(renderContext.GetCurrentFrame()); + + // End the command buffer recording + currentCmdBuffer->EndRecording(); + /*-----------------------------------------------------------------------*/ + /* Renderer end */ + /*-----------------------------------------------------------------------*/ // submit a command buffer from the current render graph and make it wait for the previous render graph before submitting it to GPU. graphicsQueue->SubmitCommandBuffer ( - { rg->GetCommandBuffer(renderContext.GetCurrentFrame()) }, + { currentCmdBuffer }, { (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.semRenderFinishHdl : graphSemaphores[!semIndex] }, { (vpIndex == 0 && renIndex == 0) ? frameData.semImgAvailableHdl : graphSemaphores[semIndex] }, { vk::PipelineStageFlagBits::eColorAttachmentOutput }, diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 90e137fe..223ceb4f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -20,20 +20,28 @@ of DigiPen Institute of Technology is prohibited. #include "SHMaterial.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Graphics/Buffers/SHVkBuffer.h" namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*-----------------------------------------------------------------------------------*/ - SHRenderer::SHRenderer(Handle logicalDevice, uint32_t numFrames, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph) + SHRenderer::SHRenderer(Handle logicalDevice, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph) : viewport { viewport } , renderGraph { renderGraph } { - cameraDescriptorSet = logicalDevice->CreateDescriptorSetGroup(descriptorPool, { cameraDescLayout }, { 1 }); + commandBuffers.resize(static_cast(numFrames)); + + for (uint32_t i = 0; i < commandBuffers.size(); ++i) + commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + + cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 }); cpuCameraData.resize(numFrames); cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData)); + + cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); } /*-----------------------------------------------------------------------------------*/ @@ -47,9 +55,9 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Drawing Functions */ /*-----------------------------------------------------------------------------------*/ - void SHRenderer::Draw(uint32_t frameIndex, std::initializer_list, uint32_t>> graphScopeBuffers) noexcept + void SHRenderer::Draw(uint32_t frameIndex) noexcept { - renderGraph->Execute(frameIndex, graphScopeBuffers); + renderGraph->Execute(frameIndex, commandBuffers[frameIndex]); } void SHRenderer::BindDescriptorSet(Handle cmdBuffer, uint32_t frameIndex) noexcept @@ -64,4 +72,9 @@ namespace SHADE return renderGraph; } + Handle SHRenderer::GetCommandBuffer(uint32_t frameIndex) const noexcept + { + return commandBuffers[frameIndex]; + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index 843ad6bf..bbb7773b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -39,6 +39,7 @@ namespace SHADE class SHVkDescriptorSetGroup; class SHGraphicsGlobalData; class SHVkDescriptorPool; + class SHVkBuffer; struct SHShaderCameraData { @@ -63,7 +64,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*-----------------------------------------------------------------------------*/ - SHRenderer(Handle logicalDevice, uint32_t numFrames, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph); + SHRenderer(Handle logicalDevice, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph); /*-----------------------------------------------------------------------------*/ /* Camera Registration */ @@ -73,13 +74,14 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Drawing Functions */ /*-----------------------------------------------------------------------------*/ - void Draw(uint32_t frameIndex, std::initializer_list, uint32_t>> graphScopeBuffers) noexcept; + void Draw(uint32_t frameIndex) noexcept; void BindDescriptorSet (Handle cmdBuffer, uint32_t frameIndex) noexcept; /*-----------------------------------------------------------------------------*/ /* Setters and Getters */ /*-----------------------------------------------------------------------------*/ Handle GetRenderGraph (void) const noexcept; + Handle GetCommandBuffer(uint32_t frameIndex) const noexcept; private: /*-----------------------------------------------------------------------------*/ @@ -92,7 +94,13 @@ namespace SHADE Handle camera; Handle renderGraph; Handle cameraDescriptorSet; + Handle cameraBuffer; std::vector cpuCameraData; + + //! Command buffers for the render graph + std::vector> commandBuffers; + + }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index 1e38acf1..25c5bca2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -49,10 +49,10 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Renderer Registration Functions */ /*---------------------------------------------------------------------------------*/ - Handle SHViewport::AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph) + Handle SHViewport::AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph) { // Create the renderer - auto renderer = resourceManager.Create(device, numFrames, descriptorPool, cameraDescLayout, GetHandle(), renderGraph); + auto renderer = resourceManager.Create(device, numFrames, cmdPools, descriptorPool, cameraDescLayout, GetHandle(), renderGraph); // Store renderers.emplace_back(renderer); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index 608446a3..d97d62ce 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -32,6 +32,7 @@ namespace SHADE class SHRenderGraph; class SHVkDescriptorPool; class SHVkDescriptorSetLayout; + class SHVkCommandPool; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -58,7 +59,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Renderers Registration Functions */ /*-----------------------------------------------------------------------------*/ - Handle AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); + Handle AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); void RemoveRenderer(Handle renderer); /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index d7404db2..d02e8f7d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -946,25 +946,6 @@ namespace SHADE } } - /***************************************************************************/ - /*! - - \brief - Configures command pools and command buffers. - - */ - /***************************************************************************/ - void SHRenderGraph::ConfigureCommands(void) noexcept - { - //commandPools.resize (static_cast(swapchainHdl->GetNumImages())); - commandBuffers.resize(static_cast(swapchainHdl->GetNumImages())); - - for (uint32_t i = 0; i < commandBuffers.size(); ++i) - { - commandBuffers[i] = commandPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - } - } - /***************************************************************************/ /*! @@ -980,12 +961,11 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::Init(Handle const& logicalDevice, Handle const& swapchain, std::vector> const& cmdPools, Handle inGlobalData) noexcept + void SHRenderGraph::Init(Handle const& logicalDevice, Handle const& swapchain, Handle inGlobalData) noexcept { logicalDeviceHdl = logicalDevice; swapchainHdl = swapchain; globalData = inGlobalData; - commandPools = cmdPools; } /***************************************************************************/ @@ -1087,33 +1067,17 @@ namespace SHADE ConfigureSubpasses(); ConfigureRenderpasses(); ConfigureFramebuffers(); - ConfigureCommands(); } // TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a // better way to manage these - void SHRenderGraph::Execute(uint32_t frameIndex, std::initializer_list, uint32_t>> graphScopeBuffers) noexcept + void SHRenderGraph::Execute(uint32_t frameIndex, Handle cmdBuffer) noexcept { - //commandPools[frameIndex]->Reset(); - - auto& cmdBuffer = commandBuffers[frameIndex]; - cmdBuffer->BeginRecording(); - // TODO: DON'T HARDCODE THIS cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080); - for (auto& [buffer, bindingPoint]: graphScopeBuffers) - { - if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer) - cmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0); - else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer) - cmdBuffer->BindIndexBuffer(buffer, 0); - } - for (auto& node : nodes) node->Execute(cmdBuffer, frameIndex); - - cmdBuffer->EndRecording(); } void SHRenderGraph::FinaliseBatch() @@ -1132,9 +1096,5 @@ namespace SHADE return {}; } - Handle const& SHRenderGraph::GetCommandBuffer(uint32_t frameIndex) const noexcept - { - return commandBuffers[frameIndex]; - } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 0ecda65a..cbb9586d 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -250,7 +250,6 @@ namespace SHADE void ConfigureSubpasses (void) noexcept; void ConfigureRenderpasses (void) noexcept; void ConfigureFramebuffers (void) noexcept; - void ConfigureCommands (void) noexcept; /*-----------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ @@ -271,12 +270,6 @@ namespace SHADE //! Resource library for graph handles ResourceManager resourceManager; - - //! Command pool for the render graph. DO NOT RESET OR FREE THESE, THEY ARE NON-OWNING. TODO: If application is multithreaded, we need more pools. - std::vector> commandPools; - - //! Command buffers for the render graph - std::vector> commandBuffers; //! Handle to global data Handle globalData; @@ -290,18 +283,17 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (Handle const& logicalDevice, Handle const& swapchain, std::vector> const& cmdPools, Handle inGlobalData) noexcept; + void Init (Handle const& logicalDevice, Handle const& swapchain, Handle inGlobalData) 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::ImageCreateFlagBits createFlags = {}); Handle AddNode (std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept; void Generate (void) noexcept; - void Execute (uint32_t frameIndex, std::initializer_list, uint32_t>> graphScopeBuffers) noexcept; + void Execute (uint32_t frameIndex, Handle cmdBuffer) noexcept; void FinaliseBatch(); /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ Handle GetNode (std::string const& nodeName) const noexcept; - Handle const& GetCommandBuffer (uint32_t frameIndex) const noexcept; }; } diff --git a/SHADE_Engine/src/Math/SHMath.h b/SHADE_Engine/src/Math/SHMath.h index 55bf73a9..5fcea9fc 100644 --- a/SHADE_Engine/src/Math/SHMath.h +++ b/SHADE_Engine/src/Math/SHMath.h @@ -9,4 +9,4 @@ #include "SHQuaternion.h" #include "SHMatrix.h" -#include "SHTransform.h" \ No newline at end of file +#include "Transform/SHTransform.h" \ No newline at end of file From 21a3d6ecd778cc9a2b3c80a9ba7944f9f45038dd Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 11:22:51 +0800 Subject: [PATCH 12/37] Added test code for scripts --- SHADE_Application/src/Scenes/SBTestScene.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 873d0fed..072a15de 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -7,6 +7,7 @@ #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Scene/SHSceneManager.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" +#include "Scripting/SHScriptEngine.h" using namespace SHADE; @@ -42,6 +43,8 @@ namespace Sandbox renderable.Mesh = CUBE_MESH; renderable.SetMaterial(matInst); renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f); + SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); + scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(entity), "TestScript"); } void SBTestScene::Update(float dt) { From 495824080696cbe62bd979ab286118d322fd4ae6 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 11:37:24 +0800 Subject: [PATCH 13/37] Added implementation of GetComponentInChildren() for scripts --- SHADE_Managed/src/Engine/ECS.cxx | 45 ++++++++++++--------- SHADE_Managed/src/Engine/GameObject.cxx | 2 +- SHADE_Managed/src/Scripts/ScriptStore.cxx | 48 ++++++++++++----------- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/SHADE_Managed/src/Engine/ECS.cxx b/SHADE_Managed/src/Engine/ECS.cxx index e4405006..36bef851 100644 --- a/SHADE_Managed/src/Engine/ECS.cxx +++ b/SHADE_Managed/src/Engine/ECS.cxx @@ -21,6 +21,9 @@ of DigiPen Institute of Technology is prohibited. #include // External Dependencies #include "ECS_Base/Managers/SHEntityManager.h" +#include "Scene/SHSceneManager.h" +#include "Scene/SHSceneGraph.h" +#include "Tools/SHLog.h" // Project Headers #include "Utility/Convert.hxx" #include "Utility/Debug.hxx" @@ -124,27 +127,31 @@ namespace SHADE return T(); } - // Get Transform component and get the children list - throw gcnew System::NotImplementedException; - //Pls::Transform* tf = Pls::ECS::GetComponent(entity); - //if (tf == nullptr) - // return T(); + // Get Entity's SceneGraphNode + SHSceneNode* sceneGraphNode = SHSceneManager::GetCurrentSceneGraph().GetNode(entity); + if (sceneGraphNode == nullptr) + { + std::ostringstream oss; + oss << "[ECS_CLI] Failed to retrieve SceneGraphNode of entity #" << entity << ". This should not happen!"; + SHLog::Warning(oss.str()); + return T(); + } - //// Search direct children first - //for (const auto& child : tf->GetChildren()) - //{ - // T component = GetComponent(child); - // if (component != nullptr) - // return component; - //} + // Search direct children first + for (const auto& child : sceneGraphNode->GetChildren()) + { + T component = GetComponent(child->GetEntityID()); + if (component != nullptr) + return component; + } - //// Search their children - //for (const auto& child : tf->GetChildren()) - //{ - // T script = GetComponentInChildren(child); - // if (script != nullptr) - // return script; - //} + // Search their children + for (const auto& child : sceneGraphNode->GetChildren()) + { + T component = GetComponentInChildren(child->GetEntityID()); + if (component != nullptr) + return component; + } // None here return T(); diff --git a/SHADE_Managed/src/Engine/GameObject.cxx b/SHADE_Managed/src/Engine/GameObject.cxx index 1fbc3b4a..8c78e399 100644 --- a/SHADE_Managed/src/Engine/GameObject.cxx +++ b/SHADE_Managed/src/Engine/GameObject.cxx @@ -56,7 +56,7 @@ namespace SHADE } bool GameObject::IsActiveInHierarchy::get() { - throw gcnew System::NotImplementedException(); + return true; // TODO: Update once we have an equivalent on the Entity object } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index d30cad6b..089da002 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -20,6 +20,7 @@ of DigiPen Institute of Technology is prohibited. #include // External Dependencies #include "ECS_Base/Managers/SHEntityManager.h" +#include "Tools/SHLog.h" // Project Headers #include "Utility/Debug.hxx" #include "Utility/Convert.hxx" @@ -147,7 +148,6 @@ namespace SHADE // Check if entity exists and is a valid GameObject if (!EntityUtils::IsValid(entity)) throw gcnew System::ArgumentException("Invalid Entity provided to get a Script from."); - // Check if entity exists in the script storage if (!scripts.ContainsKey(entity)) @@ -155,27 +155,31 @@ namespace SHADE return T(); } - // Get Transform component and get the children list - throw gcnew System::NotImplementedException; - //Pls::Transform* tf = Pls::ECS::GetComponent(Convert::ToNative(entity)); - //if (tf == nullptr) - // return T(); + // Get Entity's SceneGraphNode + SHSceneNode* sceneGraphNode = SHSceneManager::GetCurrentSceneGraph().GetNode(entity); + if (sceneGraphNode == nullptr) + { + std::ostringstream oss; + oss << "[ECS_CLI] Failed to retrieve SceneGraphNode of entity #" << entity << ". This should not happen!"; + SHLog::Warning(oss.str()); + return T(); + } - //// Search direct children first - //for (const auto& child : tf->GetChildren()) - //{ - // T script = GetScript(Convert::ToCLI(child)); - // if (script != nullptr) - // return script; - //} + // Search direct children first + for (const auto& child : sceneGraphNode->GetChildren()) + { + T script = GetScript(child->GetEntityID()); + if (script != nullptr) + return script; + } - //// Search their children - //for (const auto& child : tf->GetChildren()) - //{ - // T script = GetScriptInChildren(Convert::ToCLI(child)); - // if (script != nullptr) - // return script; - //} + // Search their children + for (const auto& child : sceneGraphNode->GetChildren()) + { + T script = GetScript(child->GetEntityID()); + if (script != nullptr) + return script; + } // None here return T(); @@ -232,7 +236,6 @@ namespace SHADE // Check if entity exists if (!EntityUtils::IsValid(entity)) throw gcnew System::ArgumentException("Invalid Entity provided to remove a Script from."); - // Check if entity exists in the script storage if (!scripts.ContainsKey(entity)) @@ -263,8 +266,7 @@ namespace SHADE Debug::LogError("[ScriptStore] Attempted to remove a Script from an invalid Entity!"); return false; } - - + // Check if entity exists in the script storage if (!scripts.ContainsKey(entity)) { From 5ff375113ff658a78b0ea1177bb453bdd7d3632c Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 11:39:50 +0800 Subject: [PATCH 14/37] Removed CallbackAction and CallbackEvent for moving to C# library in future --- SHADE_Managed/src/Events/CallbackAction.cxx | 48 ------------ SHADE_Managed/src/Events/CallbackAction.hxx | 57 -------------- SHADE_Managed/src/Events/CallbackEvent.cxx | 71 ----------------- SHADE_Managed/src/Events/CallbackEvent.hxx | 85 --------------------- 4 files changed, 261 deletions(-) delete mode 100644 SHADE_Managed/src/Events/CallbackAction.cxx delete mode 100644 SHADE_Managed/src/Events/CallbackAction.hxx delete mode 100644 SHADE_Managed/src/Events/CallbackEvent.cxx delete mode 100644 SHADE_Managed/src/Events/CallbackEvent.hxx diff --git a/SHADE_Managed/src/Events/CallbackAction.cxx b/SHADE_Managed/src/Events/CallbackAction.cxx deleted file mode 100644 index 0ad356c1..00000000 --- a/SHADE_Managed/src/Events/CallbackAction.cxx +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************************//*! -\file CallbackAction.cxx -\author Tng Kah Wei, kahwei.tng, 390009620 -\par email: kahwei.tng\@digipen.edu -\date Sep 20, 2022 -\brief Contains the definition of the functions for the CallbackAction managed - 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 -of DigiPen Institute of Technology is prohibited. -*//*************************************************************************************/ -// Precompiled Headers -#include "SHpch.h" -// Primary Header -#include "CallbackAction.hxx" - -namespace SHADE -{ - /*---------------------------------------------------------------------------------*/ - /* Constructors */ - /*---------------------------------------------------------------------------------*/ - generic - CallbackAction::CallbackAction(System::Reflection::MethodInfo^ method) - : CallbackAction(method, nullptr) - {} - generic - CallbackAction::CallbackAction(System::Reflection::MethodInfo^ method, System::Object^ obj) - : method { method } - , object { obj } - { - paramArray = gcnew cli::array(1); - } - - /*---------------------------------------------------------------------------------*/ - /* Usage Functions */ - /*---------------------------------------------------------------------------------*/ - generic - void CallbackAction::Invoke(T1 param1) - { - // Set parameters - paramArray[0] = safe_cast(param1); - // Invoke - method->Invoke(object, paramArray); - } -} diff --git a/SHADE_Managed/src/Events/CallbackAction.hxx b/SHADE_Managed/src/Events/CallbackAction.hxx deleted file mode 100644 index f8b50266..00000000 --- a/SHADE_Managed/src/Events/CallbackAction.hxx +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************************//*! -\file CallbackAction.hxx -\author Tng Kah Wei, kahwei.tng, 390009620 -\par email: kahwei.tng\@digipen.edu -\date Sep 20, 2021 -\brief Contains the definition of the managed CallbackAction 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 - -namespace SHADE -{ - /// - /// Holds a function and their associated object for invoking later. - /// - /// Type of the first parameter. - generic - public ref class CallbackAction - { - public: - /*-----------------------------------------------------------------------------*/ - /* Constructors */ - /*-----------------------------------------------------------------------------*/ - /// - /// Constructs a CallbackAction with the specified static method. - /// - /// MethodInfo representing the method to call. - /// Object to call the method on. Set null if static. - CallbackAction(System::Reflection::MethodInfo^ method); - /// - /// Constructs a CallbackAction with the specified instance method and object - /// which will invoke the method. - /// - /// MethodInfo representing the method to call. - /// Object to call the method on. - CallbackAction(System::Reflection::MethodInfo^ method, System::Object^ obj); - - /*-----------------------------------------------------------------------------*/ - /* Usage Functions */ - /*-----------------------------------------------------------------------------*/ - /// - /// Invokes this action with the specified parameters. - /// - /// - void Invoke(T1 param1); - - private: - System::Reflection::MethodInfo^ method; - cli::array^ paramArray; - System::Object^ object; - }; -} \ No newline at end of file diff --git a/SHADE_Managed/src/Events/CallbackEvent.cxx b/SHADE_Managed/src/Events/CallbackEvent.cxx deleted file mode 100644 index 9ba82ef2..00000000 --- a/SHADE_Managed/src/Events/CallbackEvent.cxx +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************************//*! -\file CallbackEvent.cxx -\author Tng Kah Wei, kahwei.tng, 390009620 -\par email: kahwei.tng\@digipen.edu -\date Sep 20, 2022 -\brief Contains the definition of the functions for the CallbackEvent managed - 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 -of DigiPen Institute of Technology is prohibited. -*//*************************************************************************************/ -// Precompiled Headers -#include "SHpch.h" -// Primary Header -#include "CallbackEvent.hxx" - -namespace SHADE -{ - /*---------------------------------------------------------------------------------*/ - /* Constructors */ - /*---------------------------------------------------------------------------------*/ - generic - CallbackEvent::CallbackEvent() - { - actions = gcnew System::Collections::Generic::List ^>(); - } - - /*---------------------------------------------------------------------------------*/ - /* Properties */ - /*---------------------------------------------------------------------------------*/ - generic - System::Collections::Generic::IEnumerable^>^ CallbackEvent::Actions::get() - { - return actions; - } - - /*---------------------------------------------------------------------------------*/ - /* Usage Functions */ - /*---------------------------------------------------------------------------------*/ - generic - void CallbackEvent::AddAction(CallbackAction^ action) - { - actions->Add(action); - } - generic - void CallbackEvent::AddAction(System::Reflection::MethodInfo^ method) - { - actions->Add(gcnew CallbackAction(method)); - } - generic - void CallbackEvent::AddAction(System::Reflection::MethodInfo^ method, System::Object^ object) - { - actions->Add(gcnew CallbackAction(method, object)); - } - generic - void CallbackEvent::RemoveAction(CallbackAction^ action) - { - actions->Remove(action); - } - generic - void CallbackEvent::Invoke(T1 param1) - { - for each (CallbackAction^ action in actions) - { - action->Invoke(param1); - } - } -} diff --git a/SHADE_Managed/src/Events/CallbackEvent.hxx b/SHADE_Managed/src/Events/CallbackEvent.hxx deleted file mode 100644 index d0d6d2f1..00000000 --- a/SHADE_Managed/src/Events/CallbackEvent.hxx +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************************//*! -\file CallbackEvent.hxx -\author Tng Kah Wei, kahwei.tng, 390009620 -\par email: kahwei.tng\@digipen.edu -\date Sep 20, 2021 -\brief Contains the definition of the managed CallbackEvent 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 "CallbackAction.hxx" - -namespace SHADE -{ - /// - /// Holds a set of CallbackActions that can be invoked together at a later time. - /// - /// Type of the first parameter. - generic - public ref class CallbackEvent - { - public: - /*-----------------------------------------------------------------------------*/ - /* Constructors */ - /*-----------------------------------------------------------------------------*/ - /// - /// Default Constructor - /// - CallbackEvent(); - - /*-----------------------------------------------------------------------------*/ - /* Properties */ - /*-----------------------------------------------------------------------------*/ - /// - /// Read only access to the list of Actions - /// - property System::Collections::Generic::IEnumerable^>^ Actions - { - System::Collections::Generic::IEnumerable^>^ get(); - } - - /*-----------------------------------------------------------------------------*/ - /* Usage Functions */ - /*-----------------------------------------------------------------------------*/ - /// - /// Adds the specified CallbackAction to the CallbackEvent. - /// - /// CallbackAction to add. - void AddAction(CallbackAction^ action); - /// - /// Adds a specified static method as a CallbackAction to the CallbackEvent. - /// - /// Method to add. - void AddAction(System::Reflection::MethodInfo^ method); - /// - /// Adds a specified instance method and associated object as a CallbackAction to - /// the CallbackEvent. - /// - /// Method to add. - /// Object that will call the specified method. - void AddAction(System::Reflection::MethodInfo^ method, System::Object^ object); - /// - /// Removes the specified CallbackAction from the CallbackEvent. - /// - /// CallbackAction to remove. - void RemoveAction(CallbackAction^ action); - /// - /// Invokes all CallbackActions registered with this CallbackEvent with the - /// specified parameters. - /// - /// - void Invoke(T1 param1); - - private: - /*-----------------------------------------------------------------------------*/ - /* Data Members */ - /*-----------------------------------------------------------------------------*/ - System::Collections::Generic::List^>^ actions; - }; -} \ No newline at end of file From 7ddf665460b326c3872338da35ec8e8051cb83ff Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 22 Sep 2022 12:12:44 +0800 Subject: [PATCH 15/37] Updated Descriptor sets Descriptor set layouts now have set index stored in them It should be noted that when passed into a pipeline layout as global descriptor sets, these don't matter since the pipeline layout will use these in the order that they are passed in. --- .../Descriptors/SHDescriptorSetUpdater.cpp | 22 ---- .../Descriptors/SHDescriptorSetUpdater.h | 6 -- .../Descriptors/SHVkDescriptorSetGroup.cpp | 102 +++++++++++++----- .../Descriptors/SHVkDescriptorSetGroup.h | 22 +++- .../Descriptors/SHVkDescriptorSetLayout.cpp | 10 +- .../Descriptors/SHVkDescriptorSetLayout.h | 4 +- .../Graphics/Devices/SHVkLogicalDevice.cpp | 4 +- .../src/Graphics/Devices/SHVkLogicalDevice.h | 2 +- .../src/Graphics/Images/SHVkSampler.cpp | 5 + .../src/Graphics/Images/SHVkSampler.h | 1 + .../GlobalData/SHGraphicsGlobalData.cpp | 8 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 8 +- .../MiddleEnd/Interface/SHRenderer.cpp | 6 ++ .../Graphics/Pipeline/SHVkPipelineLayout.cpp | 2 +- SHADE_Engine/src/Graphics/SHVkUtil.cpp | 10 ++ SHADE_Engine/src/Graphics/SHVkUtil.h | 2 + SHADE_Engine/src/Graphics/SHVulkanDefines.h | 2 + SHADE_Engine/src/Graphics/SHVulkanIncludes.h | 1 + .../src/Graphics/Shaders/SHShaderReflected.h | 2 - .../ShaderDescriptorDefinitions.glsl | 11 ++ TempShaderFolder/TestCubeVs.glsl | 8 ++ TempShaderFolder/TestCubeVs.spv | Bin 1428 -> 1680 bytes 22 files changed, 163 insertions(+), 75 deletions(-) create mode 100644 TempShaderFolder/ShaderDescriptorDefinitions.glsl diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp index a1b1cbc2..6cd7ddfd 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.cpp @@ -20,23 +20,6 @@ namespace SHADE } - /***************************************************************************/ - /*! - - \brief - Links the write infos to the vulkan write descriptor sets. - - */ - /***************************************************************************/ - void SHDescriptorSetUpdater::LinkInfoToWriteDescSet(void) noexcept - { - for (uint32_t i = 0; i < writeInfos.size(); ++i) - { - writeDescSets[i].pImageInfo = writeInfos[i].descImageInfos.data(); - writeDescSets[i].pBufferInfo = writeInfos[i].descBufferInfos.data(); - writeDescSets[i].pTexelBufferView = writeInfos[i].descTexelBufferInfos.data(); - } - } SHDescriptorWriteInfo& SHDescriptorWriteInfo::operator=(SHDescriptorWriteInfo&& rhs) noexcept { @@ -65,11 +48,6 @@ namespace SHADE } - std::vector const& SHDescriptorSetUpdater::GetWriteDescriptorSets(void) const noexcept - { - return writeDescSets; - } - SHDescriptorSetUpdater& SHDescriptorSetUpdater::operator=(SHDescriptorSetUpdater&& rhs) noexcept { if (&rhs == this) diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h index 7a5ae967..8595d2a0 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHDescriptorSetUpdater.h @@ -41,10 +41,6 @@ namespace SHADE //! When we want to update a write, we need to use this to identify the index of the write. std::unordered_map writeHashMap; - //! We keep this here because we want this to be immediately passable to vkUpdateDescriptorSets - std::vector writeDescSets; - - void LinkInfoToWriteDescSet(void) noexcept; public: SHDescriptorSetUpdater (void) noexcept; @@ -52,8 +48,6 @@ namespace SHADE SHDescriptorSetUpdater& operator= (SHDescriptorSetUpdater&& rhs) noexcept; public: - std::vector const& GetWriteDescriptorSets (void) const noexcept; - friend class SHVkDescriptorSetGroup; }; } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index 4e83d319..f579d377 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -7,6 +7,11 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" #include "Tools/SHLogger.h" +#include "Graphics/Images/SHVkImage.h" +#include "Graphics/Images/SHVkImageView.h" +#include "Graphics/Images/SHVkSampler.h" +#include "Graphics/Buffers/SHVkBuffer.h" +#include "Graphics/SHVkUtil.h" namespace SHADE { @@ -39,6 +44,7 @@ namespace SHADE : device{deviceHdl} , descPool {pool} , descSets{} + , layoutsUsed {layouts} { // Create the layout for each concurrent frame std::vector vkLayouts{ layouts.size() }; @@ -47,6 +53,7 @@ namespace SHADE for (uint32_t i = 0; i < layouts.size(); ++i) { vkLayouts[i] = layouts[i]->GetVkHandle(); + setIndexing.emplace(layouts[i]->GetSetIndex(), i); } // Check for variable descriptor count @@ -73,34 +80,22 @@ namespace SHADE // allocate descriptor sets descSets = device->GetVkLogicalDevice().allocateDescriptorSets(DESC_SET_LAYOUT_CREATE_INFO); - - - // Now we want to prepare the write descriptor sets for writing later. + // Now we want to prepare the write descriptor sets info for writing later. for (uint32_t i = 0; i < layouts.size(); ++i) { auto const& bindings = layouts[i]->GetBindings(); for (auto& binding : bindings) { BindingAndSetHash writeHash = binding.BindPoint; - writeHash |= static_cast(i) << 32; + writeHash |= static_cast(layouts[i]->GetSetIndex()) << 32; // new write for the binding updater.writeInfos.emplace_back(); updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1); auto& writeInfo = updater.writeInfos.back(); - updater.writeDescSets.emplace_back(); - auto& writeDescSet = updater.writeDescSets.back(); - - // Initialize info for write - writeDescSet.descriptorType = binding.Type; - writeDescSet.dstArrayElement = 0; - writeDescSet.dstSet = descSets[i]; - writeDescSet.dstBinding = binding.BindPoint; - // Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in uint32_t descriptorCount = (binding.flags & vk::DescriptorBindingFlagBits::eVariableDescriptorCount) ? variableDescCounts[i] : 1; - writeDescSet.descriptorCount = descriptorCount; switch (binding.Type) { @@ -114,8 +109,10 @@ namespace SHADE case vk::DescriptorType::eUniformTexelBuffer: case vk::DescriptorType::eStorageTexelBuffer: case vk::DescriptorType::eUniformBuffer: + case vk::DescriptorType::eUniformBufferDynamic: case vk::DescriptorType::eStorageBuffer: - writeInfo.descImageInfos.resize (descriptorCount); + case vk::DescriptorType::eStorageBufferDynamic: + writeInfo.descBufferInfos.resize (descriptorCount); break; //case vk::DescriptorType::eUniformBufferDynamic: // break; @@ -130,8 +127,6 @@ namespace SHADE } } } - // Link all the writeDescSet data for vkUpdateDescriptorSets to write to the linked descriptors - updater.LinkInfoToWriteDescSet(); } /***************************************************************************/ @@ -160,7 +155,7 @@ namespace SHADE */ /***************************************************************************/ - void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::vector> const& imageViewsAndSamplers) noexcept + void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span, Handle>> const& imageViewsAndSamplers) noexcept { // Find the target writeDescSet BindingAndSetHash writeHash = binding; @@ -176,32 +171,81 @@ namespace SHADE { // write sampler and image view auto& ivs = imageViewsAndSamplers[i]; - writeInfo.descImageInfos[i].imageView = ivs.first; - writeInfo.descImageInfos[i].sampler = ivs.second; + writeInfo.descImageInfos[i].imageView = ivs.first->GetImageView(); + writeInfo.descImageInfos[i].sampler = ivs.second->GetVkSampler(); } } - - void SHVkDescriptorSetGroup::UpdateDescriptorSet(void) noexcept + void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span> const& buffers) noexcept { - device->UpdateDescriptorSets(updater.GetWriteDescriptorSets()); + // Find the target writeDescSet + BindingAndSetHash writeHash = binding; + writeHash |= static_cast(set) << 32; + auto& writeInfo = updater.writeInfos[updater.writeHashMap.at(writeHash)]; + + if (buffers.size() > writeInfo.descBufferInfos.size()) + { + SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. "); + } + + for (uint32_t i = 0; i < buffers.size(); ++i) + { + // write sampler and image view + auto& buffer = buffers[i]; + writeInfo.descBufferInfos[i].buffer = buffer->GetVkBuffer(); + } + } - - void SHVkDescriptorSetGroup::UpdateSingleDescriptorSetImages(uint32_t set, uint32_t binding) noexcept + void SHVkDescriptorSetGroup::UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept { vk::WriteDescriptorSet writeDescSet{}; + // Get binding + set hash + BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); + + // to index a set + uint32_t setIndex = setIndexing[bsHash]; + + // to index a write for a binding + uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; + // Initialize info for write - writeDescSet.descriptorType = vk::DescriptorType::eCombinedImageSampler; + writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; writeDescSet.dstArrayElement = 0; - writeDescSet.dstSet = descSets[set]; + writeDescSet.dstSet = descSets[setIndex]; writeDescSet.dstBinding = binding; - writeDescSet.pImageInfo = updater.writeInfos[set].descImageInfos.data(); - writeDescSet.descriptorCount = static_cast(updater.writeInfos[set].descImageInfos.size()); + writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data(); + writeDescSet.descriptorCount = static_cast(updater.writeInfos[writeInfoIndex].descImageInfos.size()); device->UpdateDescriptorSet(writeDescSet); } + void SHVkDescriptorSetGroup::UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept + { + vk::WriteDescriptorSet writeDescSet{}; + + // Get binding + set hash + BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); + + // to index a set + uint32_t setIndex = setIndexing[bsHash]; + + // to index a write for a binding + uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; + + // Initialize info for write + writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; + writeDescSet.dstArrayElement = 0; + writeDescSet.dstSet = descSets[setIndex]; + writeDescSet.dstBinding = binding; + + writeDescSet.pBufferInfo = updater.writeInfos[writeInfoIndex].descBufferInfos.data(); + writeDescSet.descriptorCount = static_cast(updater.writeInfos[writeInfoIndex].descBufferInfos.size()); + + device->UpdateDescriptorSet(writeDescSet); + + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index b65fb1e6..bc87ff1d 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -14,6 +14,10 @@ namespace SHADE class SHVkLogicalDevice; class SHVkDescriptorPool; class SHVkDescriptorSetLayout; + class SHVkSampler; + class SHVkImage; + class SHVkImageView; + class SHVkBuffer; /*---------------------------------------------------------------------------------*/ @@ -54,12 +58,14 @@ namespace SHADE SHVkDescriptorSetGroup& operator=(SHVkDescriptorSetGroup&& rhs) noexcept = default; /*-----------------------------------------------------------------------------*/ - /* Descriptor set writing */ + /* Public member functions */ /*-----------------------------------------------------------------------------*/ - void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::vector> const& imageViewsAndSamplers) noexcept; - void UpdateDescriptorSet(void) noexcept; + void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept; + void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept; + + void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span, Handle>> const& imageViewsAndSamplers) noexcept; + void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span> const& buffers) noexcept; - void UpdateSingleDescriptorSetImages(uint32_t set, uint32_t binding) noexcept; /*-----------------------------------------------------------------------------*/ /* Getter Functions */ @@ -81,9 +87,17 @@ namespace SHADE //! Descriptor pool to allocate descriptor sets Handle descPool; + //! Sometimes when we pass in a layout, the set of the layout used in the + //! shader cannot be used to index into descSets. This is to mitigate that issue + //! when we update descriptor sets. + std::unordered_map setIndexing; + //! Descriptor sets std::vector descSets; + //! Layouts used to create this descriptor set group + std::vector> layoutsUsed; + //! for updating descriptor sets. We want to cache this so that we don't create the //! write structs at runtime. SHDescriptorSetUpdater updater; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp index da1a3645..002aa29d 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp @@ -7,9 +7,10 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Constructor/Destructor */ /*---------------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, const std::vector& bindings) + SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, SetIndex set, const std::vector& bindings) : device { device } , layoutDesc { bindings } + , setIndex {set} { // Check if auto-binding point calculation configuration is valid bool autoCalc = false; @@ -74,6 +75,7 @@ namespace SHADE : device {rhs.device} , setLayout {rhs.setLayout} , layoutDesc{std::move (rhs.layoutDesc)} + , setIndex {rhs.setIndex} { rhs.setLayout = VK_NULL_HANDLE; } @@ -90,6 +92,11 @@ namespace SHADE return layoutDesc; } + SetIndex SHVkDescriptorSetLayout::GetSetIndex(void) const noexcept + { + return setIndex; + } + SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept { if (&rhs == this) @@ -98,6 +105,7 @@ namespace SHADE device = rhs.device; setLayout = rhs.setLayout; layoutDesc = std::move(rhs.layoutDesc); + setIndex = rhs.setIndex; rhs.setLayout = VK_NULL_HANDLE; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h index 1acba189..9b436026 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h @@ -74,7 +74,7 @@ namespace SHADE /// /// /// - SHVkDescriptorSetLayout(Handle device, const std::vector& bindings); + SHVkDescriptorSetLayout(Handle device, SetIndex setIndex, const std::vector& bindings); SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete; SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept; /// @@ -97,6 +97,7 @@ namespace SHADE /// Handle to the Vulkan Descriptor Set Layout handle. inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; } std::vector const& GetBindings (void) const noexcept; + SetIndex GetSetIndex (void) const noexcept; private: /*-----------------------------------------------------------------------------*/ @@ -105,5 +106,6 @@ namespace SHADE Handle device; vk::DescriptorSetLayout setLayout; std::vector layoutDesc; // Stores description of the layout + SetIndex setIndex; // Index of the set }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index a956af2c..64508a2b 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -510,9 +510,9 @@ namespace SHADE } - Handle SHVkLogicalDevice::CreateDescriptorSetLayout(std::vector const& bindings) noexcept + Handle SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector const& bindings) noexcept { - return SHVkInstance::GetResourceManager().Create (GetHandle(), bindings); + return SHVkInstance::GetResourceManager().Create (GetHandle(), setIndex, bindings); } diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 6c59572a..365e68c9 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -182,7 +182,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 (std::vector const& bindings) noexcept; + Handle CreateDescriptorSetLayout (SetIndex setIndex, std::vector const& bindings) 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 e7a97126..b4bbf89b 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp @@ -4,4 +4,9 @@ namespace SHADE { + vk::Sampler SHVkSampler::GetVkSampler(void) const noexcept + { + return vkSampler; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.h b/SHADE_Engine/src/Graphics/Images/SHVkSampler.h index d58edb8f..eae23adf 100644 --- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.h +++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.h @@ -22,6 +22,7 @@ namespace SHADE SHVkSampler (SHVkSampler&& rhs) noexcept; SHVkSampler&& operator=(SHVkSampler&& rhs) noexcept; + vk::Sampler GetVkSampler (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index 5289b635..d9ffa6b5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -27,7 +27,7 @@ namespace SHADE }; // For global data (generic data and textures) - Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ genericDataBinding, texturesBinding }); + Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,{ genericDataBinding, texturesBinding }); SHVkDescriptorSetLayout::Binding lightBinding { @@ -38,7 +38,7 @@ namespace SHADE }; // For Dynamic global data (lights) - Handle dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ lightBinding }); + Handle dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, { lightBinding }); SHVkDescriptorSetLayout::Binding cameraDataBinding { @@ -49,7 +49,7 @@ namespace SHADE }; // For High frequency global data (camera) - Handle cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ cameraDataBinding }); + Handle cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding }); SHVkDescriptorSetLayout::Binding materialDataBinding { @@ -60,7 +60,7 @@ namespace SHADE }; // For High frequency global data (camera) - Handle materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding }); + Handle materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding }); globalDescSetLayouts.push_back(staticGlobalLayout); globalDescSetLayouts.push_back(dynamicGlobalLayout); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index b38fa275..1026d01b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -204,6 +204,7 @@ namespace SHADE { // Frame data for the current frame auto const& frameData = renderContext.GetCurrentFrameData(); + uint32_t frameIndex = renderContext.GetCurrentFrame(); // semaphore index. This is for render graphs to have semaphores to signal that the next render graph will use to wait on. bool semIndex = 0; @@ -233,7 +234,7 @@ namespace SHADE /* Renderer start */ /*-----------------------------------------------------------------------*/ // get command buffer of the renderer in the current frame - auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(renderContext.GetCurrentFrame()); + auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(frameIndex); // Begin recording the command buffer currentCmdBuffer->BeginRecording(); @@ -247,8 +248,11 @@ namespace SHADE currentCmdBuffer->BindIndexBuffer(buffer, 0); } + // bind camera data + renderers[renIndex]->BindDescriptorSet(currentCmdBuffer, frameIndex); + // Draw first - renderers[renIndex]->Draw(renderContext.GetCurrentFrame()); + renderers[renIndex]->Draw(frameIndex); // End the command buffer recording currentCmdBuffer->EndRecording(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index 223ceb4f..fd702968 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -42,6 +42,12 @@ namespace SHADE cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData)); cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + + std::array cameraBufferArray{cameraBuffer}; + + cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}); + + cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA); } /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index cc738aed..fc40f394 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -198,7 +198,7 @@ namespace SHADE // 1 descriptor set layout for every descriptor set detected. for (auto const& set : setsWithBindings) { - auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.second); + auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.first, set.second); descriptorSetLayoutsAllocate.push_back(newDescriptorSetLayout); } diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.cpp b/SHADE_Engine/src/Graphics/SHVkUtil.cpp index c570caf2..e4f9f37e 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.cpp +++ b/SHADE_Engine/src/Graphics/SHVkUtil.cpp @@ -71,4 +71,14 @@ namespace SHADE ); } } + + BindingAndSetHash SHVkUtil::GenBindingSetHash(uint32_t set, uint32_t binding) noexcept + { + // Find the target writeDescSet + BindingAndSetHash writeHash = binding; + writeHash |= static_cast(set) << 32; + + return writeHash; + } + } diff --git a/SHADE_Engine/src/Graphics/SHVkUtil.h b/SHADE_Engine/src/Graphics/SHVkUtil.h index 46ebf096..cba5b062 100644 --- a/SHADE_Engine/src/Graphics/SHVkUtil.h +++ b/SHADE_Engine/src/Graphics/SHVkUtil.h @@ -76,6 +76,8 @@ namespace SHADE */ /***********************************************************************************/ static void EnsureBufferAndCopyHostVisibleData(Handle device, Handle& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); + + static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/SHVulkanDefines.h b/SHADE_Engine/src/Graphics/SHVulkanDefines.h index 542f379d..2f625f7e 100644 --- a/SHADE_Engine/src/Graphics/SHVulkanDefines.h +++ b/SHADE_Engine/src/Graphics/SHVulkanDefines.h @@ -6,6 +6,8 @@ namespace SHADE { using SHQueueFamilyIndex = uint32_t; + using BindingAndSetHash = uint64_t; + using SetIndex = uint32_t; } diff --git a/SHADE_Engine/src/Graphics/SHVulkanIncludes.h b/SHADE_Engine/src/Graphics/SHVulkanIncludes.h index 472226a0..63aa672b 100644 --- a/SHADE_Engine/src/Graphics/SHVulkanIncludes.h +++ b/SHADE_Engine/src/Graphics/SHVulkanIncludes.h @@ -6,5 +6,6 @@ #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 #define VULKAN_HPP_NO_NODISCARD_WARNINGS #include +#include "Graphics/SHVulkanDefines.h" #endif diff --git a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h index 88c7a2e1..3986f823 100644 --- a/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h +++ b/SHADE_Engine/src/Graphics/Shaders/SHShaderReflected.h @@ -9,8 +9,6 @@ namespace SHADE { - using BindingAndSetHash = uint64_t; - struct SHShaderDescriptorBindingInfo { private: diff --git a/TempShaderFolder/ShaderDescriptorDefinitions.glsl b/TempShaderFolder/ShaderDescriptorDefinitions.glsl new file mode 100644 index 00000000..c70a9f5b --- /dev/null +++ b/TempShaderFolder/ShaderDescriptorDefinitions.glsl @@ -0,0 +1,11 @@ +#define SET_STATIC_GLOBALS 0 +#define SET_DYNAMIC_GLOBALS 1 +#define SET_HIGH_FREQUENCY_GLOBALS 2 + +#define BINDING_GENERIC_DATA 0 +#define BINDING_IMAGE_AND_SAMPLERS_DATA 1 +#define BINDING_LIGHTS_DATA 0 +#define BINDING_CAMERA_DATA 0 +#define BINDING_BATCHED_PER_INST_DATA 0 + + diff --git a/TempShaderFolder/TestCubeVs.glsl b/TempShaderFolder/TestCubeVs.glsl index f7dce787..08c465a0 100644 --- a/TempShaderFolder/TestCubeVs.glsl +++ b/TempShaderFolder/TestCubeVs.glsl @@ -1,6 +1,8 @@ #version 450 #extension GL_KHR_vulkan_glsl : enable +//#include "ShaderDescriptorDefinitions.glsl" + layout(location = 0) in vec3 aVertexPos; layout(location = 1) in vec2 aUV; layout(location = 2) in vec3 aNormal; @@ -28,6 +30,12 @@ layout(location = 0) out struct } Out; +layout(set = 2, binding = 0) uniform CameraData +{ + vec4 position; + mat4 vpMat; +} cameraData; + void main() { //const float gamma = testPushConstant.eyePosition.w; diff --git a/TempShaderFolder/TestCubeVs.spv b/TempShaderFolder/TestCubeVs.spv index 2b0d3b93c0c4a570f997eae1f3763e05cb6cbbab..be24aa3a944eff08f83a27869e46ef93dcc93eae 100644 GIT binary patch delta 293 zcmbQjJ%N{(nMs+Qfq{{Mi-DIxe#voP(Rt6mg1_tNE+|;5(m&B4p1_m}D1c`w_ zL4I*&NoIZ?h|LC7%Lrtb75FBW0BMkZJs_P7*FX6kw9PW?IXrD+jd@ dWRNBhD**YrKpLbGp;Bdp1`vZ(-aV!)n3^0DNT#AOHXW From 5bc24b09d4ef27acb4a23d89ccb939528a142e40 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 12:31:26 +0800 Subject: [PATCH 16/37] Added generalisation of csproj file location --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 107 ++++++++++-------- SHADE_Engine/src/Scripting/SHScriptEngine.h | 9 +- TempScriptsFolder/TestScript.cs | 11 ++ 3 files changed, 77 insertions(+), 50 deletions(-) create mode 100644 TempScriptsFolder/TestScript.cs diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 78b4d544..56f93812 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -22,14 +22,16 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - /*--------------------------------------------------------------------------------*/ - /* Static Definitions */ - /*--------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Static Definitions */ + /*----------------------------------------------------------------------------------*/ const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE"); + const std::string SHScriptEngine::CSPROJ_DIR = "..\\..\\TempScriptsFolder"; + const std::string SHScriptEngine::CSPROJ_PATH = std::string(CSPROJ_DIR) + "\\SHADE_Scripting.csproj"; - /*---------------------------------------------------------------------------------*/ - /* Lifecycle Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Lifecycle Functions */ + /*-----------------------------------------------------------------------------------*/ void SHScriptEngine::Init() { // Do not allow initialization if already initialised @@ -99,9 +101,9 @@ namespace SHADE dotNet.Exit(); } - /*---------------------------------------------------------------------------------*/ - /* Script Manipulation Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Script Manipulation Functions */ + /*-----------------------------------------------------------------------------------*/ bool SHScriptEngine::AddScript(const SHEntity& entity, const std::string_view& scriptName) { return csScriptsAdd(entity.GetEID(), scriptName.data()); @@ -140,41 +142,40 @@ namespace SHADE return result; } - /*---------------------------------------------------------------------------------*/ - /* Script Serialisation Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Script Serialisation Functions */ + /*-----------------------------------------------------------------------------------*/ void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml) const { csScriptDeserialise(entity.GetEID(), yaml.c_str()); } - /*---------------------------------------------------------------------------------*/ - /* Script Editor Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Script Editor Functions */ + /*-----------------------------------------------------------------------------------*/ void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity) const { csEditorRenderScripts(entity.GetEID()); } - /*---------------------------------------------------------------------------------*/ - /* Static Utility Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Static Utility Functions */ + /*-----------------------------------------------------------------------------------*/ bool SHScriptEngine::BuildScriptAssembly(bool debug) const { - constexpr std::string_view BUILD_LOG_PATH = "../Build.log"; + static const std::string BUILD_LOG_PATH = "../Build.log"; // Generate csproj file if it doesn't exist - static const std::filesystem::path CSPROJ_PATH = "../SHADE_Scripting.csproj"; if (!std::filesystem::exists(CSPROJ_PATH)) { GenerateScriptsCsProjFile(CSPROJ_PATH); } // Prepare directory (delete useless files) - deleteFolder("net5.0"); - deleteFolder("ref"); - deleteFolder("../SHADE_Scripting"); - deleteFolder("../obj"); + deleteFolder(CSPROJ_DIR + "\\net5.0"); + deleteFolder(CSPROJ_DIR + "\\ref"); + deleteFolder(CSPROJ_DIR + "\\obj"); + deleteFolder(CSPROJ_DIR + "\\bin"); // Attempt to build the assembly std::ostringstream oss; @@ -184,7 +185,7 @@ namespace SHADE const bool BUILD_SUCCESS = execProcess ( L"C:\\Windows\\system32\\cmd.exe", - L"/K \"dotnet build \"../SHADE_Scripting.csproj\" -c Debug -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet & exit\"" + L"/K \"" + generateBuildCommand(debug) + L" & exit\"" ) == 0; if (BUILD_SUCCESS) { @@ -202,6 +203,7 @@ namespace SHADE // Clean up built files deleteFolder("./tmp"); + deleteFolder(CSPROJ_DIR + "\\obj"); // Read the build log and output to the console dumpBuildLog(BUILD_LOG_PATH); @@ -209,7 +211,7 @@ namespace SHADE deleteFile(BUILD_LOG_PATH); return BUILD_SUCCESS; - } + } void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path) const { @@ -222,11 +224,11 @@ namespace SHADE Release;Debug\n\ \n\ \n\ - .\\bin_Release-x64\n\ + .\\bin\\Release\n\ x64\n\ \n\ \n\ - .\\bin_Debug-x64\n\ + .\\bin\\Debug\n\ x64\n\ DEBUG;TRACE\n\ false\n\ @@ -245,7 +247,8 @@ namespace SHADE \n\ \n\ \n\ - .\\bin\\SHADE_Managed.dll\n\ + ..\\bin\\Debug\\SHADE_Managed.dll\ + ..\\bin\\Release\\SHADE_Managed.dll\ \n\ \n\ "; @@ -262,9 +265,9 @@ namespace SHADE file.close(); } - /*---------------------------------------------------------------------------------*/ - /* Helper Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ void SHScriptEngine::loadFunctions() { std::ostringstream oss; @@ -404,25 +407,25 @@ namespace SHADE } } } - void SHScriptEngine::deleteFile(const std::string_view& filePath) + void SHScriptEngine::deleteFile(const std::string& filePath) { - try - { - std::filesystem::remove(std::filesystem::canonical(filePath)); - } - catch (...) {} // Ignore deletion failures - } - - void SHScriptEngine::deleteFolder(const std::string_view& filePath) + try { - try - { - std::filesystem::remove_all(std::filesystem::canonical(filePath)); - } - catch (...) {} // Ignore deletion failures + std::filesystem::remove(std::filesystem::canonical(filePath)); } + catch (...) {} // Ignore deletion failures + } + + void SHScriptEngine::deleteFolder(const std::string& filePath) + { + try + { + std::filesystem::remove_all(std::filesystem::canonical(filePath)); + } + catch (...) {} // Ignore deletion failures + } - bool SHScriptEngine::fileExists(const std::string_view& filePath) + bool SHScriptEngine::fileExists(const std::filesystem::path& filePath) { std::error_code error; if (std::filesystem::exists(filePath, error)) @@ -483,4 +486,14 @@ namespace SHADE } } } + + std::wstring SHScriptEngine::generateBuildCommand(bool debug) + { + std::wostringstream oss; + oss << "dotnet build \"" << SHStringUtils::StrToWstr(CSPROJ_PATH) << "\" -c "; + oss << debug ? "Debug" : "Release"; + oss << " -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet"; + return oss.str(); + } + } diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index f3d69dd5..fa205266 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -208,6 +208,8 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ static constexpr std::string_view DEFAULT_CSHARP_LIB_NAME = "SHADE_Managed"; static constexpr std::string_view MANAGED_SCRIPT_LIB_NAME = "SHADE_Scripting"; + static const std::string CSPROJ_DIR; + static const std::string CSPROJ_PATH; static const std::string DEFAULT_CSHARP_NAMESPACE; /*-----------------------------------------------------------------------------*/ @@ -260,18 +262,19 @@ namespace SHADE /// Deletes the file as specified by the file path. /// /// File path to the file to delete. - static void deleteFile(const std::string_view& filePath); + static void deleteFile(const std::string& filePath); /// /// Deletes the folder and all files in it as specified by the file path. /// /// File path to the file to delete. - static void deleteFolder(const std::string_view& filePath); + static void deleteFolder(const std::string& filePath); /// /// Checks if a specified file exists. /// /// File path to the file to check. /// True if the file exists - static bool fileExists(const std::string_view& filePath); + static bool fileExists(const std::filesystem::path& filePath); static DWORD execProcess(const std::wstring& path, const std::wstring& args); + static std::wstring generateBuildCommand(bool debug); }; } diff --git a/TempScriptsFolder/TestScript.cs b/TempScriptsFolder/TestScript.cs new file mode 100644 index 00000000..0e4823a2 --- /dev/null +++ b/TempScriptsFolder/TestScript.cs @@ -0,0 +1,11 @@ +using SHADE; + +public class TestScript : Script +{ + public TestScript(GameObject gameObj) : base(gameObj) {} + + protected override void update() + { + Debug.Log("TestScript.Update()"); + } +} \ No newline at end of file From e87c4c8dc846a5c391905f48e7dbba663e2b3742 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 12:39:05 +0800 Subject: [PATCH 17/37] Fixed SHTextureLibrary compiler errors --- .../MiddleEnd/Textures/SHTextureLibrary.cpp | 2 +- .../Graphics/MiddleEnd/Textures/SHTextureLibrary.h | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index 3be4dd11..80be81df 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -26,7 +26,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ /* Usage Functions */ /*---------------------------------------------------------------------------------*/ - Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels) + Handle SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, uint32_t mipLevels) { isDirty = true; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h index d30b02ed..5cf974ef 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.h @@ -18,6 +18,7 @@ of DigiPen Institute of Technology is prohibited. #include "Resource/Handle.h" #include "Resource/ResourceLibrary.h" #include "Math/SHMath.h" +#include "Graphics/SHVulkanIncludes.h" namespace SHADE { @@ -27,6 +28,11 @@ namespace SHADE class SHVkBuffer; class SHVkLogicalDevice; class SHVkCommandBuffer; + class SHVkImage; + class SHVkImageView; + class SHVkQueue; + class SHVkDescriptorPool; + class SHVkDescriptorSetLayout; /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -37,7 +43,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------*/ - using PixelChannel = void; + using PixelChannel = float; using TextureFormat = vk::Format; // TODO: Change using Index = uint32_t; @@ -82,7 +88,7 @@ namespace SHADE */ /*******************************************************************************/ - Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, int mipLevels); + Handle Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, uint32_t mipLevels); /*******************************************************************************/ /*! @@ -112,7 +118,7 @@ namespace SHADE queue. */ /***************************************************************************/ - void BuildImages(Handle device, Handle cmdBuffer, Handle graphicsQueue); + void BuildImages(Handle device, Handle cmdBuffer, Handle graphicsQueue, Handle descPool, Handle descLayout); /*-----------------------------------------------------------------------------*/ /* Getter Functions */ @@ -128,7 +134,7 @@ namespace SHADE uint32_t PixelCount = 0; const SHTexture::PixelChannel* PixelData = nullptr; SHTexture::TextureFormat TextureFormat = {}; - int MipLevels = 0; + uint32_t MipLevels = 0; Handle Image; Handle Handle; }; From ed143661b376305f4b06942c8eef6f422f62d48a Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 22 Sep 2022 14:26:07 +0800 Subject: [PATCH 18/37] Scene node active states propagate down the hierarchy Vulkan is throwing an exception... --- .../src/Math/Transform/SHTransformSystem.cpp | 2 +- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 77 ++++++++++++++----- SHADE_Engine/src/Scene/SHSceneGraph.h | 25 +++--- 3 files changed, 71 insertions(+), 33 deletions(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 879c2d34..f420834d 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -53,7 +53,7 @@ namespace SHADE for (const auto* child : node->GetChildren()) { // Active states of entities should sync with scene nodes - const bool IS_NODE_ACTIVE = child->isActive; + const bool IS_NODE_ACTIVE = child->IsActive(); #ifdef _DEBUG const bool IS_ENTITY_ACTIVE = SHEntityManager::GetEntityByID(child->GetEntityID())->GetActive(); diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index 82e4fd7e..84c7f1c5 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -25,14 +25,14 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept - : isActive { true } + : active { true } , entityID { eid } , parent { parent } {} SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept - : isActive { rhs.isActive } + : active { rhs.active } , entityID { rhs.entityID } , parent { rhs.parent } { @@ -40,7 +40,7 @@ namespace SHADE } SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept - : isActive { rhs.isActive } + : active { rhs.active } , entityID { rhs.entityID } , parent { rhs.parent } { @@ -52,9 +52,9 @@ namespace SHADE if (this == &rhs) return *this; - isActive = rhs.isActive; - entityID = rhs.entityID; - parent = rhs.parent; + active = rhs.active; + entityID = rhs.entityID; + parent = rhs.parent; children.clear(); std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); @@ -64,9 +64,9 @@ namespace SHADE SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept { - isActive = rhs.isActive; - entityID = rhs.entityID; - parent = rhs.parent; + active = rhs.active; + entityID = rhs.entityID; + parent = rhs.parent; children.clear(); std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children)); @@ -104,6 +104,11 @@ namespace SHADE /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ + bool SHSceneNode::IsActive() const noexcept + { + return active; + } + EntityID SHSceneNode::GetEntityID() const noexcept { return entityID; @@ -154,7 +159,7 @@ namespace SHADE if (root != nullptr) return root; - SHLOG_WARNING("Scene has no root object!") + SHLOG_ERROR("Scene has no root object!") return nullptr; } @@ -171,7 +176,7 @@ namespace SHADE const auto NODE_ITER = entityNodeMap.find(entityID); if (NODE_ITER == entityNodeMap.end()) { - SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID) + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID) return nullptr; } //////////////////////////////////////// @@ -192,7 +197,7 @@ namespace SHADE const auto NODE_ITER = entityNodeMap.find(entityID); if (NODE_ITER == entityNodeMap.end()) { - SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID) + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID) return nullptr; } //////////////////////////////////////// @@ -213,7 +218,7 @@ namespace SHADE const auto NODE_ITER = entityNodeMap.find(entityID); if (NODE_ITER == entityNodeMap.end()) { - SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID) + SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID) return nullptr; } @@ -248,7 +253,7 @@ namespace SHADE const auto NODE_ITER = entityNodeMap.find(entityID); if (NODE_ITER == entityNodeMap.end()) { - SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID) + SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID) return nullptr; } //////////////////////////////////////// @@ -269,7 +274,7 @@ namespace SHADE const auto NODE_ITER = entityNodeMap.find(entityID); if (NODE_ITER == entityNodeMap.end()) { - SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID) + SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID) return root->GetChildren(); } //////////////////////////////////////// @@ -277,6 +282,27 @@ namespace SHADE return NODE_ITER->second->GetChildren(); } + bool SHSceneGraph::IsActiveInHierarchy(EntityID entityID) const noexcept + { + //////////////////////////////////////// + // Error handling + if (!SHEntityManager::IsValidEID(entityID)) + { + SHLOG_ERROR("Entity {} is invalid!", entityID) + return false; + } + + const auto NODE_ITER = entityNodeMap.find(entityID); + if (NODE_ITER == entityNodeMap.end()) + { + SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID) + return false; + } + //////////////////////////////////////// + + return NODE_ITER->second->IsActive(); + } + /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -289,7 +315,7 @@ namespace SHADE } // Handle self assignment - if (parentNode == parent) + if (parent && parentNode->entityID == parent->entityID) return; if (parent) @@ -300,6 +326,16 @@ namespace SHADE parent->AddChild(this); } + void SHSceneNode::SetActive(bool newActiveState) noexcept + { + active = newActiveState; + + for (auto* child : children) + { + SetActive(newActiveState); + } + } + void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept { //////////////////////////////////////// @@ -318,6 +354,9 @@ namespace SHADE } //////////////////////////////////////// + if (parent == nullptr) + parent = root; + NODE_ITER->second->SetParent(parent); } @@ -340,14 +379,14 @@ namespace SHADE auto NODE_ITER = entityNodeMap.find(entityID); if (NODE_ITER == entityNodeMap.end()) { - SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to set parent!", entityID) + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to set parent!", entityID) return; } auto PARENT_ITER = entityNodeMap.find(parent); if (PARENT_ITER == entityNodeMap.end()) { - SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID) + SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID) return; } //////////////////////////////////////// @@ -476,7 +515,7 @@ namespace SHADE auto NODE_ITER = entityNodeMap.find(entityID); if (NODE_ITER == entityNodeMap.end()) { - SHLOG_WARNING("Entity {} does not exist in the scene!", entityID) + SHLOG_ERROR("Entity {} does not exist in the scene!", entityID) return false; } diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index bdb8f52c..39afbb31 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -38,12 +38,6 @@ namespace SHADE friend class SHSceneGraph; public: - /*---------------------------------------------------------------------------------*/ - /* Data Members */ - /*---------------------------------------------------------------------------------*/ - - bool isActive; - /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ @@ -60,6 +54,7 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ + [[nodiscard]] bool IsActive () const noexcept; [[nodiscard]] EntityID GetEntityID () const noexcept; [[nodiscard]] SHSceneNode* GetParent () const noexcept; [[nodiscard]] const std::vector& GetChildren () const noexcept; @@ -70,7 +65,8 @@ namespace SHADE /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetParent (SHSceneNode* parentNode) noexcept; + void SetParent (SHSceneNode* parentNode) noexcept; + void SetActive (bool newActiveState) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ @@ -88,6 +84,7 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ + bool active; EntityID entityID; SHSceneNode* parent; std::vector children; @@ -121,12 +118,14 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] const SHSceneNode* GetRoot () const noexcept; - [[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept; - [[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept; - [[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept; - [[nodiscard]] SHSceneNode* GetChild (EntityID entityID, EntityID childEntityID) const noexcept; - [[nodiscard]] const std::vector& GetChildren (EntityID entityID) const noexcept; + [[nodiscard]] const SHSceneNode* GetRoot () const noexcept; + [[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept; + [[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept; + [[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept; + [[nodiscard]] SHSceneNode* GetChild (EntityID entityID, EntityID childEntityID) const noexcept; + [[nodiscard]] const std::vector& GetChildren (EntityID entityID) const noexcept; + + [[nodiscard]] bool IsActiveInHierarchy (EntityID entityID) const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ From 2d93c9559d0fba3573e471758e85a7ecb20c6da0 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 22 Sep 2022 14:54:06 +0800 Subject: [PATCH 19/37] Restructured Transform system to match intended system structure --- .../src/Math/Transform/SHTransformSystem.cpp | 12 ++++-- .../src/Math/Transform/SHTransformSystem.h | 42 +++++++++++++++---- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 879c2d34..125de0e2 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -21,12 +21,18 @@ namespace SHADE { + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHTransformSystem::TransformUpdateRoutine SHTransformSystem::UpdateRoutine; + /*-----------------------------------------------------------------------------------*/ /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHTransformSystem::SHTransformSystem() - : SHSystemRoutine { "Transform Routine", false } + SHTransformSystem::TransformUpdateRoutine::TransformUpdateRoutine() + : SHSystemRoutine { "Transform Update", false } {} @@ -34,7 +40,7 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHTransformSystem::Execute(double dt) noexcept + void SHTransformSystem::TransformUpdateRoutine::Execute(double dt) noexcept { // Get the current scene graph to traverse and update const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index 5eebd292..4d62475a 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -21,19 +21,18 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - class SH_API SHTransformSystem : public SHSystemRoutine + class SH_API SHTransformSystem : public SHSystem { public: - /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ /*---------------------------------------------------------------------------------*/ - SHTransformSystem (); - ~SHTransformSystem () = default; + SHTransformSystem () = default; + ~SHTransformSystem () = default; - SHTransformSystem (const SHTransformSystem&) = delete; - SHTransformSystem (SHTransformSystem&&) = delete; + SHTransformSystem (const SHTransformSystem&) = delete; + SHTransformSystem (SHTransformSystem&&) = delete; /*---------------------------------------------------------------------------------*/ /* Operator Overloads */ @@ -43,10 +42,37 @@ namespace SHADE SHTransformSystem& operator= (SHTransformSystem&&) = delete; /*---------------------------------------------------------------------------------*/ - /* Function Members */ + /* System Routines */ /*---------------------------------------------------------------------------------*/ - void Execute(double dt) noexcept override; + class TransformUpdateRoutine : public SHSystemRoutine + { + public: + /*-------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-------------------------------------------------------------------------------*/ + + TransformUpdateRoutine (); + ~TransformUpdateRoutine () = default; + + TransformUpdateRoutine (const TransformUpdateRoutine&) = delete; + TransformUpdateRoutine (TransformUpdateRoutine&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-------------------------------------------------------------------------------*/ + + TransformUpdateRoutine& operator= (const TransformUpdateRoutine&) = delete; + TransformUpdateRoutine& operator= (TransformUpdateRoutine&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + void Execute(double dt) noexcept override; + }; + + static TransformUpdateRoutine UpdateRoutine; private: /*---------------------------------------------------------------------------------*/ From cda7330c5b92731c43157d1cfb0bde71d79360d6 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 22 Sep 2022 14:56:58 +0800 Subject: [PATCH 20/37] Removed static data member for transform update routine --- SHADE_Engine/src/Math/Transform/SHTransformSystem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index 4d62475a..c57cbdbd 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -72,7 +72,7 @@ namespace SHADE void Execute(double dt) noexcept override; }; - static TransformUpdateRoutine UpdateRoutine; + //static TransformUpdateRoutine UpdateRoutine; private: /*---------------------------------------------------------------------------------*/ From 38dbd0c2179bb0e15084307ccad587a3f80aab2f Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 22 Sep 2022 15:49:00 +0800 Subject: [PATCH 21/37] Removed static data member...again... --- SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index f229cbdd..adbdf746 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -25,7 +25,7 @@ namespace SHADE /* Static Data Member Definitions */ /*-----------------------------------------------------------------------------------*/ - SHTransformSystem::TransformUpdateRoutine SHTransformSystem::UpdateRoutine; + //SHTransformSystem::TransformUpdateRoutine SHTransformSystem::UpdateRoutine; /*-----------------------------------------------------------------------------------*/ /* Constructors & Destructor Definitions */ @@ -40,7 +40,7 @@ namespace SHADE /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHTransformSystem::TransformUpdateRoutine::Execute(double dt) noexcept + void SHTransformSystem::TransformUpdateRoutine::Execute(double) noexcept { // Get the current scene graph to traverse and update const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); From 3b533ac03d73cda934791767ca1452ce74c7c796 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 16:40:49 +0800 Subject: [PATCH 22/37] Added faulty registration to entityDestroyed event --- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 45 +++++++++++++------ SHADE_Engine/src/Scripting/SHScriptEngine.h | 13 +++++- TempScriptsFolder/TestScript.cs | 12 +++++ 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 56f93812..fada5b70 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -16,9 +16,14 @@ of DigiPen Institute of Technology is prohibited. // Standard Library #include // std::fstream #include // std::filesystem::canonical, std::filesystem::remove +#include // std::shared_ptr // Project Headers #include "Tools/SHLogger.h" #include "Tools/SHStringUtils.h" +#include "ECS_Base/Events/SHEntityDestroyedEvent.h" +#include "Events/SHEvent.h" +#include "Events/SHEventReceiver.h" +#include "Events/SHEventManager.hpp" namespace SHADE { @@ -54,15 +59,9 @@ namespace SHADE // Initialise the CSharp Engine csEngineInit(); - - // Link events - // - Entity Destruction - /*onEntityDestroy = [this](const SHEntity& e) - { - csScriptsRemoveAll(e.GetEID()); - csGOLibNotifyDestroyEntity(e.GetEID()); - }; - ECS::OnEntityDestroy += onEntityDestroy;*/ + + // Register entity creation events + registerEvents(); } void SHScriptEngine::UnloadScriptAssembly() { @@ -257,13 +256,23 @@ namespace SHADE std::ofstream file(path); if (!file.is_open()) throw std::runtime_error("Unable to create CsProj file!"); - + // Fill the file file << FILE_CONTENTS; - + // Close file.close(); - } + } + + /*-----------------------------------------------------------------------------------*/ + /* Event Handler Functions */ + /*-----------------------------------------------------------------------------------*/ + SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr) + { + auto eventData = reinterpret_cast*>(eventPtr.get()); + csScriptsRemoveAll(eventData->data->eid); + return eventData->handle; + } /*-----------------------------------------------------------------------------------*/ /* Helper Functions */ @@ -385,6 +394,17 @@ namespace SHADE );*/ } + void SHScriptEngine::registerEvents() + { + // Register for entity destroyed event + std::shared_ptr> destroyedEventReceiver + { + std::make_shared>(this, &SHScriptEngine::onEntityDestroyed) + }; + ReceiverPtr receiver = std::dynamic_pointer_cast(destroyedEventReceiver); + SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, receiver); + } + void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath) { std::ifstream buildLog(buildLogPath); @@ -495,5 +515,4 @@ namespace SHADE oss << " -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet"; return oss.str(); } - } diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index fa205266..0994bb5d 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -15,12 +15,14 @@ of DigiPen Institute of Technology is prohibited. #include // Project Headers +#include "SH_API.h" #include "SHDotNetRuntime.h" #include "ECS_Base/SHECSMacros.h" #include "ECS_Base/Entity/SHEntity.h" #include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystemRoutine.h" -#include "SH_API.h" +#include "Events/SHEventDefines.h" +#include "Events/SHEvent.h" namespace SHADE { @@ -242,6 +244,11 @@ namespace SHADE /*ECS::EntityEvent::Delegate onEntityCreate; ECS::EntityEvent::Delegate onEntityDestroy;*/ + /*-----------------------------------------------------------------------------*/ + /* Event Handler Functions */ + /*-----------------------------------------------------------------------------*/ + SHEventHandle onEntityDestroyed(SHEventPtr eventPtr); + /*-----------------------------------------------------------------------------*/ /* Helper Functions */ /*-----------------------------------------------------------------------------*/ @@ -250,6 +257,10 @@ namespace SHADE /// void loadFunctions(); /// + /// Registers events for the scripting system + /// + void registerEvents(); + /// /// Reads the file via the specified path that represents a build log of error /// and warning messages. /// diff --git a/TempScriptsFolder/TestScript.cs b/TempScriptsFolder/TestScript.cs index 0e4823a2..c1ed5bd5 100644 --- a/TempScriptsFolder/TestScript.cs +++ b/TempScriptsFolder/TestScript.cs @@ -4,8 +4,20 @@ public class TestScript : Script { public TestScript(GameObject gameObj) : base(gameObj) {} + protected override void awake() + { + Debug.Log("TestScript.Awake()"); + } + protected override void start() + { + Debug.Log("TestScript.Start()"); + } protected override void update() { Debug.Log("TestScript.Update()"); } + protected override void onDestroy() + { + Debug.Log("TestScript.OnDestroy()"); + } } \ No newline at end of file From 5bd35cec612412fbbfba4d32a64202128e1ad8ff Mon Sep 17 00:00:00 2001 From: Xiao Qi Date: Thu, 22 Sep 2022 17:07:59 +0800 Subject: [PATCH 23/37] Fixed SHEventReceiver constructor callback return signature. --- SHADE_Engine/src/Events/SHEventReceiver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Events/SHEventReceiver.h b/SHADE_Engine/src/Events/SHEventReceiver.h index e6e5e757..e2edd4dc 100644 --- a/SHADE_Engine/src/Events/SHEventReceiver.h +++ b/SHADE_Engine/src/Events/SHEventReceiver.h @@ -19,7 +19,7 @@ namespace SHADE SHEventHandle(T::*callback)(SHEventPtr); public: - SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventPtr)) + SHEventReceiverSpec(T* obj, SHEventHandle(T::* cb)(SHEventPtr)) :SHEventReceiver(), object{ obj }, callback{ cb } { From 1bede86ff60c9a3070f3bb46b7dea0bc4e6ae600 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 17:25:43 +0800 Subject: [PATCH 24/37] Awake(), Start() and Update(), OnDestroy() for scripts now all run as intended --- SHADE_Application/src/Scenes/SBTestScene.cpp | 9 ++++---- SHADE_Application/src/Scenes/SBTestScene.h | 1 + SHADE_Managed/src/Scripts/ScriptStore.cxx | 24 +++----------------- 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 072a15de..c59fa234 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -38,18 +38,19 @@ namespace Sandbox auto matInst = graphicsSystem->AddMaterialInstance(); // Create entity and add mesh - auto entity = SHADE::SHEntityManager::CreateEntity(); - auto& renderable = *SHADE::SHComponentManager::GetComponent_s(entity); + testObj = SHADE::SHEntityManager::CreateEntity(); + auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); renderable.Mesh = CUBE_MESH; renderable.SetMaterial(matInst); renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f); SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); - scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(entity), "TestScript"); + scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testObj), "TestScript"); } void SBTestScene::Update(float dt) { (void)dt; - + if (GetKeyState(VK_SPACE) & 0x8000) + SHADE::SHEntityManager::DestroyEntity(testObj); } void SBTestScene::Render() diff --git a/SHADE_Application/src/Scenes/SBTestScene.h b/SHADE_Application/src/Scenes/SBTestScene.h index 6776c671..4d4a3207 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.h +++ b/SHADE_Application/src/Scenes/SBTestScene.h @@ -9,6 +9,7 @@ namespace Sandbox { private: EntityID camera; + EntityID testObj; public: diff --git a/SHADE_Managed/src/Scripts/ScriptStore.cxx b/SHADE_Managed/src/Scripts/ScriptStore.cxx index 089da002..252ab071 100644 --- a/SHADE_Managed/src/Scripts/ScriptStore.cxx +++ b/SHADE_Managed/src/Scripts/ScriptStore.cxx @@ -287,14 +287,7 @@ namespace SHADE } void ScriptStore::RemoveAllScripts(Entity entity) { - SAFE_NATIVE_CALL_BEGIN - // Check if entity exists - if (!EntityUtils::IsValid(entity)) - { - Debug::LogError("[ScriptStore] Attempted to remove Scripts from an invalid Entity!"); - return; - } - + SAFE_NATIVE_CALL_BEGIN // Check if entity exists in the script storage if (!scripts.ContainsKey(entity)) return; @@ -311,13 +304,6 @@ namespace SHADE void ScriptStore::RemoveAllScriptsImmediately(Entity entity, bool callOnDestroy) { SAFE_NATIVE_CALL_BEGIN - // Check if entity exists - if (!EntityUtils::IsValid(entity)) - { - Debug::LogError("[ScriptStore] Attempted to remove Scripts from an invalid Entity!"); - return; - } - // Check if entity exists in the script storage if (!scripts.ContainsKey(entity)) return; @@ -386,10 +372,7 @@ namespace SHADE while (disposalQueue.Count > 0) { Script^ script = disposalQueue.Dequeue(); - /*if (Application::IsPlaying) - { - script->OnDestroy(); - }*/ + script->OnDestroy(); auto entity = script->Owner.GetEntity(); auto scriptList = scripts[script->Owner.GetEntity()]; scriptList->Remove(script); @@ -496,7 +479,6 @@ namespace SHADE // Check if entity exists, otherwise nothing if (!EntityUtils::IsValid(entity)) return true; - // Check if entity exists in the script storage if (!scripts.ContainsKey(entity)) @@ -667,7 +649,7 @@ namespace SHADE // Entity Validity Check if (nativeEntity == nullptr) - throw gcnew System::InvalidOperationException("Attempted to get native Component to an invalid Entity."); + return false; // Check active state return nativeEntity->GetActive(); From cb31628e663a0f0fb1ef7eb829d41f06740c1f4e Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Thu, 22 Sep 2022 19:38:43 +0800 Subject: [PATCH 25/37] Dummy pipeline layout ctor created Renderer now can update and bind descriptor set --- SHADE_Application/src/Scenes/SBTestScene.cpp | 18 +++++-- SHADE_Application/src/Scenes/SBTestScene.h | 2 +- .../src/Graphics/Buffers/SHVkBuffer.cpp | 49 ++++++----------- .../src/Graphics/Buffers/SHVkBuffer.h | 4 +- .../Graphics/Commands/SHVkCommandBuffer.cpp | 5 ++ .../src/Graphics/Commands/SHVkCommandBuffer.h | 1 + .../Descriptors/SHVkDescriptorSetGroup.cpp | 4 +- .../Descriptors/SHVkDescriptorSetGroup.h | 2 +- .../Graphics/Devices/SHVkLogicalDevice.cpp | 7 ++- .../src/Graphics/Devices/SHVkLogicalDevice.h | 3 +- .../GlobalData/SHGraphicsGlobalData.cpp | 9 ++++ .../GlobalData/SHGraphicsGlobalData.h | 6 +++ .../Graphics/MiddleEnd/Interface/SHCamera.cpp | 34 ++++++------ .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 7 +-- .../MiddleEnd/Interface/SHRenderer.cpp | 16 ++++-- .../Graphics/MiddleEnd/Interface/SHRenderer.h | 8 ++- .../Pipeline/SHPipelineLayoutParams.h | 9 ++++ .../src/Graphics/Pipeline/SHPipelineState.h | 2 +- .../Graphics/Pipeline/SHVkPipelineLayout.cpp | 50 +++++++++++++++--- .../Graphics/Pipeline/SHVkPipelineLayout.h | 3 +- TempShaderFolder/TestCubeVs.glsl | 3 +- TempShaderFolder/TestCubeVs.spv | Bin 1680 -> 1768 bytes 22 files changed, 161 insertions(+), 81 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 873d0fed..aef39ddd 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -7,6 +7,7 @@ #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Scene/SHSceneManager.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" +#include "Math/Transform/SHTransformComponent.h" using namespace SHADE; @@ -28,6 +29,8 @@ namespace Sandbox } void SBTestScene::Init() { + SHComponentManager::CreateComponentSparseSet(); + SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); // Create temp meshes const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); @@ -37,16 +40,25 @@ namespace Sandbox auto matInst = graphicsSystem->AddMaterialInstance(); // Create entity and add mesh - auto entity = SHADE::SHEntityManager::CreateEntity(); - auto& renderable = *SHADE::SHComponentManager::GetComponent_s(entity); + testEntity = SHADE::SHEntityManager::CreateEntity(); + SHComponentManager::AddComponent(testEntity); + auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testEntity); + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testEntity); + renderable.Mesh = CUBE_MESH; renderable.SetMaterial(matInst); renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f); + + transform.SetWorldPosition (SHVec3 (0.0f, 0.0f, 2.0f)); } void SBTestScene::Update(float dt) { - (void)dt; + static float rotation = 0.0f; + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testEntity); + transform.SetWorldRotation (rotation, 0.0f, 0.0f); + + rotation += dt * 10.0f; } void SBTestScene::Render() diff --git a/SHADE_Application/src/Scenes/SBTestScene.h b/SHADE_Application/src/Scenes/SBTestScene.h index 6776c671..bb382477 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.h +++ b/SHADE_Application/src/Scenes/SBTestScene.h @@ -9,7 +9,7 @@ namespace Sandbox { private: EntityID camera; - + unsigned int testEntity; public: virtual void Load(); diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 4bfc1e4b..59916731 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -49,6 +49,11 @@ namespace SHADE Init(newSize, data, srcSize, bufferUsageFlags, allocCreateInfo.usage, allocCreateInfo.flags); } + void SHVkBuffer::FlushAllocation(uint32_t srcOffset, uint32_t dstOffset) noexcept + { + vmaFlushAllocation(vmaAllocator, alloc, srcOffset, dstOffset); + } + vk::Buffer SHVkBuffer::GetVkBuffer(void) const noexcept { return vkBuffer; @@ -72,8 +77,7 @@ namespace SHADE /***************************************************************************/ void SHVkBuffer::Map(void) noexcept { - if (!boundToCoherent) - vmaMapMemory(vmaAllocator, alloc, &mappedPtr); + vmaMapMemory(vmaAllocator, alloc, &mappedPtr); } /***************************************************************************/ @@ -90,11 +94,8 @@ namespace SHADE /***************************************************************************/ void SHVkBuffer::Unmap(void) noexcept { - if (!boundToCoherent) - { - vmaUnmapMemory(vmaAllocator, alloc); - mappedPtr = nullptr; - } + vmaUnmapMemory(vmaAllocator, alloc); + mappedPtr = nullptr; } /***************************************************************************/ @@ -132,9 +133,7 @@ namespace SHADE Otherwise, only the copying is carried out. In the instance where memory is non-coherent but HOST_VISIBLE, we want to - write to data and then unmap and flush it immediately. If you want to write - to memory in random-access fashion, consider, mapping, writing a few - things, unmapping then flushing. + write to data and then unmap and flush it immediately. \param vmaAllocator The VMA allocator object. @@ -155,18 +154,11 @@ namespace SHADE /***************************************************************************/ void SHVkBuffer::MapWriteUnmap(void* data, uint32_t sizeToWrite, uint32_t srcOffset, uint32_t dstOffset) noexcept { - if (!boundToCoherent) - { - // map from host visible memory to pointer, do a DMA, and then unmap - Map(); - WriteToMemory(data, sizeToWrite, srcOffset, dstOffset); - Unmap(); - } - else - { - if (mappedPtr) - std::memcpy(static_cast(mappedPtr) + dstOffset, static_cast(data) + srcOffset, sizeToWrite); - } + // map from host visible memory to pointer, do a DMA, and then unmap + Map(); + WriteToMemory(data, sizeToWrite, srcOffset, dstOffset); + Unmap(); + FlushAllocation(srcOffset, dstOffset); } /***************************************************************************/ @@ -279,7 +271,6 @@ namespace SHADE , mappedPtr{ nullptr } , alloc {nullptr} , randomAccessOptimized{false} - , boundToCoherent {false} , vmaAllocator{allocator} {} @@ -304,7 +295,6 @@ namespace SHADE , mappedPtr{ std::move(rhs.mappedPtr) } , alloc{ std::move (rhs.alloc) } , randomAccessOptimized{ rhs.randomAccessOptimized } - , boundToCoherent{ rhs.boundToCoherent} , vmaAllocator{ rhs.vmaAllocator } , bufferUsageFlags {rhs.bufferUsageFlags} , bufferCreateInfo { rhs.bufferCreateInfo } @@ -325,7 +315,6 @@ namespace SHADE mappedPtr = std::move(rhs.mappedPtr); alloc = std::move(rhs.alloc); randomAccessOptimized = rhs.randomAccessOptimized; - boundToCoherent = rhs.boundToCoherent; vmaAllocator = std::move (rhs.vmaAllocator); rhs.vkBuffer = VK_NULL_HANDLE; bufferCreateInfo = rhs.bufferCreateInfo; @@ -430,16 +419,12 @@ namespace SHADE // mainly host visible. Can be cached (need to flush/invalidate), uncached (always coherent) and coherent (virtual). if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - // If memory is marked to be coherent between CPU and GPU (no need flush/invalidate) (TODO: Verify if VMA_ALLOCATION_CREATE_MAPPED_BIT is used when VMA_MEMORY_USAGE_AUTO is set) - // TODO: also verify that coherent bit = pointer is already mapped - if (memPropFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) - { - boundToCoherent = true; - mappedPtr = allocInfo.pMappedData; - } + if (allocFlags | VMA_ALLOCATION_CREATE_MAPPED_BIT) + mappedPtr = allocInfo.pMappedData; else mappedPtr = nullptr; + if (data) MapWriteUnmap(data, srcSize, 0, 0); } diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h index 49f22e37..648a07e8 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.h @@ -41,9 +41,6 @@ namespace SHADE //! If initialized with vma random access flag, this is true bool randomAccessOptimized; - //! Whether or not this buffer is bound to coherent memory - bool boundToCoherent; - //! buffer usage info flags vk::BufferUsageFlags bufferUsageFlags; @@ -100,6 +97,7 @@ namespace SHADE void TransferToDeviceResource(Handle const& cmdBufferHdl) noexcept; void ResizeNoCopy (uint32_t newSize); void ResizeReplace (uint32_t newSize, void* data, uint32_t srcSize); + void FlushAllocation (uint32_t srcOffset, uint32_t dstOffset) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index cddb6cdb..83095371 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -491,6 +491,11 @@ namespace SHADE // //vkCommandBuffer.pipelineBarrier() //} + void SHVkCommandBuffer::ForceSetPipelineLayout(Handle pipelineLayout) noexcept + { + boundPipelineLayoutHdl = pipelineLayout; + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index f780638a..c18527b3 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -141,6 +141,7 @@ namespace SHADE { memcpy (static_cast(pushConstantData) + boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T)); }; + void ForceSetPipelineLayout (Handle pipelineLayout) noexcept; void SubmitPushConstants (void) const noexcept; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index f579d377..c1732535 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -176,7 +176,7 @@ namespace SHADE } } - void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span> const& buffers) noexcept + void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept { // Find the target writeDescSet BindingAndSetHash writeHash = binding; @@ -193,6 +193,8 @@ namespace SHADE // write sampler and image view auto& buffer = buffers[i]; writeInfo.descBufferInfos[i].buffer = buffer->GetVkBuffer(); + writeInfo.descBufferInfos[i].offset = offset; + writeInfo.descBufferInfos[i].range = range; } } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index bc87ff1d..d92d55e9 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -64,7 +64,7 @@ namespace SHADE void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept; void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span, Handle>> const& imageViewsAndSamplers) noexcept; - void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span> const& buffers) noexcept; + void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept; /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 64508a2b..65b0d9ca 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -467,7 +467,12 @@ namespace SHADE */ /***************************************************************************/ - Handle SHVkLogicalDevice::CreatePipelineLayout(SHPipelineLayoutParams& pipelineLayoutParams) noexcept + Handle SHVkLogicalDevice::CreatePipelineLayout(SHPipelineLayoutParams const& pipelineLayoutParams) noexcept + { + return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutParams); + } + + Handle SHVkLogicalDevice::CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept { return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutParams); } diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 365e68c9..3a27e4b1 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -187,7 +187,8 @@ namespace SHADE Handle CreateDescriptorSetGroup(Handle pool, std::vector> const& layouts, std::vector const& variableDescCounts) noexcept; - Handle CreatePipelineLayout (SHPipelineLayoutParams& pipelineLayoutParams) noexcept; + Handle CreatePipelineLayout(SHPipelineLayoutParams const& pipelineLayoutParams) noexcept; + Handle CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept; Handle CreateFence (void) const noexcept; Handle CreateSemaphore (void) const noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp index d9ffa6b5..ee6d0e8c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp @@ -2,6 +2,7 @@ #include "SHGraphicsGlobalData.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Pipeline/SHPipelineState.h" +#include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" namespace SHADE @@ -66,6 +67,9 @@ namespace SHADE globalDescSetLayouts.push_back(dynamicGlobalLayout); globalDescSetLayouts.push_back(cameraDataGlobalLayout); globalDescSetLayouts.push_back(materialDataPerInstanceLayout); + + + dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{globalDescSetLayouts}); } void SHGraphicsGlobalData::InitDefaultVertexInputState(void) noexcept @@ -94,4 +98,9 @@ namespace SHADE return defaultVertexInputState; } + Handle SHGraphicsGlobalData::GetDummyPipelineLayout(void) const noexcept + { + return dummyPipelineLayout; + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h index fb595250..9333d0ab 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h @@ -9,6 +9,7 @@ namespace SHADE class SHVkLogicalDevice; class SHVkDescriptorSetLayout; class SHVkDescriptorSetGroup; + class SHVkPipelineLayout; class SH_API SHGraphicsGlobalData { @@ -22,6 +23,10 @@ namespace SHADE //! Default vertex input state (used by everything). SHVertexInputState defaultVertexInputState; + //! Since we want to bind global data but can't do so without a pipeline layout, + //! we create a dummy pipeline layout to use it for binding. + Handle dummyPipelineLayout; + void InitDescSetLayouts (Handle logicalDevice) noexcept; void InitDefaultVertexInputState(void) noexcept; public: @@ -35,5 +40,6 @@ namespace SHADE /*-----------------------------------------------------------------------*/ std::vector> const& GetDescSetLayouts (void) const noexcept; SHVertexInputState const& GetDefaultViState (void) const noexcept; + Handle GetDummyPipelineLayout (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp index 7e7412b9..992aff05 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp @@ -22,24 +22,24 @@ namespace SHADE void SHCamera::SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up) { SHVec3 view = target - pos; view = SHVec3::Normalise(view); - SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); - const SHVec3 UP = SHVec3::Cross(right, view); + SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); + const SHVec3 UP = SHVec3::Cross(right, view); - viewMatrix = SHMatrix::Identity; - viewMatrix(0, 0) = right[0]; - viewMatrix(1, 0) = right[1]; - viewMatrix(2, 0) = right[2]; - viewMatrix(0, 1) = UP[0]; - viewMatrix(1, 1) = UP[1]; - viewMatrix(2, 1) = UP[2]; - viewMatrix(0, 2) = -view[0]; - viewMatrix(1, 2) = -view[1]; - viewMatrix(2, 2) = -view[2]; - viewMatrix(3, 0) = -right.Dot(pos); - viewMatrix(3, 1) = -UP.Dot(pos); - viewMatrix(3, 2) = view.Dot(pos); - - isDirty = true; + viewMatrix = SHMatrix::Identity; + viewMatrix(0, 0) = UP[0]; + viewMatrix(1, 0) = UP[1]; + viewMatrix(2, 0) = UP[2]; + viewMatrix(0, 1) = right[0]; + viewMatrix(1, 1) = right[1]; + viewMatrix(2, 1) = right[2]; + viewMatrix(0, 2) = view[0]; + viewMatrix(1, 2) = view[1]; + viewMatrix(2, 2) = view[2]; + viewMatrix(3, 0) = -UP.Dot(pos); + viewMatrix(3, 1) = -right.Dot(pos); + viewMatrix(3, 2) = -view.Dot(pos); + + isDirty = true; } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 1026d01b..cee00c9b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -114,7 +114,7 @@ namespace SHADE screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f)); screenCamera->SetOrthographic(static_cast(windowDims.first), static_cast(windowDims.second), 0.01f, 100.0f); worldCamera = resourceManager.Create(); - worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f)); + worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); // Create Default Viewport @@ -221,7 +221,6 @@ namespace SHADE renderContext.ResetFence(); - // For every viewport for (int vpIndex = 0; vpIndex < static_cast(viewports.size()); ++vpIndex) { @@ -239,6 +238,8 @@ namespace SHADE // Begin recording the command buffer currentCmdBuffer->BeginRecording(); + currentCmdBuffer->ForceSetPipelineLayout(globalData->GetDummyPipelineLayout()); + // Bind all the buffers required for meshes for (auto& [buffer, bindingPoint] : MESH_DATA) { @@ -249,7 +250,7 @@ namespace SHADE } // bind camera data - renderers[renIndex]->BindDescriptorSet(currentCmdBuffer, frameIndex); + renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); // Draw first renderers[renIndex]->Draw(frameIndex); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index fd702968..c7e2a86d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -37,15 +37,14 @@ namespace SHADE commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 }); - cpuCameraData.resize(numFrames); cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData)); - cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); + cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); std::array cameraBufferArray{cameraBuffer}; - cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}); + cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}, 0, sizeof (SHShaderCameraData)); cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA); } @@ -66,13 +65,20 @@ namespace SHADE renderGraph->Execute(frameIndex, commandBuffers[frameIndex]); } - void SHRenderer::BindDescriptorSet(Handle cmdBuffer, uint32_t frameIndex) noexcept + void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept { - std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; + cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); + cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); + + std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); } + void SHRenderer::UpdateCameraDataToBuffer(void) noexcept + { + } + Handle SHRenderer::GetRenderGraph(void) const noexcept { return renderGraph; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index bbb7773b..255ab289 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -75,7 +75,8 @@ namespace SHADE /* Drawing Functions */ /*-----------------------------------------------------------------------------*/ void Draw(uint32_t frameIndex) noexcept; - void BindDescriptorSet (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void UpdateDataAndBind (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void UpdateCameraDataToBuffer (void) noexcept; /*-----------------------------------------------------------------------------*/ /* Setters and Getters */ @@ -95,7 +96,10 @@ namespace SHADE Handle renderGraph; Handle cameraDescriptorSet; Handle cameraBuffer; - std::vector cpuCameraData; + + // we really only need 1 copy even though we need %swapchainImages copies for + // GPU. + SHShaderCameraData cpuCameraData; //! Command buffers for the render graph std::vector> commandBuffers; diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h index 493bd114..093e03d4 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h @@ -25,6 +25,15 @@ namespace SHADE //! want to use it for allocating descriptor sets. std::vector> const& globalDescSetLayouts = {}; }; + + struct SHPipelineLayoutParamsDummy + { + /*-----------------------------------------------------------------------*/ + /* MEMBER VARIABLES */ + /*-----------------------------------------------------------------------*/ + + std::vector> const& globalDescSetLayouts = {}; + }; } #endif diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h index a43035f5..2769d6cc 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineState.h @@ -64,7 +64,7 @@ namespace SHADE vk::CullModeFlags cull_mode{ vk::CullModeFlagBits::eBack }; //! CW or CCW - vk::FrontFace frontFacingOrientation{ vk::FrontFace::eClockwise }; + vk::FrontFace frontFacingOrientation{ vk::FrontFace::eCounterClockwise }; bool depthBias{ VK_FALSE }; }; diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index fc40f394..25be112e 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -254,12 +254,6 @@ namespace SHADE // Clear pc ranges vkPcRanges.clear(); - // Kill all descriptor set layouts - for (auto& layout : descriptorSetLayoutsGlobal) - SHVkInstance::GetResourceManager().Free(layout); - - descriptorSetLayoutsGlobal.clear(); - for (auto& layout : descriptorSetLayoutsAllocate) SHVkInstance::GetResourceManager().Free(layout); @@ -285,9 +279,9 @@ namespace SHADE */ /***************************************************************************/ - SHVkPipelineLayout::SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParams& pipelineLayoutParams) noexcept + SHVkPipelineLayout::SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParams const& pipelineLayoutParams) noexcept : vkPipelineLayout {VK_NULL_HANDLE} - , shaderModules{std::move (pipelineLayoutParams.shaderModules)} + , shaderModules{pipelineLayoutParams.shaderModules} , logicalDeviceHdl {inLogicalDeviceHdl} , pushConstantInterface{} , vkPcRanges{} @@ -308,6 +302,46 @@ namespace SHADE RecreateIfNeeded (); } + + SHVkPipelineLayout::SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept + : vkPipelineLayout{ VK_NULL_HANDLE } + , shaderModules{ } + , logicalDeviceHdl{ inLogicalDeviceHdl } + , pushConstantInterface{} + , vkPcRanges{} + , descriptorSetLayoutsGlobal{} + , descriptorSetLayoutsAllocate{} + , vkDescriptorSetLayoutsAllocate{} + , vkDescriptorSetLayoutsPipeline{} + + { + vkDescriptorSetLayoutsPipeline.resize(pipelineLayoutParams.globalDescSetLayouts.size()); + for (uint32_t i = 0; auto& layout : vkDescriptorSetLayoutsPipeline) + { + layout = pipelineLayoutParams.globalDescSetLayouts[i]->GetVkHandle(); + ++i; + } + + vk::PipelineLayoutCreateInfo plCreateInfo{}; + + // Set push constant data to pipeline layout + plCreateInfo.pushConstantRangeCount = 0; + plCreateInfo.pPushConstantRanges = nullptr; + + // To initialize the descriptor set layouts for the pipeline layout. + plCreateInfo.setLayoutCount = static_cast(vkDescriptorSetLayoutsPipeline.size()); + plCreateInfo.pSetLayouts = vkDescriptorSetLayoutsPipeline.data(); + + if (auto const RESULT = logicalDeviceHdl->GetVkLogicalDevice().createPipelineLayout(&plCreateInfo, nullptr, &vkPipelineLayout); RESULT != vk::Result::eSuccess) + { + SHVulkanDebugUtil::ReportVkError(RESULT, "Failed to create Pipeline Layout. "); + return; + } + else + SHVulkanDebugUtil::ReportVkSuccess("Successfully created Pipeline Layout. "); + + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h index bce827a7..e43ceb73 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.h @@ -57,7 +57,8 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHVkPipelineLayout (Handle const& inLogicalDeviceHdl, SHPipelineLayoutParams& pipelineLayoutParams) noexcept; + SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParams const& pipelineLayoutParams) noexcept; + SHVkPipelineLayout(Handle const& inLogicalDeviceHdl, SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept; SHVkPipelineLayout (SHVkPipelineLayout&& rhs) noexcept; ~SHVkPipelineLayout (void) noexcept; SHVkPipelineLayout& operator= (SHVkPipelineLayout&& rhs) noexcept; diff --git a/TempShaderFolder/TestCubeVs.glsl b/TempShaderFolder/TestCubeVs.glsl index 08c465a0..1e3a11d7 100644 --- a/TempShaderFolder/TestCubeVs.glsl +++ b/TempShaderFolder/TestCubeVs.glsl @@ -56,6 +56,7 @@ void main() //Out.uv = aUV; // render NDC first - gl_Position = vec4(aVertexPos, 1.0); + //gl_Position = vec4(aVertexPos, 1.0f); + gl_Position = cameraData.vpMat * vec4 (aVertexPos, 1.0f); Out.vertColor = vec4 (aVertexPos, 1.0f); } \ No newline at end of file diff --git a/TempShaderFolder/TestCubeVs.spv b/TempShaderFolder/TestCubeVs.spv index be24aa3a944eff08f83a27869e46ef93dcc93eae..f0b31ea23f835273164024fc22e42f8e3c4cc918 100644 GIT binary patch literal 1768 zcmZ9LYflqF6ovA)6cQnt1#>m=i~9Dg9|GoNw`AM0r!p4p%3jC{`b}#7qs2w-+Gw^LtyZIX*zODl z?P2^Q@Y;bNdhMp&^2?c)S}q13ZLFE~OPV{m^>FmqrpMD+&=t&MughQqHC z8*`)x{bsn?ahwB=*>Us|j=nh#AC7x$D1wiUxa(6*m~kW(963t~PBmaO*Di5-;0Z@w z){(cN9Q1Va65bGI5U0PD1f`h1Vcsen`^;;u z%E-$;-~}0DO_=_Ym%1wY(o@%C@?RI`Jn-ZP(`z`F?}mKxqhHQqt!GM$e`xGVtCUZ^rbH=GI~e9-b$JFDCNQQR(m)Fo0uO+Y5Fpf|^dXR_|oJT=)`F;hZ}nK#o;x7x?;<~Z#)pTBqp zW66{p5zew%aCTY$0~^LTi<0Y-JCYsAuH=DaPg2rvO8U1pmsPdZ?zTFeR{KM@HyU-v z>5nMrMqwOu`(YCF((pWhH(TI^aW9(mi-d|8#rhTXJ+B&PQTHfFPJ<*3zRMMw;n>86 z<1h_}vCtXE=R6J%T_^ZfSFOP-q+d+`n1Do2cJ{W7{ha!7gS-_dg`RJo1F}0e~y~6%O zVa%K5wa3^ChV~e<1Y>RBFHHh!! zKDDUt&)$&FIuysByW;%+bAWU05~dHxVf4*DUza&;U-IknS*v2ft7{K^VXw=Ymaa)Q z)B}0(>2pp0v(hyQYcKb&%I4f#^5>-CgH>fQL!W~fQWI}MnwrF4=RR*0j5CDIwxo%Hkqe*u2BY>p zY4R~I`1hr$0}da5C&zp*yO(_41A8{be<)3DW=y_E(!{{okI#DntIFqo;S-1dM4Dc} z;p21fU@!Hy(Bx)uhCf1hQ*VSauT=@N`Ye=lt>u{11-71J^x%0LIY#~?bwp2_686I< z&dlE{FY~@7;f}e-x9S8RzVCzYqu9q?`Cu$xvnCs?*hf9bihXPgV}DITyx2!WKKJSS Mz=!`=Szk&10e+KzwEzGB From 495d2b4b66e512fc84ce77617b139fdeb1bc579a Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 20:04:53 +0800 Subject: [PATCH 26/37] Added per-frame update of gpu transforms buffer --- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 26 ++++++++++++------- .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 1 + .../Graphics/MiddleEnd/Batching/SHBatcher.cpp | 8 ++++++ .../Graphics/MiddleEnd/Batching/SHBatcher.h | 1 + .../MiddleEnd/Batching/SHSuperBatch.cpp | 8 ++++++ .../MiddleEnd/Batching/SHSuperBatch.h | 1 + .../Graphics/RenderGraph/SHRenderGraph.cpp | 8 ++++++ .../src/Graphics/RenderGraph/SHRenderGraph.h | 1 + 8 files changed, 45 insertions(+), 9 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 08ffa88e..c2090fc0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -86,6 +86,23 @@ namespace SHADE matPropsBuffer.Free(); } + void SHBatch::UpdateTransformBuffer() + { + // Reset Transform Data + transformData.clear(); + + // Populate on the CPU + for (auto& subBatch : subBatches) + for (const SHRenderable* renderable : subBatch.Renderables) + { + // Transform + transformData.emplace_back(renderable->TransformMatrix); + } + + // Transfer to GPU + transformDataBuffer->WriteToMemory(transformData.data(), transformData.size() * sizeof(SHMatrix), 0, 0); + } + void SHBatch::Build(Handle device) { // No need to build as there are no changes @@ -159,36 +176,27 @@ namespace SHADE // Send all buffered data to the GPU buffers using BuffUsage = vk::BufferUsageFlagBits; // - Draw Data - if (drawDataBuffer) - drawDataBuffer->Unmap(); const uint32_t DRAW_DATA_BYTES = static_cast(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, drawDataBuffer, drawData.data(), DRAW_DATA_BYTES, BuffUsage::eIndirectBuffer ); - drawDataBuffer->Map(); // - Transform Buffer - if (transformDataBuffer) - transformDataBuffer->Unmap(); const uint32_t TF_DATA_BYTES = static_cast(transformData.size() * sizeof(SHMatrix)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, transformDataBuffer, transformData.data(), TF_DATA_BYTES, BuffUsage::eVertexBuffer ); - transformDataBuffer->Map(); // - Material Properties Buffer if (!EMPTY_MAT_PROPS) { - if (matPropsBuffer) - matPropsBuffer->Unmap(); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( device, matPropsBuffer, matPropsData.get(), static_cast(matPropTotalBytes), BuffUsage::eStorageBuffer ); - matPropsBuffer->Map(); } isDirty = false; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index a5b808ff..f438d6c1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -71,6 +71,7 @@ namespace SHADE void Add(const SHRenderable* renderable); void Remove(const SHRenderable* renderable); void Clear(); + void UpdateTransformBuffer(); void Build(Handle device); void Draw(Handle cmdBuffer); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp index c92d9585..ea216ed5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp @@ -109,6 +109,14 @@ namespace SHADE superBatches.clear(); } + void SHBatcher::UpdateTransformBuffer() + { + for (auto& batch : superBatches) + { + batch->UpdateTransformBuffer(); + } + } + void SHBatcher::RegisterSuperBatch(Handle superBatch) { superBatches.emplace_back(superBatch); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h index 4c8ac811..89dea2eb 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h @@ -53,6 +53,7 @@ namespace SHADE void RemoveFromBatch(SHRenderable const* renderable); void FinaliseBatches(Handle device); void ClearBatches(); + void UpdateTransformBuffer(); void RegisterSuperBatch(Handle superBatch); void DeregisterSuperBatch(Handle superBatch); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 09d2a720..8b7ea619 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -78,6 +78,14 @@ namespace SHADE batches.clear(); } + void SHSuperBatch::UpdateTransformBuffer() + { + for (auto& batch : batches) + { + batch.UpdateTransformBuffer(); + } + } + void SHSuperBatch::Build(Handle device) noexcept { // Build all batches diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h index b44dd349..6151e56e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -55,6 +55,7 @@ namespace SHADE void Add(const SHRenderable* renderable) noexcept; void Remove(const SHRenderable* renderable) noexcept; void Clear() noexcept; + void UpdateTransformBuffer(); void Build(Handle device) noexcept; void Draw(Handle cmdBuffer) noexcept; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index d02e8f7d..f53f3e99 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -348,6 +348,9 @@ namespace SHADE void SHSubpass::Execute(Handle& commandBuffer) noexcept { + // Ensure correct transforms are provided + superBatch->UpdateTransformBuffer(); + // Draw all the batches superBatch->Draw(commandBuffer); @@ -626,6 +629,11 @@ namespace SHADE batcher.FinaliseBatches(logicalDeviceHdl); } + void SHRenderGraphNode::UpdateBatchTransforms() + { + batcher.UpdateTransformBuffer(); + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index cbb9586d..16770475 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -231,6 +231,7 @@ namespace SHADE void Execute (Handle& commandBuffer, uint32_t frameIndex) noexcept; Handle GetOrCreatePipeline (std::pair, Handle> const& vsFsPair, Handle subpass) noexcept; void FinaliseBatch(); + void UpdateBatchTransforms(); /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ From 0250687e06c0ce3d3cad92ecc1c69903a7373691 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 22 Sep 2022 20:25:23 +0800 Subject: [PATCH 27/37] Instantiated Transform System & Update Routine --- SHADE_Application/src/Application/SBApplication.cpp | 11 ++++++++++- .../src/Math/Transform/SHTransformSystem.cpp | 12 ++++++++++-- SHADE_Engine/src/Math/Transform/SHTransformSystem.h | 13 +++++++++---- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 53cc1e40..938b0b57 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -22,6 +22,7 @@ #include "ECS_Base/Managers/SHEntityManager.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Scene/SHSceneManager.h" +#include "Math/Transform/SHTransformSystem.h" #include "Scenes/SBTestScene.h" @@ -45,8 +46,10 @@ namespace Sandbox window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow); // Create Systems - SHADE::SHSystemManager::CreateSystem(); SHADE::SHSystemManager::CreateSystem(); + // TODO(Diren): Create Physics System here + SHADE::SHSystemManager::CreateSystem(); + SHADE::SHSystemManager::CreateSystem(); SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); // Create Routines @@ -54,6 +57,12 @@ namespace Sandbox SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); + + // TODO(Diren): Register Physics System & Routines here + + SHADE::SHSystemManager::RegisterRoutine(); + SHADE::SHComponentManager::CreateComponentSparseSet(); + SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index adbdf746..64ad9f43 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -25,8 +25,6 @@ namespace SHADE /* Static Data Member Definitions */ /*-----------------------------------------------------------------------------------*/ - //SHTransformSystem::TransformUpdateRoutine SHTransformSystem::UpdateRoutine; - /*-----------------------------------------------------------------------------------*/ /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -47,6 +45,16 @@ namespace SHADE UpdateEntity(SCENE_GRAPH.GetRoot()); } + void SHTransformSystem::Init() + { + + } + + void SHTransformSystem::Exit() + { + + } + /*-----------------------------------------------------------------------------------*/ /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h index c57cbdbd..02c3b6c6 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.h +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.h @@ -21,7 +21,7 @@ namespace SHADE /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ - class SH_API SHTransformSystem : public SHSystem + class SH_API SHTransformSystem final : public SHSystem { public: /*---------------------------------------------------------------------------------*/ @@ -29,7 +29,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ SHTransformSystem () = default; - ~SHTransformSystem () = default; + ~SHTransformSystem () override = default; SHTransformSystem (const SHTransformSystem&) = delete; SHTransformSystem (SHTransformSystem&&) = delete; @@ -45,7 +45,7 @@ namespace SHADE /* System Routines */ /*---------------------------------------------------------------------------------*/ - class TransformUpdateRoutine : public SHSystemRoutine + class SH_API TransformUpdateRoutine final: public SHSystemRoutine { public: /*-------------------------------------------------------------------------------*/ @@ -72,7 +72,12 @@ namespace SHADE void Execute(double dt) noexcept override; }; - //static TransformUpdateRoutine UpdateRoutine; + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void Init () override; + void Exit () override; private: /*---------------------------------------------------------------------------------*/ From 2c0fa3a6b27172a0bb358978feae8578be8b0cac Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 22 Sep 2022 20:25:42 +0800 Subject: [PATCH 28/37] Fixed warning from scene graph when adding new nodes to root. --- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index 84c7f1c5..da2dcffd 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -497,9 +497,16 @@ namespace SHADE SHSceneNode* newNode = AllocateNode(entityID); if (parent == nullptr) + { + // Specific handling for root to avoid a warning when removing a non-existent child parent = root; - - newNode->SetParent(parent); + newNode->parent = root; + root->children.emplace_back(newNode); + } + else + { + newNode->SetParent(parent); + } return newNode; } From 6d646851e256ab6698edff14798c23504cdeb6db Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 22 Sep 2022 20:39:46 +0800 Subject: [PATCH 29/37] Added missing transpose to transform update and a test component to application --- SHADE_Application/src/Scenes/SBTestScene.cpp | 9 +++++++-- .../src/Math/Transform/SHTransformSystem.cpp | 12 +++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index c59fa234..751e17a8 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -8,6 +8,7 @@ #include "Scene/SHSceneManager.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Scripting/SHScriptEngine.h" +#include "Math/Transform/SHTransformComponent.h" using namespace SHADE; @@ -38,11 +39,15 @@ namespace Sandbox auto matInst = graphicsSystem->AddMaterialInstance(); // Create entity and add mesh - testObj = SHADE::SHEntityManager::CreateEntity(); + testObj = SHADE::SHEntityManager::CreateEntity(); auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); renderable.Mesh = CUBE_MESH; renderable.SetMaterial(matInst); - renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f); + // Create transform + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); + transform.SetLocalPosition(SHVec3{ 0.0f, 0.0f, 2.0f }); + + renderable.TransformMatrix = SHMatrix::Translate(0.0f, 0.0f, 2.0f); SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testObj), "TestScript"); } diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 64ad9f43..18e54a89 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -74,11 +74,9 @@ namespace SHADE SHASSERT(IS_NODE_ACTIVE == IS_ENTITY_ACTIVE, "Entity and Node active states are not synced!") #endif + // Anything below is inactive if (!IS_NODE_ACTIVE) - { - UpdateEntity(child); - continue; - } + break; const bool HAS_TRANSFORM = SHComponentManager::HasComponent(child->GetEntityID()); if (!HAS_TRANSFORM) @@ -104,7 +102,7 @@ namespace SHADE if (parent) { localToWorld = parent->GetTRS(); - worldToLocal = SHMatrix::Inverse(tf.local.trs); + worldToLocal = SHMatrix::Inverse(localToWorld); } while (!tf.updateQueue.empty()) @@ -148,6 +146,10 @@ namespace SHADE tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One); tf.world.ComputeTRS(); + + // Transpose TRS to column major + tf.local.trs.Transpose(); + tf.world.trs.Transpose(); } } // namespace SHADE \ No newline at end of file From 5c4384b589ce146828a8c83a64b16c720338f21b Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Thu, 22 Sep 2022 20:53:03 +0800 Subject: [PATCH 30/37] Fixed SHVkBuffer initial copy data for mapped buffers and made the cube spin --- .../src/Application/SBApplication.cpp | 6 +++-- SHADE_Application/src/Scenes/SBTestScene.cpp | 21 +++++++++--------- SHADE_Application/src/Scenes/SBTestScene.h | 2 +- .../src/Graphics/Buffers/SHVkBuffer.cpp | 14 ++++++++---- .../MiddleEnd/Interface/SHRenderable.cpp | 1 - TempShaderFolder/TestCubeVs.glsl | 2 +- TempShaderFolder/TestCubeVs.spv | Bin 1768 -> 1804 bytes 7 files changed, 26 insertions(+), 20 deletions(-) diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 53cc1e40..93d1cdff 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -22,8 +22,8 @@ #include "ECS_Base/Managers/SHEntityManager.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Scene/SHSceneManager.h" - #include "Scenes/SBTestScene.h" +#include "Math/Transform/SHTransformComponent.h" using namespace SHADE; @@ -58,8 +58,10 @@ namespace Sandbox SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); SHADE::SHSystemManager::RegisterRoutine(); - SHADE::SHComponentManager::CreateComponentSparseSet(); + SHADE::SHComponentManager::CreateComponentSparseSet(); + SHADE::SHComponentManager::CreateComponentSparseSet(); + // Set up graphics system and windows graphicsSystem->SetWindow(&window); sdlWindow = SDL_CreateWindowFrom(window.GetHWND()); diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 93d4e19b..e6082d3f 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -30,8 +30,6 @@ namespace Sandbox } void SBTestScene::Init() { - SHComponentManager::CreateComponentSparseSet(); - SHADE::SHGraphicsSystem* graphicsSystem = static_cast(SHADE::SHSystemManager::GetSystem()); // Create temp meshes const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); @@ -41,27 +39,28 @@ namespace Sandbox auto matInst = graphicsSystem->AddMaterialInstance(); // Create entity and add mesh - testEntity = SHADE::SHEntityManager::CreateEntity(); - SHComponentManager::AddComponent(testEntity); - auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testEntity); - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testEntity); + testObj = SHADE::SHEntityManager::CreateEntity(); + //SHComponentManager::AddComponent(testObj); + auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); renderable.Mesh = CUBE_MESH; renderable.SetMaterial(matInst); renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f); - - transform.SetWorldPosition (SHVec3 (0.0f, 0.0f, 2.0f)); // Add script SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); - scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testEntity), "TestScript"); + scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testObj), "TestScript"); } + void SBTestScene::Update(float dt) { static float rotation = 0.0f; - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testEntity); - transform.SetWorldRotation (rotation, 0.0f, 0.0f); + auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); + SHTransform tf; + tf.rotation = SHVec3(rotation, 0.0f, 0.0f); + renderable.TransformMatrix = tf.ComputeTRS(); rotation += dt * 10.0f; diff --git a/SHADE_Application/src/Scenes/SBTestScene.h b/SHADE_Application/src/Scenes/SBTestScene.h index bb382477..81ee3e7b 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.h +++ b/SHADE_Application/src/Scenes/SBTestScene.h @@ -9,7 +9,7 @@ namespace Sandbox { private: EntityID camera; - unsigned int testEntity; + EntityID testObj; public: virtual void Load(); diff --git a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp index 59916731..da4bc292 100644 --- a/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Buffers/SHVkBuffer.cpp @@ -419,14 +419,20 @@ namespace SHADE // mainly host visible. Can be cached (need to flush/invalidate), uncached (always coherent) and coherent (virtual). if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - if (allocFlags | VMA_ALLOCATION_CREATE_MAPPED_BIT) - mappedPtr = allocInfo.pMappedData; + const bool CREATE_MAPPED = allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT; + + if (CREATE_MAPPED) + mappedPtr = allocInfo.pMappedData; else mappedPtr = nullptr; - if (data) - MapWriteUnmap(data, srcSize, 0, 0); + { + if (CREATE_MAPPED) + WriteToMemory(data, srcSize, 0, 0); + else + MapWriteUnmap(data, srcSize, 0, 0); + } } else { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index 984e753b..32a6a99a 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -27,7 +27,6 @@ namespace SHADE sharedMaterial = {}; material = {}; oldMaterial = {}; - } void SHRenderable::OnDestroy() diff --git a/TempShaderFolder/TestCubeVs.glsl b/TempShaderFolder/TestCubeVs.glsl index 1e3a11d7..b2d52104 100644 --- a/TempShaderFolder/TestCubeVs.glsl +++ b/TempShaderFolder/TestCubeVs.glsl @@ -57,6 +57,6 @@ void main() // render NDC first //gl_Position = vec4(aVertexPos, 1.0f); - gl_Position = cameraData.vpMat * vec4 (aVertexPos, 1.0f); + gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f); Out.vertColor = vec4 (aVertexPos, 1.0f); } \ No newline at end of file diff --git a/TempShaderFolder/TestCubeVs.spv b/TempShaderFolder/TestCubeVs.spv index f0b31ea23f835273164024fc22e42f8e3c4cc918..eb9a1209e697acf798dc5ab441bdbdfed631bc9c 100644 GIT binary patch literal 1804 zcmZ9LYflqF6o$uM06{=RE-KcRdPflzh>1~S3Mn6|U_ib$lXfMWY`4vJTQ8sd3;L7% zRemw?eRg-qhH1{udEfKSnKNgm#X^13m`i5b%$i-3js;T?W6X@1NakkixV1TqyPMlP zTPWsCF%hDfH&+tBq;JpqAz)T^LspSJmc5j1%XVZ%{R*1@XmLrqHe2oH;bF72-|h?s z?P2^q@Y;bNdhMF$S&>`4gFzTE>G9HrCAgMa`Yudd^6XzxJb`dlK1j_@y89QZ0SA z>9KW2xT1L|jzJHcKUQZN{h%L-N5fqmj^f1U&g|z?`K9FU>_?@yfp9swM|)z!GcTk( zb0Cg>Gu-Sr&H=~lIC=?3-yDYz$2~R`!AD2j^{Fn*IFJgCoaF?k8Zerx7dSoegd;EO z$lFv7db)lA*Mu3w-5XA8Dkblk-ZF^OuRNw_VCo>wn+Lo7c>iF|x+oUDCIrS`mN%if zDqGQd>ISp_lD<=#t1`w$hA+!!zct}$&FJAO^5~(*N`nDt=p0zG|M z)66-k7yWI`#Ng3`-950M>!~q6-=V*+IBTi7B9H$AKCwrdiNTQz%ss=g_jAqU<1FZ3 zXl8GC^kCiroU4U*kjK0O@UC7jdFUg9J^qT}O~2QdzAVe=9sPPEB|TY@!8?3YKK=Qv zHNaiFLz}0FNNZ K|EH|4Wd8wmlZ7(? literal 1768 zcmZ9LYflqF6ovA)6cQnt1#>m=i~9Dg9|GoNw`AM0r!p4p%3jC{`b}#7qs2w-+Gw^LtyZIX*zODl z?P2^Q@Y;bNdhMp&^2?c)S}q13ZLFE~OPV{m^>FmqrpMD+&=t&MughQqHC z8*`)x{bsn?ahwB=*>Us|j=nh#AC7x$D1wiUxa(6*m~kW(963t~PBmaO*Di5-;0Z@w z){(cN9Q1Va65bGI5U0PD1f`h1Vcsen`^;;u z%E-$;-~}0DO_=_Ym%1wY(o@%C@?RI`Jn-ZP(`z`F?}mKxqhHQqt!GM$e`xGVtCUZ^rbH=GI~e9-b$JFDCNQQ Date: Thu, 22 Sep 2022 22:58:14 +0800 Subject: [PATCH 31/37] Changed editor pause for transform system to true --- SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index 18e54a89..f61f3e42 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -30,7 +30,7 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHTransformSystem::TransformUpdateRoutine::TransformUpdateRoutine() - : SHSystemRoutine { "Transform Update", false } + : SHSystemRoutine { "Transform Update", true } {} From c2e948a100ca027017234697b59dc3b1a4009d60 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Fri, 23 Sep 2022 15:48:00 +0800 Subject: [PATCH 32/37] Fixed active state checks in transform system Apparently entity and scene node active states do not sync.... --- .../src/Math/Transform/SHTransformSystem.cpp | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp index f61f3e42..8f05f96f 100644 --- a/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp +++ b/SHADE_Engine/src/Math/Transform/SHTransformSystem.cpp @@ -66,17 +66,8 @@ namespace SHADE for (const auto* child : node->GetChildren()) { - // Active states of entities should sync with scene nodes - const bool IS_NODE_ACTIVE = child->IsActive(); - - #ifdef _DEBUG - const bool IS_ENTITY_ACTIVE = SHEntityManager::GetEntityByID(child->GetEntityID())->GetActive(); - SHASSERT(IS_NODE_ACTIVE == IS_ENTITY_ACTIVE, "Entity and Node active states are not synced!") - #endif - - // Anything below is inactive - if (!IS_NODE_ACTIVE) - break; + + const bool HAS_TRANSFORM = SHComponentManager::HasComponent(child->GetEntityID()); if (!HAS_TRANSFORM) @@ -84,8 +75,13 @@ namespace SHADE auto* childTransform = SHComponentManager::GetComponent(child->GetEntityID()); - if (childTransform->dirty || HAS_PARENT_CHANGED) - UpdateTransform(*childTransform, NODE_TRANSFORM); + // Only update if node in hierarchy and component are both active + const bool IS_NODE_ACTIVE = child->IsActive(); + if (IS_NODE_ACTIVE && childTransform->isActive) + { + if (childTransform->dirty || HAS_PARENT_CHANGED) + UpdateTransform(*childTransform, NODE_TRANSFORM); + } UpdateEntity(child); From 23f0f9f77e68cf050e58f7de3f84c6c02e3b521f Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 23 Sep 2022 16:24:08 +0800 Subject: [PATCH 33/37] Triple buffered the batching buffers --- .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 177 +++++++++++------- .../src/Graphics/MiddleEnd/Batching/SHBatch.h | 22 ++- .../Graphics/MiddleEnd/Batching/SHBatcher.cpp | 10 +- .../Graphics/MiddleEnd/Batching/SHBatcher.h | 4 +- .../MiddleEnd/Batching/SHSuperBatch.cpp | 14 +- .../MiddleEnd/Batching/SHSuperBatch.h | 6 +- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 2 +- .../Graphics/RenderGraph/SHRenderGraph.cpp | 25 +-- .../src/Graphics/RenderGraph/SHRenderGraph.h | 7 +- 9 files changed, 158 insertions(+), 109 deletions(-) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index c2090fc0..1ac783e0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -33,6 +33,9 @@ namespace SHADE { if (!pipeline) throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!"); + + // Mark all as dirty + setAllDirtyFlags(); } void SHBatch::Add(const SHRenderable* renderable) @@ -52,6 +55,9 @@ namespace SHADE // Add renderable in subBatch->Renderables.insert(renderable); + + // Mark all as dirty + setAllDirtyFlags(); } void SHBatch::Remove(const SHRenderable* renderable) @@ -67,6 +73,10 @@ namespace SHADE return; subBatch->Renderables.erase(renderable); + + // Mark all as dirty + for (bool& dirt : isDirty) + dirt = true; } void SHBatch::Clear() @@ -81,13 +91,22 @@ namespace SHADE // Clear GPU buffers - drawDataBuffer.Free(); - transformDataBuffer.Free(); - matPropsBuffer.Free(); + for (int i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) + { + drawDataBuffer[i].Free(); + transformDataBuffer[i].Free(); + matPropsBuffer[i].Free(); + } } - void SHBatch::UpdateTransformBuffer() + void SHBatch::UpdateTransformBuffer(uint32_t frameIndex) { + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to update transform buffers with an invalid frame index."); + return; + } + // Reset Transform Data transformData.clear(); @@ -100,13 +119,19 @@ namespace SHADE } // Transfer to GPU - transformDataBuffer->WriteToMemory(transformData.data(), transformData.size() * sizeof(SHMatrix), 0, 0); + transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), transformData.size() * sizeof(SHMatrix), 0, 0); } - void SHBatch::Build(Handle device) + void SHBatch::Build(Handle device, uint32_t frameIndex) { + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to update build batch buffers with an invalid frame index."); + return; + } + // No need to build as there are no changes - if (!isDirty) + if (!isDirty[frameIndex]) return; // Count number of elements @@ -116,61 +141,67 @@ namespace SHADE numTotalElements += subBatch.Renderables.size(); } - // Generate CPU buffers - // - Draw data - drawData.reserve(subBatches.size()); - drawData.clear(); - // - Transform data - transformData.reserve(numTotalElements); - transformData.clear(); - // - Material Properties Data - const Handle SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface - ( - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, - SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, - vk::ShaderStageFlagBits::eFragment - ); - const bool EMPTY_MAT_PROPS = !SHADER_INFO; - Byte singleMatPropSize = 0; - Byte matPropTotalBytes = 0; - if (!EMPTY_MAT_PROPS) + // Generate CPU buffers if there are changes + if (isCPUBuffersDirty) { - singleMatPropSize = SHADER_INFO->GetBytesRequired(); - matPropTotalBytes = drawData.size() * singleMatPropSize; - if (matPropsDataSize < matPropTotalBytes) + // - Draw data + drawData.reserve(subBatches.size()); + drawData.clear(); + // - Transform data + transformData.reserve(numTotalElements); + transformData.clear(); + // - Material Properties Data + const Handle SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface + ( + SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, + vk::ShaderStageFlagBits::eFragment + ); + const bool EMPTY_MAT_PROPS = !SHADER_INFO; + Byte singleMatPropSize = 0; + Byte matPropTotalBytes = 0; + if (!EMPTY_MAT_PROPS) { - matPropsData.reset(new char[matPropTotalBytes]); - matPropsDataSize = matPropTotalBytes; - } - } - - // Build Sub Batches - uint32_t nextInstanceIndex = 0; - char* propsCurrPtr = matPropsData.get(); - for (auto& subBatch : subBatches) - { - // Create command - drawData.emplace_back(vk::DrawIndexedIndirectCommand - { - .indexCount = subBatch.Mesh->IndexCount, - .instanceCount = static_cast(subBatch.Renderables.size()), - .firstIndex = subBatch.Mesh->FirstIndex, - .vertexOffset = subBatch.Mesh->FirstVertex, - .firstInstance = nextInstanceIndex - }); - - // Fill in buffers (CPU) - for (const SHRenderable* renderable : subBatch.Renderables) - { - // Transform - transformData.emplace_back(renderable->TransformMatrix); - // Material Properties - if (!EMPTY_MAT_PROPS) + singleMatPropSize = SHADER_INFO->GetBytesRequired(); + matPropTotalBytes = drawData.size() * singleMatPropSize; + if (matPropsDataSize < matPropTotalBytes) { - renderable->GetMaterial()->ExportProperties(propsCurrPtr); - propsCurrPtr += singleMatPropSize; + matPropsData.reset(new char[matPropTotalBytes]); + matPropsDataSize = matPropTotalBytes; } } + + // Build Sub Batches + uint32_t nextInstanceIndex = 0; + char* propsCurrPtr = matPropsData.get(); + for (auto& subBatch : subBatches) + { + // Create command + drawData.emplace_back(vk::DrawIndexedIndirectCommand + { + .indexCount = subBatch.Mesh->IndexCount, + .instanceCount = static_cast(subBatch.Renderables.size()), + .firstIndex = subBatch.Mesh->FirstIndex, + .vertexOffset = subBatch.Mesh->FirstVertex, + .firstInstance = nextInstanceIndex + }); + + // Fill in buffers (CPU) + for (const SHRenderable* renderable : subBatch.Renderables) + { + // Transform + transformData.emplace_back(renderable->TransformMatrix); + // Material Properties + if (!EMPTY_MAT_PROPS) + { + renderable->GetMaterial()->ExportProperties(propsCurrPtr); + propsCurrPtr += singleMatPropSize; + } + } + } + + // Successfully update CPU buffers + isCPUBuffersDirty = false; } // Send all buffered data to the GPU buffers @@ -179,36 +210,52 @@ namespace SHADE const uint32_t DRAW_DATA_BYTES = static_cast(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, drawDataBuffer, drawData.data(), DRAW_DATA_BYTES, + device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES, BuffUsage::eIndirectBuffer ); // - Transform Buffer const uint32_t TF_DATA_BYTES = static_cast(transformData.size() * sizeof(SHMatrix)); SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, transformDataBuffer, transformData.data(), TF_DATA_BYTES, + device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, BuffUsage::eVertexBuffer ); // - Material Properties Buffer - if (!EMPTY_MAT_PROPS) + if (matPropsData) { SHVkUtil::EnsureBufferAndCopyHostVisibleData ( - device, matPropsBuffer, matPropsData.get(), static_cast(matPropTotalBytes), + device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast(matPropsDataSize), BuffUsage::eStorageBuffer ); } - isDirty = false; + isDirty[frameIndex] = false; } /*---------------------------------------------------------------------------------*/ /* SHBatch - Usage Functions */ /*---------------------------------------------------------------------------------*/ - void SHBatch::Draw(Handle cmdBuffer) + void SHBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) { + if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) + { + SHLOG_WARNING("[SHBatch] Attempted to draw a batch with an invalid frame index."); + return; + } + cmdBuffer->BindPipeline(pipeline); - cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer, 0); - cmdBuffer->DrawMultiIndirect(drawDataBuffer, static_cast(drawData.size())); + cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); + cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast(drawData.size())); + } + + /*---------------------------------------------------------------------------------*/ + /* SHBatch - Helper Functions */ + /*---------------------------------------------------------------------------------*/ + void SHBatch::setAllDirtyFlags() + { + for (bool& dirt : isDirty) + dirt = true; + isCPUBuffersDirty = true; } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index f438d6c1..a572adca 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -14,12 +14,14 @@ of DigiPen Institute of Technology is prohibited. // STL Includes #include +#include // External Dependencies #include "Graphics/SHVulkanIncludes.h" // Project Includes #include "Resource/Handle.h" #include "Graphics/MiddleEnd/Interface/SHMaterial.h" #include "Math/SHMatrix.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" namespace SHADE { @@ -71,9 +73,9 @@ namespace SHADE void Add(const SHRenderable* renderable); void Remove(const SHRenderable* renderable); void Clear(); - void UpdateTransformBuffer(); - void Build(Handle device); - void Draw(Handle cmdBuffer); + void UpdateTransformBuffer(uint32_t frameIndex); + void Build(Handle device, uint32_t frameIndex); + void Draw(Handle cmdBuffer, uint32_t frameIndex); /*-----------------------------------------------------------------------------*/ /* Getter Functions */ @@ -88,15 +90,21 @@ namespace SHADE Handle pipeline; // Batch Tree std::vector subBatches; - bool isDirty = true; + std::array isDirty; // CPU Buffers std::vector drawData; std::vector transformData; std::unique_ptr matPropsData; Byte matPropsDataSize = 0; + bool isCPUBuffersDirty = true; // GPU Buffers - Handle drawDataBuffer; - Handle transformDataBuffer; - Handle matPropsBuffer; + std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> drawDataBuffer; + std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> transformDataBuffer; + std::array, SHGraphicsConstants::NUM_FRAME_BUFFERS> matPropsBuffer; + + /*-----------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------*/ + void setAllDirtyFlags(); }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp index ea216ed5..ecd99a20 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.cpp @@ -91,12 +91,12 @@ namespace SHADE (*superBatch)->Remove(renderable); } - void SHBatcher::FinaliseBatches(Handle device) + void SHBatcher::FinaliseBatches(Handle device, uint32_t frameIndex) { // Build SuperBatches for (auto& batch : superBatches) { - batch->Build(device); + batch->Build(device, frameIndex); } } @@ -109,11 +109,11 @@ namespace SHADE superBatches.clear(); } - void SHBatcher::UpdateTransformBuffer() - { + void SHBatcher::UpdateTransformBuffer(uint32_t frameIndex) +{ for (auto& batch : superBatches) { - batch->UpdateTransformBuffer(); + batch->UpdateTransformBuffer(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h index 89dea2eb..b4fff203 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatcher.h @@ -51,9 +51,9 @@ namespace SHADE void PrepareBatches(); void AddToBatch(SHRenderable const* renderable); void RemoveFromBatch(SHRenderable const* renderable); - void FinaliseBatches(Handle device); + void FinaliseBatches(Handle device, uint32_t frameIndex); void ClearBatches(); - void UpdateTransformBuffer(); + void UpdateTransformBuffer(uint32_t frameIndex); void RegisterSuperBatch(Handle superBatch); void DeregisterSuperBatch(Handle superBatch); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 8b7ea619..a259f2cf 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -78,29 +78,29 @@ namespace SHADE batches.clear(); } - void SHSuperBatch::UpdateTransformBuffer() - { + void SHSuperBatch::UpdateTransformBuffer(uint32_t frameIndex) +{ for (auto& batch : batches) { - batch.UpdateTransformBuffer(); + batch.UpdateTransformBuffer(frameIndex); } } - void SHSuperBatch::Build(Handle device) noexcept + void SHSuperBatch::Build(Handle device, uint32_t frameIndex) noexcept { // Build all batches for (auto& batch : batches) { - batch.Build(device); + batch.Build(device, frameIndex); } } - void SHSuperBatch::Draw(Handle cmdBuffer) noexcept + void SHSuperBatch::Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept { // Build all batches for (auto& batch : batches) { - batch.Draw(cmdBuffer); + batch.Draw(cmdBuffer, frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h index 6151e56e..5379ee61 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -55,9 +55,9 @@ namespace SHADE void Add(const SHRenderable* renderable) noexcept; void Remove(const SHRenderable* renderable) noexcept; void Clear() noexcept; - void UpdateTransformBuffer(); - void Build(Handle device) noexcept; - void Draw(Handle cmdBuffer) noexcept; + void UpdateTransformBuffer(uint32_t frameIndex); + void Build(Handle device, uint32_t frameIndex) noexcept; + void Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept; /*-----------------------------------------------------------------------------*/ /* Getter Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index cee00c9b..a68812f8 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -306,7 +306,7 @@ namespace SHADE for (auto vp : viewports) for (auto renderer : vp->GetRenderers()) { - renderer->GetRenderGraph()->FinaliseBatch(); + renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame()); } // Resize diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index f53f3e99..ecf9059c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -346,13 +346,13 @@ namespace SHADE inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal }); } - void SHSubpass::Execute(Handle& commandBuffer) noexcept + void SHSubpass::Execute(Handle& commandBuffer, uint32_t frameIndex) noexcept { // Ensure correct transforms are provided - superBatch->UpdateTransformBuffer(); + superBatch->UpdateTransformBuffer(frameIndex); // Draw all the batches - superBatch->Draw(commandBuffer); + superBatch->Draw(commandBuffer, frameIndex); // Draw all the exterior draw calls for (auto& drawCall : exteriorDrawCalls) @@ -591,7 +591,7 @@ namespace SHADE for (uint32_t i = 0; i < subpasses.size(); ++i) { - subpasses[i]->Execute(commandBuffer); + subpasses[i]->Execute(commandBuffer, frameIndex); // Go to next subpass if not last subpass if (i != subpasses.size() - 1) @@ -624,14 +624,9 @@ namespace SHADE return pipeline; } - void SHRenderGraphNode::FinaliseBatch() - { - batcher.FinaliseBatches(logicalDeviceHdl); - } - - void SHRenderGraphNode::UpdateBatchTransforms() - { - batcher.UpdateTransformBuffer(); + void SHRenderGraphNode::FinaliseBatch(uint32_t frameIndex) +{ + batcher.FinaliseBatches(logicalDeviceHdl, frameIndex); } /***************************************************************************/ @@ -1088,11 +1083,11 @@ namespace SHADE node->Execute(cmdBuffer, frameIndex); } - void SHRenderGraph::FinaliseBatch() - { + void SHRenderGraph::FinaliseBatch(uint32_t frameIndex) +{ for (auto& node : nodes) { - node->FinaliseBatch(); + node->FinaliseBatch(frameIndex); } } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 16770475..b8c00417 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -137,7 +137,7 @@ namespace SHADE void AddInput(std::string resourceToReference) noexcept; // Runtime functions - void Execute(Handle& commandBuffer) noexcept; + void Execute(Handle& commandBuffer, uint32_t frameIndex) noexcept; void AddExteriorDrawCalls(std::function&)> const& newDrawCall) noexcept; /*-----------------------------------------------------------------------*/ @@ -230,8 +230,7 @@ namespace SHADE // TODO: RemoveSubpass() void Execute (Handle& commandBuffer, uint32_t frameIndex) noexcept; Handle GetOrCreatePipeline (std::pair, Handle> const& vsFsPair, Handle subpass) noexcept; - void FinaliseBatch(); - void UpdateBatchTransforms(); + void FinaliseBatch(uint32_t frameIndex); /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ @@ -289,7 +288,7 @@ namespace SHADE Handle AddNode (std::string nodeName, std::initializer_list resourceNames, std::initializer_list predecessorNodes) noexcept; void Generate (void) noexcept; void Execute (uint32_t frameIndex, Handle cmdBuffer) noexcept; - void FinaliseBatch(); + void FinaliseBatch(uint32_t frameIndex); /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ From 77cccd63be66d2e0991c29f5c3d1c0751bc06ff1 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 23 Sep 2022 16:41:44 +0800 Subject: [PATCH 34/37] Renderables now use TransformComponent's matrix --- SHADE_Application/src/Scenes/SBTestScene.cpp | 10 ++------ .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 24 +++++++++++++++++-- .../MiddleEnd/Interface/SHRenderable.cpp | 1 - .../MiddleEnd/Interface/SHRenderable.h | 1 - 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index c642aa67..1c4af3a7 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -45,11 +45,7 @@ namespace Sandbox renderable.Mesh = CUBE_MESH; renderable.SetMaterial(matInst); - // Create transform - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); - transform.SetLocalPosition(SHVec3{ 0.0f, 0.0f, 2.0f }); - renderable.TransformMatrix = SHMatrix::Translate(0.0f, 0.0f, 2.0f); SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testObj), "TestScript"); } @@ -58,11 +54,9 @@ namespace Sandbox { static float rotation = 0.0f; - auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); - SHTransform tf; - tf.rotation = SHVec3(rotation, 0.0f, 0.0f); - renderable.TransformMatrix = tf.ComputeTRS(); + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); + transform.SetLocalRotation(rotation, 0.0f, 0.0f); rotation += dt * 10.0f; // Destroy entity if space is pressed diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 1ac783e0..9d496821 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -22,6 +22,8 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "Math/Transform/SHTransformComponent.h" namespace SHADE { @@ -115,7 +117,16 @@ namespace SHADE for (const SHRenderable* renderable : subBatch.Renderables) { // Transform - transformData.emplace_back(renderable->TransformMatrix); + auto transform = SHComponentManager::GetComponent_s(renderable->GetEID()); + if (!transform) + { + SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); + transformData.emplace_back(); + } + else + { + transformData.emplace_back(transform->GetTRS()); + } } // Transfer to GPU @@ -190,7 +201,16 @@ namespace SHADE for (const SHRenderable* renderable : subBatch.Renderables) { // Transform - transformData.emplace_back(renderable->TransformMatrix); + auto transform = SHComponentManager::GetComponent_s(renderable->GetEID()); + if (!transform) + { + SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); + transformData.emplace_back(); + } + else + { + transformData.emplace_back(transform->GetTRS()); + } // Material Properties if (!EMPTY_MAT_PROPS) { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp index 32a6a99a..5199565c 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.cpp @@ -92,5 +92,4 @@ namespace SHADE materialChanged = false; oldMaterial = {}; } - } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h index 0d48b5cb..3bb7cfda 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderable.h @@ -66,7 +66,6 @@ namespace SHADE /* Data Members */ /*-------------------------------------------------------------------------------*/ Handle Mesh; - SHMatrix TransformMatrix; // TODO: Replace with Transform component private: /*-------------------------------------------------------------------------------*/ From f8391d6c9e6bf3ae48bf2b8dbe1e84a06e36c566 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 23 Sep 2022 16:45:06 +0800 Subject: [PATCH 35/37] Modified TestScene space bar input to not destroy the object, only remove scripts --- SHADE_Application/src/Scenes/SBTestScene.cpp | 7 +++++-- SHADE_Engine/src/Scripting/SHScriptEngine.cpp | 12 ++++++------ SHADE_Engine/src/Scripting/SHScriptEngine.h | 6 +++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 1c4af3a7..f5985715 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -47,7 +47,7 @@ namespace Sandbox renderable.SetMaterial(matInst); SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); - scriptEngine->AddScript(*SHADE::SHEntityManager::GetEntityByID(testObj), "TestScript"); + scriptEngine->AddScript(testObj, "TestScript"); } void SBTestScene::Update(float dt) @@ -61,7 +61,10 @@ namespace Sandbox // Destroy entity if space is pressed if (GetKeyState(VK_SPACE) & 0x8000) - SHADE::SHEntityManager::DestroyEntity(testObj); + { + SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); + scriptEngine->RemoveAllScripts(testObj); + } } void SBTestScene::Render() diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index fada5b70..0c508a34 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -103,17 +103,17 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Script Manipulation Functions */ /*-----------------------------------------------------------------------------------*/ - bool SHScriptEngine::AddScript(const SHEntity& entity, const std::string_view& scriptName) + bool SHScriptEngine::AddScript(EntityID entity, const std::string_view& scriptName) { - return csScriptsAdd(entity.GetEID(), scriptName.data()); + return csScriptsAdd(entity, scriptName.data()); } - void SHScriptEngine::RemoveAllScripts(const SHEntity& entity) + void SHScriptEngine::RemoveAllScripts(EntityID entity) { - csScriptsRemoveAll(entity.GetEID()); + csScriptsRemoveAll(entity); } - void SHScriptEngine::RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy) + void SHScriptEngine::RemoveAllScriptsImmediately(EntityID entity, bool callOnDestroy) { - csScriptsRemoveAllImmediately(entity.GetEID(), callOnDestroy); + csScriptsRemoveAllImmediately(entity, callOnDestroy); } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 0994bb5d..08852e90 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -116,14 +116,14 @@ namespace SHADE /// True if successfully added. False otherwise with the error logged to the /// console. /// - bool AddScript(const SHEntity& entity, const std::string_view& scriptName); + bool AddScript(EntityID entity, const std::string_view& scriptName); /// /// Removes all Scripts attached to the specified Entity. Does not do anything /// if the specified Entity is invalid or does not have any Scripts /// attached. /// /// The entity to remove the scripts from. - void RemoveAllScripts(const SHEntity& entity); + void RemoveAllScripts(EntityID entity); /// /// Removes all Scripts attached to the specified Entity. Unlike /// RemoveAllScripts(), this removes all the scripts immediately. @@ -135,7 +135,7 @@ namespace SHADE /// Whether or not to call OnDestroy on the scripts. This is ignored if not in /// play mode. /// - void RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy); + void RemoveAllScriptsImmediately(EntityID entity, bool callOnDestroy); /*-----------------------------------------------------------------------------*/ /* Script Serialisation Functions */ From bb382461115fb4f7d9b4abd160aadfd3edbbb5fa Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Fri, 23 Sep 2022 18:49:04 +0800 Subject: [PATCH 36/37] Added stress test code for 20000 objects --- SHADE_Application/src/Scenes/SBTestScene.cpp | 43 ++++++++++++++----- SHADE_Application/src/Scenes/SBTestScene.h | 1 + .../Graphics/MiddleEnd/Batching/SHBatch.cpp | 3 +- .../MiddleEnd/Batching/SHSuperBatch.cpp | 2 +- .../Graphics/MiddleEnd/Interface/SHCamera.cpp | 36 ++++++++-------- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 3 +- 6 files changed, 57 insertions(+), 31 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index f5985715..0caf3c7e 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -38,26 +38,49 @@ namespace Sandbox // Create Materials auto matInst = graphicsSystem->AddMaterialInstance(); - // Create entity and add mesh - testObj = SHADE::SHEntityManager::CreateEntity(); - auto& renderable = *SHADE::SHComponentManager::GetComponent_s(testObj); - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); + // Create Stress Test Objects + static const SHVec3 TEST_OBJ_SCALE = { 0.2f, 0.2f, 0.2f }; + constexpr int NUM_ROWS = 200; + constexpr int NUM_COLS = 100; + static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f }; + static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ), 0.0f, 0.0f }; + for (int z = 0; z < NUM_ROWS; ++z) + for (int x = 0; x < NUM_COLS; ++x) + { + auto entity = SHEntityManager::CreateEntity(); + auto& renderable = *SHComponentManager::GetComponent_s(entity); + auto& transform = *SHComponentManager::GetComponent_s(entity); - renderable.Mesh = CUBE_MESH; - renderable.SetMaterial(matInst); + renderable.Mesh = CUBE_MESH; + renderable.SetMaterial(matInst); + // Set initial positions + transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, 0.0f, z * TEST_OBJ_SPACING.z }); + //transform.SetLocalScale(TEST_OBJ_SCALE); + + stressTestObjects.emplace_back(entity); + } + + // Create blank entity with a script + testObj = SHADE::SHEntityManager::CreateEntity(); SHADE::SHScriptEngine* scriptEngine = static_cast(SHADE::SHSystemManager::GetSystem()); scriptEngine->AddScript(testObj, "TestScript"); } void SBTestScene::Update(float dt) { - static float rotation = 0.0f; + /*static float rotation = 0.0f; - auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); + auto& transform = *SHADE::SHComponentManager::GetComponent_s(testObj); - transform.SetLocalRotation(rotation, 0.0f, 0.0f); - rotation += dt * 10.0f; + transform.SetLocalRotation(rotation, 0.0f, 0.0f); + rotation += dt * 10.0f;*/ + /*static float rotation = 0.0f; + + auto& transform = *SHADE::SHComponentManager::GetComponent_s(stressTestObjects[0]); + + transform.SetWorldPosition({rotation, 0.0f, 0.0f}); + rotation += dt * 10.0f;*/ // Destroy entity if space is pressed if (GetKeyState(VK_SPACE) & 0x8000) diff --git a/SHADE_Application/src/Scenes/SBTestScene.h b/SHADE_Application/src/Scenes/SBTestScene.h index 81ee3e7b..3a1598d5 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.h +++ b/SHADE_Application/src/Scenes/SBTestScene.h @@ -10,6 +10,7 @@ namespace Sandbox private: EntityID camera; EntityID testObj; + std::vector stressTestObjects; public: virtual void Load(); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 9d496821..a68ee7fa 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -117,7 +117,7 @@ namespace SHADE for (const SHRenderable* renderable : subBatch.Renderables) { // Transform - auto transform = SHComponentManager::GetComponent_s(renderable->GetEID()); + auto transform = SHComponentManager::GetComponent(renderable->GetEID()); if (!transform) { SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); @@ -211,6 +211,7 @@ namespace SHADE { transformData.emplace_back(transform->GetTRS()); } + // Material Properties if (!EMPTY_MAT_PROPS) { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index a259f2cf..633d40a9 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -79,7 +79,7 @@ namespace SHADE } void SHSuperBatch::UpdateTransformBuffer(uint32_t frameIndex) -{ + { for (auto& batch : batches) { batch.UpdateTransformBuffer(frameIndex); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp index 992aff05..4a1117c3 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHCamera.cpp @@ -22,24 +22,24 @@ namespace SHADE void SHCamera::SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up) { SHVec3 view = target - pos; view = SHVec3::Normalise(view); - SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); - const SHVec3 UP = SHVec3::Cross(right, view); - - viewMatrix = SHMatrix::Identity; - viewMatrix(0, 0) = UP[0]; - viewMatrix(1, 0) = UP[1]; - viewMatrix(2, 0) = UP[2]; - viewMatrix(0, 1) = right[0]; - viewMatrix(1, 1) = right[1]; - viewMatrix(2, 1) = right[2]; - viewMatrix(0, 2) = view[0]; - viewMatrix(1, 2) = view[1]; - viewMatrix(2, 2) = view[2]; - viewMatrix(3, 0) = -UP.Dot(pos); - viewMatrix(3, 1) = -right.Dot(pos); - viewMatrix(3, 2) = -view.Dot(pos); - - isDirty = true; + SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right); + const SHVec3 UP = SHVec3::Cross(right, view); + + viewMatrix = SHMatrix::Identity; + viewMatrix(0, 0) = UP[0]; + viewMatrix(1, 0) = UP[1]; + viewMatrix(2, 0) = UP[2]; + viewMatrix(0, 1) = right[0]; + viewMatrix(1, 1) = right[1]; + viewMatrix(2, 1) = right[2]; + viewMatrix(0, 2) = view[0]; + viewMatrix(1, 2) = view[1]; + viewMatrix(2, 2) = view[2]; + viewMatrix(3, 0) = -UP.Dot(pos); + viewMatrix(3, 1) = -right.Dot(pos); + viewMatrix(3, 2) = -view.Dot(pos); + + isDirty = true; } /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index a68812f8..48f16713 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -114,7 +114,8 @@ namespace SHADE screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f)); screenCamera->SetOrthographic(static_cast(windowDims.first), static_cast(windowDims.second), 0.01f, 100.0f); worldCamera = resourceManager.Create(); - worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); + //worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); + worldCamera->SetLookAt(SHVec3(0.0f, 5.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f)); worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); // Create Default Viewport From bd54b16e0170834d33b11cd740289f1af7df6acd Mon Sep 17 00:00:00 2001 From: Brandon Mak Date: Fri, 23 Sep 2022 18:50:40 +0800 Subject: [PATCH 37/37] Ctor for compute pipelines --- .../Graphics/Devices/SHVkLogicalDevice.cpp | 4 +-- .../src/Graphics/Devices/SHVkLogicalDevice.h | 6 ++-- .../MiddleEnd/Pipeline/SHPipelineLibrary.cpp | 2 +- .../src/Graphics/Pipeline/SHVkPipeline.cpp | 35 ++++++++++++++++--- .../src/Graphics/Pipeline/SHVkPipeline.h | 6 ++-- 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 65b0d9ca..5ed17511 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -493,9 +493,9 @@ namespace SHADE */ /***************************************************************************/ - Handle SHVkLogicalDevice::CreatePipeline(Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass, SH_PIPELINE_TYPE type) noexcept + Handle SHVkLogicalDevice::CreateGraphicsPipeline(Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass) noexcept { - return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutHdl, state, renderpassHdl, subpass, type); + return SHVkInstance::GetResourceManager().Create (GetHandle(), pipelineLayoutHdl, state, renderpassHdl, subpass); } diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index 3a27e4b1..8a197ef8 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -21,6 +21,7 @@ #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" #include "Graphics/Images/SHVkImage.h" + namespace SHADE { /*-----------------------------------------------------------------------*/ @@ -171,12 +172,11 @@ namespace SHADE std::string const& shaderName ) noexcept; - Handle CreatePipeline ( + Handle CreateGraphicsPipeline ( Handle const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle const& renderpassHdl, - Handle subpass, - SH_PIPELINE_TYPE type + Handle subpass ) noexcept; Handle CreateRenderpass (std::span const vkDescriptions, std::vector const& subpasses) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index e09a4945..92d832f1 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -18,7 +18,7 @@ namespace SHADE auto pipelineLayout = logicalDevice->CreatePipelineLayout(params); // Create the pipeline and configure the default vertex input state - auto newPipeline = logicalDevice->CreatePipeline(pipelineLayout, nullptr, renderpass, subpass, SH_PIPELINE_TYPE::GRAPHICS); + auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass); newPipeline->GetPipelineState().SetVertexInputState(globalData->GetDefaultViState()); // Actually construct the pipeline diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp index 1c47c21a..c03fd2a7 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.cpp @@ -179,7 +179,7 @@ namespace SHADE /*! \brief - Non-default ctor. + Non-default ctor for creating graphics pipeline. \param inLogicalDeviceHdl Needed for creation and destruction. @@ -200,14 +200,12 @@ namespace SHADE The subpass that this pipeline will be used in. If state is not nullptr, this parameter is ignored. - \param type - The type of the pipeline. */ /***************************************************************************/ - SHVkPipeline::SHVkPipeline(Handle const& inLogicalDeviceHdl, Handle const& inPipelineLayout, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass, SH_PIPELINE_TYPE type) noexcept + SHVkPipeline::SHVkPipeline(Handle const& inLogicalDeviceHdl, Handle const& inPipelineLayout, SHVkPipelineState const* const state, Handle const& renderpassHdl, Handle subpass) noexcept : pipelineState{ } - , pipelineType {type} + , pipelineType {SH_PIPELINE_TYPE::GRAPHICS} , vkPipeline {VK_NULL_HANDLE} , logicalDeviceHdl{ inLogicalDeviceHdl } , pipelineLayout { inPipelineLayout } @@ -250,6 +248,33 @@ namespace SHADE vkPipeline = VK_NULL_HANDLE; } + /***************************************************************************/ + /*! + + \brief + Just to differentiate between compute and graphics pipeline, we will + have a constructor that takes in less parameters; sufficient for the + compute pipeline to be created. + + \param inLogicalDeviceHdl + \param inPipelineLayout + + \return + + */ + /***************************************************************************/ + SHVkPipeline::SHVkPipeline(Handle const& inLogicalDeviceHdl, Handle const& inPipelineLayout) noexcept + : pipelineState{ } + , pipelineType{ SH_PIPELINE_TYPE::COMPUTE } + , vkPipeline{ VK_NULL_HANDLE } + , logicalDeviceHdl{ inLogicalDeviceHdl } + , pipelineLayout{ inPipelineLayout } + , created{ false } + + { + + } + /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h index 6edf0e98..fe55a41e 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipeline.h @@ -51,8 +51,10 @@ namespace SHADE Handle const& inPipelineLayout, SHVkPipelineState const* const state, Handle const& renderpassHdl, - Handle subpass, - SH_PIPELINE_TYPE type) noexcept; + Handle subpass) noexcept; + + SHVkPipeline(Handle const& inLogicalDeviceHdl, + Handle const& inPipelineLayout) noexcept; SHVkPipeline (SHVkPipeline&& rhs) noexcept; ~SHVkPipeline (void) noexcept;