Merge branch 'main' into SP3-4-editor_fix

This commit is contained in:
Sri Sham Haran 2022-10-19 09:49:10 +08:00
commit 5bd5cec9d4
74 changed files with 2002 additions and 402 deletions

View File

@ -0,0 +1,3 @@
Name: Cube.003
ID: 110152941
Type: 

View File

@ -0,0 +1,3 @@
Name: Cube.012
ID: 107348815
Type: 

View File

@ -9,8 +9,8 @@ Size=1920,1036
Collapsed=0 Collapsed=0
[Window][Hierarchy Panel] [Window][Hierarchy Panel]
Pos=0,89 Pos=0,120
Size=286,971 Size=225,940
Collapsed=0 Collapsed=0
DockId=0x00000004,0 DockId=0x00000004,0
@ -20,23 +20,29 @@ Size=400,400
Collapsed=0 Collapsed=0
[Window][Inspector] [Window][Inspector]
Pos=1494,24 Pos=1686,24
Size=426,1036 Size=234,1036
Collapsed=0 Collapsed=0
DockId=0x00000006,0 DockId=0x00000006,0
[Window][Profiler] [Window][Profiler]
Pos=0,24 Pos=0,24
Size=286,63 Size=225,94
Collapsed=0 Collapsed=0
DockId=0x00000003,0 DockId=0x00000003,0
[Window][Viewport]
Pos=227,24
Size=1457,1036
Collapsed=0
DockId=0x00000002,0
[Docking][Data] [Docking][Data]
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,55 Size=1920,1036 Split=X DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,55 Size=1920,1036 Split=X
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1492,1036 Split=X DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1684,1036 Split=X
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=286,1036 Split=Y Selected=0xE096E5AE DockNode ID=0x00000001 Parent=0x00000005 SizeRef=225,1036 Split=Y Selected=0x1E6EB881
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=140,63 Selected=0x1E6EB881 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=140,971 Selected=0xE096E5AE DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1204,1036 CentralNode=1 DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1293,1036 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=426,1036 Selected=0xE7039252 DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=234,1036 Selected=0xE7039252

View File

@ -0,0 +1,3 @@
Name: RaccoonPreTexturedVer1_Base9
ID: 91918845
Type: 

View File

@ -104,10 +104,10 @@ namespace Sandbox
//TODO: REMOVE AFTER PRESENTATION //TODO: REMOVE AFTER PRESENTATION
//SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); //SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh"); //SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds"); //SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds"); //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex"); //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
//TODO: REMOVE AFTER PRESENTATION //TODO: REMOVE AFTER PRESENTATION
@ -125,6 +125,8 @@ namespace Sandbox
SHSceneManager::InitSceneManager<SBTestScene>("TestScene"); SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
SHFrameRateController::UpdateFRC(); SHFrameRateController::UpdateFRC();
SHAssetManager::Load();
} }
void SBApplication::Update(void) void SBApplication::Update(void)
@ -139,17 +141,10 @@ namespace Sandbox
SHSceneManager::UpdateSceneManager(); SHSceneManager::UpdateSceneManager();
#ifdef SHEDITOR #ifdef SHEDITOR
if(editor->editorState == SHEditor::State::PLAY) if(editor->editorState == SHEditor::State::PLAY)
#endif
SHSceneManager::SceneUpdate(0.016f); SHSceneManager::SceneUpdate(0.016f);
#ifdef SHEDITOR
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
{
editor->PollPicking();
}
#else
SHSystemManager::RunRoutines(false, 0.016f);
#endif #endif
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
editor->PollPicking();
} }
// Finish all graphics jobs first // Finish all graphics jobs first
graphicsSystem->AwaitGraphicsExecution(); graphicsSystem->AwaitGraphicsExecution();
@ -165,6 +160,7 @@ namespace Sandbox
SHSceneManager::Exit(); SHSceneManager::Exit();
SHSystemManager::Exit(); SHSystemManager::Exit();
SHAssetManager::Unload();
} }
} }

View File

@ -9,6 +9,7 @@ namespace SHADE
{ {
bool compiled; bool compiled;
std::string name;
uint32_t numBytes; uint32_t numBytes;
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;

View File

@ -16,7 +16,7 @@
#include <fstream> #include <fstream>
void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept std::string SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
{ {
std::string newPath{ path.string() }; std::string newPath{ path.string() };
newPath = newPath.substr(0, newPath.find_last_of('/') + 1); newPath = newPath.substr(0, newPath.find_last_of('/') + 1);
@ -67,4 +67,6 @@ void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPat
); );
file.close(); file.close();
return newPath;
} }

View File

@ -21,6 +21,6 @@ namespace SHADE
{ {
private: private:
public: public:
static void CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept; static std::string CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
}; };
} }

View File

@ -142,8 +142,7 @@ namespace SHADE
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string()); SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
} }
std::string name{ path.filename().string() }; const std::string name{ path.stem().string() };
name = name.substr(0, name.find_last_of('.'));
file.seekg(0); file.seekg(0);

View File

@ -29,8 +29,8 @@ namespace SHADE
static void LoadExternal(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept; static void LoadExternal(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept;
public: public:
static void LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept; static void LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept;
}; };
} }

View File

@ -17,7 +17,7 @@
namespace SHADE namespace SHADE
{ {
void SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path) std::string SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path)
{ {
std::string newPath{ path.string() }; std::string newPath{ path.string() };
newPath = newPath.substr(0, newPath.find_last_of('.')); newPath = newPath.substr(0, newPath.find_last_of('.'));
@ -69,5 +69,7 @@ namespace SHADE
); );
file.close(); file.close();
return newPath;
} }
} }

View File

@ -19,6 +19,6 @@ namespace SHADE
{ {
struct SHTextureCompiler struct SHTextureCompiler
{ {
static void CompileTextureBinary(SHTextureAsset const& asset, AssetPath path); static std::string CompileTextureBinary(SHTextureAsset const& asset, AssetPath path);
}; };
} }

View File

@ -93,6 +93,7 @@ namespace SHADE
std::memcpy(pixel, file.GetImageData()->m_mem, totalBytes); std::memcpy(pixel, file.GetImageData()->m_mem, totalBytes);
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData())); //pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
asset.name = path.stem().string();
asset.compiled = false; asset.compiled = false;
asset.numBytes = static_cast<uint32_t>(totalBytes); asset.numBytes = static_cast<uint32_t>(totalBytes);
asset.width = file.GetWidth(); asset.width = file.GetWidth();

View File

@ -26,8 +26,8 @@ namespace SHADE
static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept; static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept;
static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
public: public:
static void LoadImageAsset(AssetPath paths, SHTextureAsset& image); static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
}; };
} }

View File

@ -40,7 +40,7 @@ typedef FMOD::Sound* SHSound;
#define ASSET_META_VER "1.0" #define ASSET_META_VER "1.0"
// Asset type enum // Asset type enum
enum class AssetType : uint8_t enum class AssetType : AssetTypeMeta
{ {
INVALID = 0, INVALID = 0,
AUDIO = 1, AUDIO = 1,
@ -57,7 +57,12 @@ enum class AssetType : uint8_t
}; };
//Directory //Directory
#define ASSET_ROOT "./Assets/" #ifdef _PUBLISH
#define ASSET_ROOT "Assets"
#else
#define ASSET_ROOT "../../Assets"
#endif
// ASSET EXTENSIONS // ASSET EXTENSIONS
#define META_EXTENSION ".shmeta" #define META_EXTENSION ".shmeta"

View File

@ -255,6 +255,26 @@ namespace SHADE
return result; return result;
} }
SHMeshAsset const* SHAssetManager::GetMesh(AssetID id) noexcept
{
if (meshCollection.find(id) == meshCollection.end())
{
return nullptr;
}
return &meshCollection[id];
}
SHTextureAsset const* SHAssetManager::GetTexture(AssetID id) noexcept
{
if (textureCollection.find(id) == textureCollection.end())
{
return nullptr;
}
return &textureCollection[id];
}
/**************************************************************************** /****************************************************************************
* \param Path for meta data file * \param Path for meta data file
* \param Path for asset file * \param Path for asset file
@ -307,12 +327,22 @@ namespace SHADE
for (auto const& mesh : meshes) for (auto const& mesh : meshes)
{ {
meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh); auto id{ GenerateAssetID(AssetType::MESH) };
meshCollection.emplace(id, mesh);
AssetPath path;
if (!mesh.compiled) if (!mesh.compiled)
{ {
SHMeshCompiler::CompileMeshBinary(mesh, asset.path); path = SHMeshCompiler::CompileMeshBinary(mesh, asset.path);
} }
assetCollection.emplace_back(
mesh.header.meshName,
id,
AssetType::MESH,
path,
0
);
} }
} }
@ -322,11 +352,20 @@ namespace SHADE
SHTextureLoader::LoadImageAsset(asset.path, image); SHTextureLoader::LoadImageAsset(asset.path, image);
textureCollection.emplace(GenerateAssetID(AssetType::DDS), image);
if (!image.compiled) if (!image.compiled)
{ {
SHTextureCompiler::CompileTextureBinary(image, asset.path); auto id{ GenerateAssetID(AssetType::TEXTURE) };
textureCollection.emplace(id, image);
auto path{ SHTextureCompiler::CompileTextureBinary(image, asset.path) };
assetCollection.emplace_back(
image.name,
id,
AssetType::TEXTURE,
path,
0
);
} }
} }
@ -344,8 +383,24 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
void SHAssetManager::LoadAllData() noexcept void SHAssetManager::LoadAllData() noexcept
{ {
//TODO Remove when on demand loading is done
for (auto const& asset : assetCollection) for (auto const& asset : assetCollection)
{ {
switch (asset.type)
{
case AssetType::MESH:
meshCollection.emplace(asset.id, SHMeshAsset());
SHMeshLoader::LoadSHMesh(meshCollection[asset.id], asset.path);
break;
case AssetType::TEXTURE:
textureCollection.emplace(asset.id, SHTextureAsset());
SHTextureLoader::LoadSHTexture(asset.path, textureCollection[asset.id]);
break;
default:
void;
}
} }
} }
@ -362,40 +417,51 @@ namespace SHADE
std::vector<AssetPath> metaFiles; std::vector<AssetPath> metaFiles;
std::vector<AssetPath> AssetFiles; std::vector<AssetPath> AssetFiles;
//TODO: Write new function for file manager to loop through all files for (auto const dir : std::filesystem::recursive_directory_iterator(ASSET_ROOT))
SHFileSystem::StartupFillDirectories(ASSET_ROOT);
FolderPointer rootFolder = SHFileSystem::GetRoot();
for (auto const& meta : metaFiles)
{ {
for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() }; if (dir.path().extension().string() == META_EXTENSION)
it != AssetFiles.cend();
++it)
{ {
// Asset exists for meta file auto meta{ SHAssetMetaHandler::RetrieveMetaData(dir.path()) };
std::string fileExtCheck{ it->filename().string() };
fileExtCheck += META_EXTENSION; assetCollection.push_back(meta);
if (meta.filename().string() == fileExtCheck) assetRegistry.emplace(meta.id, meta);
{
RegisterAsset(meta, *it);
AssetFiles.erase(it);
break;
}
} }
} }
//TODO: Write new function for file manager to loop through all files
//SHFileSystem::StartupFillDirectories(ASSET_ROOT);
//FolderPointer rootFolder = SHFileSystem::GetRoot();
//for (auto const& meta : metaFiles)
//{
// for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() };
// it != AssetFiles.cend();
// ++it)
// {
// // Asset exists for meta file
// std::string fileExtCheck{ it->filename().string() };
// fileExtCheck += META_EXTENSION;
// if (meta.filename().string() == fileExtCheck)
// {
// RegisterAsset(meta, *it);
// AssetFiles.erase(it);
// break;
// }
// }
//}
//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa) //TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
for (auto const& file : AssetFiles) //for (auto const& file : AssetFiles)
{ //{
if (IsRecognised(file.extension().string().c_str())) // if (IsRecognised(file.extension().string().c_str()))
{ // {
SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file)); // SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file));
} // }
else // else
{ // {
std::cout << "Unsupported File Format: " << file.filename() << "\n"; // std::cout << "Unsupported File Format: " << file.filename() << "\n";
} // }
} //}
} }
AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept

View File

@ -75,6 +75,8 @@ namespace SHADE
static std::vector<SHMeshAsset> GetAllMeshes() noexcept; static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
static std::vector<SHTextureAsset> GetAllTextures() noexcept; static std::vector<SHTextureAsset> GetAllTextures() noexcept;
static SHMeshAsset const* GetMesh(AssetID id) noexcept;
static SHTextureAsset const* GetTexture(AssetID id) noexcept;
private: private:
/**************************************************************************** /****************************************************************************
* \brief Load resource data into memory * \brief Load resource data into memory

View File

@ -72,6 +72,13 @@ namespace SHADE
std::string line; std::string line;
SHAsset meta; SHAsset meta;
// Get resource name
GetFieldValue(metaFile, line);
std::stringstream nameStream{ line };
AssetName name;
nameStream >> name;
meta.name = name;
// Get resource id // Get resource id
GetFieldValue(metaFile, line); GetFieldValue(metaFile, line);
std::stringstream idStream{ line }; std::stringstream idStream{ line };
@ -88,6 +95,8 @@ namespace SHADE
metaFile.close(); metaFile.close();
meta.path = path.parent_path().string() + "/" + path.stem().string();
return meta; return meta;
} }
@ -103,7 +112,7 @@ namespace SHADE
std::string path{ meta.path.string() }; std::string path{ meta.path.string() };
path.append(META_EXTENSION); path.append(META_EXTENSION);
std::ofstream metaFile{ path, std::ios_base::out }; std::ofstream metaFile{ path, std::ios_base::out | std::ios_base::trunc };
if (!metaFile.is_open()) if (!metaFile.is_open())
{ {
@ -113,17 +122,17 @@ namespace SHADE
metaFile << "Name: " << meta.name << "\n"; metaFile << "Name: " << meta.name << "\n";
metaFile << "ID: " << meta.id << "\n"; metaFile << "ID: " << meta.id << "\n";
metaFile << "Type: " << static_cast<int>(meta.type) << std::endl; metaFile << "Type: " << static_cast<AssetTypeMeta>(meta.type) << std::endl;
//TODO Add in information that is specific to types like mesh ////TODO Add in information that is specific to types like mesh
switch(meta.type) //switch(meta.type)
{ //{
case AssetType::MESH: //case AssetType::MESH:
break; // break;
default: //default:
break; // break;
} //}
metaFile.close(); metaFile.close();
} }

View File

@ -21,6 +21,8 @@
//#==============================================================# //#==============================================================#
#include <imgui.h> #include <imgui.h>
#include "Serialization/SHSerialization.h"
namespace SHADE namespace SHADE
{ {
@ -181,6 +183,10 @@ namespace SHADE
editor->selectedEntities.clear(); editor->selectedEntities.clear();
editor->selectedEntities.push_back(eid); editor->selectedEntities.push_back(eid);
} }
if(ImGui::Selectable("Copy"))
{
SHLOG_INFO(SHSerialization::SerializeEntitiesToString(editor->selectedEntities))
}
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data())) if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
{ {
SHEntityManager::DestroyEntity(eid); SHEntityManager::DestroyEntity(eid);

View File

@ -17,6 +17,8 @@
#include <imgui_internal.h> #include <imgui_internal.h>
#include <rttr/type> #include <rttr/type>
#include "Serialization/SHSerialization.h"
namespace SHADE namespace SHADE
{ {
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
@ -73,7 +75,14 @@ namespace SHADE
{ {
if (ImGui::BeginMenu("File")) if (ImGui::BeginMenu("File"))
{ {
if(ImGui::Selectable("Save"))
{
SHSerialization::SerializeSceneToFile("../../Assets/Scenes/Test.SHADE");
}
if(ImGui::Selectable("Load"))
{
SHSerialization::DeserializeSceneFromFile("../../Assets/Scenes/Test.SHADE");
}
ImGui::EndMenu(); ImGui::EndMenu();
} }
if(ImGui::BeginMenu("Edit")) if(ImGui::BeginMenu("Edit"))

View File

@ -54,6 +54,7 @@ namespace SHADE
windowPos = {wndPos.x, wndPos.y}; windowPos = {wndPos.x, wndPos.y};
OnPosChange(); OnPosChange();
} }
isWindowHovered = ImGui::IsWindowHovered();
return result; return result;
} }

View File

@ -24,6 +24,7 @@ namespace SHADE
virtual void Update(); virtual void Update();
virtual void Exit(); virtual void Exit();
bool isOpen; bool isOpen;
bool isWindowHovered;
std::string_view windowName; std::string_view windowName;
protected: protected:
virtual bool Begin(); virtual bool Begin();
@ -34,5 +35,6 @@ namespace SHADE
ImGuiIO& io; ImGuiIO& io;
SHVec2 windowSize; SHVec2 windowSize;
SHVec2 windowPos; SHVec2 windowPos;
SHVec2 viewportMousePos;
};//class SHEditorWindow };//class SHEditorWindow
}//namespace SHADE }//namespace SHADE

View File

@ -2,7 +2,11 @@
#include "SHEditorViewport.h" #include "SHEditorViewport.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.hpp"
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
namespace SHADE namespace SHADE
{ {
@ -24,8 +28,27 @@ namespace SHADE
{ {
DrawMenuBar(); DrawMenuBar();
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>(); auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
//auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0]; auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
//ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize()); auto mousePos = ImGui::GetMousePos();
auto cursorPos = ImGui::GetCursorScreenPos();
viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y};
gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos);
//if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
//{
// auto eid = gfxSystem->GetMousePickSystem ()->GetPickedEntity();
// if(eid != MAX_EID)
// {
// auto editor = SHSystemManager::GetSystem<SHEditor>();
// editor->selectedEntities.clear();
// editor->selectedEntities.push_back(eid);
// if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>())
// {
// hierarchyPanel->SetScrollTo(eid);
// }
// }
//}
ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize());
} }
ImGui::End(); ImGui::End();
} }
@ -39,6 +62,11 @@ namespace SHADE
{ {
SHEditorWindow::OnResize(); SHEditorWindow::OnResize();
//Get graphics system to resize swapchain image //Get graphics system to resize swapchain image
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
//auto pos = ImGui::GetCursorPos();
//windowCursorPos = {}
gfxSystem->PrepareResize(static_cast<uint32_t>(windowSize.x), static_cast<uint32_t>(windowSize.y));
} }
void SHEditorViewport::OnPosChange() void SHEditorViewport::OnPosChange()

View File

@ -304,10 +304,11 @@ namespace SHADE
imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers(); //auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
auto const& renderers = gfxSystem->GetEditorViewport()->GetRenderers();
SHASSERT(!renderers.empty(), "No Renderers available") SHASSERT(!renderers.empty(), "No Renderers available")
auto renderGraph = renderers[0]->GetRenderGraph(); auto renderGraph = renderers[SHGraphicsConstants::RenderGraphIndices::EDITOR]->GetRenderGraph();
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass(); auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false) if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
@ -336,7 +337,8 @@ namespace SHADE
{ {
if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>()) if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
{ {
if (!ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
if (viewportWindow->isWindowHovered && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{ {
EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity(); EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity();
if(pickedEID == MAX_EID) if(pickedEID == MAX_EID)

View File

@ -67,6 +67,11 @@ namespace SHADE
ImGui::Separator(); ImGui::Separator();
} }
bool SHEditorUI::IsItemHovered()
{
return ImGui::IsItemHovered();
}
bool SHEditorUI::BeginMenu(const std::string& label) bool SHEditorUI::BeginMenu(const std::string& label)
{ {
return ImGui::BeginMenu(label.data()); return ImGui::BeginMenu(label.data());
@ -82,6 +87,16 @@ namespace SHADE
ImGui::EndMenu(); ImGui::EndMenu();
} }
void SHEditorUI::BeginTooltip()
{
ImGui::BeginTooltip();
}
void SHEditorUI::EndTooltip()
{
ImGui::EndTooltip();
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - Pop Ups */ /* ImGui Wrapper Functions - Pop Ups */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -135,24 +150,30 @@ namespace SHADE
return ImGui::Selectable(std::format("{} {}", icon, label).data()); return ImGui::Selectable(std::format("{} {}", icon, label).data());
} }
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value) bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::Checkbox("#", &value); return ImGui::Checkbox("#", &value);
} }
bool SHEditorUI::InputInt(const std::string& label, int& value) bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::InputInt("#", &value, return ImGui::InputInt("#", &value,
1, 10, 1, 10,
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value) bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered)
{ {
int signedVal = static_cast<int>(value); int signedVal = static_cast<int>(value);
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
const bool CHANGED = InputInt("#", signedVal); const bool CHANGED = InputInt("#", signedVal);
if (CHANGED) if (CHANGED)
@ -162,35 +183,43 @@ namespace SHADE
} }
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputFloat(const std::string& label, float& value) bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::InputFloat("#", &value, return ImGui::InputFloat("#", &value,
0.1f, 1.0f, "%.3f", 0.1f, 1.0f, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputDouble(const std::string& label, double& value) bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::InputDouble("#", &value, return ImGui::InputDouble("#", &value,
0.1, 1.0, "%.3f", 0.1, 1.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputAngle(const std::string& label, double& value) bool SHEditorUI::InputAngle(const std::string& label, double& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::InputDouble("#", &value, return ImGui::InputDouble("#", &value,
1.0, 45.0, "%.3f", 1.0, 45.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value) bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered)
{ {
float val = static_cast<float>(value); float val = static_cast<float>(value);
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
const bool CHANGED = ImGui::SliderFloat("#", &val, const bool CHANGED = ImGui::SliderFloat("#", &val,
static_cast<float>(min), static_cast<float>(max), "%.3f", static_cast<float>(min), static_cast<float>(max), "%.3f",
@ -204,22 +233,24 @@ namespace SHADE
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value) bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered)
{ {
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y" }; static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y" };
return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y }); return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y }, 0.1f, "%.3f", float{}, float{}, 0, isHovered);
} }
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, float speed) bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered, float speed)
{ {
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"}; static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"};
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f"); return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f", float{}, float{}, 0, isHovered);
} }
bool SHEditorUI::InputTextField(const std::string& label, std::string& value) bool SHEditorUI::InputTextField(const std::string& label, std::string& value, bool* isHovered)
{ {
std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' }; std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' };
strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str()); strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str());
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH); const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
if (CHANGED) if (CHANGED)
@ -229,13 +260,15 @@ namespace SHADE
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames) bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered)
{ {
// Clamp input value // Clamp input value
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v]; const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
bool b = false; bool b = false;
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None)) if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
{ {

View File

@ -90,12 +90,19 @@ namespace SHADE
static void SameLine(); static void SameLine();
static void Separator(); static void Separator();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - Queries */
/*-----------------------------------------------------------------------------*/
static bool IsItemHovered();
/*-----------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - Menu */ /* ImGui Wrapper Functions - Menu */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
static bool BeginMenu(const std::string& label); static bool BeginMenu(const std::string& label);
static bool BeginMenu(const std::string& label, const char* icon); static bool BeginMenu(const std::string& label, const char* icon);
static void EndMenu(); static void EndMenu();
static void BeginTooltip();
static void EndTooltip();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - Pop Ups */ /* ImGui Wrapper Functions - Pop Ups */
@ -165,8 +172,9 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputCheckbox(const std::string& label, bool& value); static bool InputCheckbox(const std::string& label, bool& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a integer field widget for integer input. /// Creates a integer field widget for integer input.
/// <br/> /// <br/>
@ -174,8 +182,9 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputInt(const std::string& label, int& value); static bool InputInt(const std::string& label, int& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a integer field widget for unsigned integer input. /// Creates a integer field widget for unsigned integer input.
/// <br/> /// <br/>
@ -186,8 +195,9 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputUnsignedInt(const std::string& label, unsigned int& value); static bool InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a decimal field widget for single precision float input. /// Creates a decimal field widget for single precision float input.
/// <br/> /// <br/>
@ -195,8 +205,9 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputFloat(const std::string& label, float& value); static bool InputFloat(const std::string& label, float& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a decimal field widget for double precision float input. /// Creates a decimal field widget for double precision float input.
/// <br/> /// <br/>
@ -204,8 +215,9 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputDouble(const std::string& label, double& value); static bool InputDouble(const std::string& label, double& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a decimal field widget for double input with increments of higher /// Creates a decimal field widget for double input with increments of higher
/// steps meant for angle variables. /// steps meant for angle variables.
@ -214,8 +226,9 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputAngle(const std::string& label, double& value); static bool InputAngle(const std::string& label, double& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a double slider field widget for double input. /// Creates a double slider field widget for double input.
/// <br/> /// <br/>
@ -225,8 +238,9 @@ namespace SHADE
/// <param name="min">Minimum value of the slider.</param> /// <param name="min">Minimum value of the slider.</param>
/// <param name="max">Maximum value of the slider.</param> /// <param name="max">Maximum value of the slider.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputSlider(const std::string& label, double min, double max, double& value); static bool InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a 2x double field widget for Vector2 input. /// Creates a 2x double field widget for Vector2 input.
/// <br/> /// <br/>
@ -234,8 +248,9 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputVec2(const std::string& label, SHVec2& value); static bool InputVec2(const std::string& label, SHVec2& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a 3x double field widget for Vector3 input. /// Creates a 3x double field widget for Vector3 input.
/// <br/> /// <br/>
@ -243,8 +258,9 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputVec3(const std::string& label, SHVec3& value, float speed = 0.1f); static bool InputVec3(const std::string& label, SHVec3& value, bool* isHovered = nullptr, float speed = 0.1f);
/// <summary> /// <summary>
/// Creates a text field widget for string input. /// Creates a text field widget for string input.
/// <br/> /// <br/>
@ -252,8 +268,9 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputTextField(const std::string& label, std::string& value); static bool InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a combo box for enumeration input. /// Creates a combo box for enumeration input.
/// </summary> /// </summary>
@ -264,17 +281,19 @@ namespace SHADE
/// <param name="toStrFn"> /// <param name="toStrFn">
/// Conversion function from the type of enum to C-style string. /// Conversion function from the type of enum to C-style string.
/// </param> /// </param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>Whether the value was modified.</returns> /// <returns>Whether the value was modified.</returns>
template<typename Enum> template<typename Enum>
static bool InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char*(Enum)> toStrFn); static bool InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char*(Enum)> toStrFn, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a combo box for enumeration input using a specified list of names. /// Creates a combo box for enumeration input using a specified list of names.
/// </summary> /// </summary>
/// <param name="label">The name of the input.</param> /// <param name="label">The name of the input.</param>
/// <param name="v">The reference to the value to modify.</param> /// <param name="v">The reference to the value to modify.</param>
/// <param name="enumNames">Vector of names for each enumeration value.</param> /// <param name="enumNames">Vector of names for each enumeration value.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>Whether the value was modified.</returns> /// <returns>Whether the value was modified.</returns>
static bool InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames); static bool InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered = nullptr);
private: private:

View File

@ -20,7 +20,7 @@ namespace SHADE
/* ImGui Wrapper Functions - Widgets */ /* ImGui Wrapper Functions - Widgets */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
template<typename Enum> template<typename Enum>
inline bool SHEditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char* (Enum)> toStrFn) inline bool SHEditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char* (Enum)> toStrFn, bool* isHovered)
{ {
std::vector<Enum> values; std::vector<Enum> values;
for (int i = 0; i <= maxVal; ++i) for (int i = 0; i <= maxVal; ++i)
@ -28,6 +28,11 @@ namespace SHADE
values.emplace_back(static_cast<Enum>(i)); values.emplace_back(static_cast<Enum>(i));
} }
bool b = false; bool b = false;
ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
if (ImGui::BeginCombo(label.c_str(), toStrFn(v), ImGuiComboFlags_None)) if (ImGui::BeginCombo(label.c_str(), toStrFn(v), ImGuiComboFlags_None))
{ {
for (int i = 0; i <= maxVal; ++i) for (int i = 0; i <= maxVal; ++i)

View File

@ -160,7 +160,7 @@ namespace SHADE
template <typename T, std::size_t N> template <typename T, std::size_t N>
static bool DragN(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, static bool DragN(const std::string& fieldLabel, std::vector<std::string>const& componentLabels,
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(), std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(),
ImGuiSliderFlags flags = 0) ImGuiSliderFlags flags = 0, bool* isHovered = nullptr)
{ {
const ImGuiWindow* const window = ImGui::GetCurrentWindow(); const ImGuiWindow* const window = ImGui::GetCurrentWindow();
if (window->SkipItems) if (window->SkipItems)
@ -174,6 +174,8 @@ namespace SHADE
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize); ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
ImGui::SetColumnWidth(-1, 80.0f); ImGui::SetColumnWidth(-1, 80.0f);
ImGui::Text(fieldLabel.c_str()); ImGui::Text(fieldLabel.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::NextColumn(); ImGui::NextColumn();
for (std::size_t i = 0; i < N; ++i) for (std::size_t i = 0; i < N; ++i)
{ {

View File

@ -99,7 +99,7 @@ namespace SHADE
void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message) noexcept void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message) noexcept
{ {
SHLOGV_INFO(message); //SHLOGV_INFO(message);
} }
/***************************************************************************/ /***************************************************************************/

View File

@ -172,7 +172,7 @@ namespace SHADE
// write sampler and image view // write sampler and image view
auto& [view, sampler, layout] = imageViewsAndSamplers[i]; auto& [view, sampler, layout] = imageViewsAndSamplers[i];
writeInfo.descImageInfos[i].imageView = view->GetImageView(); writeInfo.descImageInfos[i].imageView = view->GetImageView();
writeInfo.descImageInfos[i].sampler = sampler->GetVkSampler(); writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
writeInfo.descImageInfos[i].imageLayout = layout; writeInfo.descImageInfos[i].imageLayout = layout;
} }
} }

View File

@ -1,16 +1,18 @@
#include "SHPch.h" #include "SHPch.h"
#include "SHVkDescriptorSetLayout.h" #include "SHVkDescriptorSetLayout.h"
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Images/SHVkSampler.h"
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructor/Destructor */ /* Constructor/Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex set, const std::vector<Binding>& bindings) SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex set, const std::vector<Binding>& bindings, bool genImmutableSamplers/* = false*/)
: device { device } : device { device }
, layoutDesc { bindings } , layoutDesc { bindings }
, setIndex {set} , setIndex {set}
, immutableSampler{}
{ {
// Check if auto-binding point calculation configuration is valid // Check if auto-binding point calculation configuration is valid
bool autoCalc = false; bool autoCalc = false;
@ -26,6 +28,25 @@ namespace SHADE
} }
} }
vk::Sampler tempVkSampler = nullptr;
if (genImmutableSamplers)
{
// Create sampler
immutableSampler = device->CreateSampler(
{
.minFilter = vk::Filter::eLinear,
.magFilter = vk::Filter::eLinear,
.addressMode = vk::SamplerAddressMode::eRepeat,
.mipmapMode = vk::SamplerMipmapMode::eLinear,
.minLod = -1000,
.maxLod = 1000
}
);
tempVkSampler = immutableSampler->GetVkSampler();
}
// Fill up VK bindings with auto calculated bind points if needed // Fill up VK bindings with auto calculated bind points if needed
std::vector<vk::DescriptorSetLayoutBinding> layoutBindings; std::vector<vk::DescriptorSetLayoutBinding> layoutBindings;
layoutBindings.reserve(bindings.size()); layoutBindings.reserve(bindings.size());
@ -39,7 +60,7 @@ namespace SHADE
.descriptorType = binding.Type, .descriptorType = binding.Type,
.descriptorCount = binding.DescriptorCount, .descriptorCount = binding.DescriptorCount,
.stageFlags = binding.Stage, .stageFlags = binding.Stage,
.pImmutableSamplers = nullptr // We will create our own samplers .pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr,
}; };
layoutBindings.emplace_back(VK_BINDING); layoutBindings.emplace_back(VK_BINDING);
@ -75,7 +96,8 @@ namespace SHADE
: device {rhs.device} : device {rhs.device}
, setLayout {rhs.setLayout} , setLayout {rhs.setLayout}
, layoutDesc{std::move (rhs.layoutDesc)} , layoutDesc{std::move (rhs.layoutDesc)}
, setIndex {rhs.setIndex} , setIndex{ rhs.setIndex }
, immutableSampler{ rhs.immutableSampler }
{ {
rhs.setLayout = VK_NULL_HANDLE; rhs.setLayout = VK_NULL_HANDLE;
} }
@ -106,6 +128,7 @@ namespace SHADE
setLayout = rhs.setLayout; setLayout = rhs.setLayout;
layoutDesc = std::move(rhs.layoutDesc); layoutDesc = std::move(rhs.layoutDesc);
setIndex = rhs.setIndex; setIndex = rhs.setIndex;
immutableSampler = rhs.immutableSampler;
rhs.setLayout = VK_NULL_HANDLE; rhs.setLayout = VK_NULL_HANDLE;

View File

@ -10,6 +10,7 @@ namespace SHADE
/* Forward Declarations */ /* Forward Declarations */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
class SHVkLogicalDevice; class SHVkLogicalDevice;
class SHVkSampler;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -74,7 +75,7 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="device"></param> /// <param name="device"></param>
/// <param name="bindings"></param> /// <param name="bindings"></param>
SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex setIndex, const std::vector<Binding>& bindings); SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex setIndex, const std::vector<Binding>& bindings, bool genImmutableSamplers = false);
SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete; SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete;
SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept; SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept;
/// <summary> /// <summary>
@ -107,5 +108,6 @@ namespace SHADE
vk::DescriptorSetLayout setLayout; vk::DescriptorSetLayout setLayout;
std::vector<Binding> layoutDesc; // Stores description of the layout std::vector<Binding> layoutDesc; // Stores description of the layout
SetIndex setIndex; // Index of the set SetIndex setIndex; // Index of the set
Handle<SHVkSampler> immutableSampler;
}; };
} }

View File

@ -550,10 +550,9 @@ namespace SHADE
} }
Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers/* = false*/) noexcept
{ {
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex, bindings); return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex, bindings, genImmutableSamplers);
} }
Handle<SHVkDescriptorPool> SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept Handle<SHVkDescriptorPool> SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept

View File

@ -186,7 +186,7 @@ namespace SHADE
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept; Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept;
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept; Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept;
Handle<SHVkFramebuffer> CreateFramebuffer (Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept; Handle<SHVkFramebuffer> CreateFramebuffer (Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept;
Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept; Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers = false) noexcept;
Handle<SHVkDescriptorPool> CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept; Handle<SHVkDescriptorPool> CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept;
Handle<SHVkDescriptorSetGroup> CreateDescriptorSetGroup(Handle<SHVkDescriptorPool> pool, Handle<SHVkDescriptorSetGroup> CreateDescriptorSetGroup(Handle<SHVkDescriptorPool> pool,
std::vector<Handle<SHVkDescriptorSetLayout>> const& layouts, std::vector<Handle<SHVkDescriptorSetLayout>> const& layouts,

View File

@ -24,14 +24,15 @@ namespace SHADE
{ {
const vk::SamplerCreateInfo SAMPLER_CREATE_INFO const vk::SamplerCreateInfo SAMPLER_CREATE_INFO
{ {
.magFilter = params.magFilter, .magFilter = params.magFilter,
.minFilter = params.minFilter, .minFilter = params.minFilter,
.mipmapMode = params.mipmapMode, .mipmapMode = params.mipmapMode,
.addressModeU = params.addressMode, .addressModeU = params.addressMode,
.addressModeV = params.addressMode, .addressModeV = params.addressMode,
.addressModeW = params.addressMode, .addressModeW = params.addressMode,
.minLod = params.minLod, .maxAnisotropy = 1.0f,
.maxLod = params.maxLod .minLod = params.minLod,
.maxLod = params.maxLod,
}; };
// Create the sampler // Create the sampler
@ -39,7 +40,8 @@ namespace SHADE
} }
SHVkSampler::SHVkSampler(SHVkSampler&& rhs) noexcept SHVkSampler::SHVkSampler(SHVkSampler&& rhs) noexcept
: vkSampler { rhs.vkSampler } : vkSampler{ rhs.vkSampler }
, device{ rhs.device }
{ {
rhs.vkSampler = nullptr; rhs.vkSampler = nullptr;
} }
@ -56,6 +58,7 @@ namespace SHADE
SHADE::SHVkSampler& SHVkSampler::operator=(SHVkSampler&& rhs) noexcept SHADE::SHVkSampler& SHVkSampler::operator=(SHVkSampler&& rhs) noexcept
{ {
vkSampler = rhs.vkSampler; vkSampler = rhs.vkSampler;
device = rhs.device;
rhs.vkSampler = nullptr; rhs.vkSampler = nullptr;
return *this; return *this;
} }

View File

@ -25,6 +25,12 @@ namespace SHADE
struct SHGraphicsConstants struct SHGraphicsConstants
{ {
public: public:
struct RenderGraphIndices
{
static constexpr uint32_t WORLD = 0;
static constexpr uint32_t EDITOR = 0;
};
struct DescriptorSetIndex struct DescriptorSetIndex
{ {
/***************************************************************************/ /***************************************************************************/

View File

@ -36,11 +36,9 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
#pragma region INIT_EXIT
/*---------------------------------------------------------------------------------*/ void SHGraphicsSystem::InitBoilerplate(void) noexcept
/* Constructor/Destructors */
/*---------------------------------------------------------------------------------*/
void SHGraphicsSystem::Init(void)
{ {
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* BACKEND BOILERPLATE */ /* BACKEND BOILERPLATE */
@ -71,7 +69,15 @@ namespace SHADE
if (width == 0 || height == 0) if (width == 0 || height == 0)
return; return;
renderContext.SetIsResized(true); #ifdef SHEDITOR
//PrepareResize(1, 1, SHVec2(0, 0));
#else
PrepareResize(resizeWidth, resizeHeight, SHVec2(0, 0));
#endif
}); });
window->RegisterWindowCloseCallback([&](void) window->RegisterWindowCloseCallback([&](void)
@ -106,9 +112,10 @@ namespace SHADE
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
}
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
{
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* MIDDLE END SETUP /* MIDDLE END SETUP
- Viewports - Viewports
@ -118,8 +125,8 @@ namespace SHADE
- Default vertex input state - Default vertex input state
- Global data - Global data
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
auto windowDims = window->GetWindowSize();
SHGraphicsGlobalData::Init(device);
// Set Up Cameras // Set Up Cameras
screenCamera = resourceManager.Create<SHCamera>(); screenCamera = resourceManager.Create<SHCamera>();
@ -131,12 +138,12 @@ namespace SHADE
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f); worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
// Create Default Viewport // Create Default Viewport
defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f)); worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
// Get render graph from default viewport world renderer // Get render graph from default viewport world renderer
worldRenderGraph = resourceManager.Create<SHRenderGraph>(); worldRenderGraph = resourceManager.Create<SHRenderGraph>();
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{swapchain->GetNumImages()}; std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
{ {
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
@ -144,44 +151,27 @@ namespace SHADE
// Initialize world render graph // Initialize world render graph
worldRenderGraph->Init(device, swapchain); worldRenderGraph->Init(device, swapchain);
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat); auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
//worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm);
auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Present"}, {}); // no predecessors
//First subpass to write to G-Buffer //First subpass to write to G-Buffer
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write"); auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
gBufferWriteSubpass->AddColorOutput("Present"); gBufferWriteSubpass->AddColorOutput("Scene");
gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddColorOutput("Entity ID");
gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
// We do this to just transition our scene layout to shader read
auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition");
sceneLayoutTransitionSubpass->AddInput("Scene");
// TODO: Use macro to add this node when SH_EDITOR is enabled // Generate world render graph
auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"});
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
imguiSubpass->AddColorOutput("Present");
worldRenderGraph->Generate(); worldRenderGraph->Generate();
// Create Semaphore
for (auto& semaHandle : graphSemaphores)
{
semaHandle = device->CreateSemaphore();
}
// Create Debug Renderers
/*debugScreenRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph);
debugScreenRenderer->SetCamera(screenCamera);
debugWorldRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph);
debugWorldRenderer->SetCamera(worldCamera);*/
// Add world renderer to default viewport // Add world renderer to default viewport
worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
worldRenderer->SetCamera(worldCamera); worldRenderer->SetCamera(worldCamera);
@ -198,17 +188,97 @@ namespace SHADE
cubeFS->Reflect(); cubeFS->Reflect();
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass); defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
}
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
{
SHGraphicsGlobalData::Init(device);
InitSceneRenderGraph();
#ifdef SHEDITOR
InitEditorRenderGraph();
#endif
// Create Semaphore
for (auto& semaHandle : graphSemaphores)
{
semaHandle = device->CreateSemaphore();
}
}
void SHGraphicsSystem::InitSubsystems(void) noexcept
{
mousePickSystem = resourceManager.Create<SHMousePickSystem>(); mousePickSystem = resourceManager.Create<SHMousePickSystem>();
std::vector<Handle<SHVkCommandPool>> cmdPools; std::vector<Handle<SHVkCommandPool>> cmdPools;
cmdPools.reserve(swapchain->GetNumImages()); cmdPools.reserve(swapchain->GetNumImages());
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i) for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]);
mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID"));
// Register the post offscreen render to the system
postOffscreenRender = resourceManager.Create<SHPostOffscreenRenderSystem>();
postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool);
} }
#ifdef SHEDITOR
void SHGraphicsSystem::InitEditorRenderGraph(void) noexcept
{
auto windowDims = window->GetWindowSize();
// Create Default Viewport
editorViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 1.0f));
// Get render graph from viewport editor renderer
editorRenderGraph = resourceManager.Create<SHRenderGraph>();
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
editorRenderGraph->Init(device, swapchain);
editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
auto imguiNode = editorRenderGraph->AddNode("ImGui Node", { "Present"}, {});
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
imguiSubpass->AddColorOutput("Present");
// Generate world render graph
editorRenderGraph->Generate();
// Add world renderer to default viewport
editorRenderer = editorViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], editorRenderGraph);
editorRenderer->SetCamera(worldCamera);
}
#endif
/*---------------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*---------------------------------------------------------------------------------*/
void SHGraphicsSystem::Init(void)
{
InitBoilerplate();
InitMiddleEnd();
InitSubsystems();
}
void SHGraphicsSystem::Exit(void)
{
}
#pragma endregion INIT_EXIT
#pragma region LIFECYCLE
/*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -227,12 +297,6 @@ namespace SHADE
if (window->IsMinimized() || renderContext.GetWindowIsDead()) if (window->IsMinimized() || renderContext.GetWindowIsDead())
return; return;
if (renderContext.GetResized())
{
return;
}
// Frame data for the current frame // Frame data for the current frame
auto const& frameData = renderContext.GetCurrentFrameData(); auto const& frameData = renderContext.GetCurrentFrameData();
uint32_t frameIndex = renderContext.GetCurrentFrame(); uint32_t frameIndex = renderContext.GetCurrentFrame();
@ -329,13 +393,6 @@ namespace SHADE
} }
} }
void SHGraphicsSystem::Exit(void)
{
}
/*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -400,12 +457,6 @@ namespace SHADE
if (window->IsMinimized() || renderContext.GetWindowIsDead()) if (window->IsMinimized() || renderContext.GetWindowIsDead())
return; return;
if (renderContext.GetResized())
{
return;
}
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
auto& currFrameData = renderContext.GetCurrentFrameData(); auto& currFrameData = renderContext.GetCurrentFrameData();
@ -417,9 +468,7 @@ namespace SHADE
// If swapchain is incompatible/outdated // If swapchain is incompatible/outdated
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR) if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
{ {
HandleResize(); HandleResize();
} }
} }
@ -427,6 +476,10 @@ namespace SHADE
renderContext.AdvanceFrame(); renderContext.AdvanceFrame();
} }
#pragma endregion LIFECYCLE
#pragma region ADD_REMOVE_BUILD
Handle<SHViewport> SHGraphicsSystem::AddViewport(const vk::Viewport& viewport) Handle<SHViewport> SHGraphicsSystem::AddViewport(const vk::Viewport& viewport)
{ {
// Create the viewport // Create the viewport
@ -537,36 +590,9 @@ namespace SHADE
); );
} }
void SHGraphicsSystem::HandleResize(void) noexcept #pragma endregion ADD_REMOVE
{
if (window->IsMinimized() || renderContext.GetWindowIsDead())
return;
auto windowDims = window->GetWindowSize();
// Resize the swapchain
swapchain->Resize(surface, windowDims.first, windowDims.second);
renderContext.HandleResize();
worldRenderGraph->HandleResize(windowDims.first, windowDims.second);
defaultViewport->SetWidth(static_cast<float>(windowDims.first));
defaultViewport->SetHeight(static_cast<float>(windowDims.second));
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
}
void SHGraphicsSystem::AwaitGraphicsExecution()
{
device->WaitIdle();
}
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
{
window = wind;
}
#pragma region ROUTINES
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* System Routine Functions - BeginRoutine */ /* System Routine Functions - BeginRoutine */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -638,5 +664,62 @@ namespace SHADE
renderable.ResetChangedFlag(); renderable.ResetChangedFlag();
} }
} }
#pragma endregion ROUTINES
#pragma region MISC
void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept
{
resizeWidth = newWidth;
resizeHeight = newHeight;
renderContext.SetIsResized(true);
}
void SHGraphicsSystem::HandleResize(void) noexcept
{
device->WaitIdle();
if (window->IsMinimized() || renderContext.GetWindowIsDead())
return;
graphSemaphores[0].Free();
graphSemaphores[1].Free();
auto windowDims = window->GetWindowSize();
// Resize the swapchain
swapchain->Resize(surface, windowDims.first, windowDims.second);
renderContext.HandleResize();
worldRenderGraph->HandleResize(resizeWidth, resizeHeight);
editorRenderGraph->HandleResize(windowDims.first, windowDims.second);
mousePickSystem->HandleResize();
postOffscreenRender->HandleResize();
worldViewport->SetWidth(static_cast<float>(resizeWidth));
worldViewport->SetHeight(static_cast<float>(resizeHeight));
worldCamera->SetPerspective(90.0f, static_cast<float>(resizeWidth), static_cast<float>(resizeHeight), 0.0f, 100.0f);
for (auto& semaHandle : graphSemaphores)
semaHandle = device->CreateSemaphore();
}
void SHGraphicsSystem::AwaitGraphicsExecution()
{
device->WaitIdle();
}
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
{
window = wind;
}
#pragma endregion MISC
} }

View File

@ -31,6 +31,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h" #include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
#include "../Textures/SHTextureLibrary.h" #include "../Textures/SHTextureLibrary.h"
#include "../Textures/SHVkSamplerCache.h" #include "../Textures/SHVkSamplerCache.h"
#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h"
namespace SHADE namespace SHADE
{ {
@ -66,6 +67,16 @@ namespace SHADE
/***********************************************************************************/ /***********************************************************************************/
class SH_API SHGraphicsSystem : public SHSystem class SH_API SHGraphicsSystem : public SHSystem
{ {
private:
void InitBoilerplate (void) noexcept;
void InitSceneRenderGraph (void) noexcept;
void InitMiddleEnd (void) noexcept;
void InitSubsystems (void) noexcept;
#ifdef SHEDITOR
void InitEditorRenderGraph (void) noexcept;
#endif
public: public:
class SH_API BeginRoutine final : public SHSystemRoutine class SH_API BeginRoutine final : public SHSystemRoutine
{ {
@ -251,6 +262,7 @@ namespace SHADE
/***************************************************************************/ /***************************************************************************/
void BuildTextures(); void BuildTextures();
void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
void HandleResize(void) noexcept; void HandleResize(void) noexcept;
void AwaitGraphicsExecution(); void AwaitGraphicsExecution();
@ -262,20 +274,25 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Getters (Temporary) */ /* Getters (Temporary) */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHVkLogicalDevice> GetDevice() const { return device; } Handle<SHVkLogicalDevice> GetDevice() const { return device; }
Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; } Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; }
Handle<SHVkSurface> GetSurface() const { return surface; } Handle<SHVkSurface> GetSurface() const { return surface; }
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; } Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; } Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; } Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;} Handle<SHViewport> GetDefaultViewport() const {return worldViewport;}
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;}; #ifdef SHEDITOR
Handle<SHViewport> GetEditorViewport () const {return editorViewport;};
#endif
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
//SHRenderGraph const& GetRenderGraph(void) const noexcept; //SHRenderGraph const& GetRenderGraph(void) const noexcept;
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; } //Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -296,13 +313,19 @@ namespace SHADE
SHWindow* window = nullptr; SHWindow* window = nullptr;
// Middle End Resources // Middle End Resources
ResourceManager resourceManager; ResourceManager resourceManager;
SHMeshLibrary meshLibrary; SHMeshLibrary meshLibrary;
SHTextureLibrary texLibrary; SHTextureLibrary texLibrary;
SHSamplerCache samplerCache; SHSamplerCache samplerCache;
SHMaterialInstanceCache materialInstanceCache; SHMaterialInstanceCache materialInstanceCache;
// Viewports // Viewports
Handle<SHViewport> defaultViewport; // Whole screen #ifdef SHEDITOR
Handle<SHViewport> editorViewport;
Handle<SHRenderer> editorRenderer;
Handle<SHRenderGraph> editorRenderGraph;
#endif
Handle<SHViewport> worldViewport; // Whole screen
std::vector<Handle<SHViewport>> viewports; // Additional viewports std::vector<Handle<SHViewport>> viewports; // Additional viewports
// Debug Renderers // Debug Renderers
@ -327,5 +350,9 @@ namespace SHADE
// Sub systems // Sub systems
Handle<SHMousePickSystem> mousePickSystem; Handle<SHMousePickSystem> mousePickSystem;
Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
uint32_t resizeWidth;
uint32_t resizeHeight;
}; };
} }

View File

@ -6,11 +6,16 @@
#include "Graphics/Synchronization/SHVkFence.h" #include "Graphics/Synchronization/SHVkFence.h"
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/SHVkUtil.h" #include "Graphics/SHVkUtil.h"
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
namespace SHADE namespace SHADE
{ {
void SHMousePickSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept void SHMousePickSystem::Init(Handle<SHVkLogicalDevice> device, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept
{ {
logicalDevice = device;
pickedEID = MAX_EID;
// Create command buffers // Create command buffers
for (auto& pool : cmdPools) for (auto& pool : cmdPools)
{ {
@ -20,13 +25,7 @@ namespace SHADE
// assign the attachment // assign the attachment
entityIDAttachment = eidAttachment; entityIDAttachment = eidAttachment;
// Create the fence HandleResize();
afterCopyFence = logicalDevice->CreateFence();
uint32_t bufferSize = entityIDAttachment->GetWidth() * eidAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
// Create the buffer
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
} }
void SHMousePickSystem::Run(Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept void SHMousePickSystem::Run(Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept
@ -54,13 +53,36 @@ namespace SHADE
// wait for the copy to be done // wait for the copy to be done
afterCopyFence->Wait(true, std::numeric_limits<uint64_t>::max()); afterCopyFence->Wait(true, std::numeric_limits<uint64_t>::max());
int mouseX = 0, mouseY = 0; pickedEID = imageDataDstBuffer->GetDataFromMappedPointer<uint32_t>(static_cast<uint32_t>(viewportMousePos.y) * entityIDAttachment->GetWidth() + static_cast<uint32_t>(viewportMousePos.x));
SHInputManager::GetMouseWindowPosition(&mouseX, &mouseY);
pickedEID = imageDataDstBuffer->GetDataFromMappedPointer<uint32_t>(mouseY * entityIDAttachment->GetWidth() + mouseX);
} }
} }
void SHMousePickSystem::HandleResize(void) noexcept
{
if (afterCopyFence)
{
afterCopyFence->Reset();
afterCopyFence.Free();
}
if (imageDataDstBuffer)
imageDataDstBuffer.Free();
// Create the fence
afterCopyFence = logicalDevice->CreateFence();
uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
// Create the buffer
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
}
void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept
{
viewportMousePos = vpMousePos;
}
EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept
{ {
return pickedEID; return pickedEID;

View File

@ -13,10 +13,13 @@ namespace SHADE
class SHVkFence; class SHVkFence;
class SHVkQueue; class SHVkQueue;
class SHVkBuffer; class SHVkBuffer;
class SHViewport;
class SHMousePickSystem class SHMousePickSystem
{ {
private: private:
Handle<SHVkLogicalDevice> logicalDevice;
//! Handle to the render graph resource that will contain the entity IDs //! Handle to the render graph resource that will contain the entity IDs
Handle<SHRenderGraphResource> entityIDAttachment; Handle<SHRenderGraphResource> entityIDAttachment;
@ -30,17 +33,24 @@ namespace SHADE
Handle<SHVkBuffer> imageDataDstBuffer; Handle<SHVkBuffer> imageDataDstBuffer;
//! eid picked from screen //! eid picked from screen
EntityID pickedEID = MAX_EID; EntityID pickedEID;
//! mouse position relative to the viewport window displaying the world
SHVec2 viewportMousePos;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept; void Init(Handle<SHVkLogicalDevice> device, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept;
void Run (Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept; void Run (Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept;
void HandleResize (void) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void SetViewportMousePos (SHVec2 vpMousePos) noexcept;
EntityID GetPickedEntity (void) const noexcept; EntityID GetPickedEntity (void) const noexcept;
}; };

View File

@ -0,0 +1,84 @@
#include "SHpch.h"
#include "SHPostOffscreenRenderSystem.h"
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Images/SHVkSampler.h"
#include "Graphics/RenderGraph/SHRenderGraphResource.h"
namespace SHADE
{
/***************************************************************************/
/*!
\brief
This function basically creates the entities required for offscreen
rendering. It takes in a render graph resource. Side note: it creates
a descriptor set layout that is similar to the one created in imgui. This
is so that the descriptor set passed to imGui won't be invalid.
\param logicalDevice
For vulkan object creation
\param renderGraphResource
The resource in which has been
\param descriptorPool
\return
*/
/***************************************************************************/
void SHPostOffscreenRenderSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHRenderGraphResource> renderGraphResource, Handle<SHVkDescriptorPool> descriptorPool) noexcept
{
offscreenRender = renderGraphResource;
// Create sampler
offscreenRenderSampler = logicalDevice->CreateSampler(
{
.minFilter = vk::Filter::eLinear,
.magFilter = vk::Filter::eLinear,
.addressMode = vk::SamplerAddressMode::eRepeat,
.mipmapMode = vk::SamplerMipmapMode::eLinear,
.minLod = -1000,
.maxLod = 1000
}
);
// Create descriptor set layout binding
SHVkDescriptorSetLayout::Binding imageBinding
{
.Type = vk::DescriptorType::eCombinedImageSampler,
.Stage = vk::ShaderStageFlagBits::eFragment,
.BindPoint = 0,
.DescriptorCount = 1,
};
// Create descriptor set layout
offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, false);
// Create descriptor set
offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 });
HandleResize();
}
void SHPostOffscreenRenderSystem::HandleResize(void) noexcept
{
std::vector combinedImageSampler
{
std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal),
};
// Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change
offscreenRenderDescSet->ModifyWriteDescImage(0, 0, combinedImageSampler);
offscreenRenderDescSet->UpdateDescriptorSetImages(0, 0);
}
Handle<SHVkDescriptorSetGroup> SHPostOffscreenRenderSystem::GetDescriptorSetGroup(void) const noexcept
{
return offscreenRenderDescSet;
}
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "Resource/Handle.h"
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorSetLayout;
class SHVkDescriptorSetGroup;
class SHVkDescriptorPool;
class SHVkSampler;
class SHRenderGraphResource;
class SHPostOffscreenRenderSystem
{
private:
Handle<SHRenderGraphResource> offscreenRender;
Handle<SHVkDescriptorSetLayout> offscreenRenderDescSetLayout;
Handle<SHVkDescriptorSetGroup> offscreenRenderDescSet;
Handle<SHVkSampler> offscreenRenderSampler;
public:
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHRenderGraphResource> renderGraphResource, Handle<SHVkDescriptorPool> descriptorPool) noexcept;
//void Run ()
void HandleResize (void) noexcept;
Handle<SHVkDescriptorSetGroup> GetDescriptorSetGroup (void) const noexcept;
};
}

View File

@ -75,12 +75,15 @@ namespace SHADE
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{ {
cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); if (camera)
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); {
cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize }; std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
}
} }
void SHRenderer::UpdateCameraDataToBuffer(void) noexcept void SHRenderer::UpdateCameraDataToBuffer(void) noexcept

View File

@ -85,4 +85,14 @@ namespace SHADE
} }
void SHViewport::SetX(float x) noexcept
{
viewport.x = x;
}
void SHViewport::SetY(float y) noexcept
{
viewport.y = y;
}
} }

View File

@ -67,6 +67,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void SetWidth(float w) noexcept; void SetWidth(float w) noexcept;
void SetHeight (float h) noexcept; void SetHeight (float h) noexcept;
void SetX (float x) noexcept;
void SetY (float y) noexcept;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Getters */ /* Getters */

View File

@ -52,7 +52,6 @@ namespace SHADE
{ {
frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient)); frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient));
} }
} }
// Initialize all the info. // Initialize all the info.

View File

@ -0,0 +1,7 @@
#include "SHpch.h"
#include "SHAttachmentDescInitParams.h"
namespace SHADE
{
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "Resource/Handle.h"
namespace SHADE
{
class SHRenderGraphResource;
struct SHAttachmentDescInitParams
{
Handle<SHRenderGraphResource> resourceHdl;
bool dontClearOnLoad{false};
};
}

View File

@ -3,12 +3,13 @@
namespace SHADE namespace SHADE
{ {
// Used for attachment description creation for renderpass node // Used for attachment description creation for renderpass node
enum class SH_ATT_DESC_TYPE enum class SH_ATT_DESC_TYPE_FLAGS
{ {
COLOR, COLOR = 0x01,
COLOR_PRESENT, COLOR_PRESENT = 0x02,
DEPTH, DEPTH = 0x04,
STENCIL, STENCIL = 0x08,
DEPTH_STENCIL, DEPTH_STENCIL = 0x10,
INPUT = 0x20
}; };
} }

View File

@ -8,10 +8,17 @@
#include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "Graphics/Framebuffer/SHVkFramebuffer.h"
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
#include "Tools/SHLogger.h" #include "Tools/SHLogger.h"
#include "SHAttachmentDescInitParams.h"
namespace SHADE namespace SHADE
{ {
SHRenderGraph::ResourceInstruction::ResourceInstruction(char const* resourceName, bool dontClearOnLoad /*= false*/) noexcept
: resourceName{ resourceName }
, dontClearOnLoad{ dontClearOnLoad }
{
}
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -40,7 +47,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/) void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
{ {
// If we set to // If we set to
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1)) if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
@ -50,7 +57,7 @@ namespace SHADE
format = swapchainHdl->GetSurfaceFormatKHR().format; format = swapchainHdl->GetSurfaceFormatKHR().format;
} }
graphResources.try_emplace(resourceName, resourceManager.Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, usageFlags, createFlags)); graphResources.try_emplace(resourceName, resourceManager->Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags));
} }
/***************************************************************************/ /***************************************************************************/
@ -82,7 +89,7 @@ namespace SHADE
{ {
for (auto& color : subpass->colorReferences) for (auto& color : subpass->colorReferences)
{ {
if (i == nodes.size() - 1 && node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)))
resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR; resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
else else
resourceAttLayouts[color.attachment] = color.layout; resourceAttLayouts[color.attachment] = color.layout;
@ -95,11 +102,11 @@ namespace SHADE
resourceAttLayouts[input.attachment] = input.layout; resourceAttLayouts[input.attachment] = input.layout;
} }
for (uint32_t i = 0; i < node->attachmentDescriptions.size(); ++i) for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
{ {
auto& att = node->attachmentDescriptions[i]; auto& att = node->attachmentDescriptions[j];
att.initialLayout = vk::ImageLayout::eUndefined; att.initialLayout = vk::ImageLayout::eUndefined;
att.finalLayout = resourceAttLayouts[i]; att.finalLayout = resourceAttLayouts[j];
} }
++i; ++i;
} }
@ -210,10 +217,18 @@ namespace SHADE
for (auto& inputAtt : subpass->inputReferences) for (auto& inputAtt : subpass->inputReferences)
{ {
auto resource = node->attResources[inputAtt.attachment]; auto resource = node->attResources[inputAtt.attachment];
if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR || resource->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::INPUT))
colorRead |= (1 << i); {
else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL) if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR) ||
depthRead |= (1 << i); resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
colorRead |= (1 << i);
else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL))
depthRead |= (1 << i);
}
else
{
SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. ");
}
} }
++i; ++i;
@ -350,10 +365,9 @@ namespace SHADE
, swapchainHdl{ } , swapchainHdl{ }
, nodes{} , nodes{}
, graphResources{} , graphResources{}
, resourceManager{} , resourceManager{nullptr}
{ {
resourceManager = std::make_shared<ResourceManager>();
} }
SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept
@ -400,7 +414,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
Handle<SHRenderGraphNode> SHRenderGraph::AddNode(std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept SHADE::Handle<SHADE::SHRenderGraphNode> SHRenderGraph::AddNode(std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept
{ {
if (nodeIndexing.contains(nodeName)) if (nodeIndexing.contains(nodeName))
{ {
@ -408,12 +422,19 @@ namespace SHADE
return {}; return {};
} }
std::vector<Handle<SHRenderGraphResource>> resources; std::vector<SHAttachmentDescInitParams> descInitParams;
for (auto const& name : resourceNames) for (auto const& instruction : resourceInstruction)
{ {
// If the resource that the new node is requesting for exists, allow the graph to reference it // If the resource that the new node is requesting for exists, allow the graph to reference it
if (graphResources.contains(name)) if (graphResources.contains(instruction.resourceName))
resources.push_back(graphResources.at(name)); {
descInitParams.push_back(
{
.resourceHdl = graphResources.at(instruction.resourceName),
.dontClearOnLoad = false,
}
);
}
else else
{ {
SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node."); SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node.");
@ -435,7 +456,7 @@ namespace SHADE
} }
} }
nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources)); nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources));
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u); nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
return nodes.at(nodeIndexing[nodeName]); return nodes.at(nodeIndexing[nodeName]);
} }

View File

@ -16,6 +16,7 @@
#include <string> #include <string>
#include <map> #include <map>
#include <memory>
namespace SHADE namespace SHADE
{ {
@ -33,7 +34,17 @@ namespace SHADE
class SH_API SHRenderGraph class SH_API SHRenderGraph
{ {
public:
struct ResourceInstruction
{
std::string resourceName;
bool dontClearOnLoad;
ResourceInstruction (char const* resourceName, bool dontClearOnLoad = false) noexcept;
};
private: private:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -60,7 +71,7 @@ namespace SHADE
std::unordered_map<std::string, Handle<SHRenderGraphResource>> graphResources; std::unordered_map<std::string, Handle<SHRenderGraphResource>> graphResources;
//! Resource library for graph handles //! Resource library for graph handles
ResourceManager resourceManager; std::shared_ptr<ResourceManager> resourceManager;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -74,13 +85,14 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept; void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
void AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); void AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept; Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
void Generate (void) noexcept; void Generate (void) noexcept;
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept; void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool); void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */

View File

@ -42,7 +42,7 @@ namespace SHADE
for (uint32_t j = 0; j < attResources.size(); ++j) for (uint32_t j = 0; j < attResources.size(); ++j)
{ {
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0; uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
imageViews[j] = attResources[j]->imageViews[imageViewIndex]; imageViews[j] = attResources[j]->imageViews[imageViewIndex];
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
@ -69,7 +69,7 @@ namespace SHADE
for (uint32_t j = 0; j < attResources.size(); ++j) for (uint32_t j = 0; j < attResources.size(); ++j)
{ {
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0; uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
imageViews[j] = attResources[j]->imageViews[imageViewIndex]; imageViews[j] = attResources[j]->imageViews[imageViewIndex];
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
@ -104,14 +104,14 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr<ResourceManager> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
: logicalDeviceHdl{ logicalDevice } : logicalDeviceHdl{ logicalDevice }
, renderpass{} , renderpass{}
, framebuffers{} , framebuffers{}
, prereqNodes{ std::move(predecessors) } , prereqNodes{ std::move(predecessors) }
, attachmentDescriptions{} , attachmentDescriptions{}
, resourceAttachmentMapping{} , resourceAttachmentMapping{}
, attResources{ std::move(attRes) } , attResources{ }
, subpasses{} , subpasses{}
, executed{ false } , executed{ false }
, configured{ false } , configured{ false }
@ -121,6 +121,12 @@ namespace SHADE
// pipeline library initialization // pipeline library initialization
pipelineLibrary.Init(logicalDeviceHdl); pipelineLibrary.Init(logicalDeviceHdl);
// Store all the handles to resources
attResources.reserve (attDescInitParams.size());
for (auto& param : attDescInitParams)
attResources.push_back(param.resourceHdl);
// We have as many descriptions as we have resources
attachmentDescriptions.resize(attResources.size()); attachmentDescriptions.resize(attResources.size());
bool containsSwapchainImage = false; bool containsSwapchainImage = false;
@ -140,7 +146,7 @@ namespace SHADE
newDesc.format = attResources[i]->resourceFormat; newDesc.format = attResources[i]->resourceFormat;
if (attResources[i]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
containsSwapchainImage = true; containsSwapchainImage = true;
resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i); resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i);
@ -156,7 +162,7 @@ namespace SHADE
} }
SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept
: resourceManager{ rhs.resourceManager } : resourceManager{ std::move (rhs.resourceManager) }
, logicalDeviceHdl{ rhs.logicalDeviceHdl } , logicalDeviceHdl{ rhs.logicalDeviceHdl }
, renderpass{ rhs.renderpass } , renderpass{ rhs.renderpass }
, framebuffers{ std::move(rhs.framebuffers) } , framebuffers{ std::move(rhs.framebuffers) }
@ -171,6 +177,8 @@ namespace SHADE
, ptrToResources{ rhs.ptrToResources } , ptrToResources{ rhs.ptrToResources }
, pipelineLibrary{ std::move(rhs.pipelineLibrary) } , pipelineLibrary{ std::move(rhs.pipelineLibrary) }
, batcher{ std::move(rhs.batcher) } , batcher{ std::move(rhs.batcher) }
, spDescs{ std::move(rhs.spDescs) }
, spDeps{ std::move(rhs.spDeps) }
{ {
rhs.renderpass = {}; rhs.renderpass = {};
@ -181,7 +189,7 @@ namespace SHADE
if (&rhs == this) if (&rhs == this)
return *this; return *this;
resourceManager = rhs.resourceManager; resourceManager = std::move(rhs.resourceManager);
logicalDeviceHdl = rhs.logicalDeviceHdl; logicalDeviceHdl = rhs.logicalDeviceHdl;
renderpass = rhs.renderpass; renderpass = rhs.renderpass;
framebuffers = std::move(rhs.framebuffers); framebuffers = std::move(rhs.framebuffers);
@ -194,6 +202,9 @@ namespace SHADE
ptrToResources = std::move(rhs.ptrToResources); ptrToResources = std::move(rhs.ptrToResources);
pipelineLibrary = std::move(rhs.pipelineLibrary); pipelineLibrary = std::move(rhs.pipelineLibrary);
batcher = std::move(rhs.batcher); batcher = std::move(rhs.batcher);
spDescs = std::move(rhs.spDescs);
spDeps = std::move(rhs.spDeps);
rhs.renderpass = {}; rhs.renderpass = {};
@ -224,10 +235,10 @@ namespace SHADE
} }
// Add subpass to container and create mapping for it // Add subpass to container and create mapping for it
subpasses.emplace_back(resourceManager.Create<SHSubpass>(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources)); subpasses.emplace_back(resourceManager->Create<SHSubpass>(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u); subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
Handle<SHSubpass> subpass = subpasses.back(); Handle<SHSubpass> subpass = subpasses.back();
subpass->Init(resourceManager); subpass->Init(*resourceManager);
// Register the SuperBatch // Register the SuperBatch
batcher.RegisterSuperBatch(subpass->GetSuperBatch()); batcher.RegisterSuperBatch(subpass->GetSuperBatch());

View File

@ -9,6 +9,7 @@
#include "SH_API.h" #include "SH_API.h"
#include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h" #include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h"
#include "Graphics/MiddleEnd/Batching/SHBatcher.h" #include "Graphics/MiddleEnd/Batching/SHBatcher.h"
#include "SHAttachmentDescInitParams.h"
namespace SHADE namespace SHADE
{ {
@ -25,7 +26,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
ResourceManager& resourceManager; std::shared_ptr<ResourceManager> resourceManager;
//! For Vulkan object creation //! For Vulkan object creation
Handle<SHVkLogicalDevice> logicalDeviceHdl; Handle<SHVkLogicalDevice> logicalDeviceHdl;
@ -87,7 +88,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept; SHRenderGraphNode(std::shared_ptr<ResourceManager> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;

View File

@ -45,10 +45,10 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
: logicalDevice {logicalDevice} : logicalDevice {logicalDevice}
, swapchain{ swapchain } , swapchain{ swapchain }
, resourceType{ type } , resourceTypeFlags{ }
, resourceFormat{ format } , resourceFormat{ format }
, images{} , images{}
, imageViews{} , imageViews{}
@ -58,52 +58,10 @@ namespace SHADE
, resourceName{ name } , resourceName{ name }
{ {
// If the resource type is an arbitrary image and not swapchain image // If the resource type is an arbitrary image and not swapchain image
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) if (typeFlags.size() == 1 && *typeFlags.begin() == SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)
{ {
imageAspectFlags = vk::ImageAspectFlags{}; resourceTypeFlags |= static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT);
usage = usageFlags;
// Check the resource type and set image usage flags and image aspect flags accordingly
switch (resourceType)
{
case SH_ATT_DESC_TYPE::COLOR:
usage |= vk::ImageUsageFlagBits::eColorAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
break;
case SH_ATT_DESC_TYPE::DEPTH:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
break;
case SH_ATT_DESC_TYPE::STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
break;
case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
break;
}
// The resource is not a swapchain image, just use the first slot of the vector
images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
// prepare image view details
SHImageViewDetails viewDetails
{
.viewType = vk::ImageViewType::e2D,
.format = images[0]->GetImageFormat(),
.imageAspectFlags = imageAspectFlags,
.baseMipLevel = 0,
.mipLevelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = 1,
};
// just 1 image view created
imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
}
else // if swapchain image resource
{
// Prepare image view details // Prepare image view details
SHImageViewDetails viewDetails SHImageViewDetails viewDetails
{ {
@ -126,6 +84,65 @@ namespace SHADE
imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails); imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails);
} }
} }
else // if swapchain image resource
{
imageAspectFlags = vk::ImageAspectFlags{};
usage = usageFlags;
for (auto& type : typeFlags)
{
// store the flags
resourceTypeFlags |= static_cast<uint32_t>(type);
// Check the resource type and set image usage flags and image aspect flags accordingly
switch (type)
{
case SH_ATT_DESC_TYPE_FLAGS::COLOR:
usage |= vk::ImageUsageFlagBits::eColorAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
break;
case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
break;
case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
break;
case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
break;
case SH_ATT_DESC_TYPE_FLAGS::INPUT:
usage |= vk::ImageUsageFlagBits::eInputAttachment;
usage |= vk::ImageUsageFlagBits::eSampled;
break;
case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT:
{
SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. ");
return;
}
}
}
// The resource is not a swapchain image, just use the first slot of the vector
images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
// prepare image view details
SHImageViewDetails viewDetails
{
.viewType = vk::ImageViewType::e2D,
.format = images[0]->GetImageFormat(),
.imageAspectFlags = imageAspectFlags,
.baseMipLevel = 0,
.mipLevelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = 1,
};
// just 1 image view created
imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
}
} }
/***************************************************************************/ /***************************************************************************/
@ -141,7 +158,7 @@ namespace SHADE
/***************************************************************************/ /***************************************************************************/
SHRenderGraphResource::SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept SHRenderGraphResource::SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept
: resourceName{ std::move(rhs.resourceName) } : resourceName{ std::move(rhs.resourceName) }
, resourceType{ std::move(rhs.resourceType) } , resourceTypeFlags{ std::move(rhs.resourceTypeFlags) }
, images{ std::move(rhs.images) } , images{ std::move(rhs.images) }
, imageViews{ std::move(rhs.imageViews) } , imageViews{ std::move(rhs.imageViews) }
, resourceFormat{ std::move(rhs.resourceFormat) } , resourceFormat{ std::move(rhs.resourceFormat) }
@ -149,6 +166,7 @@ namespace SHADE
, height{ rhs.height } , height{ rhs.height }
, mipLevels{ rhs.mipLevels } , mipLevels{ rhs.mipLevels }
, imageAspectFlags{ rhs.imageAspectFlags } , imageAspectFlags{ rhs.imageAspectFlags }
, swapchain {rhs.swapchain}
{ {
} }
@ -172,7 +190,7 @@ namespace SHADE
return *this; return *this;
resourceName = std::move(rhs.resourceName); resourceName = std::move(rhs.resourceName);
resourceType = std::move(rhs.resourceType); resourceTypeFlags = std::move(rhs.resourceTypeFlags);
images = std::move(rhs.images); images = std::move(rhs.images);
imageViews = std::move(rhs.imageViews); imageViews = std::move(rhs.imageViews);
resourceFormat = std::move(rhs.resourceFormat); resourceFormat = std::move(rhs.resourceFormat);
@ -180,6 +198,7 @@ namespace SHADE
height = rhs.height; height = rhs.height;
mipLevels = rhs.mipLevels; mipLevels = rhs.mipLevels;
imageAspectFlags = rhs.imageAspectFlags; imageAspectFlags = rhs.imageAspectFlags;
swapchain = rhs.swapchain;
return *this; return *this;
} }
@ -202,7 +221,7 @@ namespace SHADE
width = newWidth; width = newWidth;
height = newHeight; height = newHeight;
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT) if ((resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) == 0)
{ {
// prepare image view details // prepare image view details
SHImageViewDetails viewDetails SHImageViewDetails viewDetails
@ -299,4 +318,9 @@ namespace SHADE
return height; return height;
} }
Handle<SHVkImageView> SHRenderGraphResource::GetImageView(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept
{
return imageViews [index];
}
} }

View File

@ -16,6 +16,8 @@ namespace SHADE
class SHVkCommandBuffer; class SHVkCommandBuffer;
class SHVkBuffer; class SHVkBuffer;
static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0;
class SH_API SHRenderGraphResource class SH_API SHRenderGraphResource
{ {
private: private:
@ -32,7 +34,7 @@ namespace SHADE
std::string resourceName; std::string resourceName;
//! Used for initializing image layouts //! Used for initializing image layouts
SH_ATT_DESC_TYPE resourceType; SHRenderGraphResourceFlags resourceTypeFlags;
//! The resource itself (this is a vector because if the resource happens //! The resource itself (this is a vector because if the resource happens
//! to be a swapchain image, then we need however many frames in flight). //! to be a swapchain image, then we need however many frames in flight).
@ -67,7 +69,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept; SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept; SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
~SHRenderGraphResource(void) noexcept; ~SHRenderGraphResource(void) noexcept;
@ -82,9 +84,10 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
vk::Format GetResourceFormat (void) const noexcept; vk::Format GetResourceFormat (void) const noexcept;
uint32_t GetWidth (void) const noexcept; uint32_t GetWidth (void) const noexcept;
uint32_t GetHeight (void) const noexcept; uint32_t GetHeight (void) const noexcept;
Handle<SHVkImageView> GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
friend class SHRenderGraphNode; friend class SHRenderGraphNode;
friend class SHRenderGraph; friend class SHRenderGraph;

View File

@ -23,7 +23,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
SHSubpass::SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept SHSubpass::SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
: resourceAttachmentMapping{ mapping } : resourceAttachmentMapping{ mapping }
, ptrToResources{ resources } , ptrToResources{ resources }
, parentNode{ parent } , parentNode{ parent }
@ -55,6 +55,8 @@ namespace SHADE
, inputReferences{ std::move(rhs.inputReferences) } , inputReferences{ std::move(rhs.inputReferences) }
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping } , resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
, ptrToResources{ rhs.ptrToResources } , ptrToResources{ rhs.ptrToResources }
, descriptorSetLayout{ rhs.descriptorSetLayout }
, exteriorDrawCalls{ std::move (rhs.exteriorDrawCalls) }
{ {
} }
@ -83,6 +85,8 @@ namespace SHADE
inputReferences = std::move(rhs.inputReferences); inputReferences = std::move(rhs.inputReferences);
resourceAttachmentMapping = rhs.resourceAttachmentMapping; resourceAttachmentMapping = rhs.resourceAttachmentMapping;
ptrToResources = rhs.ptrToResources; ptrToResources = rhs.ptrToResources;
descriptorSetLayout = rhs.descriptorSetLayout;
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
return *this; return *this;
} }
@ -120,18 +124,18 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType) noexcept
{ {
vk::ImageLayout imageLayout; vk::ImageLayout imageLayout;
switch (attachmentDescriptionType) switch (attachmentDescriptionType)
{ {
case SH_ATT_DESC_TYPE::DEPTH: case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
imageLayout = vk::ImageLayout::eDepthAttachmentOptimal; imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
break; break;
case SH_ATT_DESC_TYPE::STENCIL: case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal; imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
break; break;
case SH_ATT_DESC_TYPE::DEPTH_STENCIL: case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal; imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
break; break;
default: default:

View File

@ -62,7 +62,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept; SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass(SHSubpass&& rhs) noexcept;
SHSubpass& operator=(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept;
@ -71,7 +71,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Preparation functions // Preparation functions
void AddColorOutput(std::string resourceToReference) noexcept; void AddColorOutput(std::string resourceToReference) noexcept;
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept; void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept;
void AddInput(std::string resourceToReference) noexcept; void AddInput(std::string resourceToReference) noexcept;
// Runtime functions // Runtime functions

View File

@ -253,7 +253,8 @@ namespace SHADE
SHVkRenderpass::~SHVkRenderpass(void) noexcept SHVkRenderpass::~SHVkRenderpass(void) noexcept
{ {
logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr); if (vkRenderpass)
logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr);
} }

View File

@ -12,6 +12,7 @@ namespace SHADE
using BindingAndSetHash = uint64_t; using BindingAndSetHash = uint64_t;
using SetIndex = uint32_t; using SetIndex = uint32_t;
using SHSubPassIndex = uint32_t; using SHSubPassIndex = uint32_t;
using SHRenderGraphResourceFlags = uint32_t;
} }

View File

@ -59,9 +59,9 @@ namespace SHADE
SparseSet(); SparseSet();
~SparseSet() = default; ~SparseSet() = default;
// Disallow moving or copying //// Disallow moving or copying
SparseSet(const SparseSet&) = delete; //SparseSet(const SparseSet&) = delete;
SparseSet(SparseSet&&) = delete; //SparseSet(SparseSet&&) = delete;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Usage Functions */ /* Usage Functions */

View File

@ -115,7 +115,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Script Serialisation Functions */ /* Script Serialisation Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity) const std::string SHScriptEngine::SerialiseScripts(EntityID entity) const
{ {
// Create buffer needed to store serialised script data // Create buffer needed to store serialised script data
constexpr int BUFFER_SIZE = 10240; constexpr int BUFFER_SIZE = 10240;
@ -124,7 +124,7 @@ namespace SHADE
// Attempt to serialise the script // Attempt to serialise the script
std::string result; std::string result;
if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE)) if (csScriptsSerialise(entity, buffer.get(), BUFFER_SIZE))
{ {
result = std::string(buffer.get()); result = std::string(buffer.get());
} }
@ -140,9 +140,9 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Script Serialisation Functions */ /* Script Serialisation Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml) const void SHScriptEngine::DeserialiseScript(EntityID entity, const std::string& yaml) const
{ {
csScriptDeserialise(entity.GetEID(), yaml.c_str()); csScriptDeserialise(entity, yaml.c_str());
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -148,7 +148,7 @@ namespace SHADE
/// <returns> /// <returns>
/// String that represents the set of scripts attached to the specified Entity. /// String that represents the set of scripts attached to the specified Entity.
/// </returns> /// </returns>
std::string SerialiseScripts(const SHEntity& entity) const; std::string SerialiseScripts(EntityID entity) const;
/// <summary> /// <summary>
/// Loads the specified JSON string and creates a Script for the specified Entity /// Loads the specified JSON string and creates a Script for the specified Entity
/// based on the specified JSON string. /// based on the specified JSON string.
@ -157,7 +157,7 @@ namespace SHADE
/// <param name="yaml"> /// <param name="yaml">
/// The YAML string that represents the Script to load into the Entity. /// The YAML string that represents the Script to load into the Entity.
/// </param> /// </param>
void DeserialiseScript(const SHEntity& entity, const std::string& yaml) const; void DeserialiseScript(EntityID entity, const std::string& yaml) const;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Script Editor Functions */ /* Script Editor Functions */

View File

@ -0,0 +1,220 @@
#include "SHpch.h"
#include "SHSerializationHelper.hpp"
#include "SHSerialization.h"
#include <yaml-cpp/yaml.h>
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Scene/SHSceneManager.h"
#include "Tools/SHException.h"
#include "Assets/SHAssetManager.h"
#include <fstream>
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Physics/Components/SHRigidBodyComponent.h"
namespace SHADE
{
void SHSerialization::SerializeSceneToFile(std::filesystem::path const& path)
{
YAML::Emitter out;
SerializeSceneToEmitter(out);
std::ofstream file(path.c_str());
if (file.good())
{
file << out.c_str();
file.close();
}
}
std::string SHSerialization::SerializeSceneToString()
{
YAML::Emitter out;
SerializeSceneToEmitter(out);
return std::basic_string<char>(out.c_str());
}
void SHSerialization::SerializeSceneToEmitter(YAML::Emitter& out)
{
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
auto root = sceneGraph.GetRoot();
SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node.");
auto const& children = root->GetChildren();
out << YAML::BeginSeq;
auto pred = [&out](SHSceneNode* node) {out << SerializeEntityToNode(node); };
sceneGraph.Traverse(pred);
//out << SerializeEntityToNode(child);
out << YAML::EndSeq;
}
static void DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
{
if (!node[EIDNode])
return;
EntityID eid = node[EIDNode].as<EntityID>();
std::string name = "Default";
if (node[EntityNameNode])
name = node[EntityNameNode].as<std::string>();
//Compile component IDs
const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]);
eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID);
createdEntities.push_back(eid);
if (node[NumberOfChildrenNode])
{
if(const int numOfChildren = node[NumberOfChildrenNode].as<int>(); numOfChildren > 0)
{
++it;
for (int i = 0; i < numOfChildren; ++i)
{
DeserializeEntity(it, (*it), createdEntities, eid);
if((i + 1) < numOfChildren)
++it;
}
}
}
}
void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path)
{
//TODO:Shift to using XQ's FileIO
std::ifstream iFile;
iFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
std::string fileContent = "";
try
{
// Open file
// Read file's buffer contents into streams
iFile.open(path);
std::stringstream fileStream;
fileStream << iFile.rdbuf();
fileContent = fileStream.str();
// Close file handler
iFile.close();
}
catch (std::ifstream::failure e)
{
SHLOG_ERROR("Could not read file");
}
YAML::Node entities = YAML::Load(fileContent);
std::vector<EntityID> createdEntities{};
//Create Entities
for (auto it = entities.begin(); it != entities.end(); ++it)
{
DeserializeEntity(it, (*it), createdEntities);
}
//Initialize Entity
auto entityVecIt = createdEntities.begin();
for (auto it = entities.begin(); it != entities.end(); ++it)
{
InitializeEntity(*it, *entityVecIt++);
}
}
void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out)
{
out << SerializeEntityToNode(entityNode);
auto const& children = entityNode->GetChildren();
for(auto const& child : children)
{
EmitEntity(child, out);
}
}
std::string SHSerialization::SerializeEntitiesToString(std::vector<EntityID> const& entities)
{
YAML::Emitter out;
YAML::Node node;
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
for (auto const& eid : entities)
{
auto entityNode = sceneGraph.GetNode(eid);
EmitEntity(entityNode, out);
}
return std::basic_string<char>(out.c_str());
}
void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
{
}
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
{
YAML::Node node;
auto eid = sceneNode->GetEntityID();
auto entity = SHEntityManager::GetEntityByID(eid);
if (!sceneNode || !entity)
{
node = YAML::Null;
return node;
}
node.SetStyle(YAML::EmitterStyle::Block);
node[EIDNode] = eid;
node[EntityNameNode] = entity->name;
node[IsActiveNode] = sceneNode->IsActive();
auto const& children = sceneNode->GetChildren();
node[NumberOfChildrenNode] = children.size();
YAML::Node components;
if (const auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
{
components[rttr::type::get<SHTransformComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(transform);
}
if (const auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(eid))
{
components[rttr::type::get<SHRenderable>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(renderable);
}
if (const auto rigidbody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid))
{
components[rttr::type::get<SHRigidBodyComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody);
}
node[ComponentsNode] = components;
return node;
}
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
std::optional<ComponentTypeID> GetComponentID(YAML::Node const& componentNode)
{
if (componentNode[rttr::type::get<ComponentType>().get_name().data()])
return { SHFamilyID<SHComponent>::GetID<ComponentType>() };
else
return std::nullopt;
}
std::vector<ComponentTypeID> SHSerialization::GetComponentIDList(YAML::Node const& componentsNode)
{
std::vector<ComponentTypeID> componentIDList;
auto id = GetComponentID<SHTransformComponent>(componentsNode);
if (id.has_value())
componentIDList.push_back(id.value());
id = GetComponentID<SHRenderable>(componentsNode);
if (id.has_value())
componentIDList.push_back(id.value());
id = GetComponentID<SHRigidBodyComponent>(componentsNode);
if (id.has_value())
componentIDList.push_back(id.value());
return componentIDList;
}
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
{
auto const componentsNode = entityNode[ComponentsNode];
if (!componentsNode)
return;
SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid);
}
}

View File

@ -0,0 +1,43 @@
#pragma once
#include "SH_API.h"
#include <string>
#include <filesystem>
#include <ECS_Base/Components/SHComponent.h>
namespace YAML
{
class Emitter;
class Node;
}
namespace SHADE
{
class SHSceneNode;
constexpr const char* ComponentsNode = "Components";
constexpr const char* EntityNameNode = "Name";
constexpr const char* EIDNode = "EID";
constexpr const char* IsActiveNode = "IsActive";
constexpr const char* NumberOfChildrenNode = "NumberOfChildren";
struct SH_API SHSerialization
{
//TODO: change paths to resource ID
static void SerializeSceneToFile(std::filesystem::path const& path);
static std::string SerializeSceneToString();
static void SerializeSceneToEmitter(YAML::Emitter& out);
static void DeserializeSceneFromFile(std::filesystem::path const& path);
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
static std::string SerializeEntitiesToString(std::vector<EntityID> const& entities);
static void SerializeEntityToFile(std::filesystem::path const& path);
static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode);
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
private:
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
};
}

View File

@ -0,0 +1,204 @@
#pragma once
#include "ECS_Base/Components/SHComponent.h"
#include <yaml-cpp/yaml.h>
#include <rttr/registration>
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h"
namespace SHADE
{
struct SHSerializationHelper
{
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static std::string SerializeComponentToString(ComponentType* component)
{
return std::string();
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path)
{
}
static YAML::Node RTTRToNode(const rttr::variant& var)
{
YAML::Node node;
auto varType = var.get_type();
if (varType == rttr::type::get<SHVec4>())
{
node.SetStyle(YAML::EmitterStyle::Flow);
node["X"] = var.convert<SHVec4>().x;
node["Y"] = var.convert<SHVec4>().y;
node["Z"] = var.convert<SHVec4>().z;
node["W"] = var.convert<SHVec4>().w;
}
else if (varType == rttr::type::get<SHVec3>())
{
node.SetStyle(YAML::EmitterStyle::Flow);
node["X"] = var.convert<SHVec3>().x;
node["Y"] = var.convert<SHVec3>().y;
node["Z"] = var.convert<SHVec3>().z;
}
else if (varType == rttr::type::get<SHVec2>())
{
node.SetStyle(YAML::EmitterStyle::Flow);
node["X"] = var.convert<SHVec3>().x;
node["Y"] = var.convert<SHVec3>().y;
}
else if (varType.is_arithmetic())
{
bool ok = false;
if (varType == rttr::type::get<bool>())
node = var.to_bool();
else if (varType == rttr::type::get<int8_t>())
node = var.to_int8(&ok);
else if (varType == rttr::type::get<int16_t>())
node = var.to_int16(&ok);
else if (varType == rttr::type::get<int32_t>())
node = var.to_int32(&ok);
else if (varType == rttr::type::get<int64_t>())
node = var.to_int64(&ok);
else if (varType == rttr::type::get<uint8_t>())
node = var.to_uint8(&ok);
else if (varType == rttr::type::get<uint16_t>())
node = var.to_uint16(&ok);
else if (varType == rttr::type::get<uint32_t>())
node = var.to_uint32(&ok);
else if (varType == rttr::type::get<uint64_t>())
node = var.to_uint64(&ok);
else if (varType == rttr::type::get<float>())
node = var.to_float(&ok);
else if (varType == rttr::type::get<double>())
node = var.to_double(&ok);
//else if (varType == rttr::type::get<char>()) //same as uint8_t
// node = var.to_uint8();
}
else if (varType.is_enumeration())
{
bool ok = false;
auto result = var.to_string(&ok);
if (ok)
{
node = var.to_string();
}
else
{
ok = false;
auto value = var.to_uint64(&ok);
if (ok)
node = value;
else
node = YAML::Null;
}
}
else
{
auto properties = var.get_type().get_properties();
for (auto property : properties)
{
node[property.get_name().data()] = RTTRToNode(property.get_value(var));
}
}
return node;
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static YAML::Node SerializeComponentToNode(ComponentType* component)
{
YAML::Node node{};
if (!component)
return node;
auto componentType = rttr::type::get<ComponentType>();
node = RTTRToNode(*component);
return node;
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void InitializeProperty(ComponentType* component, rttr::property const& prop, YAML::Node const& propertyNode)
{
auto propType = prop.get_type();
if (propType == rttr::type::get<SHVec4>())
{
SHVec4 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>(), propertyNode["W"].as<float>() };
prop.set_value(component, vec);
}
else if (propType == rttr::type::get<SHVec3>())
{
SHVec3 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>() };
prop.set_value(component, vec);
}
else if (propType == rttr::type::get<SHVec2>())
{
SHVec2 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>() };
prop.set_value(component, vec);
}
else if (propType.is_arithmetic())
{
bool ok = false;
if (propType == rttr::type::get<bool>())
prop.set_value(component, propertyNode.as<bool>());
else if (propType == rttr::type::get<int8_t>())
prop.set_value(component, propertyNode.as<int8_t>());
else if (propType == rttr::type::get<int16_t>())
prop.set_value(component, propertyNode.as<int16_t>());
else if (propType == rttr::type::get<int32_t>())
prop.set_value(component, propertyNode.as<int32_t>());
else if (propType == rttr::type::get<int64_t>())
prop.set_value(component, propertyNode.as<int64_t>());
else if (propType == rttr::type::get<uint8_t>())
prop.set_value(component, propertyNode.as<uint8_t>());
else if (propType == rttr::type::get<uint16_t>())
prop.set_value(component, propertyNode.as<uint16_t>());
else if (propType == rttr::type::get<uint32_t>())
prop.set_value(component, propertyNode.as<uint32_t>());
else if (propType == rttr::type::get<uint64_t>())
prop.set_value(component, propertyNode.as<uint64_t>());
else if (propType == rttr::type::get<float>())
prop.set_value(component, propertyNode.as<float>());
else if (propType == rttr::type::get<double>())
prop.set_value(component, propertyNode.as<double>());
}
else if (propType.is_enumeration())
{
auto enumAlign = prop.get_enumeration();
prop.set_value(component, enumAlign.name_to_value(propertyNode.as<std::string>()));
}
else
{
auto properties = propType.get_properties();
for (auto property : properties)
{
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
}
}
}
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
static void InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid)
{
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
if (componentsNode.IsNull() && !component)
return;
auto rttrType = rttr::type::get<ComponentType>();
auto componentNode = componentsNode[rttrType.get_name().data()];
if (componentsNode.IsNull())
return;
auto properties = rttrType.get_properties();
for (auto const& prop : properties)
{
if (componentNode[prop.get_name().data()])
{
InitializeProperty<ComponentType>(component, prop, componentNode[prop.get_name().data()]);
}
}
}
};
}

View File

@ -29,6 +29,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Editor/IconsMaterialDesign.h" #include "Editor/IconsMaterialDesign.h"
#include "Editor/Command/SHCommandManager.h" #include "Editor/Command/SHCommandManager.h"
#include "Editor/Command/SHCommand.hpp" #include "Editor/Command/SHCommand.hpp"
#include "TooltipAttribute.hxx"
// Using Directives // Using Directives
using namespace System; using namespace System;
@ -48,17 +49,17 @@ using namespace System::Collections::Generic;
/// <param name="MANAGED_TYPE">The managed type of the object to edit.</param> /// <param name="MANAGED_TYPE">The managed type of the object to edit.</param>
/// <param name="NATIVE_TYPE">The native type of the object to edit.</param> /// <param name="NATIVE_TYPE">The native type of the object to edit.</param>
/// <param name="FUNC">The SHEditorUI:: function to use for editing.</param> /// <param name="FUNC">The SHEditorUI:: function to use for editing.</param>
#define RENDER_FIELD(MANAGED_TYPE, NATIVE_TYPE, FUNC) \ #define RENDER_FIELD(MANAGED_TYPE, NATIVE_TYPE, FUNC) \
(field->FieldType == MANAGED_TYPE::typeid) \ (field->FieldType == MANAGED_TYPE::typeid) \
{ \ { \
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \ NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
NATIVE_TYPE oldVal = val; \ NATIVE_TYPE oldVal = val; \
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \ if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered))\
{ \ { \
field->SetValue(object, val); \ field->SetValue(object, val); \
registerUndoAction(object, field, val, oldVal); \ registerUndoAction(object, field, val, oldVal); \
} \ } \
} \ } \
/// <summary> /// <summary>
/// Macro expansion that is used in renderFieldInInspector() to check the type of a field /// Macro expansion that is used in renderFieldInInspector() to check the type of a field
/// named "field" against the specified type and if it matches, retrieves the value of /// named "field" against the specified type and if it matches, retrieves the value of
@ -76,7 +77,7 @@ using namespace System::Collections::Generic;
{ \ { \
NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \ NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \
NATIVE_TYPE oldVal = val; \ NATIVE_TYPE oldVal = val; \
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \ if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered)) \
{ \ { \
field->SetValue(object, Convert::ToCLI(val)); \ field->SetValue(object, Convert::ToCLI(val)); \
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \ registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \
@ -196,6 +197,8 @@ namespace SHADE
} }
void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object) void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object)
{ {
bool isHovered = false;
if RENDER_FIELD (Int16, int, InputInt) if RENDER_FIELD (Int16, int, InputInt)
else if RENDER_FIELD (Int32, int, InputInt) else if RENDER_FIELD (Int32, int, InputInt)
else if RENDER_FIELD (Int64, int, InputInt) else if RENDER_FIELD (Int64, int, InputInt)
@ -244,6 +247,15 @@ namespace SHADE
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal));
} }
} }
// Check if the field has a specific attribute
TooltipAttribute^ toolTip = hasAttribute<TooltipAttribute^>(field);
if (toolTip && isHovered)
{
SHEditorUI::BeginTooltip();
SHEditorUI::Text(Convert::ToNative(toolTip->Description));
SHEditorUI::EndTooltip();
}
} }
void Editor::renderScriptContextMenu(Entity entity, Script^ script) void Editor::renderScriptContextMenu(Entity entity, Script^ script)
@ -274,4 +286,24 @@ namespace SHADE
SHCommandManager::RegisterCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCLICommand>())); SHCommandManager::RegisterCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCLICommand>()));
} }
generic<typename Attribute>
Attribute Editor::hasAttribute(System::Reflection::FieldInfo^ field)
{
array<System::Object^>^ attributes = field->GetCustomAttributes(true);
for each (System::Object^ attrib in attributes)
{
try
{
Attribute attribute = safe_cast<Attribute>(attrib);
if (attribute != nullptr)
return attribute;
}
catch (System::InvalidCastException^)
{
continue;
}
}
// Failed to find
return Attribute{};
}
} }

View File

@ -23,7 +23,7 @@ namespace SHADE
/// <summary> /// <summary>
/// Static class for Editor-related functions /// Static class for Editor-related functions
/// </summary> /// </summary>
public ref class Editor abstract sealed private ref class Editor abstract sealed
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -48,7 +48,13 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* UndoRedoStack Functions */ /* UndoRedoStack Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary>
/// Undoes the last script inspector change if there is any.
/// </summary>
static void Undo(); static void Undo();
/// <summary>
/// Redoes the last script inspector change if there is any.
/// </summary>
static void Redo(); static void Redo();
private: private:
@ -86,5 +92,7 @@ namespace SHADE
/// <param name="script">The Script to render the inspector for.</param> /// <param name="script">The Script to render the inspector for.</param>
static void renderScriptContextMenu(Entity entity, Script^ script); static void renderScriptContextMenu(Entity entity, Script^ script);
static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData); static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData);
generic<typename Attribute> where Attribute : System::Attribute
static Attribute hasAttribute(System::Reflection::FieldInfo^ field);
}; };
} }

View File

@ -1,27 +1,34 @@
/************************************************************************************//*! /************************************************************************************//*!
\file SerializeFieldAttribute.cxx \file TooltipAttribute.cxx
\author Tng Kah Wei, kahwei.tng, 390009620 \author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu \par email: kahwei.tng\@digipen.edu
\date Nov 5, 2021 \date Oct 18, 2022
\brief Contains the definition of the functions of the managed SerializeField \brief Contains the definition of the functions of the managed Tooltip Attribute
Attribute class. class.
Note: This file is written in C++17/CLI. Note: This file is written in C++17/CLI.
Copyright (C) 2021 DigiPen Institute of Technology. Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited. of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h" #include "SHpch.h"
// Primary Header #include "TooltipAttribute.hxx"
#include "SerializeFieldAttribute.hxx"
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/
/* Properties */
/*---------------------------------------------------------------------------------*/
System::String^ TooltipAttribute::Description::get()
{
return desc;
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors */ /* Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SerializeField::SerializeField() TooltipAttribute::TooltipAttribute(System::String^ description)
: desc { description }
{} {}
} }

View File

@ -0,0 +1,53 @@
/************************************************************************************//*!
\file TooltipAttribute.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 18, 2022
\brief Contains the definition of the managed Tooltip Attribute class with
the declaration of functions for working with it.
Note: This file is written in C++17/CLI.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
namespace SHADE
{
/// <summary>
/// Simple attribute to mark that a field in a Script should be serialised.
/// </summary>
[System::AttributeUsage(System::AttributeTargets::Field)]
public ref class TooltipAttribute : public System::Attribute
{
public:
/*-----------------------------------------------------------------------------*/
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Description that is to be shown in the Tooltip.
/// </summary>
property System::String^ Description
{
System::String^ get();
}
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Constructor for a Tooltip attribute that fills in the description.
/// </summary>
/// <param name="description">Text to be shown when a field is hovered.</param>
TooltipAttribute(System::String^ description);
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
System::String^ desc;
};
}

View File

@ -0,0 +1,102 @@
/************************************************************************************//*!
\file Input.cxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 16, 2022
\brief Contains the definition of the managed Input static class.
Note: This file is written in C++17/CLI.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "Input.hxx"
#include "Utility/Convert.hxx"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Properties */
/*---------------------------------------------------------------------------------*/
Vector3 Input::MousePosition::get()
{
int x, y;
SHInputManager::GetMouseWindowPosition(&x, &y);
return Vector3(static_cast<float>(x), static_cast<float>(y), 0.0f);
}
int Input::MouseScrollDelta::get()
{
return SHInputManager::GetMouseWheelVerticalDelta();
}
/*---------------------------------------------------------------------------------*/
/* Usage Functions */
/*---------------------------------------------------------------------------------*/
bool Input::GetKey(KeyCode key)
{
return SHInputManager::GetKey(static_cast<SHInputManager::SH_KEYCODE>(key));
}
bool Input::GetKeyDown(KeyCode key)
{
return SHInputManager::GetKeyDown(static_cast<SHInputManager::SH_KEYCODE>(key));
}
bool Input::GetKeyUp(KeyCode key)
{
return SHInputManager::GetKeyUp(static_cast<SHInputManager::SH_KEYCODE>(key));
}
bool Input::GetMouseButton(MouseCode mouseButton)
{
return SHInputManager::GetKey(static_cast<SHInputManager::SH_KEYCODE>(mouseButton));
}
bool Input::GetMouseButtonDown(MouseCode mouseButton)
{
return SHInputManager::GetKeyDown(static_cast<SHInputManager::SH_KEYCODE>(mouseButton));
}
bool Input::GetMouseButtonUp(MouseCode mouseButton)
{
return SHInputManager::GetKeyUp(static_cast<SHInputManager::SH_KEYCODE>(mouseButton));
}
/*---------------------------------------------------------------------------------*/
/* Cursor Functions */
/*---------------------------------------------------------------------------------*/
void Input::SetMousePosition(Vector2 pos)
{
SHInputManager::SetMouseWindowPosition
(
static_cast<int>(pos.x),
static_cast<int>(pos.y)
);
}
/*---------------------------------------------------------------------------------*/
/* Time Functions */
/*---------------------------------------------------------------------------------*/
double Input::GetKeyHeldTime(KeyCode key)
{
return SHInputManager::GetKeyHeldTime(static_cast<SHInputManager::SH_KEYCODE>(key));
}
double Input::GetKeyReleasedTime(KeyCode key)
{
return SHInputManager::GetKeyReleasedTime(static_cast<SHInputManager::SH_KEYCODE>(key));
}
double Input::GetMouseHeldTime(MouseCode key)
{
return SHInputManager::GetKeyHeldTime(static_cast<SHInputManager::SH_KEYCODE>(key));
}
double Input::GetMouseReleasedTime(MouseCode key)
{
return SHInputManager::GetKeyReleasedTime(static_cast<SHInputManager::SH_KEYCODE>(key));
}
}

View File

@ -0,0 +1,325 @@
/************************************************************************************//*!
\file Input.hxx
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 16, 2022
\brief Contains the definition of the managed Input static class.
Note: This file is written in C++17/CLI.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
#include "Input/SHInputManager.h"
#include "Math/Vector2.hxx"
#include "Math/Vector3.hxx"
namespace SHADE
{
/// <summary>
/// Static class responsible for providing access to Input-related functionality.
/// </summary>
public ref class Input abstract sealed
{
public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Represents the available supported keycodes that can be passed into the
/// key-based Input functions.
/// </summary>
enum class KeyCode : int
{
Space = static_cast<int>(SHInputManager::SH_KEYCODE::SPACE),
//Apostrophe = static_cast<int>(SHInputManager::SH_KEYCODE::APOSTROPHE),
Comma = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_COMMA),
Minus = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_MINUS),
Period = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_PERIOD),
//Slash = static_cast<int>(SHInputManager::SH_KEYCODE::SLASH),
Key0 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_0),
Key1 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_1),
Key2 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_2),
Key3 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_3),
Key4 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_4),
Key5 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_5),
Key6 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_6),
Key7 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_7),
Key8 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_8),
Key9 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_9),
//Semicolon = static_cast<int>(SHInputManager::SH_KEYCODE::SEMICOLON),
//Equal = static_cast<int>(SHInputManager::SH_KEYCODE::EQUAL),
A = static_cast<int>(SHInputManager::SH_KEYCODE::A),
B = static_cast<int>(SHInputManager::SH_KEYCODE::B),
C = static_cast<int>(SHInputManager::SH_KEYCODE::C),
D = static_cast<int>(SHInputManager::SH_KEYCODE::D),
E = static_cast<int>(SHInputManager::SH_KEYCODE::E),
F = static_cast<int>(SHInputManager::SH_KEYCODE::F),
G = static_cast<int>(SHInputManager::SH_KEYCODE::G),
H = static_cast<int>(SHInputManager::SH_KEYCODE::H),
I = static_cast<int>(SHInputManager::SH_KEYCODE::I),
J = static_cast<int>(SHInputManager::SH_KEYCODE::J),
K = static_cast<int>(SHInputManager::SH_KEYCODE::K),
L = static_cast<int>(SHInputManager::SH_KEYCODE::L),
M = static_cast<int>(SHInputManager::SH_KEYCODE::M),
N = static_cast<int>(SHInputManager::SH_KEYCODE::N),
O = static_cast<int>(SHInputManager::SH_KEYCODE::O),
P = static_cast<int>(SHInputManager::SH_KEYCODE::P),
Q = static_cast<int>(SHInputManager::SH_KEYCODE::Q),
R = static_cast<int>(SHInputManager::SH_KEYCODE::R),
S = static_cast<int>(SHInputManager::SH_KEYCODE::S),
T = static_cast<int>(SHInputManager::SH_KEYCODE::T),
U = static_cast<int>(SHInputManager::SH_KEYCODE::U),
V = static_cast<int>(SHInputManager::SH_KEYCODE::V),
W = static_cast<int>(SHInputManager::SH_KEYCODE::W),
X = static_cast<int>(SHInputManager::SH_KEYCODE::X),
Y = static_cast<int>(SHInputManager::SH_KEYCODE::Y),
Z = static_cast<int>(SHInputManager::SH_KEYCODE::Z),
//LeftBracket = static_cast<int>(SHInputManager::SH_KEYCODE::LEFTBRACKET),
//BackSlash = static_cast<int>(SHInputManager::SH_KEYCODE::BACKSLASH),
//RightBracket = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHTBRACKET),
//GraveAccent = static_cast<int>(SHInputManager::SH_KEYCODE::GRAVEACCENT),
//WORLD1 = static_cast<int>(SHInputManager::SH_KEYCODE::WORLD1),
//WORLD2 = static_cast<int>(SHInputManager::SH_KEYCODE::WORLD2),
/* Function keys */
Escape = static_cast<int>(SHInputManager::SH_KEYCODE::ESCAPE),
Enter = static_cast<int>(SHInputManager::SH_KEYCODE::ENTER),
Tab = static_cast<int>(SHInputManager::SH_KEYCODE::TAB),
Backspace = static_cast<int>(SHInputManager::SH_KEYCODE::BACKSPACE),
Insert = static_cast<int>(SHInputManager::SH_KEYCODE::INSERT),
Delete = static_cast<int>(SHInputManager::SH_KEYCODE::DEL),
Right = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_ARROW),
Left = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_ARROW),
Down = static_cast<int>(SHInputManager::SH_KEYCODE::DOWN_ARROW),
Up = static_cast<int>(SHInputManager::SH_KEYCODE::UP_ARROW),
PageUp = static_cast<int>(SHInputManager::SH_KEYCODE::PAGE_UP),
PageDown = static_cast<int>(SHInputManager::SH_KEYCODE::PAGE_DOWN),
Home = static_cast<int>(SHInputManager::SH_KEYCODE::HOME),
End = static_cast<int>(SHInputManager::SH_KEYCODE::END),
CapsLock = static_cast<int>(SHInputManager::SH_KEYCODE::CAPS_LOCK),
ScrollLock = static_cast<int>(SHInputManager::SH_KEYCODE::SCROLL_LOCK),
NumLock = static_cast<int>(SHInputManager::SH_KEYCODE::NUM_LOCK),
PrintScreen = static_cast<int>(SHInputManager::SH_KEYCODE::PRINT_SCREEN),
Pause = static_cast<int>(SHInputManager::SH_KEYCODE::PAUSE),
F1 = static_cast<int>(SHInputManager::SH_KEYCODE::F1),
F2 = static_cast<int>(SHInputManager::SH_KEYCODE::F2),
F3 = static_cast<int>(SHInputManager::SH_KEYCODE::F3),
F4 = static_cast<int>(SHInputManager::SH_KEYCODE::F4),
F5 = static_cast<int>(SHInputManager::SH_KEYCODE::F5),
F6 = static_cast<int>(SHInputManager::SH_KEYCODE::F6),
F7 = static_cast<int>(SHInputManager::SH_KEYCODE::F7),
F8 = static_cast<int>(SHInputManager::SH_KEYCODE::F8),
F9 = static_cast<int>(SHInputManager::SH_KEYCODE::F9),
F10 = static_cast<int>(SHInputManager::SH_KEYCODE::F10),
F11 = static_cast<int>(SHInputManager::SH_KEYCODE::F11),
F12 = static_cast<int>(SHInputManager::SH_KEYCODE::F12),
F13 = static_cast<int>(SHInputManager::SH_KEYCODE::F13),
F14 = static_cast<int>(SHInputManager::SH_KEYCODE::F14),
F15 = static_cast<int>(SHInputManager::SH_KEYCODE::F15),
F16 = static_cast<int>(SHInputManager::SH_KEYCODE::F16),
F17 = static_cast<int>(SHInputManager::SH_KEYCODE::F17),
F18 = static_cast<int>(SHInputManager::SH_KEYCODE::F18),
F19 = static_cast<int>(SHInputManager::SH_KEYCODE::F19),
F20 = static_cast<int>(SHInputManager::SH_KEYCODE::F20),
F21 = static_cast<int>(SHInputManager::SH_KEYCODE::F21),
F22 = static_cast<int>(SHInputManager::SH_KEYCODE::F22),
F23 = static_cast<int>(SHInputManager::SH_KEYCODE::F23),
F24 = static_cast<int>(SHInputManager::SH_KEYCODE::F24),
/* Keypad */
KeyPad0 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_0),
KeyPad1 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_1),
KeyPad2 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_2),
KeyPad3 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_3),
KeyPad4 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_4),
KeyPad5 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_5),
KeyPad6 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_6),
KeyPad7 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_7),
KeyPad8 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_8),
KeyPad9 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_9),
//KeyPadDecimal = static_cast<int>(SHInputManager::SH_KEYCODE::KPDECIMAL),
//KeyPadDivide = static_cast<int>(SHInputManager::SH_KEYCODE::KPDIVIDE),
//KeyPadMultiply = static_cast<int>(SHInputManager::SH_KEYCODE::KPMULTIPLY),
//KeyPadSubtract = static_cast<int>(SHInputManager::SH_KEYCODE::KPSUBTRACT),
//KeyPadAdd = static_cast<int>(SHInputManager::SH_KEYCODE::KPADD),
//KeyPadEnter = static_cast<int>(SHInputManager::SH_KEYCODE::KPENTER),
//KeyPadEqual = static_cast<int>(SHInputManager::SH_KEYCODE::KEYPAD),
Shift = static_cast<int>(SHInputManager::SH_KEYCODE::SHIFT),
LeftControl = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_CTRL),
LeftAlt = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_ALT),
LeftSuper = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_WINDOWS),
RightShift = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_SHIFT),
RightControl = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_CTRL),
RightAlt = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_ALT),
RightSuper = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_WINDOWS),
/* Gamepad */
JoystickA = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_A),
JoystickB = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_B),
JoystickX = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_X),
JoystickY = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_Y),
JoystickLeftBumper = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTSHOULDER),
JoystickRightBumper = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTSHOULDER),
JoystickLeftTrigger = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTTRIGGER),
JoystickRightTrigger = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTTRIGGER),
JoystickDPadUp = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_UP),
JoystickDPadDown = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_DOWN),
JoystickDPadLeft = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_LEFT),
JoystickDPadRight = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_RIGHT),
JoystickMenu = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_MENU),
JoystickView = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_VIEW),
JoystickLeftStick = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_LEFT_THUMBSTICK_BUTTON),
JoystickRightStick = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHT_THUMBSTICK_BUTTON),
/* Unity Gamepad Mappings */
JoystickButton0 = JoystickA,
JoystickButton1 = JoystickB,
JoystickButton2 = JoystickX,
JoystickButton3 = JoystickY,
JoystickButton4 = JoystickLeftBumper,
JoystickButton5 = JoystickRightBumper,
JoystickButton6 = JoystickView,
JoystickButton7 = JoystickMenu,
JoystickButton8 = JoystickLeftStick,
JoystickButton9 = JoystickRightStick
};
/// <summary>
/// Represents the available supported mouse keycodes that can be passed into the
/// mouse-button-based Input functions.
/// </summary>
enum class MouseCode : int
{
LeftButton = static_cast<int>(SHInputManager::SH_KEYCODE::LMB),
RightButton = static_cast<int>(SHInputManager::SH_KEYCODE::RMB),
MiddleButton = static_cast<int>(SHInputManager::SH_KEYCODE::MMB),
Button3 = static_cast<int>(SHInputManager::SH_KEYCODE::XMB1),
Button4 = static_cast<int>(SHInputManager::SH_KEYCODE::XMB2)
};
/*-----------------------------------------------------------------------------*/
/* Properites */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Mouse position in screen coordinates relative to the top left of the window.
/// This value is a Vector3 for compatibility with functions that have Vector3
/// arguments. The z component of the Vector3 is always 0
/// </summary>
static property Vector3 MousePosition
{
Vector3 get();
}
/// <summary>
/// Amnount of vertical mouse scroll in this frame.
/// </summary>
static property int MouseScrollDelta
{
int get();
}
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Checks if a specified key is being held down.
/// This will also be true if GetKeyDown() is true.
/// </summary>
/// <param name="key">KeyCode of the key to check.</param>
/// <returns>True while the user holds down the key specified.</returns>
static bool GetKey(KeyCode key);
/// <summary>
/// Checks if a specified key is pressed and was not pressed before.
/// </summary>
/// <param name="key">KeyCode of the key to check.</param>
/// <returns>
/// True during the frame the user starts pressing down the key specified.
/// </returns>
static bool GetKeyDown(KeyCode key);
/// <summary>
/// Checks if a specified key is no longer pressed pressed and was pressed
/// before.
/// </summary>
/// <param name="key">KeyCode of the key to check.</param>
/// <returns>
/// True during the frame the user releases the key identified by name.
/// </returns>
static bool GetKeyUp(KeyCode key);
/// <summary>
/// Checks if a specified mouse button is being held down.
/// This will also be true if GetMouseButtonDown() is true.
/// </summary>
/// <param name="mouseButton">MouseCode of the mouse button to check.</param>
/// <returns>True while the user holds down the mouse button specified.</returns>
static bool GetMouseButton(MouseCode mouseButton);
/// <summary>
/// Checks if a specified mouse button is pressed and was not pressed before.
/// </summary>
/// <param name="mouseButton">MouseCode of the mouse button to check.</param>
/// <returns>
/// True during the frame the user pressed the given mouse button.
/// </returns>
static bool GetMouseButtonDown(MouseCode mouseButton);
/// <summary>
/// Checks if a specified mouse button is no longer pressed and was pressed
/// before.
/// </summary>
/// <param name="mouseButton">MouseCode of the mouse button to check.</param>
/// <returns>
/// True during the frame the user releases the given mouse button.
/// </returns>
static bool GetMouseButtonUp(MouseCode mouseButton);
/*-----------------------------------------------------------------------------*/
/* Cursor Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Sets the position of the mouse cursor relative to the top left corner of the
/// window.
/// </summary>
/// <param name="pos">
/// Position of the mouse in window pixel coordinates to set.
/// </param>
static void SetMousePosition(Vector2 pos);
/*-----------------------------------------------------------------------------*/
/* Timing Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Retrieves the duration that the specified key has been held or was last held
/// for.
/// </summary>
/// <param name="key">The key to check.</param>
/// <returns>Time in seconds that the key was held.</returns>
static double GetKeyHeldTime(KeyCode key);
/// <summary>
/// Retrieves the duration that the specified key has not been held or was last
/// not been held for.
/// </summary>
/// <param name="key">The key to check.</param>
/// <returns>Time in seconds that the key was held.</returns>
static double GetKeyReleasedTime(KeyCode key);
/// <summary>
/// Retrieves the duration that the specified key has been held or was last held
/// for.
/// </summary>
/// <param name="key">The key to check.</param>
/// <returns>Time in seconds that the key was held.</returns>
static double GetMouseHeldTime(MouseCode mouseButton);
/// <summary>
/// Retrieves the duration that the specified key has not been held or was last
/// not been held for.
/// </summary>
/// <param name="key">The key to check.</param>
/// <returns>Time in seconds that the key was held.</returns>
static double GetMouseReleasedTime(MouseCode mouseButton);
};
}

View File

@ -21,15 +21,6 @@ namespace SHADE
/// </summary> /// </summary>
[System::AttributeUsage(System::AttributeTargets::Field)] [System::AttributeUsage(System::AttributeTargets::Field)]
public ref class SerializeField : public System::Attribute public ref class SerializeField : public System::Attribute
{ {};
public:
/*-----------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Default Constructor
/// </summary>
SerializeField();
};
} }

View File

@ -3,8 +3,12 @@ using System;
public class RaccoonShowcase : Script public class RaccoonShowcase : Script
{ {
public double RotateSpeed = 1.0; [SerializeField]
public Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0); [Tooltip("Speed of the rotation in radians per second.")]
private double RotateSpeed = 1.0;
[SerializeField]
[Tooltip("Speed of the scaling in radians per second around each axis.")]
private Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0);
private Transform Transform; private Transform Transform;
private double rotation = 0.0; private double rotation = 0.0;
private Vector3 scale = Vector3.Zero; private Vector3 scale = Vector3.Zero;

View File

@ -3,7 +3,9 @@ using System;
public class RaccoonSpin : Script public class RaccoonSpin : Script
{ {
public double RotateSpeed = 1.0; [SerializeField]
[Tooltip("Speed of the rotation in radians per second.")]
private double RotateSpeed = 1.0;
private double rotation = 0.0; private double rotation = 0.0;
private Transform Transform; private Transform Transform;
public RaccoonSpin(GameObject gameObj) : base(gameObj) { } public RaccoonSpin(GameObject gameObj) : base(gameObj) { }