Merge remote-tracking branch 'origin/main' into SP3-2-Physics

This commit is contained in:
Diren D Bharwani 2022-10-24 02:46:08 +08:00
commit 7643ca4289
207 changed files with 8909 additions and 1962 deletions

2
.gitignore vendored
View File

@ -362,3 +362,5 @@ MigrationBackup/
*.csproj *.csproj
*.filters *.filters
Assets/Editor/Layouts/UserLayout.ini

View File

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

View File

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

Binary file not shown.

View File

@ -0,0 +1,48 @@
[Window][MainStatusBar]
Pos=0,1060
Size=1920,20
Collapsed=0
[Window][SHEditorMenuBar]
Pos=0,24
Size=1920,1036
Collapsed=0
[Window][Hierarchy Panel]
Pos=0,120
Size=225,940
Collapsed=0
DockId=0x00000004,0
[Window][Debug##Default]
Pos=60,60
Size=400,400
Collapsed=0
[Window][Inspector]
Pos=1686,24
Size=234,1036
Collapsed=0
DockId=0x00000006,0
[Window][Profiler]
Pos=0,24
Size=225,94
Collapsed=0
DockId=0x00000003,0
[Window][Viewport]
Pos=227,24
Size=1457,1036
Collapsed=0
DockId=0x00000002,0
[Docking][Data]
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,55 Size=1920,1036 Split=X
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1684,1036 Split=X
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=225,1036 Split=Y Selected=0x1E6EB881
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1293,1036 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=234,1036 Selected=0xE7039252

View File

@ -0,0 +1,54 @@
[Window][MainStatusBar]
Pos=0,1060
Size=1920,20
Collapsed=0
[Window][SHEditorMenuBar]
Pos=0,48
Size=1920,1012
Collapsed=0
[Window][Hierarchy Panel]
Pos=0,142
Size=387,918
Collapsed=0
DockId=0x00000004,0
[Window][Debug##Default]
Pos=60,60
Size=400,400
Collapsed=0
[Window][Inspector]
Pos=1649,48
Size=271,1012
Collapsed=0
DockId=0x00000006,0
[Window][Profiler]
Pos=0,48
Size=387,92
Collapsed=0
DockId=0x00000003,0
[Window][Viewport]
Pos=648,48
Size=2519,1319
Collapsed=0
DockId=0x00000002,0
[Window][ Viewport]
Pos=389,48
Size=1258,1012
Collapsed=0
DockId=0x00000002,0
[Docking][Data]
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=387,1036 Split=Y Selected=0x1E6EB881
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1258,1036 CentralNode=1 Selected=0xB41284E7
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252

View File

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

View File

@ -37,7 +37,8 @@ project "SHADE_Application"
"%{IncludeDir.VULKAN}/include", "%{IncludeDir.VULKAN}/include",
"%{IncludeDir.spdlog}/include", "%{IncludeDir.spdlog}/include",
"%{IncludeDir.tinyddsloader}", "%{IncludeDir.tinyddsloader}",
"%{IncludeDir.reactphysics3d}\\include" "%{IncludeDir.reactphysics3d}\\include",
"%{IncludeDir.yamlcpp}"
} }
externalwarnings "Off" externalwarnings "Off"
@ -51,6 +52,7 @@ project "SHADE_Application"
{ {
"SHADE_Engine", "SHADE_Engine",
"SHADE_Managed", "SHADE_Managed",
"yaml-cpp",
"SDL2.lib", "SDL2.lib",
"SDL2main.lib" "SDL2main.lib"
} }

View File

@ -30,6 +30,7 @@
#include "Input/SHInputManager.h" #include "Input/SHInputManager.h"
#include "FRC/SHFramerateController.h" #include "FRC/SHFramerateController.h"
#include "AudioSystem/SHAudioSystem.h" #include "AudioSystem/SHAudioSystem.h"
#include "Camera/SHCameraSystem.h"
// Components // Components
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
@ -67,6 +68,7 @@ namespace Sandbox
SHSystemManager::CreateSystem<SHTransformSystem>(); SHSystemManager::CreateSystem<SHTransformSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>()); SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
SHSystemManager::CreateSystem<SHAudioSystem>(); SHSystemManager::CreateSystem<SHAudioSystem>();
SHSystemManager::CreateSystem<SHCameraSystem>();
#ifdef SHEDITOR #ifdef SHEDITOR
SDL_Init(SDL_INIT_VIDEO); SDL_Init(SDL_INIT_VIDEO);
@ -81,14 +83,19 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::LateUpdateRoutine>(); SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::LateUpdateRoutine>();
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameCleanUpRoutine>(); SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameCleanUpRoutine>();
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostLogicUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>(); SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>(); SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>(); SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformUpdateRoutine>(); SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>();
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::CameraSystemUpdate>();
#ifdef SHEDITOR #ifdef SHEDITOR
SHSystemManager::RegisterRoutine<SHEditor, SHEditor::EditorRoutine>(); SHSystemManager::RegisterRoutine<SHEditor, SHEditor::EditorRoutine>();
@ -101,13 +108,14 @@ namespace Sandbox
SHComponentManager::CreateComponentSparseSet<SHColliderComponent>(); SHComponentManager::CreateComponentSparseSet<SHColliderComponent>();
SHComponentManager::CreateComponentSparseSet<SHTransformComponent>(); SHComponentManager::CreateComponentSparseSet<SHTransformComponent>();
SHComponentManager::CreateComponentSparseSet<SHRenderable>(); SHComponentManager::CreateComponentSparseSet<SHRenderable>();
SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
//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,23 +133,29 @@ namespace Sandbox
SHSceneManager::InitSceneManager<SBTestScene>("TestScene"); SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
SHFrameRateController::UpdateFRC(); SHFrameRateController::UpdateFRC();
SHAssetManager::Load();
} }
void SBApplication::Update(void) void SBApplication::Update(void)
{ {
SHGraphicsSystem* graphicsSystem = SHADE::SHSystemManager::GetSystem<SHGraphicsSystem>(); SHGraphicsSystem* graphicsSystem = SHADE::SHSystemManager::GetSystem<SHGraphicsSystem>();
SHEditor* editor = SHADE::SHSystemManager::GetSystem<SHEditor>();
//TODO: Change true to window is open //TODO: Change true to window is open
while (!window.WindowShouldClose()) while (!window.WindowShouldClose())
{ {
SHFrameRateController::UpdateFRC(); SHFrameRateController::UpdateFRC();
SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime()); SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime());
SHSceneManager::UpdateSceneManager(); SHSceneManager::UpdateSceneManager();
SHSceneManager::SceneUpdate(0.016f); #ifdef SHEDITOR
SHSystemManager::RunRoutines(false, 0.016f); if(editor->editorState == SHEditor::State::PLAY)
SHSceneManager::SceneUpdate(0.016f);
#endif
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
//editor->PollPicking();
} }
// Finish all graphics jobs first // Finish all graphics jobs first
graphicsSystem->AwaitGraphicsExecution(); graphicsSystem->AwaitGraphicsExecution();
} }
@ -154,6 +168,7 @@ namespace Sandbox
SHSceneManager::Exit(); SHSceneManager::Exit();
SHSystemManager::Exit(); SHSystemManager::Exit();
SHAssetManager::Unload();
} }
} }

View File

@ -1,4 +1,4 @@
#include "SBpch.h" #include "SBpch.h"
#include "SBTestScene.h" #include "SBTestScene.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
@ -14,6 +14,8 @@
#include "Physics/Components/SHColliderComponent.h" #include "Physics/Components/SHColliderComponent.h"
#include "Assets/SHAssetManager.h" #include "Assets/SHAssetManager.h"
#include "Camera/SHCameraComponent.h"
#include "Resource/SHResourceManager.h"
using namespace SHADE; using namespace SHADE;
@ -40,34 +42,22 @@ namespace Sandbox
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem); const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
//Test Racoon mesh //Test Racoon mesh
auto meshes = SHADE::SHAssetManager::GetAllMeshes();
std::vector<Handle<SHMesh>> handles; std::vector<Handle<SHMesh>> handles;
for (auto const& mesh : meshes) std::vector<Handle<SHTexture>> texHandles;
for (const auto& asset : SHAssetManager::GetAllAssets())
{ {
if (mesh.header.meshName == "Cube.012") switch (asset.type)
{ {
handles.push_back(graphicsSystem->AddMesh( case AssetType::MESH:
mesh.header.vertexCount, if (asset.name == "Cube.012")
mesh.vertexPosition.data(), handles.emplace_back(SHResourceManager::LoadOrGet<SHMesh>(asset.id));
mesh.texCoords.data(), break;
mesh.vertexTangent.data(), case AssetType::IMAGE:
mesh.vertexNormal.data(), texHandles.emplace_back(SHResourceManager::LoadOrGet<SHTexture>(asset.id));
mesh.header.indexCount, break;
mesh.indices.data()
));
} }
} }
graphicsSystem->BuildMeshBuffers(); SHResourceManager::FinaliseChanges();
// Load Textures
auto textures = SHADE::SHAssetManager::GetAllTextures();
std::vector<Handle<SHTexture>> texHandles;
for (const auto& tex : textures)
{
auto texture = graphicsSystem->Add(tex);
texHandles.push_back(texture);
}
graphicsSystem->BuildTextures();
// Create Materials // Create Materials
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance(); auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
@ -77,9 +67,9 @@ namespace Sandbox
customMat->SetProperty("data.alpha", 0.1f); customMat->SetProperty("data.alpha", 0.1f);
// Create Stress Test Objects // Create Stress Test Objects
static const SHVec3 TEST_OBJ_SCALE = SHVec3::One * 0.5f; static const SHVec3 TEST_OBJ_SCALE = SHVec3::One;
constexpr int NUM_ROWS = 10; constexpr int NUM_ROWS = 3;
constexpr int NUM_COLS = 10; constexpr int NUM_COLS = 1;
static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f }; static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f };
static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f }; static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f };
@ -101,13 +91,13 @@ namespace Sandbox
//Set initial positions //Set initial positions
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f) }); transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f) });
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f}); //transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber()); transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f));
transform.SetWorldScale(TEST_OBJ_SCALE); transform.SetWorldScale(TEST_OBJ_SCALE);
if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN) //if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN)
collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero); collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero);
else //else
collider.AddBoundingSphere(0.5f, SHVec3::Zero); // collider.AddBoundingSphere(0.5f, SHVec3::Zero);
stressTestObjects.emplace_back(entity); stressTestObjects.emplace_back(entity);
} }
@ -166,6 +156,10 @@ namespace Sandbox
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f }); transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f }); transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase"); scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase");
SHComponentManager::AddComponent<SHCameraComponent>(0);
SHComponentManager::RemoveComponent <SHRigidBodyComponent>(0);
SHComponentManager::RemoveComponent <SHColliderComponent>(0);
} }
void SBTestScene::Update(float dt) void SBTestScene::Update(float dt)

View File

@ -0,0 +1,30 @@
/*************************************************************************//**
* \file SHAnimationAsset.h
* \author Loh Xiao Qi
* \date October 2022
* \brief
*
* 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 <vector>
#include <assimp/anim.h>
#include "SH_API.power h"
namespace SHADE
{
struct SH_API SHAnimationAsset
{
std::string name;
std::vector<aiNodeAnim*> nodeChannels;
std::vector<aiMeshAnim*> meshChannels;
std::vector<aiMeshMorphAnim*> morphMeshChannels;
double duration;
double ticksPerSecond;
};
}

View File

@ -0,0 +1,30 @@
/*************************************************************************//**
* \file SHAnimationAsset.h
* \author Loh Xiao Qi
* \date October 2022
* \brief
*
* 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 <vector>
#include <assimp/anim.h>
#include "SHAssetData.h"
namespace SHADE
{
struct SH_API SHAnimationAsset : SHAssetData
{
std::string name;
std::vector<aiNodeAnim*> nodeChannels;
std::vector<aiMeshAnim*> meshChannels;
std::vector<aiMeshMorphAnim*> morphMeshChannels;
double duration;
double ticksPerSecond;
};
}

View File

@ -0,0 +1,19 @@
/*************************************************************************//**
* \file SHAssetDataBase.h
* \author Loh Xiao Qi
* \date October 2022
* \brief
*
* 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
{
struct SHAssetData
{
virtual ~SHAssetData(){}
};
}

View File

@ -0,0 +1,4 @@
#pragma once
#include "SHMeshAsset.h"
#include "SHTextureAsset.h"

View File

@ -0,0 +1,21 @@
/*************************************************************************//**
* \file SHInternalAsset.h
* \author Loh Xiao Qi
* \date October 2022
* \brief
*
* 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 "SHAsset.h"
namespace SHADE
{
struct SHInternalAsset : SHAsset
{
};
}

View File

@ -14,7 +14,7 @@
#include <vector> #include <vector>
#include "Math/SHMath.h" #include "Math/SHMath.h"
#include "SH_API.h" #include "SHAssetData.h"
namespace SHADE namespace SHADE
{ {
@ -22,10 +22,10 @@ namespace SHADE
{ {
uint32_t vertexCount; uint32_t vertexCount;
uint32_t indexCount; uint32_t indexCount;
std::string meshName; std::string name;
}; };
struct SH_API SHMeshAsset struct SH_API SHMeshAsset : SHAssetData
{ {
bool compiled; bool compiled;
bool changed; bool changed;

View File

@ -2,13 +2,15 @@
#include "tinyddsloader.h" #include "tinyddsloader.h"
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h" #include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
#include "SHAssetData.h"
namespace SHADE namespace SHADE
{ {
struct SHTextureAsset struct SHTextureAsset : SHAssetData
{ {
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

@ -0,0 +1,21 @@
/*************************************************************************//**
* \file SHAssetLoader.h
* \author Loh Xiao Qi
* \date October 2022
* \brief
*
* 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 "Assets/Asset Types/SHAssetData.h"
namespace SHADE
{
struct SHAssetLoader
{
virtual SHAssetData* Load(AssetPath path) = 0;
};
}

View File

@ -0,0 +1,141 @@
/*************************************************************************//**
* \file SHAssimpLibrary.cpp
* \author Loh Xiao Qi
* \date October 2022
* \brief
*
* 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 "SHAssimpLibrary.h"
#include <assimp/postprocess.h>
namespace SHADE
{
Assimp::Importer SHAssimpLibrary::aiImporter;
void SHAssimpLibrary::ProcessNode(aiNode const& node, aiScene const& scene, MeshVectorRef meshes) noexcept
{
for (size_t i {0}; i < node.mNumMeshes; ++i)
{
aiMesh* mesh = scene.mMeshes[node.mMeshes[i]];
meshes.push_back(ProcessMesh(*mesh));
}
for (size_t i{ 0 }; i < node.mNumChildren; ++i)
{
ProcessNode(*node.mChildren[i], scene, meshes);
}
}
void SHAssimpLibrary::ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept
{
if (scene.HasAnimations())
{
std::vector<SHAnimationAsset> anims(scene.mNumAnimations);
for (auto i{0}; i < scene.mNumAnimations; ++i)
{
auto const& anim {*scene.mAnimations[i]};
anims[i].name = anim.mName.C_Str();
anims[i].duration = anim.mDuration;
anims[i].ticksPerSecond = anim.mTicksPerSecond;
std::copy_n(anim.mChannels, anim.mNumChannels, anims[i].nodeChannels.data());
std::copy_n(anim.mMeshChannels, anim.mNumMeshChannels, anims[i].meshChannels.data());
std::copy_n(anim.mMorphMeshChannels, anim.mNumMorphMeshChannels, anims[i].morphMeshChannels.data());
}
}
}
SHMeshAsset* SHAssimpLibrary::ProcessMesh(aiMesh const& mesh) noexcept
{
SHMeshAsset* result = new SHMeshAsset();
result->compiled = false;
result->changed = false;
for (size_t i{0}; i < mesh.mNumVertices; ++i)
{
// Vertex position
SHVec3 vertex;
vertex.x = mesh.mVertices[i].x;
vertex.y = mesh.mVertices[i].y;
vertex.z = mesh.mVertices[i].z;
result->vertexPosition.push_back(vertex);
// Tex coords
SHVec2 texCoord{0.f, 0.f};
if (mesh.mTextureCoords[0])
{
texCoord.x = mesh.mTextureCoords[0][i].x;
texCoord.y = mesh.mTextureCoords[0][i].y;
}
result->texCoords.push_back(texCoord);
// Normals
SHVec3 normal{0.f, 0.f, 0.f};
if (mesh.mNormals)
{
normal.x = mesh.mNormals[i].x;
normal.y = mesh.mNormals[i].y;
normal.z = mesh.mNormals[i].z;
}
result->vertexNormal.push_back(normal);
// Tangent
SHVec3 tangent{0.f, 0.f, 0.f};
if (mesh.mTangents)
{
tangent.x = mesh.mTangents[i].x;
tangent.y = mesh.mTangents[i].y;
tangent.z = mesh.mTangents[i].z;
}
result->vertexTangent.push_back(tangent);
}
for (size_t i {0}; i < mesh.mNumFaces; ++i)
{
aiFace face = mesh.mFaces[i];
for (size_t j{0}; j < face.mNumIndices; ++j)
{
result->indices.push_back(face.mIndices[j]);
}
}
result->header.vertexCount = static_cast<uint32_t>(result->vertexPosition.size());
result->header.indexCount = static_cast<uint32_t>(result->indices.size());
result->header.name = mesh.mName.C_Str();
return result;
}
void SHAssimpLibrary::LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept
{
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons
| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
| aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...)
| aiProcess_FindInstances // search for instanced meshes and remove them by references to one master
| aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible
| aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing
| aiProcess_RemoveRedundantMaterials // remove redundant materials
| aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
);
if (!scene || !scene->HasMeshes())
{
SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string());
return;
}
ExtractAnimations(*scene, anims);
ProcessNode(*scene->mRootNode, *scene, meshes);
aiImporter.FreeScene();
}
}

View File

@ -0,0 +1,36 @@
/*************************************************************************//**
* \file SHAssimpLibrary.h
* \author Loh Xiao Qi
* \date October 2022
* \brief
*
* 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 <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <vector>
#include "../SHAssetMacros.h"
#include "../Asset Types/SHMeshAsset.h"
#include "../Asset Types/SHAnimationAsset.h"
namespace SHADE
{
class SHAssimpLibrary
{
private:
using MeshVectorRef = std::vector<SHMeshAsset*>&;
using AnimVectorRef = std::vector<SHAnimationAsset*>&;
static Assimp::Importer aiImporter;
static void ProcessNode(aiNode const& node, aiScene const& scene,MeshVectorRef meshes) noexcept;
static void ExtractAnimations(aiScene const& scene, AnimVectorRef anims) noexcept;
static SHMeshAsset* ProcessMesh(aiMesh const& mesh) noexcept;
public:
static void LoadFromFile(AssetPath path, MeshVectorRef meshes, AnimVectorRef anims) noexcept;
};
}

View File

@ -16,11 +16,11 @@
#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);
newPath += asset.header.meshName + MESH_EXTENSION; newPath += asset.header.name + MESH_EXTENSION.data();
std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc }; std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc };
if (!file.is_open()) if (!file.is_open())
@ -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

@ -12,129 +12,11 @@
*****************************************************************************/ *****************************************************************************/
#include "SHpch.h" #include "SHpch.h"
#include "SHMeshLoader.h" #include "SHMeshLoader.h"
#include <assimp/postprocess.h>
#include <fstream> #include <fstream>
namespace SHADE namespace SHADE
{ {
Assimp::Importer SHMeshLoader::aiImporter; void SHMeshLoader::LoadSHMesh(AssetPath path, SHMeshAsset& mesh) noexcept
void SHMeshLoader::ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes) noexcept
{
for (size_t i {0}; i < node.mNumMeshes; ++i)
{
aiMesh* mesh = scene.mMeshes[node.mMeshes[i]];
meshes.push_back(ProcessMesh(*mesh, scene));
}
for (size_t i{ 0 }; i < node.mNumChildren; ++i)
{
ProcessNode(*node.mChildren[i], scene, meshes);
}
}
SHMeshAsset SHMeshLoader::ProcessMesh(aiMesh const& mesh, aiScene const& scene) noexcept
{
(void)scene;
SHMeshAsset result
{
.compiled { false},
.changed { false }
};
for (size_t i{0}; i < mesh.mNumVertices; ++i)
{
// Vertex position
SHVec3 vertex;
vertex.x = mesh.mVertices[i].x;
vertex.y = mesh.mVertices[i].y;
vertex.z = mesh.mVertices[i].z;
result.vertexPosition.push_back(vertex);
// Tex coords
SHVec2 texCoord{0.f, 0.f};
if (mesh.mTextureCoords[0])
{
texCoord.x = mesh.mTextureCoords[0][i].x;
texCoord.y = mesh.mTextureCoords[0][i].y;
}
result.texCoords.push_back(texCoord);
// Normals
SHVec3 normal{0.f, 0.f, 0.f};
if (mesh.mNormals)
{
normal.x = mesh.mNormals[i].x;
normal.y = mesh.mNormals[i].y;
normal.z = mesh.mNormals[i].z;
}
result.vertexNormal.push_back(normal);
// Tangent
SHVec3 tangent{0.f, 0.f, 0.f};
if (mesh.mTangents)
{
tangent.x = mesh.mTangents[i].x;
tangent.y = mesh.mTangents[i].y;
tangent.z = mesh.mTangents[i].z;
}
result.vertexTangent.push_back(tangent);
}
for (size_t i {0}; i < mesh.mNumFaces; ++i)
{
aiFace face = mesh.mFaces[i];
for (size_t j{0}; j < face.mNumIndices; ++j)
{
result.indices.push_back(face.mIndices[j]);
}
}
result.header.vertexCount = static_cast<uint32_t>(result.vertexPosition.size());
result.header.indexCount = static_cast<uint32_t>(result.indices.size());
result.header.meshName = mesh.mName.C_Str();
return result;
}
void SHMeshLoader::LoadExternal(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept
{
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons
| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
| aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...)
| aiProcess_FindInstances // search for instanced meshes and remove them by references to one master
| aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible
| aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing
| aiProcess_RemoveRedundantMaterials // remove redundant materials
| aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
);
if (!scene || !scene->HasMeshes())
{
SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string());
return;
}
//TODO MATERIALS FROM MESHES
//if (scene->HasMaterials())
//{
// for (int i{0}; i < scene->mNumMaterials; ++i)
// {
// if (scene->mMaterials[i]->mNumProperties > 0)
// {
// for (int j{0}; j < scene->mMaterials[i]->mProperties[j].)
// }
//std::cout << scene->mMaterials[i]->;
// }
//}
ProcessNode(*scene->mRootNode, *scene, meshes);
}
void SHMeshLoader::LoadSHMesh(SHMeshAsset& mesh, AssetPath path) noexcept
{ {
std::ifstream file{ path.string(), std::ios::in | std::ios::binary }; std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
if (!file.is_open()) if (!file.is_open())
@ -142,8 +24,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);
@ -169,45 +50,13 @@ namespace SHADE
file.read(reinterpret_cast<char *>(vertNorm.data()), vertexVec3Byte); file.read(reinterpret_cast<char *>(vertNorm.data()), vertexVec3Byte);
file.read(reinterpret_cast<char *>(texCoord.data()), vertexVec2Byte); file.read(reinterpret_cast<char *>(texCoord.data()), vertexVec2Byte);
file.read(reinterpret_cast<char *>(indices.data()), sizeof(uint32_t) * indexCount); file.read(reinterpret_cast<char *>(indices.data()), sizeof(uint32_t) * indexCount);
//for (auto i{ 0 }; i < vertCount; ++i)
//{
// file >> vertPos[i].x;
// file >> vertPos[i].y;
// file >> vertPos[i].z;
//}
//
//for (auto i{ 0 }; i < vertCount; ++i)
//{
// file >> vertTan[i].x;
// file >> vertTan[i].y;
// file >> vertTan[i].z;
//}
//for (auto i{ 0 }; i < vertCount; ++i)
//{
// file >> vertNorm[i].x;
// file >> vertNorm[i].y;
// file >> vertNorm[i].z;
//}
//for (auto i{ 0 }; i < vertCount; ++i)
//{
// file >> texCoord[i].x;
// file >> texCoord[i].y;
//}
//for (auto i{ 0 }; i < indexCount; ++i)
//{
// file >> indices[i];
//}
mesh.compiled = true; mesh.compiled = true;
mesh.changed = false; mesh.changed = false;
mesh.header.indexCount = indexCount; mesh.header.indexCount = indexCount;
mesh.header.vertexCount = vertCount; mesh.header.vertexCount = vertCount;
mesh.header.meshName = name; mesh.header.name = name;
mesh.vertexPosition = std::move(vertPos); mesh.vertexPosition = std::move(vertPos);
mesh.vertexTangent = std::move(vertTan); mesh.vertexTangent = std::move(vertTan);
@ -218,15 +67,12 @@ namespace SHADE
file.close(); file.close();
} }
void SHMeshLoader::LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept SHAssetData* SHMeshLoader::Load(AssetPath path)
{ {
if (path.extension().string() == GLTF_EXTENSION) auto result = new SHMeshAsset();
{
LoadExternal(meshes, path);
return;
}
meshes.emplace_back(); LoadSHMesh(path, *result);
LoadSHMesh(meshes.back(), path);
return result;
} }
} }

View File

@ -10,27 +10,15 @@
* of DigiPen Institute of Technology is prohibited. * of DigiPen Institute of Technology is prohibited.
*****************************************************************************/ *****************************************************************************/
#pragma once #pragma once
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include "../SHAssetMacros.h" #include "../SHAssetMacros.h"
#include "../Asset Types/SHMeshAsset.h" #include "../Asset Types/SHMeshAsset.h"
#include <vector> #include "SHAssetLoader.h"
namespace SHADE namespace SHADE
{ {
class SHMeshLoader struct SHMeshLoader : public SHAssetLoader
{ {
private: void LoadSHMesh(AssetPath path, SHMeshAsset& meshes) noexcept;
static Assimp::Importer aiImporter; SHAssetData* Load(AssetPath path) override;
static void ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes) noexcept;
static SHMeshAsset ProcessMesh(aiMesh const& mesh, aiScene const& scene) noexcept;
static void LoadExternal(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept;
public:
static void LoadMesh(std::vector<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();
@ -132,6 +133,15 @@ namespace SHADE
file.close(); file.close();
} }
SHAssetData* SHTextureLoader::Load(AssetPath path)
{
auto result = new SHTextureAsset();
LoadImageAsset(path, *result);
return result;
}
void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset) void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset)
{ {
if (path.extension().string() == DDS_EXTENSION) if (path.extension().string() == DDS_EXTENSION)

View File

@ -15,19 +15,20 @@
#include "../SHAssetMacros.h" #include "../SHAssetMacros.h"
#include "../Asset Types/SHTextureAsset.h" #include "../Asset Types/SHTextureAsset.h"
#include "tinyddsloader.h" #include "tinyddsloader.h"
#include "SHAssetLoader.h"
namespace SHADE namespace SHADE
{ {
class SHTextureLoader class SHTextureLoader : public SHAssetLoader
{ {
private: private:
static std::string TinyDDSResultToString(tinyddsloader::Result value); std::string TinyDDSResultToString(tinyddsloader::Result value);
static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear); vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear);
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); void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
SHAssetData* Load(AssetPath path) override;
}; };
} }

View File

@ -12,11 +12,12 @@
#pragma once #pragma once
#include "Filesystem/SHFileSystem.h" #include "Filesystem/SHFileSystem.h"
#include "SHAssetMacros.h" #include "Assets/SHAssetMacros.h"
#include "SH_API.h"
namespace SHADE namespace SHADE
{ {
struct SHAsset struct SH_API SHAsset
{ {
AssetName name; AssetName name;
AssetID id; AssetID id;

View File

@ -32,15 +32,15 @@ typedef std::filesystem::path AssetPath;
typedef unsigned char* AssetData; typedef unsigned char* AssetData;
typedef std::string AssetMetaVersion; typedef std::string AssetMetaVersion;
typedef std::string AssetExtension; typedef std::string AssetExtension;
typedef unsigned char AssetTypeMeta; typedef size_t AssetTypeMeta;
typedef FMOD::Sound* SHSound; typedef FMOD::Sound* SHSound;
// Asset Meta Version // Asset Meta Version
#define ASSET_META_VER "1.0" constexpr std::string_view 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,
@ -53,29 +53,35 @@ enum class AssetType : uint8_t
SCENE, SCENE,
PREFAB, PREFAB,
AUDIO_WAV, AUDIO_WAV,
DDS DDS,
MAX_COUNT
}; };
//Directory //Directory
#define ASSET_ROOT "./Assets/" #ifdef _PUBLISH
constexpr std::string_view ASSET_ROOT {"Assets"};
#else
constexpr std::string_view ASSET_ROOT {"../../Assets"};
#endif
// ASSET EXTENSIONS // ASSET EXTENSIONS
#define META_EXTENSION ".shmeta" constexpr std::string_view META_EXTENSION {".shmeta"};
#define IMAGE_EXTENSION ".png" constexpr std::string_view IMAGE_EXTENSION {".png"};
#define AUDIO_EXTENSION ".ogg" constexpr std::string_view AUDIO_EXTENSION {".ogg"};
#define AUDIO_WAV_EXTENSION ".wav" constexpr std::string_view AUDIO_WAV_EXTENSION {".wav"};
#define SHADER_EXTENSION ".glsl" constexpr std::string_view SHADER_EXTENSION {".glsl"};
#define SCRIPT_EXTENSION ".cs" constexpr std::string_view SCRIPT_EXTENSION {".cs"};
#define SCENE_EXTENSION ".SHADE" constexpr std::string_view SCENE_EXTENSION {".SHADE"};
#define PREFAB_EXTENSION ".SHPrefab" constexpr std::string_view PREFAB_EXTENSION {".SHPrefab"};
#define MATERIAL_EXTENSION ".SHMat" constexpr std::string_view MATERIAL_EXTENSION {".SHMat"};
#define TEXTURE_EXTENSION ".shtex" constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
#define DDS_EXTENSION ".dds" constexpr std::string_view DDS_EXTENSION {".dds"};
#define FBX_EXTENSION ".fbx" constexpr std::string_view FBX_EXTENSION {".fbx"};
#define GLTF_EXTENSION ".gltf" constexpr std::string_view GLTF_EXTENSION {".gltf"};
#define MESH_EXTENSION ".shmesh" constexpr std::string_view MESH_EXTENSION {".shmesh"};
std::string const EXTENSIONS[] = { constexpr std::string_view EXTENSIONS[] = {
AUDIO_EXTENSION, AUDIO_EXTENSION,
SHADER_EXTENSION, SHADER_EXTENSION,
MATERIAL_EXTENSION, MATERIAL_EXTENSION,
@ -91,10 +97,12 @@ std::string const EXTENSIONS[] = {
GLTF_EXTENSION GLTF_EXTENSION
}; };
constexpr size_t TYPE_COUNT {static_cast<size_t>(AssetType::MAX_COUNT) };
// Error flags // Error flags
#define FILE_NOT_FOUND_ERR "FILE NOT FOUND" constexpr std::string_view FILE_NOT_FOUND_ERR {"FILE NOT FOUND"};
#define META_NOT_FOUND_ERR "META NOT FOUND" constexpr std::string_view META_NOT_FOUND_ERR {"META NOT FOUND"};
#define ASSET_NOT_FOUND_ERR "ASSET NOT FOUND" constexpr std::string_view ASSET_NOT_FOUND_ERR {"ASSET NOT FOUND"};
#define EXT_DOES_NOT_EXIST "TYPE DOES NOT HAVE EXTENSION DEFINED" constexpr std::string_view EXT_DOES_NOT_EXIST {"TYPE DOES NOT HAVE EXTENSION DEFINED"};
#endif // !SH_ASSET_MACROS_H #endif // !SH_ASSET_MACROS_H

View File

@ -14,6 +14,7 @@
#include "SHAssetMetaHandler.h" #include "SHAssetMetaHandler.h"
#include "Filesystem/SHFileSystem.h" #include "Filesystem/SHFileSystem.h"
#include "Libraries/SHAssimpLibrary.h"
#include "Libraries/SHMeshLoader.h" #include "Libraries/SHMeshLoader.h"
#include "Libraries/SHTextureLoader.h" #include "Libraries/SHTextureLoader.h"
@ -25,11 +26,10 @@ namespace SHADE
FMOD::System* SHAssetManager::audioSystem; FMOD::System* SHAssetManager::audioSystem;
std::unordered_map<AssetID, SHSound >* SHAssetManager::audioSoundList; std::unordered_map<AssetID, SHSound >* SHAssetManager::audioSoundList;
std::vector<SHAsset> SHAssetManager::assetCollection; std::vector<SHAssetLoader*> SHAssetManager::loaders(TYPE_COUNT);
std::unordered_map<AssetID, SHAsset> SHAssetManager::assetRegistry;
std::unordered_map<AssetID, SHMeshAsset> SHAssetManager::meshCollection; std::vector<SHAsset> SHAssetManager::assetCollection;
std::unordered_map<AssetID, SHTextureAsset> SHAssetManager::textureCollection; std::unordered_map<AssetID, SHAssetData * const> SHAssetManager::assetData;
/**************************************************************************** /****************************************************************************
* \brief Static function to generate asset ID. * \brief Static function to generate asset ID.
@ -56,13 +56,15 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
void SHAssetManager::Unload() noexcept void SHAssetManager::Unload() noexcept
{ {
for (auto const& asset : assetCollection)
{
SHAssetMetaHandler::WriteMetaData(asset);
}
} }
AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept void SHAssetManager::Unload(AssetID assetId) noexcept
{
// TODO
}
AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept
{ {
if (!IsRecognised(path.extension().string().c_str())) if (!IsRecognised(path.extension().string().c_str()))
{ {
@ -80,7 +82,37 @@ namespace SHADE
// return std::filesystem::path(); // return std::filesystem::path();
//} //}
return std::filesystem::path(ASSET_ROOT + folder + path.filename().string()); return std::filesystem::path(std::string(ASSET_ROOT) + folder + path.filename().string());
}
AssetPath SHAssetManager::GenerateNewPath(AssetName name, AssetType type)
{
std::string folder;
switch(type)
{
case AssetType::SCENE:
folder = "scenes/";
break;
case AssetType::PREFAB:
folder = "prefabs/";
break;
case AssetType::MATERIAL:
folder = "materials/";
break;
default:
folder = "/";
}
return std::filesystem::path{
std::string(ASSET_ROOT) +
folder +
name +
std::string(EXTENSIONS[static_cast<size_t>(type)])
};
} }
/**************************************************************************** /****************************************************************************
@ -116,7 +148,7 @@ namespace SHADE
// folder = ""; // folder = "";
// break; // break;
//} //}
AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) }; AssetPath path{ std::string{ASSET_ROOT} + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
SHAssetMetaHandler::WriteMetaData(meta); SHAssetMetaHandler::WriteMetaData(meta);
@ -125,6 +157,19 @@ namespace SHADE
return id; return id;
} }
AssetID SHAssetManager::CreateAsset(AssetName name, AssetType type) noexcept
{
AssetID id = GenerateAssetID(type);
assetCollection.emplace_back(
name,
id,
type,
GenerateNewPath(name, type),
0
);
return id;
}
/**************************************************************************** /****************************************************************************
* \brief Import new asset from outside editor window. * \brief Import new asset from outside editor window.
* *
@ -133,7 +178,10 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
AssetID SHAssetManager::ImportNewAsset(char const* p) noexcept AssetID SHAssetManager::ImportNewAsset(char const* p) noexcept
{ {
std::filesystem::path const path{ p }; std::filesystem::path const path{ p };
auto const type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string());
auto const id = GenerateAssetID(type);
std::filesystem::path const newPath{ GenerateLocalPath(path) }; std::filesystem::path const newPath{ GenerateLocalPath(path) };
if (newPath.empty()) if (newPath.empty())
@ -144,11 +192,7 @@ namespace SHADE
std::filesystem::copy(path, newPath); std::filesystem::copy(path, newPath);
AssetID id{ RetrieveAsset(newPath.string().c_str()) }; assetCollection.push_back(CreateAssetFromPath(newPath));
if (id != 0)
{
LoadData(id);
}
return id; return id;
} }
@ -159,138 +203,14 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
void SHAssetManager::RefreshAllAssets() noexcept void SHAssetManager::RefreshAllAssets() noexcept
{ {
std::vector<AssetPath> metaFiles;
std::vector<AssetPath> AssetFiles;
//SHFileSystem::LoadAllFiles(metaFiles, AssetFiles);
//std::vector<AssetPath> AssetFilesVerified;
std::vector<AssetPath> AssetFilesNew;
for (auto const& asset : AssetFiles)
{
bool found = false;
for (auto it {metaFiles.begin()}; it != metaFiles.end(); ++it)
{
std::string fileExtCheck{ asset.filename().string() };
fileExtCheck += META_EXTENSION;
if (it->filename().string() == fileExtCheck)
{
metaFiles.erase(it);
found = true;
break;
}
}
if (!found && IsRecognised(asset.extension().string().c_str()))
{
AssetFilesNew.push_back(asset);
}
}
std::vector<SHAsset> newLoad;
newLoad.reserve(AssetFilesNew.size());
//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
for (auto const& file : AssetFilesNew)
{
newLoad.push_back(RegisterAssetNew(file));
}
//UpdateAllSpriteSets();
}
void SHAssetManager::LoadDataTemp(std::string p) noexcept
{
AssetPath path{ p };
if (path.extension().string() == FBX_EXTENSION
|| path.extension().string() == GLTF_EXTENSION
|| path.extension().string() == MESH_EXTENSION)
{
LoadGLTF(
{
.name {path.filename().string()},
.id {0},
.type {AssetType::MESH},
.path {path},
.location {0}
}
);
}
else if (path.extension().string() == DDS_EXTENSION
|| path.extension().string() == TEXTURE_EXTENSION)
{
LoadDDS(
{
.name {path.filename().string()},
.id {0},
.type {AssetType::DDS},
.path {path},
.location {0}
}
);
}
}
std::vector<SHMeshAsset> SHAssetManager::GetAllMeshes() noexcept
{
std::vector<SHMeshAsset> result;
for (auto const& mesh : meshCollection)
{
result.push_back(mesh.second);
}
return result;
}
std::vector<SHTextureAsset> SHAssetManager::GetAllTextures() noexcept
{
std::vector<SHTextureAsset> result;
for (auto const& dds : textureCollection)
{
result.push_back(dds.second);
}
return result;
}
/****************************************************************************
* \param Path for meta data file
* \param Path for asset file
* \brief Links meta data to asset in registries. Meta data should
* already exist
****************************************************************************/
void SHAssetManager::RegisterAsset(AssetPath const& metaPath, AssetPath const& path) noexcept
{
SHAsset const meta = SHAssetMetaHandler::RetrieveMetaData(metaPath);
assetCollection.push_back(meta);
}
/****************************************************************************
* \param Path for asset file
* \brief Creates new meta data for new asset.
****************************************************************************/
SHAsset SHAssetManager::RegisterAssetNew(AssetPath const& asset) noexcept
{
SHAsset meta;
meta.type = SHAssetMetaHandler::GetTypeFromExtension(asset.extension().string());
meta.id = GenerateAssetID(meta.type);
assetCollection.push_back(meta);
SHAssetMetaHandler::WriteMetaData(meta);
return assetCollection.back();
} }
bool SHAssetManager::IsRecognised(char const* ext) noexcept bool SHAssetManager::IsRecognised(char const* ext) noexcept
{ {
for (auto const& e : EXTENSIONS) for (auto const& e : EXTENSIONS)
{ {
if (strcmp(ext, e.c_str()) == 0) if (strcmp(ext, e.data()) == 0)
{ {
return true; return true;
} }
@ -299,35 +219,31 @@ namespace SHADE
return false; return false;
} }
void SHAssetManager::LoadGLTF(SHAsset asset) noexcept SHAsset SHAssetManager::CreateAssetFromPath(AssetPath path) noexcept
{ {
std::vector<SHMeshAsset> meshes; SHAsset result;
SHMeshLoader::LoadMesh(meshes, asset.path); result.name = path.stem().string();
result.type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string());
result.id = GenerateAssetID(result.type);
result.path = path;
for (auto const& mesh : meshes) return result;
{
meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh);
if (!mesh.compiled)
{
SHMeshCompiler::CompileMeshBinary(mesh, asset.path);
}
}
} }
void SHAssetManager::LoadDDS(SHAsset asset) noexcept void SHAssetManager::InitLoaders() noexcept
{ {
SHTextureAsset image; loaders[static_cast<size_t>(AssetType::AUDIO)] = nullptr;
loaders[static_cast<size_t>(AssetType::SHADER)] = nullptr;
SHTextureLoader::LoadImageAsset(asset.path, image); loaders[static_cast<size_t>(AssetType::MATERIAL)] = nullptr;
loaders[static_cast<size_t>(AssetType::IMAGE)] = dynamic_cast<SHAssetLoader*>(new SHTextureLoader());
textureCollection.emplace(GenerateAssetID(AssetType::DDS), image); loaders[static_cast<size_t>(AssetType::TEXTURE)] = nullptr;
loaders[static_cast<size_t>(AssetType::MESH)] = dynamic_cast<SHAssetLoader*>(new SHMeshLoader());
if (!image.compiled) loaders[static_cast<size_t>(AssetType::SCRIPT)] = nullptr;
{ loaders[static_cast<size_t>(AssetType::SCENE)] = nullptr;
SHTextureCompiler::CompileTextureBinary(image, asset.path); loaders[static_cast<size_t>(AssetType::PREFAB)] = nullptr;
} loaders[static_cast<size_t>(AssetType::AUDIO_WAV)] = nullptr;
loaders[static_cast<size_t>(AssetType::DDS)] = nullptr;
} }
/**************************************************************************** /****************************************************************************
@ -335,8 +251,9 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
void SHAssetManager::Load() noexcept void SHAssetManager::Load() noexcept
{ {
RetrieveAssets(); InitLoaders();
LoadAllData(); BuildAssetCollection();
//LoadAllData();
} }
/**************************************************************************** /****************************************************************************
@ -346,114 +263,38 @@ namespace SHADE
{ {
for (auto const& asset : assetCollection) for (auto const& asset : assetCollection)
{ {
SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path);
assetData.emplace(asset.id, data);
} }
} }
void SHAssetManager::LoadData(AssetID id) noexcept SHAssetData* SHAssetManager::LoadData(SHAsset const& asset) noexcept
{ {
(void)id; SHAssetData* data = loaders[static_cast<size_t>(asset.type)]->Load(asset.path);
}
/**************************************************************************** if (data == nullptr)
* \brief Retrieve all asset files and meta files from filesystem
****************************************************************************/
void SHAssetManager::RetrieveAssets() noexcept
{
std::vector<AssetPath> metaFiles;
std::vector<AssetPath> AssetFiles;
//TODO: Write new function for file manager to loop through all files
SHFileSystem::StartupFillDirectories(ASSET_ROOT);
FolderPointer rootFolder = SHFileSystem::GetRoot();
for (auto const& meta : metaFiles)
{ {
for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() }; SHLOG_ERROR("Unable to load asset into memory: {}\n", asset.path.string());
it != AssetFiles.cend();
++it)
{
// Asset exists for meta file
std::string fileExtCheck{ it->filename().string() };
fileExtCheck += META_EXTENSION;
if (meta.filename().string() == fileExtCheck)
{
RegisterAsset(meta, *it);
AssetFiles.erase(it);
break;
}
}
}
//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
for (auto const& file : AssetFiles)
{
if (IsRecognised(file.extension().string().c_str()))
{
SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file));
}
else
{
std::cout << "Unsupported File Format: " << file.filename() << "\n";
}
}
}
AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept
{
std::filesystem::path p{ path };
if (IsRecognised(p.extension().string().c_str()))
{
SHAsset const& meta{ RegisterAssetNew(p) };
SHAssetMetaHandler::WriteMetaData(meta);
return meta.id;
} }
else else
{ {
std::cout << "Unsupported File Format: " << p.filename() << "\n"; assetData.emplace(asset.id, data);
} }
// Assert that file imported is not recognised return data;
return 0;
} }
/**************************************************************************** void SHAssetManager::BuildAssetCollection() noexcept
* \param Full path of file
* \brief Extracts file name from path. Formats file name into readable
* with spaces and capitalises first letter of every word
****************************************************************************/
AssetName SHAssetManager::GetNameFromPath(AssetPath filepath) noexcept
{ {
std::string name{ filepath.filename().string() }; for (auto const& dir : std::filesystem::recursive_directory_iterator{ASSET_ROOT})
name = name.substr(0, name.find_last_of('.')); {
if (dir.is_regular_file())
//if (name[0] <= 122 && name[0] >= 97) {
//{ if (dir.path().extension().string() == META_EXTENSION.data())
// name[0] -= 32; {
//} assetCollection.push_back(SHAssetMetaHandler::RetrieveMetaData(dir.path()));
}
//for (size_t i{ 1 }; i < name.length(); ++i) }
//{ }
// // Replace all underscores with spaces
// if (name[i] == '_')
// {
// name[i] = ' ';
// continue;
// }
// if (name[i + 1] <= 'Z' && name[i + 1] >= 'A'
// && name[i] <= 'z' && name[i] >= 'a')
// {
// name.insert(i + 1, 1, ' ');
// continue;
// }
// if (name[i - 1] == ' ' && name[i] <= 'z' && name[i] >= 'a')
// {
// name[i] -= 32;
// }
//}
return name;
} }
} }

View File

@ -11,9 +11,10 @@
#pragma once #pragma once
#include "tinyddsloader.h" #include "tinyddsloader.h"
#include "SHAsset.h" #include "SHAsset.h"
#include "Asset Types/SHAssetData.h"
#include "Libraries/SHAssetLoader.h"
#include <memory>
#include "Asset Types/SHMeshAsset.h"
#include "Asset Types/SHTextureAsset.h"
#include "SH_API.h" #include "SH_API.h"
namespace SHADE namespace SHADE
@ -28,10 +29,13 @@ namespace SHADE
static AssetPath GenerateLocalPath(AssetPath path) noexcept; static AssetPath GenerateLocalPath(AssetPath path) noexcept;
static AssetPath GenerateNewPath(AssetName name, AssetType type);
/**************************************************************************** /****************************************************************************
* \brief Deallocate all memory used by resource data * \brief Deallocate all memory used by resource data
****************************************************************************/ ****************************************************************************/
static void Unload() noexcept; static void Unload() noexcept;
static void Unload(AssetID assetId) noexcept;
/**************************************************************************** /****************************************************************************
* \brief Load all resources that are in the folder * \brief Load all resources that are in the folder
@ -54,6 +58,7 @@ namespace SHADE
* \return resource id generated for new asset * \return resource id generated for new asset
****************************************************************************/ ****************************************************************************/
static AssetID CreateNewAsset(AssetType, AssetName) noexcept; static AssetID CreateNewAsset(AssetType, AssetName) noexcept;
static AssetID CreateAsset(AssetName name, AssetType type) noexcept;
/**************************************************************************** /****************************************************************************
* \brief Import new resource from outside editor window. * \brief Import new resource from outside editor window.
@ -70,64 +75,33 @@ namespace SHADE
static void RefreshAllAssets() noexcept; static void RefreshAllAssets() noexcept;
// -------------------------------------------------------------------------/ // -------------------------------------------------------------------------/
//TODO: TEMPORARY FOR TESTING GLTF & DDS template<typename T>
static void LoadDataTemp(std::string path) noexcept; static std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const* const> GetData(AssetID id) noexcept;
static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
static std::vector<SHTextureAsset> GetAllTextures() noexcept;
private: private:
/**************************************************************************** /****************************************************************************
* \brief Load resource data into memory * \brief Load resource data into memory
****************************************************************************/ ****************************************************************************/
static void LoadAllData() noexcept; static void LoadAllData() noexcept;
static void LoadData(AssetID id) noexcept; static SHAssetData* LoadData(SHAsset const& asset) noexcept;
/**************************************************************************** inline static void BuildAssetCollection() noexcept;
* \brief Retrieve all resource files and meta files from filesystem
****************************************************************************/
static void RetrieveAssets() noexcept;
static AssetID RetrieveAsset(char const* path) noexcept;
/****************************************************************************
* \param Full path of file
* \brief Extracts file name from path. Formats file name into readable
* with spaces and capitalises first letter of every word
****************************************************************************/
static AssetName GetNameFromPath(AssetPath) noexcept;
/****************************************************************************
* \param Path for meta data file
* \param Path for resource file
* \brief Links meta data to resource in registries. Meta data should
* already exist
****************************************************************************/
static void RegisterAsset(AssetPath const&, AssetPath const&) noexcept;
/****************************************************************************
* \param Path for resource file
* \brief Creates new meta data for new resource.
****************************************************************************/
static SHAsset RegisterAssetNew(AssetPath const&) noexcept;
static bool IsRecognised(char const*) noexcept; static bool IsRecognised(char const*) noexcept;
static SHAsset CreateAssetFromPath(AssetPath path) noexcept;
// Specialised load calls static void InitLoaders() noexcept;
static void LoadGLTF(SHAsset asset) noexcept;
static void LoadDDS(SHAsset asset) noexcept;
static FMOD::System* audioSystem; static FMOD::System* audioSystem;
static std::unordered_map<AssetID,SHSound>* audioSoundList; static std::unordered_map<AssetID,SHSound>* audioSoundList;
static std::vector<SHAssetLoader*> loaders;
// For all resources // For all resources
static std::vector<SHAsset> assetCollection; static std::vector<SHAsset> assetCollection;
static std::unordered_map<AssetID, SHAsset> assetRegistry; static std::unordered_map<AssetID, SHAssetData * const> assetData;
static std::unordered_map<AssetID, SHMeshAsset> meshCollection;
static std::unordered_map<AssetID, SHTextureAsset> textureCollection;
}; };
} }
#include "SHAssetManager.hpp"

View File

@ -0,0 +1,26 @@
#include "SHAssetManager.h"
namespace SHADE
{
template<typename T>
std::enable_if_t<std::is_base_of_v<SHAssetData, T>, T const* const> SHAssetManager::GetData(AssetID id) noexcept
{
if (!assetData.contains(id))
{
for (auto const& asset : assetCollection)
{
if (asset.id == id)
{
assetData.emplace(id, LoadData(asset));
return dynamic_cast<T const* const>(assetData[id]);
}
}
SHLOG_ERROR("Asset ID provided does not exist: {}", id);
return nullptr;
}
return dynamic_cast<T const* const>(assetData[id]);
}
}

View File

@ -37,7 +37,7 @@ namespace SHADE
{ {
for (int i{0}; i < EXTENSIONS->size(); ++i) for (int i{0}; i < EXTENSIONS->size(); ++i)
{ {
if (ext == EXTENSIONS[i]) if (strcmp(ext.c_str(), EXTENSIONS[i].data()) == 0)
{ {
return static_cast<AssetType>(i); return static_cast<AssetType>(i);
} }
@ -53,7 +53,7 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
AssetExtension SHAssetMetaHandler::GetExtensionFromType(AssetType type) noexcept AssetExtension SHAssetMetaHandler::GetExtensionFromType(AssetType type) noexcept
{ {
return EXTENSIONS[static_cast<size_t>(type)]; return AssetExtension(EXTENSIONS[static_cast<size_t>(type)]);
} }
/**************************************************************************** /****************************************************************************
@ -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,7 @@ 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
switch(meta.type)
{
case AssetType::MESH:
break;
default:
break;
}
metaFile.close(); metaFile.close();
} }

View File

@ -0,0 +1,189 @@
#include "SHpch.h"
#include "SHCameraComponent.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "SHCameraSystem.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Math/Transform/SHTransformComponent.h"
namespace SHADE
{
SHCameraComponent::SHCameraComponent()
:yaw(0.0f), pitch(0.0f), roll(0.0f)
, width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f)
, perspProj(true), dirtyView(true), dirtyProj(true)
, viewMatrix(), projMatrix()
, position()
{
ComponentFamily::GetID<SHCameraComponent>();
}
SHCameraComponent::~SHCameraComponent()
{
}
void SHCameraComponent::SetYaw(float yaw) noexcept
{
this->yaw = yaw;
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
SHVec3 rotation = transform->GetWorldRotation();
transform->SetWorldRotation(SHVec3{rotation.x,yaw, rotation.z});
}
dirtyView = true;
}
void SHCameraComponent::SetPitch(float pitch) noexcept
{
this->pitch = pitch;
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
SHVec3 rotation = transform->GetWorldRotation();
transform->SetWorldRotation(SHVec3{ pitch,rotation.y, rotation.z });
}
dirtyView = true;
}
void SHCameraComponent::SetRoll(float roll) noexcept
{
this->roll = roll;
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
SHVec3 rotation = transform->GetWorldRotation();
transform->SetWorldRotation(SHVec3{ rotation.x,rotation.y, roll});
}
dirtyView = true;
}
void SHCameraComponent::SetPositionX(float x) noexcept
{
position.x = x;
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
SHVec3 position = transform->GetWorldPosition();
transform->SetWorldRotation(SHVec3{ x,position.y, position.z});
}
dirtyView = true;
}
void SHCameraComponent::SetPositionY(float y) noexcept
{
position.y = y;
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
SHVec3 position = transform->GetWorldPosition();
transform->SetWorldRotation(SHVec3{ position.x,y, position.z });
}
dirtyView = true;
}
void SHCameraComponent::SetPositionZ(float z) noexcept
{
position.z = z;
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
SHVec3 position = transform->GetWorldPosition();
transform->SetWorldRotation(SHVec3{ position.x,position.y, z });
}
dirtyView = true;
}
void SHCameraComponent::SetPosition(float x,float y, float z) noexcept
{
position.x = x;
position.y = y;
position.z = z;
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
SHVec3 position = transform->GetWorldPosition();
transform->SetWorldRotation(SHVec3{ x,y, z });
}
dirtyView = true;
}
void SHCameraComponent::SetPosition(SHVec3& pos) noexcept
{
this->position = pos;
if (SHComponentManager::HasComponent<SHTransformComponent>(GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
SHVec3 position = transform->GetWorldPosition();
transform->SetWorldRotation(pos);
}
dirtyView = true;
}
void SHCameraComponent::SetWidth(float width) noexcept
{
this->width = width;
dirtyProj = true;
}
void SHCameraComponent::SetHeight(float height) noexcept
{
this->height = height;
dirtyProj = true;
}
void SHCameraComponent::SetNear(float znear) noexcept
{
this->zNear = znear;
dirtyProj = true;
}
void SHCameraComponent::SetFar(float zFar) noexcept
{
this->zFar = zFar;
dirtyProj = true;
}
void SHCameraComponent::SetFOV(float fov) noexcept
{
this->fov = fov;
dirtyProj = true;
}
float SHCameraComponent::GetYaw() const noexcept
{
return yaw;
}
float SHCameraComponent::GetPitch() const noexcept
{
return pitch;
}
float SHCameraComponent::GetRoll() const noexcept
{
return roll;
}
float SHCameraComponent::GetAspectRatio() const noexcept
{
return width/height;
}
float SHCameraComponent::GetFOV() const noexcept
{
return fov;
}
const SHMatrix& SHCameraComponent::GetViewMatrix() const noexcept
{
return viewMatrix;
}
const SHMatrix& SHCameraComponent::GetProjMatrix() const noexcept
{
return projMatrix;
}
void SHCameraComponent::SetMainCamera(size_t directorCameraIndex) noexcept
{
auto system = SHSystemManager::GetSystem<SHCameraSystem>();
system->GetDirector(directorCameraIndex)->SetMainCamera(*this);
}
}

View File

@ -0,0 +1,87 @@
#pragma once
#include "ECS_Base/Components/SHComponent.h"
#include "Math/Vector/SHVec3.h"
#include "Math/SHMatrix.h"
#include "SH_API.h"
namespace SHADE
{
class SH_API SHCameraComponent final : public SHComponent
{
private:
float yaw;
float pitch;
float roll;
float width;
float height;
float zNear;
float zFar;
float fov;
bool dirtyView;
bool dirtyProj;
SHMatrix viewMatrix;
SHMatrix projMatrix;
SHVec3 position;
bool perspProj;
public:
friend class SHCameraSystem;
SHCameraComponent();
~SHCameraComponent();
//Getters and setters.
void SetYaw(float yaw) noexcept;
void SetPitch(float pitch) noexcept;
void SetRoll(float roll) noexcept;
void SetPositionX(float x) noexcept;
void SetPositionY(float y) noexcept;
void SetPositionZ(float z) noexcept;
void SetPosition(float x, float y, float z) noexcept;
void SetPosition(SHVec3& pos) noexcept;
void SetWidth(float width) noexcept;
void SetHeight(float height) noexcept;
void SetNear(float znear) noexcept;
void SetFar(float zfar) noexcept;
void SetFOV(float fov) noexcept;
float GetYaw() const noexcept;
float GetPitch() const noexcept;
float GetRoll() const noexcept;
float GetAspectRatio() const noexcept;
float GetFOV() const noexcept;
const SHMatrix& GetViewMatrix() const noexcept;
const SHMatrix& GetProjMatrix() const noexcept;
void SetMainCamera(size_t cameraDirectorIndex = 0) noexcept;
float movementSpeed;
SHVec3 turnSpeed;
protected:
};
}

View File

@ -0,0 +1,65 @@
#include "SHpch.h"
#include "SHCameraDirector.h"
#include "SHCameraComponent.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/SHECSMacros.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Tools/SHLog.h"
namespace SHADE
{
SHCameraDirector::SHCameraDirector()
:mainCameraEID(MAX_EID), transitionCameraEID(MAX_EID)
{
}
SHMatrix SHCameraDirector::GetViewMatrix() const noexcept
{
return viewMatrix;
}
SHMatrix SHCameraDirector::GetProjMatrix() const noexcept
{
return projMatrix;
}
SHMatrix SHCameraDirector::GetVPMatrix() const noexcept
{
return projMatrix * viewMatrix;
}
void SHCameraDirector::UpdateMatrix() noexcept
{
if (mainCameraEID == MAX_EID)
{
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
if (dense.size() == 0)
{
return;
}
mainCameraEID = dense[0].GetEID();
}
SHCameraComponent* camComponent = SHComponentManager::GetComponent_s<SHCameraComponent>(mainCameraEID);
if (!camComponent)
{
SHLOG_WARNING("Camera Director warning: Entity does not have a camera");
}
else
{
viewMatrix = camComponent->GetViewMatrix();
projMatrix = camComponent->GetProjMatrix();
}
}
void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept
{
if (SHEntityManager::IsValidEID(camera.GetEID()) == false)
{
SHLOG_WARNING("Camera Director Warning: Attempting to set an invalid entity as main camera.")
return;
}
mainCameraEID = camera.GetEID();
}
}

View File

@ -0,0 +1,43 @@
#pragma once
#include "SH_API.h"
#include "ECS_Base/Entity/SHEntity.h"
#include "Math/SHMatrix.h"
#include "Resource/SHHandle.h"
namespace SHADE
{
class SHCameraComponent;
class SH_API SHCameraDirector
{
public:
SHCameraDirector();
~SHCameraDirector() = default;
EntityID mainCameraEID;
EntityID transitionCameraEID;
SHMatrix GetViewMatrix() const noexcept;
SHMatrix GetProjMatrix() const noexcept;
SHMatrix GetVPMatrix() const noexcept;
void UpdateMatrix() noexcept;
void SetMainCamera(SHCameraComponent& cam) noexcept;
private:
protected:
SHMatrix viewMatrix;
SHMatrix projMatrix;
};
typedef Handle<SHCameraDirector> DirectorHandle;
}

View File

@ -0,0 +1,291 @@
#include "SHpch.h"
#include "SHCameraSystem.h"
#include "Math/SHMathHelpers.h"
#include "Input/SHInputManager.h"
#include "Math/Vector/SHVec2.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Transform/SHTransformComponent.h"
namespace SHADE
{
void SHCameraSystem::UpdateEditorCamera(double dt) noexcept
{
auto& camera = editorCamera;
SHVec3 view, right, UP;
GetCameraAxis(camera, view, right, UP);
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A))
{
camera.position -= right * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::D))
{
camera.position += right * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::W))
{
camera.position += view * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::S))
{
camera.position -= view * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::Q))
{
camera.position += UP * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::E))
{
camera.position -= UP * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::RMB))
{
double mouseX, mouseY;
SHInputManager::GetMouseVelocity(&mouseX, &mouseY);
//std::cout << camera.yaw << std::endl;
camera.pitch -= mouseY * dt * camera.turnSpeed.x;
camera.yaw -= mouseX * dt * camera.turnSpeed.y;
camera.dirtyView = true;
}
UpdateCameraComponent(editorCamera);
}
void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept
{
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
auto& camera = system->editorCamera;
SHVec3 view, right, UP;
system->GetCameraAxis(camera, view, right, UP);
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A))
{
//std::cout << "Camera movement: "<<right.x<<", " << right.y << std::endl;
camera.position -= right * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::D))
{
camera.position += right * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::W))
{
camera.position += view * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::S))
{
camera.position -= view * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::Q))
{
camera.position += UP * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::E))
{
camera.position -= UP * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::RMB))
{
double mouseX, mouseY;
SHInputManager::GetMouseVelocity(&mouseX,&mouseY);
//std::cout << camera.yaw << std::endl;
camera.pitch -= mouseY * dt * camera.turnSpeed.x;
camera.yaw -= mouseX * dt * camera.turnSpeed.y;
camera.dirtyView = true;
}
//std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl;
system->UpdateCameraComponent(system->editorCamera);
}
void SHCameraSystem::Init(void)
{
editorCamera.SetPosition(0.0f, 0.0f, 0.0f);
editorCamera.SetPitch(0.0f);
editorCamera.SetYaw(0.0f);
editorCamera.SetRoll(0.0f);
editorCamera.movementSpeed = 2.0f;
}
void SHCameraSystem::Exit(void)
{
}
SHCameraComponent* SHCameraSystem::GetEditorCamera(void) noexcept
{
return &editorCamera;
}
void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept
{
if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true && &camera != &editorCamera)
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(camera.GetEID());
SHVec3 rotation = transform->GetWorldRotation();
camera.pitch = SHMath::RadiansToDegrees(rotation.x);
camera.yaw = SHMath::RadiansToDegrees(rotation.y);
camera.roll = SHMath::RadiansToDegrees(rotation.z);
camera.position = transform->GetWorldPosition();
camera.dirtyView = true;
}
if (camera.dirtyView)
{
SHVec3 view, right, UP;
//ClampCameraRotation(camera);
GetCameraAxis(camera, view, right, UP);
camera.viewMatrix = SHMatrix::Identity;
camera.viewMatrix(0, 0) = right[0];
camera.viewMatrix(0, 1) = right[1];
camera.viewMatrix(0, 2) = right[2];
camera.viewMatrix(1, 0) = UP[0];
camera.viewMatrix(1, 1) = UP[1];
camera.viewMatrix(1, 2) = UP[2];
camera.viewMatrix(2, 0) = view[0];
camera.viewMatrix(2, 1) = view[1];
camera.viewMatrix(2, 2) = view[2];
camera.viewMatrix(0, 3) = -right.Dot(camera.position);
camera.viewMatrix(1, 3) = -UP.Dot(camera.position);
camera.viewMatrix(2, 3) = -view.Dot(camera.position);
camera.dirtyView = false;
}
if (camera.dirtyProj == true)
{
if (camera.perspProj == true)
{
const float ASPECT_RATIO = (camera.GetAspectRatio());
const float TAN_HALF_FOV = tan(SHMath::DegreesToRadians(camera.fov) * 0.5f);
camera.projMatrix = SHMatrix::Identity;
camera.projMatrix(0, 0) = 1.0f / (ASPECT_RATIO * TAN_HALF_FOV);
camera.projMatrix(1, 1) = 1.0f / TAN_HALF_FOV;
camera.projMatrix(2, 2) = camera.zFar / (camera.zFar - camera.zNear);
camera.projMatrix(3, 3) = 0.0f;
camera.projMatrix(3, 2) = 1.0f;
camera.projMatrix(2, 3) = -(camera.zFar * camera.zNear) / (camera.zFar - camera.zNear);
camera.dirtyProj = false;
}
else
{
//const float R = camera.width * 0.5f;
//const float L = -R;
//const float T = camera.height * 0.5f;
//const float B = -T;
//camera.projMatrix = SHMatrix::Identity;
//camera.projMatrix(0, 0) = 2.0f / (R - L);
//camera.projMatrix(1, 1) = 2.0f / (B - T);
//camera.projMatrix(2, 2) = 1.0f / (camera.zFar - camera.zNear);
//camera.projMatrix(3, 0) = -(R + L) / (R - L);
//camera.projMatrix(3, 1) = -(B + T) / (B - T);
//camera.projMatrix(3, 2) = -camera.zNear / (camera.zFar - camera.zNear);
camera.dirtyProj = false;
}
}
}
void SHCameraSystem::GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& upVec) const noexcept
{
SHVec3 target{ 0.0f,0.0f,-1.0f };
SHVec3 up = { 0.0f,1.0f,0.0f };
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
target =SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
target += camera.position;
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));
//target = SHVec3::Normalise(target);
SHVec3::RotateZ(up, camera.roll);
up = SHVec3::Normalise(up);
forward = target - camera.position; forward = SHVec3::Normalise(forward);
right = SHVec3::Cross(forward, up); right = SHVec3::Normalise(right);
upVec = SHVec3::Cross(forward, right);
}
void SHCameraSystem::CameraSystemUpdate::Execute(double dt) noexcept
{
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
for (auto& cam : dense)
{
system->UpdateCameraComponent(cam);
}
for (auto& handle : system->directorHandleList)
{
handle->UpdateMatrix();
}
}
DirectorHandle SHCameraSystem::CreateDirector() noexcept
{
auto handle = directorLibrary.Create();
directorHandleList.emplace_back(handle);
return handle;
}
DirectorHandle SHCameraSystem::GetDirector(size_t index) noexcept
{
if (index < directorHandleList.size())
{
return directorHandleList[index];
}
else
{
return CreateDirector();
}
}
void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept
{
if (camera.pitch > 85)
camera.SetPitch(85);
if (camera.pitch < -85)
camera.SetPitch(-85);
if (camera.roll > 85)
camera.SetRoll(85);
if (camera.roll < -85)
camera.SetRoll(-85);
}
}

View File

@ -0,0 +1,64 @@
#pragma once
#include "ECS_Base/System/SHSystem.h"
#include "SHCameraComponent.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/SHResourceLibrary.h"
#include "SHCameraDirector.h"
#include "SH_API.h"
namespace SHADE
{
class SH_API SHCameraSystem final : public SHSystem
{
private:
//A camera component that represents editor camera.
//This is not tied to any entity. Hence this EID should not be used.
SHCameraComponent editorCamera;
SHResourceLibrary<SHCameraDirector> directorLibrary;
std::vector<DirectorHandle> directorHandleList;
public:
SHCameraSystem(void) = default;
virtual ~SHCameraSystem(void) = default;
void Init (void);
void Exit (void);
class SH_API EditorCameraUpdate final : public SHSystemRoutine
{
public:
EditorCameraUpdate() : SHSystemRoutine("Editor Camera Update", true) { };
virtual void Execute(double dt) noexcept override final;
};
friend class EditorCameraUpdate;
class SH_API CameraSystemUpdate final: public SHSystemRoutine
{
public:
CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {};
virtual void Execute(double dt)noexcept override final;
};
friend class CameraSystemUpdate;
SHCameraComponent* GetEditorCamera (void) noexcept;
void GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& up) const noexcept;
DirectorHandle CreateDirector() noexcept;
DirectorHandle GetDirector(size_t index) noexcept;
void ClampCameraRotation(SHCameraComponent& camera) noexcept;
void UpdateEditorCamera(double dt) noexcept;
protected:
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
};
}

View File

@ -48,6 +48,9 @@ namespace SHADE
{ {
} }
public: public:
//Whether or not this component is active. //Whether or not this component is active.
//Systems using this component should are responsible for checking the active state of the component before running their functionality. //Systems using this component should are responsible for checking the active state of the component before running their functionality.
@ -59,7 +62,7 @@ namespace SHADE
* \return uint32_t * \return uint32_t
* The entityID that this component belongs to. * The entityID that this component belongs to.
***************************************************************************/ ***************************************************************************/
uint32_t GetEID()const uint32_t GetEID()const noexcept
{ {
return this->entityID; return this->entityID;
} }

View File

@ -24,6 +24,7 @@ namespace SHADE
class SHCommand : SHBaseCommand class SHCommand : SHBaseCommand
{ {
public: public:
using SHCommandPtr = std::unique_ptr<T>;
typedef std::function<void(T const&)> SetterFunction; typedef std::function<void(T const&)> SetterFunction;
SHCommand(T const& oldVal, T const& value, SetterFunction setFnc) SHCommand(T const& oldVal, T const& value, SetterFunction setFnc)

View File

@ -13,7 +13,7 @@ namespace SHADE
SHCommandManager::CommandStack SHCommandManager::undoStack{}; SHCommandManager::CommandStack SHCommandManager::undoStack{};
SHCommandManager::CommandStack SHCommandManager::redoStack{}; SHCommandManager::CommandStack SHCommandManager::redoStack{};
void SHCommandManager::PerformCommand(CommandPtr commandPtr, bool const& overrideValue) void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
{ {
redoStack = CommandStack(); redoStack = CommandStack();
commandPtr->Execute(); commandPtr->Execute();
@ -27,9 +27,9 @@ namespace SHADE
} }
} }
void SHCommandManager::RegisterCommand(CommandPtr commandPtr) void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
{ {
undoStack.push(commandPtr); undoStack.push(commandPtr);
} }
void SHCommandManager::UndoCommand() void SHCommandManager::UndoCommand()
@ -59,4 +59,14 @@ namespace SHADE
{ {
return redoStack.size(); return redoStack.size();
} }
void SHCommandManager::PopLatestCommandFromRedoStack()
{
redoStack.pop();
}
void SHCommandManager::PopLatestCommandFromUndoStack()
{
undoStack.pop();
}
}//namespace SHADE }//namespace SHADE

View File

@ -19,16 +19,21 @@ namespace SHADE
//#==============================================================# //#==============================================================#
//|| Type Aliases || //|| Type Aliases ||
//#==============================================================# //#==============================================================#
using CommandPtr = std::shared_ptr<SHBaseCommand>; using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
using CommandStack = std::stack<CommandPtr>; template<typename T>
using SHCommandPtr = std::shared_ptr<SHCommand<T>>;
using CommandStack = std::stack<BaseCommandPtr>;
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false); static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false);
static void RegisterCommand(CommandPtr commandPtr); static void RegisterCommand(BaseCommandPtr commandPtr);
static void UndoCommand(); static void UndoCommand();
static void RedoCommand(); static void RedoCommand();
static std::size_t GetUndoStackSize(); static std::size_t GetUndoStackSize();
static std::size_t GetRedoStackSize(); static std::size_t GetRedoStackSize();
static void PopLatestCommandFromRedoStack();
static void PopLatestCommandFromUndoStack();
private: private:
static CommandStack undoStack; static CommandStack undoStack;
static CommandStack redoStack; static CommandStack redoStack;

View File

@ -21,6 +21,9 @@
//#==============================================================# //#==============================================================#
#include <imgui.h> #include <imgui.h>
#include "Serialization/SHSerialization.h"
#include "Tools/SHClipboardUtilities.h"
namespace SHADE namespace SHADE
{ {
@ -50,6 +53,7 @@ namespace SHADE
if(const auto root = sceneGraph.GetRoot()) if(const auto root = sceneGraph.GetRoot())
{ {
auto const& children = root->GetChildren(); auto const& children = root->GetChildren();
for (const auto child : children) for (const auto child : children)
{ {
RecursivelyDrawEntityNode(child); RecursivelyDrawEntityNode(child);
@ -66,8 +70,8 @@ namespace SHADE
editor->selectedEntities.clear(); editor->selectedEntities.clear();
} }
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal); ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
ImGui::End();
} }
ImGui::End();
} }
void SHHierarchyPanel::Exit() void SHHierarchyPanel::Exit()
@ -75,6 +79,13 @@ namespace SHADE
SHEditorWindow::Exit(); SHEditorWindow::Exit();
} }
void SHHierarchyPanel::SetScrollTo(EntityID eid)
{
if(eid == MAX_EID)
return;
scrollTo = eid;
}
//#==============================================================# //#==============================================================#
//|| Private Member Functions || //|| Private Member Functions ||
//#==============================================================# //#==============================================================#
@ -82,9 +93,22 @@ namespace SHADE
{ {
if (ImGui::BeginMenuBar()) if (ImGui::BeginMenuBar())
{ {
if (ImGui::SmallButton(ICON_MD_ADD))
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x - 35.0f);
if(ImGui::SmallButton(ICON_MD_DESELECT))
{ {
SHEntityManager::CreateEntity(); auto editor = SHSystemManager::GetSystem<SHEditor>();
editor->selectedEntities.clear();
}
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::Text("Clear Selections");
ImGui::EndTooltip();
}
if (ImGui::SmallButton(ICON_MD_ADD_CIRCLE))
{
SHCommandManager::PerformCommand(std::make_shared<SHCreateEntityCommand>());
} }
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
{ {
@ -103,6 +127,13 @@ namespace SHADE
//Get node data (Children, eid, selected) //Get node data (Children, eid, selected)
auto& children = currentNode->GetChildren(); auto& children = currentNode->GetChildren();
EntityID eid = currentNode->GetEntityID(); EntityID eid = currentNode->GetEntityID();
if(scrollTo != MAX_EID && eid == scrollTo)
{
ImGui::SetScrollHereY();
scrollTo = MAX_EID;
}
auto editor = SHSystemManager::GetSystem<SHEditor>(); auto editor = SHSystemManager::GetSystem<SHEditor>();
const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end()); const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
@ -117,23 +148,32 @@ namespace SHADE
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID()); auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
//Draw Node //Draw Node
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(entity), nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str()); bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(entity), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str());
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
//Check For Begin Drag //Check For Begin Drag
if (SHDragDrop::BeginSource()) if (SHDragDrop::BeginSource())
{ {
ImGui::Text("Moving EID: %zu", eid); std::string moveLabel = "Moving EID: ";
SHDragDrop::SetPayload<EntityID>(DRAG_EID, &eid); if(!isSelected)
editor->selectedEntities.push_back(eid);
for(int i = 0; i < static_cast<int>(editor->selectedEntities.size()); ++i)
{
moveLabel.append(std::to_string(editor->selectedEntities[i]));
if(i + 1 < static_cast<int>(editor->selectedEntities.size()))
{
moveLabel.append(", ");
}
}
ImGui::Text(moveLabel.c_str());
SHDragDrop::SetPayload<std::vector<EntityID>>(DRAG_EID, &editor->selectedEntities);
SHDragDrop::EndSource(); SHDragDrop::EndSource();
} }
else if (SHDragDrop::BeginTarget()) //If Received DragDrop else if (SHDragDrop::BeginTarget()) //If Received DragDrop
{ {
if (const EntityID* eidPayload = SHDragDrop::AcceptPayload<EntityID>(DRAG_EID)) //If payload is valid if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(DRAG_EID)) //If payload is valid
{ {
EntityID const dropEID = *eidPayload; ParentSelectedEntities(eid);
if(!sceneGraph.GetChild(dropEID, eid))
sceneGraph.SetParent(dropEID, eid); //Set dropEID parent to eid (belonging to current Node)
SHDragDrop::EndTarget(); SHDragDrop::EndTarget();
} }
} }
@ -146,6 +186,18 @@ namespace SHADE
editor->selectedEntities.clear(); editor->selectedEntities.clear();
editor->selectedEntities.push_back(eid); editor->selectedEntities.push_back(eid);
} }
if(ImGui::Selectable("Copy"))
{
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities));
}
if(ImGui::Selectable("Paste"))
{
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard()));
}
if(ImGui::Selectable("Paste as Child"))
{
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), eid));
}
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);
@ -153,11 +205,11 @@ namespace SHADE
if((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data())) if((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
{ {
sceneGraph.SetParent(currentNode->GetEntityID(), nullptr); ParentSelectedEntities(MAX_EID);
} }
ImGui::EndPopup(); ImGui::EndPopup();
} }
//Handle node selection //Handle node selection
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
{ {
@ -165,7 +217,15 @@ namespace SHADE
{ {
if (!isSelected) if (!isSelected)
{ {
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) if(ImGui::IsKeyDown(ImGuiKey_LeftShift))
{
if(editor->selectedEntities.size() >= 1)
{
SelectRangeOfEntities(editor->selectedEntities[0], eid);
}
else editor->selectedEntities.clear();
}
else if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
editor->selectedEntities.clear(); editor->selectedEntities.clear();
editor->selectedEntities.push_back(eid); editor->selectedEntities.push_back(eid);
}//if not selected }//if not selected
@ -212,4 +272,90 @@ namespace SHADE
{ {
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID); SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
} }
void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID) const noexcept
{
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
auto const editor = SHSystemManager::GetSystem<SHEditor>();
SHEntityParentCommand::EntityParentData entityParentData;
std::vector<EntityID> parentedEIDS;
for(auto const& eid : editor->selectedEntities)
{
if(sceneGraph.GetChild(eid, parentEID) == nullptr)
{
parentedEIDS.push_back(eid);
if(auto parent = sceneGraph.GetParent(eid))
entityParentData[eid].oldParentEID = parent->GetEntityID();
entityParentData[eid].newParentEID = parentEID;
}
}
SHCommandManager::PerformCommand(std::make_shared<SHEntityParentCommand>(parentedEIDS, entityParentData));
}
void SHHierarchyPanel::SelectRangeOfEntities(EntityID beginEID, EntityID endEID)
{
bool startSelecting = false; bool endSelecting = false;
auto const editor = SHSystemManager::GetSystem<SHEditor>();
editor->selectedEntities.clear();
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
{
auto eid = nodePtr->GetEntityID();
if(!startSelecting)
{
if(eid == beginEID || eid == endEID)
{
startSelecting = true;
editor->selectedEntities.push_back(eid);
}
}
else
{
if(!endSelecting)
{
editor->selectedEntities.push_back(eid);
if(eid == endEID || eid == beginEID)
{
endSelecting = true;
}
}
}
});
}
void SHCreateEntityCommand::Execute()
{
EntityID newEID = SHEntityManager::CreateEntity(eid);
if(eid == MAX_EID)
eid = newEID;
}
void SHCreateEntityCommand::Undo()
{
SHEntityManager::DestroyEntity(eid);
}
void SHEntityParentCommand::Execute()
{
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
for(auto const& eid : entities)
{
if(entityParentData[eid].newParentEID == MAX_EID)
sceneGraph.SetParent(eid, nullptr);
else
sceneGraph.SetParent(eid, entityParentData[eid].newParentEID);
}
}
void SHEntityParentCommand::Undo()
{
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
for(auto const& eid : entities)
{
if(entityParentData[eid].oldParentEID == MAX_EID)
sceneGraph.SetParent(eid, nullptr);
else
sceneGraph.SetParent(eid, entityParentData[eid].oldParentEID);
}
}
}//namespace SHADE }//namespace SHADE

View File

@ -10,7 +10,7 @@
#include "imgui_internal.h" #include "imgui_internal.h"
#include "ECS_Base/SHECSMacros.h" #include "ECS_Base/SHECSMacros.h"
#include "Editor/EditorWindow/SHEditorWindow.h" #include "Editor/EditorWindow/SHEditorWindow.h"
#include "Editor/Command/SHCommand.hpp"
namespace SHADE namespace SHADE
{ {
class SHSceneNode; class SHSceneNode;
@ -23,11 +23,45 @@ namespace SHADE
void Init() override; void Init() override;
void Update() override; void Update() override;
void Exit() override; void Exit() override;
void SetScrollTo(EntityID eid);
private: private:
void DrawMenuBar() const noexcept; void DrawMenuBar() const noexcept;
ImRect RecursivelyDrawEntityNode(SHSceneNode*); ImRect RecursivelyDrawEntityNode(SHSceneNode*);
void CreateChildEntity(EntityID parentEID) const noexcept; void CreateChildEntity(EntityID parentEID) const noexcept;
void ParentSelectedEntities(EntityID parentEID) const noexcept;
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
std::string filter; std::string filter;
bool isAnyNodeSelected = false; bool isAnyNodeSelected = false;
EntityID scrollTo = MAX_EID;
};//class SHHierarchyPanel };//class SHHierarchyPanel
//Might move to a different file
class SHCreateEntityCommand final : public SHBaseCommand
{
public:
void Execute() override;
void Undo() override;
private:
EntityID eid = MAX_EID;
};
class SHEntityParentCommand final : public SHBaseCommand
{
public:
struct Data
{
EntityID oldParentEID = MAX_EID;
EntityID newParentEID = MAX_EID;
};
using EntityParentData = std::unordered_map<EntityID, Data>;
SHEntityParentCommand(std::vector<EntityID> entityIDs, EntityParentData inEntityParentData):entities(entityIDs),entityParentData(inEntityParentData){}
void Execute() override;
void Undo() override;
private:
std::vector<EntityID> entities;
std::unordered_map<EntityID, Data> entityParentData;
};
}//namespace SHADE }//namespace SHADE

View File

@ -10,6 +10,7 @@
//|| SHADE Includes || //|| SHADE Includes ||
//#==============================================================# //#==============================================================#
#include "Editor/IconsMaterialDesign.h" #include "Editor/IconsMaterialDesign.h"
#include "Editor/IconsFontAwesome6.h"
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "Editor/SHEditorWidgets.hpp" #include "Editor/SHEditorWidgets.hpp"
#include "Physics/Components/SHColliderComponent.h" #include "Physics/Components/SHColliderComponent.h"
@ -207,14 +208,16 @@ namespace SHADE
auto& colliders = component->GetColliders(); auto& colliders = component->GetColliders();
int const size = static_cast<int>(colliders.size()); int const size = static_cast<int>(colliders.size());
ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true); ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true);
std::optional<int> colliderToDelete{std::nullopt};
for (int i{}; i < size; ++i) for (int i{}; i < size; ++i)
{ {
ImGui::PushID(i);
SHCollider& collider = component->GetCollider(i); SHCollider& collider = component->GetCollider(i);
auto cursorPos = ImGui::GetCursorPos(); auto cursorPos = ImGui::GetCursorPos();
if (collider.GetType() == SHCollider::Type::BOX) if (collider.GetType() == SHCollider::Type::BOX)
{ {
SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_MD_VIEW_IN_AR, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
auto box = reinterpret_cast<SHBoundingBox*>(collider.GetShape()); auto box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);}); SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);});
} }
@ -235,9 +238,14 @@ namespace SHADE
} }
if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data())) if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
{ {
component->RemoveCollider(i); colliderToDelete = i;
} }
SHEditorWidgets::EndPanel(); SHEditorWidgets::EndPanel();
ImGui::PopID();
}
if(colliderToDelete.has_value())
{
component->RemoveCollider(colliderToDelete.value());
} }
ImGui::EndChild(); ImGui::EndChild();

View File

@ -55,7 +55,11 @@ namespace SHADE
{ {
EntityID const& eid = editor->selectedEntities[0]; EntityID const& eid = editor->selectedEntities[0];
SHEntity* entity = SHEntityManager::GetEntityByID(eid); SHEntity* entity = SHEntityManager::GetEntityByID(eid);
if(!entity)
{
ImGui::End();
return;
}
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid); ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); }); SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
ImGui::SameLine(); ImGui::SameLine();
@ -99,8 +103,8 @@ namespace SHADE
} }
} }
ImGui::End();
} }
ImGui::End();
} }
void SHEditorInspector::Exit() void SHEditorInspector::Exit()

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 |
@ -36,6 +38,11 @@ namespace SHADE
void SHEditorMenuBar::Init() void SHEditorMenuBar::Init()
{ {
SHEditorWindow::Init(); SHEditorWindow::Init();
constexpr std::string_view path = "../../Assets/Editor/Layouts";
for(auto const& entry : std::filesystem::directory_iterator(path))
{
layoutPaths.push_back(entry.path());
}
} }
void SHEditorMenuBar::Update() void SHEditorMenuBar::Update()
@ -68,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"))
@ -87,20 +101,6 @@ namespace SHADE
ImGui::EndDisabled(); ImGui::EndDisabled();
ImGui::EndMenu(); ImGui::EndMenu();
} }
if(ImGui::BeginMenu("Theme"))
{
auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
auto values = styles.get_values();
for (auto style : values)
{
if(ImGui::Selectable(style.to_string().c_str()))
{
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
editor->SetStyle(style.convert<SHEditor::Style>());
}
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Scripts")) if (ImGui::BeginMenu("Scripts"))
{ {
if (ImGui::Selectable("Generate Visual Studio Project")) if (ImGui::Selectable("Generate Visual Studio Project"))
@ -120,18 +120,79 @@ namespace SHADE
} }
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Window"))
{
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
{
if (window.get() != this)
ImGui::Checkbox(window->windowName.data(), &window->isOpen);
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Theme"))
{
const auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
auto values = styles.get_values();
for (auto style : values)
{
if (ImGui::Selectable(style.to_string().c_str()))
{
if (auto editor = SHSystemManager::GetSystem<SHEditor>())
editor->SetStyle(style.convert<SHEditor::Style>());
}
}
ImGui::EndMenu();
}
if(ImGui::BeginMenu("Layout"))
{
for(auto const& entry : layoutPaths)
{
if(ImGui::Selectable(entry.stem().string().c_str()))
{
ImGui::LoadIniSettingsFromDisk(entry.string().c_str());
}
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar(); ImGui::EndMainMenuBar();
} }
const ImGuiID dockspace_id = ImGui::GetID("DockSpace"); const ImGuiID dockspaceId = ImGui::GetID("DockSpace");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspaceFlags); ImGui::DockSpace(dockspaceId, ImVec2(0.0f, 0.0f), dockspaceFlags);
ImGui::End(); ImGui::End();
} }
} }
void SHEditorMenuBar::DrawSecondaryBar() const noexcept void SHEditorMenuBar::DrawSecondaryBar() const noexcept
{ {
ImGuiViewport* viewport = ImGui::GetMainViewport();
if(ImGui::BeginViewportSideBar("##SecondaryMenuBar", viewport, ImGuiDir_Up, ImGui::GetFrameHeight(), ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_MenuBar))
{
ImGui::BeginMenuBar();
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.5f - 80.f);
const auto editor = SHSystemManager::GetSystem<SHEditor>();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
{
editor->editorState = SHEditor::State::PLAY;
}
ImGui::EndDisabled();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
if(ImGui::SmallButton(ICON_MD_PAUSE))
{
editor->editorState = SHEditor::State::PAUSE;
}
ImGui::EndDisabled();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
if(ImGui::SmallButton(ICON_MD_STOP))
{
editor->editorState = SHEditor::State::STOP;
}
ImGui::EndDisabled();
ImGui::EndMenuBar();
}
ImGui::End();
} }
void SHEditorMenuBar::DrawStatusBar() const noexcept void SHEditorMenuBar::DrawStatusBar() const noexcept
@ -142,8 +203,8 @@ namespace SHADE
if (ImGui::BeginViewportSideBar("MainStatusBar", ImGui::GetMainViewport(), ImGuiDir_Down, menuBarHeight, editorMenuBarFlags)) if (ImGui::BeginViewportSideBar("MainStatusBar", ImGui::GetMainViewport(), ImGuiDir_Down, menuBarHeight, editorMenuBarFlags))
{ {
ImGui::Text("Entity count: "); ImGui::Text("Entity count: ");
ImGui::End();
} }
ImGui::End();
ImGui::PopStyleVar(3); ImGui::PopStyleVar(3);
} }

View File

@ -18,5 +18,6 @@ namespace SHADE
void DrawSecondaryBar() const noexcept; void DrawSecondaryBar() const noexcept;
void DrawStatusBar() const noexcept; void DrawStatusBar() const noexcept;
float menuBarHeight = 20.0f; float menuBarHeight = 20.0f;
std::vector<std::filesystem::path> layoutPaths;
};//class SHEditorMenuBar };//class SHEditorMenuBar
}//namespace SHADE }//namespace SHADE

View File

@ -3,6 +3,7 @@
#include <imgui.h> #include <imgui.h>
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/Command/SHCommandManager.h"
#include "FRC/SHFramerateController.h" #include "FRC/SHFramerateController.h"
namespace SHADE namespace SHADE
@ -37,8 +38,13 @@ namespace SHADE
if(Begin()) if(Begin())
{ {
ImGui::PlotLines("DT", frames.data(), static_cast<int>(frames.size()), 0, nullptr, 0.0f, 16.0f); ImGui::PlotLines("DT", frames.data(), static_cast<int>(frames.size()), 0, nullptr, 0.0f, 16.0f);
ImGui::End();
} }
if(ImGui::CollapsingHeader("Command Manager"))
{
ImGui::Text("Undo: %zu", SHCommandManager::GetUndoStackSize());
ImGui::Text("Redo: %zu", SHCommandManager::GetRedoStackSize());
}
ImGui::End();
} }
void SHEditorProfiler::Exit() void SHEditorProfiler::Exit()

View File

@ -19,7 +19,7 @@ namespace SHADE
//|| Public Member Functions || //|| Public Member Functions ||
//#==============================================================# //#==============================================================#
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags) SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
: isOpen(true), windowName(name), windowFlags(inFlags), io(ImGui::GetIO()) : windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
{ {
} }
@ -40,7 +40,33 @@ namespace SHADE
//#==============================================================# //#==============================================================#
bool SHEditorWindow::Begin() bool SHEditorWindow::Begin()
{ {
return ImGui::Begin(windowName.data(), &isOpen, windowFlags); bool result = ImGui::Begin(windowName.data(), &isOpen, windowFlags);
auto wndSize = ImGui::GetWindowSize();
auto contentRegionAvail = ImGui::GetContentRegionAvail();
if( beginContentRegionAvailable.x != contentRegionAvail.x || beginContentRegionAvailable.y != contentRegionAvail.y || windowSize.x != wndSize.x || windowSize.y != wndSize.y)
{
windowSize = {wndSize.x, wndSize.y};
beginContentRegionAvailable = {contentRegionAvail.x, contentRegionAvail.y};
OnResize();
}
auto wndPos = ImGui::GetWindowPos();
if(windowPos.x != wndPos.x || windowPos.y != wndPos.y)
{
windowPos = {wndPos.x, wndPos.y};
OnPosChange();
}
isWindowHovered = ImGui::IsWindowHovered();
return result;
}
void SHEditorWindow::OnResize()
{
}
void SHEditorWindow::OnPosChange()
{
} }
}//namespace SHADE }//namespace SHADE

View File

@ -5,6 +5,8 @@
//#==============================================================# //#==============================================================#
#include <string> #include <string>
#include "Math/Vector/SHVec2.h"
//#==============================================================# //#==============================================================#
//|| Forward Declarations || //|| Forward Declarations ||
//#==============================================================# //#==============================================================#
@ -21,11 +23,20 @@ namespace SHADE
virtual void Init(); virtual void Init();
virtual void Update(); virtual void Update();
virtual void Exit(); virtual void Exit();
bool isOpen = false; bool isOpen;
bool isWindowHovered;
std::string_view windowName; std::string_view windowName;
SHVec2 windowSize;
SHVec2 windowPos;
SHVec2 viewportMousePos;
SHVec2 beginContentRegionAvailable;
protected: protected:
virtual bool Begin(); virtual bool Begin();
virtual void OnResize();
virtual void OnPosChange();
ImGuiWindowFlags windowFlags = 0; ImGuiWindowFlags windowFlags = 0;
ImGuiIO& io; ImGuiIO& io;
};//class SHEditorWindow };//class SHEditorWindow
}//namespace SHADE }//namespace SHADE

View File

@ -2,4 +2,5 @@
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar #include "MenuBar/SHEditorMenuBar.h" //Menu Bar
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel #include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
#include "Inspector/SHEditorInspector.h" //Inspector #include "Inspector/SHEditorInspector.h" //Inspector
#include "Profiling/SHEditorProfiler.h" //Profiler #include "Profiling/SHEditorProfiler.h" //Profiler
#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport

View File

@ -0,0 +1,129 @@
#include "SHpch.h"
#include "Editor/SHImGuiHelpers.hpp"
#include "SHEditorViewport.h"
#include "ImGuizmo.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/IconsMaterialDesign.h"
#include "Editor/SHEditor.hpp"
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
#include <Editor/IconsFontAwesome6.h>
constexpr std::string_view windowName = "\xef\x80\x95 Viewport";
namespace SHADE
{
SHEditorViewport::SHEditorViewport()
:SHEditorWindow("\xee\x90\x8b Viewport", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar)
{
}
void SHEditorViewport::Init()
{
SHEditorWindow::Init();
}
void SHEditorViewport::Update()
{
SHEditorWindow::Update();
if(Begin())
{
ImGuizmo::SetDrawlist();
DrawMenuBar();
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
auto mousePos = ImGui::GetMousePos();
beginCursorPos = ImGui::GetCursorScreenPos();
viewportMousePos = {mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y};
gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos);
ImGui::Image((ImTextureID)descriptorSet, {beginContentRegionAvailable.x, beginContentRegionAvailable.y});
if(ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right))
{
ImGui::SetMouseCursor(ImGuiMouseCursor_None);
ImGui::SetCursorScreenPos(ImGui::GetMousePos());
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiColors::green);
ImGui::Text(ICON_FA_EYE);
ImGui::PopStyleColor();
}
}
ImGuizmo::SetRect(beginCursorPos.x , beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
transformGizmo.Draw();
ImGui::End();
}
void SHEditorViewport::Exit()
{
SHEditorWindow::Exit();
}
void SHEditorViewport::OnResize()
{
SHEditorWindow::OnResize();
//Get graphics system to resize swapchain image
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
//auto pos = ImGui::GetCursorPos();
//windowCursorPos = {}
if(beginContentRegionAvailable.x == 0 || beginContentRegionAvailable.y == 0)
{
beginContentRegionAvailable = windowSize;
}
gfxSystem->PrepareResize(static_cast<uint32_t>(beginContentRegionAvailable.x), static_cast<uint32_t>(beginContentRegionAvailable.y));
}
void SHEditorViewport::OnPosChange()
{
SHEditorWindow::OnPosChange();
}
void SHEditorViewport::DrawMenuBar() noexcept
{
if(ImGui::BeginMenuBar())
{
bool const isTranslate = transformGizmo.operation == SHTransformGizmo::Operation::TRANSLATE;
ImGui::BeginDisabled(isTranslate);
if(isTranslate)
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
if(ImGui::Button(ICON_MD_OPEN_WITH))
{
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
}
ImGui::EndDisabled();
if(isTranslate)
ImGui::PopStyleColor();
bool const isRotate = transformGizmo.operation == SHTransformGizmo::Operation::ROTATE;
ImGui::BeginDisabled(isRotate);
if(isRotate)
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
if(ImGui::Button(ICON_MD_AUTORENEW))
{
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
}
ImGui::EndDisabled();
if(isRotate)
ImGui::PopStyleColor();
bool const isScale = transformGizmo.operation == SHTransformGizmo::Operation::SCALE;
ImGui::BeginDisabled(isScale);
if(isScale)
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
if(ImGui::Button(ICON_MD_EXPAND))
{
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
}
ImGui::EndDisabled();
if(isScale)
ImGui::PopStyleColor();
ImGui::EndMenuBar();
}
}
}//namespace SHADE

View File

@ -0,0 +1,32 @@
#pragma once
//#==============================================================#
//|| Library Includes ||
//#==============================================================#
#include <imgui.h>
//#==============================================================#
//|| SHADE Includes ||
//#==============================================================#
#include "imgui_internal.h"
#include "ECS_Base/SHECSMacros.h"
#include "Editor/EditorWindow/SHEditorWindow.h"
#include "Editor/Gizmos/SHTransformGizmo.h"
namespace SHADE
{
class SHEditorViewport final : public SHEditorWindow
{
public:
SHEditorViewport();
void Init() override;
void Update() override;
void Exit() override;
SHTransformGizmo transformGizmo;
protected:
void OnResize() override;
void OnPosChange() override;
private:
void DrawMenuBar() noexcept;
SHVec2 beginCursorPos;
};//class SHEditorViewport
}//namespace SHADE

View File

@ -0,0 +1,85 @@
#include "SHpch.h"
#include "SHTransformGizmo.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.hpp"
#include "Editor/SHImGuiHelpers.hpp"
#include <imgui.h>
#include <ImGuizmo.h>
#include "Camera/SHCameraSystem.h"
#include "Editor/Command/SHCommandManager.h"
#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h"
namespace SHADE
{
void SHTransformGizmo::Draw()
{
bool justChangedTfm = false;
if (!editorCamera)
{
auto const cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
editorCamera = cameraSystem->GetEditorCamera();
}
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
ImGuizmo::SetOrthographic(false);
SHMatrix view = SHMatrix::Transpose(editorCamera->GetViewMatrix());
SHMatrix proj = SHMatrix::Transpose(editorCamera->GetProjMatrix());
proj(1, 1) *= -1;
static SHMatrix gridMat = SHMatrix::Translate(0, -0.5f, 0.f) * SHMatrix::Identity;
//ImGuizmo::DrawGrid(&view._11, &proj._11, &gridMat._11, 100.f);
if (selectedEntityTransformComponent == nullptr)
{
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
if (editor->selectedEntities.empty())
return;
EntityID eid = editor->selectedEntities.back();
selectedEntityTransformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
justChangedTfm = true;
}
else
{
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
if (editor->selectedEntities.empty())
return;
EntityID eid = editor->selectedEntities.back();
auto tfmComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
if (selectedEntityTransformComponent != tfmComponent)
{
selectedEntityTransformComponent = tfmComponent;
justChangedTfm = true;
}
}
if (selectedEntityTransformComponent == nullptr)
return;
SHMatrix mat = selectedEntityTransformComponent->GetTRS();
isManipulating = ImGuizmo::Manipulate(&view._11, &proj._11, static_cast<ImGuizmo::OPERATION>(operation), ImGuizmo::MODE::WORLD, &mat._11);
if (!justChangedTfm)
{
if (ImGui::IsItemClicked())
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHMatrix>>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx)
{
if (!tfm)
return;
SHVec3 translate{}, rotate{}, scale{};
mtx.Decompose(translate, rotate, scale);
tfm->SetWorldPosition(translate);
tfm->SetWorldRotation(rotate);
tfm->SetWorldScale(scale);
})));
else if (ImGui::IsItemHovered(ImGuiMouseButton_Left) && ImGui::IsMouseDown(ImGuiMouseButton_Left) && isManipulating)
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHMatrix>>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx)
{
if (!tfm)
return;
SHVec3 translate{}, rotate{}, scale{};
mtx.Decompose(translate, rotate, scale);
tfm->SetWorldPosition(translate);
tfm->SetWorldRotation(rotate);
tfm->SetWorldScale(scale);
})), true);
}
}
}

View File

@ -0,0 +1,48 @@
#pragma once
#include "Camera/SHCameraComponent.h"
#include "Math/Transform/SHTransformComponent.h"
namespace SHADE
{
class SHTransformGizmo
{
public:
enum class Mode
{
WORLD,
LOCAL
};
enum class Operation
{
TRANSLATE_X = (1u << 0),
TRANSLATE_Y = (1u << 1),
TRANSLATE_Z = (1u << 2),
ROTATE_X = (1u << 3),
ROTATE_Y = (1u << 4),
ROTATE_Z = (1u << 5),
ROTATE_SCREEN = (1u << 6),
SCALE_X = (1u << 7),
SCALE_Y = (1u << 8),
SCALE_Z = (1u << 9),
BOUNDS = (1u << 10),
SCALE_XU = (1u << 11),
SCALE_YU = (1u << 12),
SCALE_ZU = (1u << 13),
TRANSLATE = TRANSLATE_X | TRANSLATE_Y | TRANSLATE_Z,
ROTATE = ROTATE_X | ROTATE_Y | ROTATE_Z | ROTATE_SCREEN,
SCALE = SCALE_X | SCALE_Y | SCALE_Z,
SCALEU = SCALE_XU | SCALE_YU | SCALE_ZU, // universal
UNIVERSAL = TRANSLATE | ROTATE | SCALEU
};
void Draw();
bool isManipulating = false;
Mode mode = Mode::WORLD;
Operation operation = Operation::TRANSLATE;
private:
SHTransformComponent* selectedEntityTransformComponent{nullptr};
SHCameraComponent* editorCamera{nullptr};
};
}

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
#include "SHpch.h" #include "SHpch.h"
#include "IconsMaterialDesign.h" #include "IconsMaterialDesign.h"
#include "IconsFontAwesome6.h"
#include "DragDrop/SHDragDrop.hpp" #include "DragDrop/SHDragDrop.hpp"
//#==============================================================# //#==============================================================#
@ -36,6 +37,7 @@
#include <imgui.h> #include <imgui.h>
#include <SDL.h> #include <SDL.h>
#include <rttr/registration> #include <rttr/registration>
#include <ImGuizmo.h>
//#==============================================================# //#==============================================================#
//|| ImGui Backend Includes || //|| ImGui Backend Includes ||
@ -43,6 +45,8 @@
#include <backends/imgui_impl_sdl.h> #include <backends/imgui_impl_sdl.h>
#include <backends/imgui_impl_vulkan.h> #include <backends/imgui_impl_vulkan.h>
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
RTTR_REGISTRATION RTTR_REGISTRATION
{ {
using namespace SHADE; using namespace SHADE;
@ -73,6 +77,7 @@ namespace SHADE
//#==============================================================# //#==============================================================#
void SHEditor::Init() void SHEditor::Init()
{ {
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
if(auto context = ImGui::CreateContext()) if(auto context = ImGui::CreateContext())
{ {
@ -82,11 +87,21 @@ namespace SHADE
} }
} }
ImGuiIO& io = ImGui::GetIO(); (void)io; //Add editor windows
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io = &ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini";
io->ConfigWindowsMoveFromTitleBarOnly = true;
InitLayout();
InitFonts(); InitFonts();
@ -98,11 +113,11 @@ namespace SHADE
SetStyle(Style::SHADE); SetStyle(Style::SHADE);
//Add editor windows
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>(); for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>(); {
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>(); window->Init();
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>(); }
SHLOG_INFO("Successfully initialised SHADE Engine Editor") SHLOG_INFO("Successfully initialised SHADE Engine Editor")
} }
@ -114,8 +129,12 @@ namespace SHADE
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
{ {
if(window->isOpen) if(window->isOpen)
{
window->Update(); window->Update();
}
} }
PollPicking();
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z)) if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
{ {
@ -125,36 +144,47 @@ namespace SHADE
{ {
SHCommandManager::UndoCommand(); SHCommandManager::UndoCommand();
} }
Render(); Render();
} }
void SHEditor::Render() void SHEditor::Render()
{ {
ImGui::Render(); ImGui::Render();
ImGuiIO& io = ImGui::GetIO(); if (io->ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{ {
ImGui::UpdatePlatformWindows(); ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault(); ImGui::RenderPlatformWindowsDefault();
} }
} }
void SHEditor::InitLayout() noexcept
{
if(!std::filesystem::exists(io->IniFilename))
{
std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename);
}
//eventually load preferred layout here
}
void SHEditor::InitFonts() noexcept void SHEditor::InitFonts() noexcept
{ {
ImGuiIO& io = ImGui::GetIO(); ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
ImFont* mainFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
io.Fonts->Build(); constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_MD, 0 };
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
io->Fonts->Build();
} }
void SHEditor::Exit() void SHEditor::Exit()
{ {
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
{
window->Init();
}
ImGui_ImplVulkan_Shutdown(); ImGui_ImplVulkan_Shutdown();
ImGui_ImplSDL2_Shutdown(); ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
@ -167,86 +197,86 @@ namespace SHADE
default: default:
case Style::SHADE: case Style::SHADE:
{ {
ImGuiStyle& imStyle = ImGui::GetStyle(); ImGuiStyle& imStyle = ImGui::GetStyle();
ImVec4* colors = imStyle.Colors; ImVec4* colors = imStyle.Colors;
colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f); colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f); colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f); colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f);
colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f); colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f); colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg]; colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg];
colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg]; colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg];
colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg]; colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg];
colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f); colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f);
colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg]; colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg];
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f); colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f); colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f); colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f); colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f); colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f); colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f); colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f);
colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg]; colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg];
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f); colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f); colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg]; colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg];
colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f); colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f);
colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg]; colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg];
colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg]; colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg];
colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f); colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f); colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f); colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f); colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f); colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f); colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f);
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.141f, 0.141f, 0.141f, 0.70f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.141f, 0.141f, 0.141f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight]; colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight];
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f); colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f);
imStyle.WindowPadding = ImVec2(8.00f, 8.00f); imStyle.WindowPadding = ImVec2(8.00f, 8.00f);
imStyle.FramePadding = ImVec2(5.00f, 2.00f); imStyle.FramePadding = ImVec2(5.00f, 2.00f);
imStyle.CellPadding = ImVec2(6.00f, 8.00f); imStyle.CellPadding = ImVec2(6.00f, 8.00f);
imStyle.ItemSpacing = ImVec2(6.00f, 6.00f); imStyle.ItemSpacing = ImVec2(6.00f, 6.00f);
imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f); imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f);
imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f); imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f);
imStyle.IndentSpacing = 25; imStyle.IndentSpacing = 25;
imStyle.ScrollbarSize = 15; imStyle.ScrollbarSize = 15;
imStyle.GrabMinSize = 10; imStyle.GrabMinSize = 10;
imStyle.WindowBorderSize = 0.6f; imStyle.WindowBorderSize = 0.6f;
imStyle.ChildBorderSize = 1; imStyle.ChildBorderSize = 1;
imStyle.PopupBorderSize = 1; imStyle.PopupBorderSize = 1;
imStyle.FrameBorderSize = 1; imStyle.FrameBorderSize = 1;
imStyle.TabBorderSize = 1; imStyle.TabBorderSize = 1;
imStyle.WindowRounding = 7; imStyle.WindowRounding = 7;
imStyle.ChildRounding = 4; imStyle.ChildRounding = 4;
imStyle.FrameRounding = 3; imStyle.FrameRounding = 3;
imStyle.PopupRounding = 4; imStyle.PopupRounding = 4;
imStyle.ScrollbarRounding = 9; imStyle.ScrollbarRounding = 9;
imStyle.GrabRounding = 3; imStyle.GrabRounding = 3;
imStyle.LogSliderDeadzone = 4; imStyle.LogSliderDeadzone = 4;
imStyle.TabRounding = 4; imStyle.TabRounding = 4;
imStyle.WindowMenuButtonPosition = ImGuiDir_None; imStyle.WindowMenuButtonPosition = ImGuiDir_None;
} }
break; break;
@ -281,10 +311,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)
@ -309,6 +340,29 @@ namespace SHADE
}); });
} }
void SHEditor::PollPicking()
{
if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
{
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
if (viewportWindow->isWindowHovered && !viewportWindow->transformGizmo.isManipulating && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{
EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity();
if(pickedEID == MAX_EID)
return;
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
{
if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>())
{
hierarchyPanel->SetScrollTo(pickedEID);
}
selectedEntities.clear();
}
selectedEntities.push_back(pickedEID);
}
}
}
void SHEditor::NewFrame() void SHEditor::NewFrame()
{ {
SDL_Event event; SDL_Event event;
@ -319,6 +373,7 @@ namespace SHADE
ImGui_ImplVulkan_NewFrame(); ImGui_ImplVulkan_NewFrame();
ImGui_ImplSDL2_NewFrame(); ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
ImGuizmo::BeginFrame();
} }

View File

@ -13,9 +13,11 @@
#include "ECS_Base/SHECSMacros.h" #include "ECS_Base/SHECSMacros.h"
#include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
#include "EditorWindow/SHEditorWindow.h" #include "EditorWindow/SHEditorWindow.h"
#include "Tools/SHLogger.h" #include "Tools/SHLogger.h"
#include "Gizmos/SHTransformGizmo.h"
//#==============================================================# //#==============================================================#
//|| Library Includes || //|| Library Includes ||
@ -90,11 +92,11 @@ namespace SHADE
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get()); return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
} }
static EditorWindowMap editorWindows;
private: private:
// Number of windows; used for Editor Window ID Generation // Number of windows; used for Editor Window ID Generation
static EditorWindowID windowCount; static EditorWindowID windowCount;
// Map of Editor Windows // Map of Editor Windows
static EditorWindowMap editorWindows;
friend class SHEditor; friend class SHEditor;
}; };
@ -110,10 +112,17 @@ namespace SHADE
class SH_API EditorRoutine final : public SHSystemRoutine class SH_API EditorRoutine final : public SHSystemRoutine
{ {
public: public:
EditorRoutine() = default; EditorRoutine():SHSystemRoutine("Editor routine", true) {};
void Execute(double dt) noexcept override final; void Execute(double dt) noexcept override final;
}; };
enum class State : uint8_t
{
PLAY,
PAUSE,
STOP
};
/** /**
* @brief Style options * @brief Style options
* *
@ -162,9 +171,13 @@ namespace SHADE
void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;}; void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
void PollPicking();
// List of selected entities // List of selected entities
std::vector<EntityID> selectedEntities; std::vector<EntityID> selectedEntities;
State editorState = State::STOP;
private: private:
/** /**
* @brief Start new frame for editor * @brief Start new frame for editor
@ -177,7 +190,7 @@ namespace SHADE
*/ */
void Render(); void Render();
void InitLayout() noexcept;
void InitFonts() noexcept; void InitFonts() noexcept;
@ -186,6 +199,10 @@ namespace SHADE
// Handle to command buffer used for ImGui Vulkan Backend // Handle to command buffer used for ImGui Vulkan Backend
Handle<SHVkCommandBuffer> imguiCommandBuffer; Handle<SHVkCommandBuffer> imguiCommandBuffer;
SDL_Window* sdlWindow; SDL_Window* sdlWindow {nullptr};
ImGuiIO* io{nullptr};
//SHTransformGizmo transformGizmo;
};//class SHEditor };//class SHEditor
}//namespace SHADE }//namespace SHADE

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,64 +183,101 @@ 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, int min, int max, int& value, bool* isHovered /*= nullptr*/)
{ {
float val = static_cast<float>(value); ImGui::Text(label.c_str());
ImGui::Text(label.c_str()); if (isHovered)
ImGui::SameLine(); *isHovered = ImGui::IsItemHovered();
const bool CHANGED = ImGui::SliderFloat("#", &val, ImGui::SameLine();
static_cast<float>(min), static_cast<float>(max), "%.3f", return ImGui::SliderInt("##", &value,
ImGuiInputTextFlags_EnterReturnsTrue); static_cast<float>(min), static_cast<float>(max), "%d",
ImGuiInputTextFlags_EnterReturnsTrue);
if (CHANGED)
{
value = val;
}
return CHANGED;
} }
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value) bool SHEditorUI::InputSlider(const std::string& label, unsigned int min, unsigned int max, unsigned int& value, bool* isHovered /*= nullptr*/)
{
int val = static_cast<int>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED)
{
value = static_cast<int>(val);
}
return CHANGED;
}
bool SHEditorUI::InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered)
{
ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::SliderFloat("##", &value,
static_cast<float>(min), static_cast<float>(max), "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered /*= nullptr*/)
{
float val = static_cast<float>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED)
{
value = static_cast<double>(val);
}
return CHANGED;
}
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 +287,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,19 +226,57 @@ 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 an int slider field widget for double input.
/// <br/> /// <br/>
/// Wraps up ImGui::InputSliderFloat(). /// Wraps up ImGui::SliderInt().
/// </summary> /// </summary>
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <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, int min, int max, int& value, bool* isHovered = nullptr);
/// <summary>
/// Creates an unsigned int slider field widget for double input.
/// <br/>
/// Wraps up ImGui::SliderInt().
/// </summary>
/// <param name="label">Label used to identify this widget.</param>
/// <param name="min">Minimum 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="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns>
static bool InputSlider(const std::string& label, unsigned int min, unsigned int max, unsigned int& value, bool* isHovered = nullptr);
/// <summary>
/// Creates a float slider field widget for double input.
/// <br/>
/// Wraps up ImGui::SliderFloat().
/// </summary>
/// <param name="label">Label used to identify this widget.</param>
/// <param name="min">Minimum 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="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns>
static bool InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered = nullptr);
/// <summary>
/// Creates a double slider field widget for double input.
/// <br/>
/// Wraps up ImGui::SliderFloat().
/// </summary>
/// <param name="label">Label used to identify this widget.</param>
/// <param name="min">Minimum 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="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns>
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 +284,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 +294,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 +304,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 +317,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

@ -16,11 +16,11 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE 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

@ -15,7 +15,7 @@
//#==============================================================# //#==============================================================#
#ifndef SH_IM_MATH #ifndef SH_IM_MATH
#define IM_VEC2_CLASS_EXTRA \ #define IM_VEC2_CLASS_EXTRA \
ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \ ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \
operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);} operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);}
#define IM_VEC3_CLASS_EXTRA \ #define IM_VEC3_CLASS_EXTRA \
ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \ ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \
@ -43,6 +43,10 @@ namespace SHADE
constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f}; constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f};
constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f}; constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f};
constexpr int colors_red = 0;
constexpr int colors_green = 1;
constexpr int colors_blue = 2;
constexpr int colors_white = 3;
constexpr ImU32 colors[] = { constexpr ImU32 colors[] = {
0xBB0000FF, // red 0xBB0000FF, // red
0xBB00FF00, // green 0xBB00FF00, // green

View File

@ -5,8 +5,9 @@ typedef uint32_t SHEventIdentifier;
typedef uint32_t SHEventHandle; typedef uint32_t SHEventHandle;
//Add your event identifiers here: //Add your event identifiers here:
constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0}; constexpr SHEventIdentifier SH_EXAMPLE_EVENT { 0 };
constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT{ 1 }; constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 };
constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT{ 2 }; constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 };
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT{ 3 }; constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT{ 4 }; constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };

View File

@ -14,7 +14,6 @@
#pragma once #pragma once
#include <chrono> #include <chrono>
#include "Tools/SHLogger.h"
#include "SH_API.h" #include "SH_API.h"
namespace SHADE namespace SHADE

View File

@ -3,7 +3,7 @@
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "vk_mem_alloc.h" #include "vk_mem_alloc.h"
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
namespace SHADE namespace SHADE
{ {

View File

@ -10,6 +10,7 @@
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Images/SHVkImage.h" #include "Graphics/Images/SHVkImage.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/SHVkUtil.h"
namespace SHADE namespace SHADE
@ -299,7 +300,7 @@ namespace SHADE
SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. "); SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. ");
return; return;
} }
boundPipelineLayoutHdl = pipelineHdl->GetPipelineLayout(); bindPointData[static_cast<uint32_t>(pipelineHdl->GetPipelineType())].boundPipelineLayoutHdl = pipelineHdl->GetPipelineLayout();
vkCommandBuffer.bindPipeline(pipelineHdl->GetPipelineBindPoint(), pipelineHdl->GetVkPipeline()); vkCommandBuffer.bindPipeline(pipelineHdl->GetPipelineBindPoint(), pipelineHdl->GetVkPipeline());
} }
@ -358,9 +359,10 @@ namespace SHADE
} }
} }
void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets) void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets)
{ {
vkCommandBuffer.bindDescriptorSets(bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets); uint32_t bindPointIndex = static_cast<uint32_t>(bindPoint);
vkCommandBuffer.bindDescriptorSets(SHVkUtil::GetPipelineBindPointFromType(bindPoint), bindPointData[bindPointIndex].boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets);
} }
/***************************************************************************/ /***************************************************************************/
@ -452,6 +454,11 @@ namespace SHADE
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand)); vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
} }
void SHVkCommandBuffer::ComputeDispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) noexcept
{
vkCommandBuffer.dispatch (groupCountX, groupCountY, groupCountZ);
}
void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo) void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo)
{ {
vkCommandBuffer.copyBufferToImage vkCommandBuffer.copyBufferToImage
@ -500,9 +507,9 @@ namespace SHADE
// //vkCommandBuffer.pipelineBarrier() // //vkCommandBuffer.pipelineBarrier()
//} //}
void SHVkCommandBuffer::ForceSetPipelineLayout(Handle<SHVkPipelineLayout> pipelineLayout) noexcept void SHVkCommandBuffer::ForceSetPipelineLayout(Handle<SHVkPipelineLayout> pipelineLayout, SH_PIPELINE_TYPE pipelineType) noexcept
{ {
boundPipelineLayoutHdl = pipelineLayout; bindPointData[static_cast<uint32_t>(pipelineType)].boundPipelineLayoutHdl = pipelineLayout;
} }
/***************************************************************************/ /***************************************************************************/
@ -513,12 +520,13 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHVkCommandBuffer::SubmitPushConstants(void) const noexcept void SHVkCommandBuffer::SubmitPushConstants(SH_PIPELINE_TYPE bindPoint) const noexcept
{ {
vkCommandBuffer.pushConstants(boundPipelineLayoutHdl->GetVkPipelineLayout(), auto layoutHdl = bindPointData[static_cast<uint32_t>(bindPoint)].boundPipelineLayoutHdl;
boundPipelineLayoutHdl->GetPushConstantInterface().GetShaderStageFlags(), vkCommandBuffer.pushConstants(layoutHdl->GetVkPipelineLayout(),
layoutHdl->GetPushConstantInterface().GetShaderStageFlags(),
0, 0,
boundPipelineLayoutHdl->GetPushConstantInterface().GetSize(), pushConstantData); layoutHdl->GetPushConstantInterface().GetSize(), pushConstantData);
} }
/***************************************************************************/ /***************************************************************************/
@ -695,7 +703,7 @@ namespace SHADE
, usageFlags{ rhs.usageFlags } , usageFlags{ rhs.usageFlags }
, commandBufferCount{ rhs.commandBufferCount } , commandBufferCount{ rhs.commandBufferCount }
, parentPool{ rhs.parentPool } , parentPool{ rhs.parentPool }
, boundPipelineLayoutHdl{ rhs.boundPipelineLayoutHdl } , bindPointData{ std::move (rhs.bindPointData)}
{ {
memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE); memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
@ -728,7 +736,7 @@ namespace SHADE
usageFlags = rhs.usageFlags; usageFlags = rhs.usageFlags;
commandBufferCount = rhs.commandBufferCount; commandBufferCount = rhs.commandBufferCount;
parentPool = rhs.parentPool; parentPool = rhs.parentPool;
boundPipelineLayoutHdl = rhs.boundPipelineLayoutHdl; bindPointData = std::move(rhs.bindPointData);
memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE); memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
rhs.vkCommandBuffer = VK_NULL_HANDLE; rhs.vkCommandBuffer = VK_NULL_HANDLE;

View File

@ -4,8 +4,9 @@
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "Graphics/SHVulkanDefines.h" #include "Graphics/SHVulkanDefines.h"
#include "SHCommandPoolResetMode.h" #include "SHCommandPoolResetMode.h"
#include "Resource/ResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
#include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h"
#include "Graphics/Pipeline/SHPipelineType.h"
namespace SHADE namespace SHADE
{ {
@ -36,10 +37,17 @@ namespace SHADE
class SHVkCommandBuffer class SHVkCommandBuffer
{ {
friend class SHVkCommandPool; friend class SHVkCommandPool;
friend class ResourceLibrary<SHVkCommandBuffer>; friend class SHResourceLibrary<SHVkCommandBuffer>;
static constexpr uint16_t PUSH_CONSTANT_SIZE = 512; static constexpr uint16_t PUSH_CONSTANT_SIZE = 512;
private: private:
struct PipelineBindPointData
{
//! The currently bound pipeline
Handle<SHVkPipelineLayout> boundPipelineLayoutHdl;
};
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -66,8 +74,8 @@ namespace SHADE
//! The command pool that this command buffer belongs to //! The command pool that this command buffer belongs to
Handle<SHVkCommandPool> parentPool; Handle<SHVkCommandPool> parentPool;
//! The currently bound pipeline //! Every command buffer will have a set of pipeline bind point specific data
Handle<SHVkPipelineLayout> boundPipelineLayoutHdl; std::array<PipelineBindPointData, static_cast<uint32_t>(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData;
//! The push constant data for the command buffer //! The push constant data for the command buffer
uint8_t pushConstantData[PUSH_CONSTANT_SIZE]; uint8_t pushConstantData[PUSH_CONSTANT_SIZE];
@ -112,13 +120,16 @@ namespace SHADE
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept; void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
void BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept; void BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept;
void BindIndexBuffer (Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept; void BindIndexBuffer (Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept;
void BindDescriptorSet (Handle<SHVkDescriptorSetGroup> descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets); void BindDescriptorSet (Handle<SHVkDescriptorSetGroup> descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets);
// Draw Commands // Draw Commands
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept; void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;
void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept; void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept;
void DrawMultiIndirect (Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount); void DrawMultiIndirect (Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount);
// Compute Commands
void ComputeDispatch (uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ) noexcept;
// Buffer Copy // Buffer Copy
void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo); void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
void CopyImageToBuffer (const vk::Image& src, const vk::Buffer& dst, const std::vector<vk::BufferImageCopy>& copyInfo); void CopyImageToBuffer (const vk::Image& src, const vk::Buffer& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
@ -138,13 +149,13 @@ namespace SHADE
// Push Constant variable setting // Push Constant variable setting
template <typename T> template <typename T>
void SetPushConstantVariable(std::string variableName, T const& data) noexcept void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept
{ {
memcpy (static_cast<uint8_t*>(pushConstantData) + boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T)); memcpy (static_cast<uint8_t*>(pushConstantData) + bindPointData[static_cast<uint32_t>(bindPoint)].boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T));
}; };
void ForceSetPipelineLayout (Handle<SHVkPipelineLayout> pipelineLayout) noexcept; void ForceSetPipelineLayout (Handle<SHVkPipelineLayout> pipelineLayout, SH_PIPELINE_TYPE pipelineType) noexcept;
void SubmitPushConstants (void) const noexcept; void SubmitPushConstants (SH_PIPELINE_TYPE bindPoint) const noexcept;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* GETTERS AND SETTERS */ /* GETTERS AND SETTERS */

View File

@ -2,7 +2,7 @@
#include "SHVkCommandPool.h" #include "SHVkCommandPool.h"
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Instance/SHVkInstance.h" #include "Graphics/Instance/SHVkInstance.h"
#include "Resource/ResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
#include "Tools/SHLogger.h" #include "Tools/SHLogger.h"
namespace SHADE namespace SHADE

View File

@ -6,7 +6,7 @@
#include "Graphics/Queues/SHVkQueue.h" #include "Graphics/Queues/SHVkQueue.h"
#include "SHCommandPoolResetMode.h" #include "SHCommandPoolResetMode.h"
#include "SHVkCommandBuffer.h" #include "SHVkCommandBuffer.h"
#include "Resource/ResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
namespace SHADE namespace SHADE
{ {

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

@ -25,7 +25,8 @@ namespace SHADE
} }
SHVkDescriptorPool::SHVkDescriptorPool(SHVkDescriptorPool&& rhs) noexcept SHVkDescriptorPool::SHVkDescriptorPool(SHVkDescriptorPool&& rhs) noexcept
: device{ rhs.device } : ISelfHandle (rhs)
, device{ rhs.device }
, pool{ rhs.pool } , pool{ rhs.pool }
{ {
rhs.pool = VK_NULL_HANDLE; rhs.pool = VK_NULL_HANDLE;

View File

@ -2,7 +2,7 @@
// Project Includes // Project Includes
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
namespace SHADE namespace SHADE
{ {

View File

@ -91,7 +91,7 @@ namespace SHADE
// new write for the binding // new write for the binding
updater.writeInfos.emplace_back(); updater.writeInfos.emplace_back();
updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1); updater.writeHashMap.try_emplace(writeHash, static_cast<uint32_t>(updater.writeInfos.size()) - 1u);
auto& writeInfo = updater.writeInfos.back(); auto& writeInfo = updater.writeInfos.back();
// Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in // Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in
@ -102,10 +102,10 @@ namespace SHADE
//case vk::DescriptorType::eSampler: //case vk::DescriptorType::eSampler:
//case vk::DescriptorType::eSampledImage: //case vk::DescriptorType::eSampledImage:
case vk::DescriptorType::eCombinedImageSampler: case vk::DescriptorType::eCombinedImageSampler:
case vk::DescriptorType::eStorageImage:
case vk::DescriptorType::eInputAttachment:
writeInfo.descImageInfos.resize(descriptorCount); writeInfo.descImageInfos.resize(descriptorCount);
break; break;
//case vk::DescriptorType::eStorageImage:
// break;
case vk::DescriptorType::eUniformTexelBuffer: case vk::DescriptorType::eUniformTexelBuffer:
case vk::DescriptorType::eStorageTexelBuffer: case vk::DescriptorType::eStorageTexelBuffer:
case vk::DescriptorType::eUniformBuffer: case vk::DescriptorType::eUniformBuffer:
@ -165,6 +165,7 @@ namespace SHADE
if (imageViewsAndSamplers.size() > writeInfo.descImageInfos.size()) if (imageViewsAndSamplers.size() > writeInfo.descImageInfos.size())
{ {
SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. "); SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. ");
return;
} }
for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i) for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i)
@ -172,7 +173,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

@ -4,7 +4,7 @@
// Project Includes // Project Includes
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
#include "Graphics/Shaders/SHShaderReflected.h" #include "Graphics/Shaders/SHShaderReflected.h"
#include "SHDescriptorSetUpdater.h" #include "SHDescriptorSetUpdater.h"
@ -31,6 +31,8 @@ namespace SHADE
class SHVkDescriptorSetGroup class SHVkDescriptorSetGroup
{ {
public: public:
using viewSamplerLayout = std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */ /* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

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

@ -2,7 +2,7 @@
// Project Includes // Project Includes
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
namespace SHADE namespace SHADE
{ {
@ -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

@ -233,6 +233,8 @@ namespace SHADE
, vmaAllocator{rhs.vmaAllocator} , vmaAllocator{rhs.vmaAllocator}
, nonDedicatedBestIndex {0} , nonDedicatedBestIndex {0}
, parentPhysicalDeviceHdl {rhs.parentPhysicalDeviceHdl} , parentPhysicalDeviceHdl {rhs.parentPhysicalDeviceHdl}
, uboBufferMemoryAlignment{ 0 }
, ssboBufferMemoryAlignment{ 0 }
{ {
rhs.vkLogicalDevice = VK_NULL_HANDLE; rhs.vkLogicalDevice = VK_NULL_HANDLE;
} }
@ -261,6 +263,8 @@ namespace SHADE
vmaAllocator = rhs.vmaAllocator; vmaAllocator = rhs.vmaAllocator;
nonDedicatedBestIndex = 0; nonDedicatedBestIndex = 0;
parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl; parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl;
uboBufferMemoryAlignment = rhs.uboBufferMemoryAlignment;
ssboBufferMemoryAlignment = rhs.ssboBufferMemoryAlignment;
rhs.vkLogicalDevice = VK_NULL_HANDLE; rhs.vkLogicalDevice = VK_NULL_HANDLE;
@ -529,6 +533,11 @@ namespace SHADE
} }
Handle<SHVkPipeline> SHVkLogicalDevice::CreateComputePipeline(Handle<SHVkPipelineLayout> const& pipelineLayoutHdl) noexcept
{
return SHVkInstance::GetResourceManager().Create <SHVkPipeline>(GetHandle(), pipelineLayoutHdl);
}
Handle<SHVkSampler> SHVkLogicalDevice::CreateSampler(const SHVkSamplerParams& params) noexcept Handle<SHVkSampler> SHVkLogicalDevice::CreateSampler(const SHVkSamplerParams& params) noexcept
{ {
return SHVkInstance::GetResourceManager().Create <SHVkSampler>(GetHandle(), params); return SHVkInstance::GetResourceManager().Create <SHVkSampler>(GetHandle(), params);
@ -550,10 +559,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

@ -8,8 +8,8 @@
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "Graphics/Devices/SHVkPhysicalDevice.h" #include "Graphics/Devices/SHVkPhysicalDevice.h"
#include "Graphics/Queues/SHVkQueue.h" #include "Graphics/Queues/SHVkQueue.h"
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
#include "Resource/ResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
#include "Graphics/Swapchain/SHSwapchainParams.h" #include "Graphics/Swapchain/SHSwapchainParams.h"
#include "Graphics/Commands/SHCommandPoolResetMode.h" #include "Graphics/Commands/SHCommandPoolResetMode.h"
#include "Graphics/Commands/SHVkCommandPool.h" #include "Graphics/Commands/SHVkCommandPool.h"
@ -175,18 +175,23 @@ namespace SHADE
std::string const& shaderName std::string const& shaderName
) noexcept; ) noexcept;
Handle<SHVkPipeline> CreateGraphicsPipeline ( Handle<SHVkPipeline> CreateGraphicsPipeline (
Handle<SHVkPipelineLayout> const& pipelineLayoutHdl, Handle<SHVkPipelineLayout> const& pipelineLayoutHdl,
SHVkPipelineState const* const state, SHVkPipelineState const* const state,
Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkRenderpass> const& renderpassHdl,
Handle<SHSubpass> subpass Handle<SHSubpass> subpass
) noexcept; ) noexcept;
Handle<SHVkPipeline> CreateComputePipeline (
Handle<SHVkPipelineLayout> const& pipelineLayoutHdl
) noexcept;
Handle<SHVkSampler> CreateSampler (const SHVkSamplerParams& params) noexcept; Handle<SHVkSampler> CreateSampler (const SHVkSamplerParams& params) 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::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

@ -2,7 +2,7 @@
#define SH_VK_FRAMEBUFFER_H #define SH_VK_FRAMEBUFFER_H
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
#include <span> #include <span>
namespace SHADE namespace SHADE

View File

@ -3,7 +3,7 @@
#include "SHImageViewDetails.h" #include "SHImageViewDetails.h"
#include "Graphics/SHVulkanDefines.h" #include "Graphics/SHVulkanDefines.h"
#include "Resource/ResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
#include "vk_mem_alloc.h" #include "vk_mem_alloc.h"
namespace SHADE namespace SHADE

View File

@ -2,7 +2,7 @@
#define SH_VK_IMAGE_VIEW_H #define SH_VK_IMAGE_VIEW_H
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
#include "SHImageViewDetails.h" #include "SHImageViewDetails.h"
namespace SHADE namespace SHADE

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

View File

@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited.
#include <vector> #include <vector>
// Project Includes // Project Includes
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
namespace SHADE namespace SHADE
{ {

View File

@ -15,7 +15,7 @@ namespace SHADE
bool SHVkInstance::validationLayersOn; bool SHVkInstance::validationLayersOn;
vk::Instance SHVkInstance::vkInstance; vk::Instance SHVkInstance::vkInstance;
SHVkDebugMessenger SHVkInstance::debugMessenger; SHVkDebugMessenger SHVkInstance::debugMessenger;
ResourceManager SHVkInstance::resourceManager; SHResourceHub SHVkInstance::resourceManager;
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -258,7 +258,7 @@ namespace SHADE
return vkInstance; return vkInstance;
} }
ResourceManager& SHVkInstance::GetResourceManager(void) noexcept SHResourceHub& SHVkInstance::GetResourceManager(void) noexcept
{ {
return resourceManager; return resourceManager;
} }

View File

@ -18,7 +18,7 @@ written consent of DigiPen Institute of Technology is prohibited.
#include "Graphics/Debugging/SHVkDebugMessenger.h" #include "Graphics/Debugging/SHVkDebugMessenger.h"
#include "Graphics/Devices/SHVkPhysicalDevice.h" #include "Graphics/Devices/SHVkPhysicalDevice.h"
#include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Resource/ResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
namespace SHADE namespace SHADE
@ -61,7 +61,7 @@ namespace SHADE
static SHVkDebugMessenger debugMessenger; static SHVkDebugMessenger debugMessenger;
//! Resource management for vulkan project //! Resource management for vulkan project
static ResourceManager resourceManager; static SHResourceHub resourceManager;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
@ -85,7 +85,7 @@ namespace SHADE
/* Getters and Setters */ /* Getters and Setters */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static vk::Instance const& GetVkInstance (void) noexcept; static vk::Instance const& GetVkInstance (void) noexcept;
static ResourceManager& GetResourceManager(void) noexcept; static SHResourceHub& GetResourceManager(void) noexcept;
}; };
} }

View File

@ -369,7 +369,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
{ {
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS) if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
{ {
SHLOG_WARNING("[SHBatch] Attempted to draw a batch with an invalid frame index."); SHLOG_WARNING("[SHBatch] Attempted to draw a batch with an invalid frame index.");
return; return;
@ -385,7 +385,7 @@ namespace SHADE
cmdBuffer->BindDescriptorSet cmdBuffer->BindDescriptorSet
( (
matPropsDescSet[frameIndex], matPropsDescSet[frameIndex],
vk::PipelineBindPoint::eGraphics, SH_PIPELINE_TYPE::GRAPHICS,
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
dynamicOffset dynamicOffset
); );

View File

@ -18,7 +18,7 @@ of DigiPen Institute of Technology is prohibited.
// External Dependencies // External Dependencies
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
// Project Includes // Project Includes
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
#include "Graphics/MiddleEnd/Interface/SHMaterial.h" #include "Graphics/MiddleEnd/Interface/SHMaterial.h"
#include "Math/SHMatrix.h" #include "Math/SHMatrix.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"

View File

@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes // STL Includes
#include <vector> #include <vector>
// Project Includes // Project Includes
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
namespace SHADE namespace SHADE
{ {

View File

@ -20,91 +20,91 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructor/Destructors */ /* Constructor/Destructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHSuperBatch::SHSuperBatch(Handle<SHSubpass> sp) SHSuperBatch::SHSuperBatch(Handle<SHSubpass> sp)
: subpass { sp } : subpass{ sp }
{} {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Usage Functions */ /* Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SHSuperBatch::Add(const SHRenderable* renderable) noexcept void SHSuperBatch::Add(const SHRenderable* renderable) noexcept
{
const Handle<SHVkPipeline> PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline();
// Check if we have a batch with the same pipeline first
auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch)
{
return batch.GetPipeline() == PIPELINE;
});
// Create one if not found
if (batch == batches.end())
{ {
const Handle<SHVkPipeline> PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); batches.emplace_back(PIPELINE);
batch = batches.end() - 1;
// Check if we have a batch with the same pipeline first
auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch)
{
return batch.GetPipeline() == PIPELINE;
});
// Create one if not found
if (batch == batches.end())
{
batches.emplace_back(PIPELINE);
batch = batches.end() - 1;
}
// Add renderable in
batch->Add(renderable);
} }
void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept // Add renderable in
batch->Add(renderable);
}
void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept
{
const Handle<SHVkPipeline> PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline();
// Check if we have a Batch with the same pipeline yet
auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch)
{
return batch.GetPipeline() == PIPELINE;
});
// Attempt to remove if it exists
if (batch == batches.end())
return;
batch->Remove(renderable);
}
void SHSuperBatch::Clear() noexcept
{
for (auto& batch : batches)
{ {
const Handle<SHVkPipeline> PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); batch.Clear();
// Check if we have a Batch with the same pipeline yet
auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch)
{
return batch.GetPipeline() == PIPELINE;
});
// Attempt to remove if it exists
if (batch == batches.end())
return;
batch->Remove(renderable);
} }
batches.clear();
}
void SHSuperBatch::Clear() noexcept void SHSuperBatch::UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
{
for (auto& batch : batches)
{ {
for (auto& batch : batches) batch.UpdateMaterialBuffer(frameIndex, descPool);
{ batch.UpdateTransformBuffer(frameIndex);
batch.Clear(); batch.UpdateEIDBuffer(frameIndex);
}
batches.clear();
} }
}
void SHSuperBatch::UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) void SHSuperBatch::Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
{
// Build all batches
for (auto& batch : batches)
{ {
for (auto& batch : batches) batch.Build(device, descPool, frameIndex);
{
batch.UpdateMaterialBuffer(frameIndex, descPool);
batch.UpdateTransformBuffer(frameIndex);
batch.UpdateEIDBuffer(frameIndex);
}
} }
}
void SHSuperBatch::Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{
// Build all batches
for (auto& batch : batches)
{ {
// Build all batches batch.Draw(cmdBuffer, frameIndex);
for (auto& batch : batches)
{
batch.Build(device, descPool, frameIndex);
}
}
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{
// Build all batches
for (auto& batch : batches)
{
batch.Draw(cmdBuffer, frameIndex);
}
} }
}
} }

View File

@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited.
// External Dependencies // External Dependencies
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
// Project Includes // Project Includes
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
#include "SHBatch.h" #include "SHBatch.h"
#include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/Pipeline/SHVkPipeline.h"

View File

@ -97,14 +97,16 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHMatrix SHCamera::GetViewMatrix() const SHMatrix SHCamera::GetViewMatrix()
{ {
return viewMatrix; updateMatrices();
return viewMatrix;
} }
SHMatrix SHCamera::GetProjectionMatrix() const SHMatrix SHCamera::GetProjectionMatrix()
{ {
return projMatrix; updateMatrices();
return projMatrix;
} }
SHMatrix SHCamera::GetViewProjectionMatrix() SHMatrix SHCamera::GetViewProjectionMatrix()
{ {

View File

@ -3,11 +3,11 @@
\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 Aug 21, 2022 \date Aug 21, 2022
\brief \brief
Copyright (C) 2022 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.
*//*************************************************************************************/ *//*************************************************************************************/
#pragma once #pragma once
@ -17,64 +17,66 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/***********************************************************************************/ /***********************************************************************************/
/*! /*!
\brief \brief
Object that manages the view and projection transformations for rendering Object that manages the view and projection transformations for rendering
a 3D scene. a 3D scene.
*/ */
/***********************************************************************************/ /***********************************************************************************/
class SHCamera class SHCamera
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */ /* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* View Set Functions */ /* View Set Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up); void SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Projection Set Functions */ /* Projection Set Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void SetPerspective(float fov, float width, float height, float zNear, float zFar); void SetPerspective(float fov, float width, float height, float zNear, float zFar);
void SetOrthographic(float width, float height, float zNear, float zFar); void SetOrthographic(float width, float height, float zNear, float zFar);
//void SetPerspectiveMatrixExplicit (
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Getter Functions */ /* Getter Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
SHMatrix GetViewMatrix() const; SHMatrix GetViewMatrix();
SHMatrix GetProjectionMatrix() const; SHMatrix GetProjectionMatrix();
SHMatrix GetViewProjectionMatrix(); SHMatrix GetViewProjectionMatrix();
SHMatrix GetInverseViewMatrix() const; SHMatrix GetInverseViewMatrix() const;
SHMatrix GetInverseProjectionMatrix() const; SHMatrix GetInverseProjectionMatrix() const;
SHMatrix GetInverseViewProjectionMatrix(); SHMatrix GetInverseViewProjectionMatrix();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Mapping Functions */ /* Mapping Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
SHVec3 ScreenToWorld(const SHVec3& vec) const; SHVec3 ScreenToWorld(const SHVec3& vec) const;
SHVec3 WorldToScreen(const SHVec3& vec) const; SHVec3 WorldToScreen(const SHVec3& vec) const;
SHVec3 CameraToWorld(const SHVec3& vec) const; SHVec3 CameraToWorld(const SHVec3& vec) const;
SHVec3 WorldToCamera(const SHVec3& vec) const; SHVec3 WorldToCamera(const SHVec3& vec) const;
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
SHMatrix viewMatrix; SHMatrix viewMatrix;
SHMatrix projMatrix; SHMatrix projMatrix;
SHMatrix vpMatrix; SHMatrix vpMatrix;
SHMatrix inverseViewMatrix; SHMatrix inverseViewMatrix;
SHMatrix inverseProjMatrix; SHMatrix inverseProjMatrix;
SHMatrix inverseVpMatrix; SHMatrix inverseVpMatrix;
bool isDirty = true; bool isDirty = true;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void updateMatrices(); void updateMatrices();
static SHVec3 multiplyHomogenous(const SHMatrix& mat, const SHVec3& vec); static SHVec3 multiplyHomogenous(const SHMatrix& mat, const SHVec3& vec);
}; };
} }

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
{ {
/***************************************************************************/ /***************************************************************************/
@ -57,6 +63,14 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
static constexpr uint32_t PER_INSTANCE = 3; static constexpr uint32_t PER_INSTANCE = 3;
/***************************************************************************/
/*!
\brief
DescriptorSet Index for render graph resources.
*/
/***************************************************************************/
static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
}; };

View File

@ -16,6 +16,9 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Instance/SHVkInstance.h" #include "Graphics/Instance/SHVkInstance.h"
#include "Graphics/Windowing/Surface/SHVkSurface.h" #include "Graphics/Windowing/Surface/SHVkSurface.h"
#include "Graphics/Swapchain/SHVkSwapchain.h" #include "Graphics/Swapchain/SHVkSwapchain.h"
#include "Camera/SHCameraSystem.h"
#include "Editor/SHEditor.hpp"
#include "ECS_Base/Managers/SHSystemManager.h"
//#include "SHRenderer.h" //#include "SHRenderer.h"
#include "Graphics/Windowing/SHWindow.h" #include "Graphics/Windowing/SHWindow.h"
#include "Graphics/MiddleEnd/PerFrame/SHPerFrameData.h" #include "Graphics/MiddleEnd/PerFrame/SHPerFrameData.h"
@ -36,11 +39,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 */
@ -51,7 +52,7 @@ namespace SHADE
// Get Physical Device and Construct Logical Device // Get Physical Device and Construct Logical Device
physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST); physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST);
device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice); device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice);
// Construct surface // Construct surface
surface = device->CreateSurface(window->GetHWND()); surface = device->CreateSurface(window->GetHWND());
@ -71,7 +72,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)
@ -108,9 +117,27 @@ namespace SHADE
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
// TODO: This is VERY temporarily here until a more solid resource management system is implemented
shaderSourceLibrary.Init("../../TempShaderFolder/");
shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true);
shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true);
shaderSourceLibrary.LoadShader(2, "KirschCs.glsl", SH_SHADER_TYPE::COMPUTE, true);
shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary);
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
cubeVS->Reflect();
cubeFS->Reflect();
greyscale->Reflect();
}
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
{
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* MIDDLE END SETUP /* MIDDLE END SETUP
- Viewports - Viewports
- Renderer - Renderer
- Render graph in renderers - Render graph in renderers
@ -118,8 +145,9 @@ namespace SHADE
- Default vertex input state - Default vertex input state
- Global data - Global data
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
auto windowDims = window->GetWindowSize();
SHGraphicsGlobalData::Init(device); auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
// Set Up Cameras // Set Up Cameras
screenCamera = resourceManager.Create<SHCamera>(); screenCamera = resourceManager.Create<SHCamera>();
@ -131,12 +159,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,71 +172,64 @@ 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_FLAGS::COLOR_PRESENT}, windowDims.first, windowDims.second); worldRenderGraph->AddResource("Scene Pre-Process", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, 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("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
worldRenderGraph->AddResource("Depth Buffer", {SH_ATT_DESC_TYPE_FLAGS::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_FLAGS::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", "Scene Pre-Process"}, {}); // 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", "Scene"}, {}); // 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("Scene"); gBufferWriteSubpass->AddColorOutput("Scene Pre-Process");
gBufferWriteSubpass->AddColorOutput("Entity ID"); gBufferWriteSubpass->AddColorOutput("Entity ID");
gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL); gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
// We do this to just transition our scene layout to shader read auto greyscale = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition"); node->AddNodeCompute (greyscale, {"Scene Pre-Process", "Scene"});
sceneLayoutTransitionSubpass->AddInput("Scene");
// Generate world render graph
worldRenderGraph->Generate();
// Add world renderer to default viewport
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
worldRenderer->SetCamera(worldCamera);
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
}
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
{
SHGraphicsGlobalData::Init(device);
InitSceneRenderGraph();
#ifdef SHEDITOR #ifdef SHEDITOR
auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"}); InitEditorRenderGraph();
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
imguiSubpass->AddColorOutput("Present");
#endif #endif
worldRenderGraph->Generate();
// Create Semaphore // Create Semaphore
for (auto& semaHandle : graphSemaphores) for (auto& semaHandle : graphSemaphores)
{ {
semaHandle = device->CreateSemaphore(); semaHandle = device->CreateSemaphore();
} }
}
// Create Debug Renderers void SHGraphicsSystem::InitSubsystems(void) noexcept
/*debugScreenRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph); {
debugScreenRenderer->SetCamera(screenCamera);
debugWorldRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph);
debugWorldRenderer->SetCamera(worldCamera);*/
// Add world renderer to default viewport
worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
worldRenderer->SetCamera(worldCamera);
// TODO: This is VERY temporarily here until a more solid resource management system is implemented
shaderSourceLibrary.Init("../../TempShaderFolder/");
shaderSourceLibrary.LoadShader(0, "TestCubeVs.glsl", SH_SHADER_TYPE::VERTEX, true);
shaderSourceLibrary.LoadShader(1, "TestCubeFs.glsl", SH_SHADER_TYPE::FRAGMENT, true);
shaderModuleLibrary.ImportFromSourceLibrary(device, shaderSourceLibrary);
auto cubeVS = shaderModuleLibrary.GetShaderModule("TestCubeVs.glsl");
auto cubeFS = shaderModuleLibrary.GetShaderModule("TestCubeFs.glsl");
cubeVS->Reflect();
cubeFS->Reflect();
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
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"));
@ -217,6 +238,61 @@ namespace SHADE
postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool);
} }
#ifdef SHEDITOR
void SHGraphicsSystem::InitEditorRenderGraph(void) noexcept
{
auto windowDims = window->GetWindowSize();
// Create Default Viewport
editorViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<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 */
/*---------------------------------------------------------------------------------*/
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -235,12 +311,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();
@ -262,6 +332,9 @@ namespace SHADE
// Bind textures // Bind textures
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
// For every viewport // For every viewport
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex) for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
@ -284,7 +357,7 @@ namespace SHADE
uint32_t h = static_cast<uint32_t>(viewports[vpIndex]->GetHeight()); uint32_t h = static_cast<uint32_t>(viewports[vpIndex]->GetHeight());
currentCmdBuffer->SetViewportScissor (static_cast<float>(w), static_cast<float>(h), w, h); currentCmdBuffer->SetViewportScissor (static_cast<float>(w), static_cast<float>(h), w, h);
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout()); currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::GRAPHICS);
// Bind all the buffers required for meshes // Bind all the buffers required for meshes
for (auto& [buffer, bindingPoint] : MESH_DATA) for (auto& [buffer, bindingPoint] : MESH_DATA)
@ -304,14 +377,29 @@ namespace SHADE
currentCmdBuffer->BindDescriptorSet currentCmdBuffer->BindDescriptorSet
( (
textureDescSet, textureDescSet,
vk::PipelineBindPoint::eGraphics, SH_PIPELINE_TYPE::GRAPHICS,
0, 0,
texDynamicOffset texDynamicOffset
); );
} }
// bind camera data // bind camera data
//renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
#ifdef SHEDITOR
if (renderers[renIndex] == worldRenderer)
{
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
if (editorSystem->editorState != SHEditor::State::PLAY)
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, SHMatrix::Transpose(cameraSystem->GetEditorCamera()->GetProjMatrix() * cameraSystem->GetEditorCamera()->GetViewMatrix()));
else
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
}
else
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
#else
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
#endif
// Draw first // Draw first
renderers[renIndex]->Draw(frameIndex, descPool); renderers[renIndex]->Draw(frameIndex, descPool);
@ -336,14 +424,7 @@ namespace SHADE
} }
} }
} }
void SHGraphicsSystem::Exit(void)
{
}
/*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -408,12 +489,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();
@ -425,9 +500,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();
} }
} }
@ -435,6 +508,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
@ -520,19 +597,19 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Texture Registration Functions */ /* Texture Registration Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHTexture> SHGraphicsSystem::Add(const SHTextureAsset& texAsset) Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset)
{ {
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(texAsset.mipOffsets.size()) }); auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(texAsset.mipOffsets.size()) });
return texLibrary.Add(texAsset, sampler); return texLibrary.Add(texAsset, sampler);
} }
SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets) SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets)
{ {
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(mipOffsets.size()) }); auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(mipOffsets.size()) });
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler); return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler);
} }
void SHGraphicsSystem::Remove(Handle<SHTexture> tex) void SHGraphicsSystem::RemoveTexture(Handle<SHTexture> tex)
{ {
texLibrary.Remove(tex); texLibrary.Remove(tex);
} }
@ -545,43 +622,14 @@ 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);
mousePickSystem->HandleResize();
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 */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHGraphicsSystem::BeginRoutine::BeginRoutine() SHGraphicsSystem::BeginRoutine::BeginRoutine()
: SHSystemRoutine("Graphics System Frame Set Up", false) : SHSystemRoutine("Graphics System Frame Set Up", true)
{} {}
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
@ -593,7 +641,7 @@ namespace SHADE
/* System Routine Functions - RenderRoutine */ /* System Routine Functions - RenderRoutine */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHGraphicsSystem::RenderRoutine::RenderRoutine() SHGraphicsSystem::RenderRoutine::RenderRoutine()
: SHSystemRoutine("Graphics System Render", false) : SHSystemRoutine("Graphics System Render", true)
{} {}
void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept
@ -605,7 +653,7 @@ namespace SHADE
/* System Routine Functions - EndRoutine */ /* System Routine Functions - EndRoutine */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHGraphicsSystem::EndRoutine::EndRoutine() SHGraphicsSystem::EndRoutine::EndRoutine()
: SHSystemRoutine("Graphics System Frame Clean Up", false) : SHSystemRoutine("Graphics System Frame Clean Up", true)
{} {}
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
@ -617,7 +665,7 @@ namespace SHADE
/* System Routine Functions - BatcherDispatcherRoutine */ /* System Routine Functions - BatcherDispatcherRoutine */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHGraphicsSystem::BatcherDispatcherRoutine::BatcherDispatcherRoutine() SHGraphicsSystem::BatcherDispatcherRoutine::BatcherDispatcherRoutine()
: SHSystemRoutine("Graphics System Batcher Dispatcher", false) : SHSystemRoutine("Graphics System Batcher Dispatcher", true)
{} {}
void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept
@ -648,5 +696,70 @@ 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);
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
#ifdef SHEDITOR
cameraSystem->GetEditorCamera()->SetWidth(static_cast<float>(resizeWidth));
cameraSystem->GetEditorCamera()->SetHeight(static_cast<float>(resizeHeight));
#else
#endif
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

@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited.
#include <array> #include <array>
// Project Includes // Project Includes
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
#include "Graphics/SHVulkanIncludes.h" #include "Graphics/SHVulkanIncludes.h"
#include "Graphics/MiddleEnd/PerFrame/SHRenderContext.h" #include "Graphics/MiddleEnd/PerFrame/SHRenderContext.h"
#include "Graphics/RenderGraph/SHRenderGraph.h" #include "Graphics/RenderGraph/SHRenderGraph.h"
@ -67,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
{ {
@ -221,8 +231,8 @@ namespace SHADE
*/ */
/*******************************************************************************/ /*******************************************************************************/
Handle<SHTexture> Add(const SHTextureAsset& texAsset); Handle<SHTexture> AddTexture(const SHTextureAsset& texAsset);
Handle<SHTexture> Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets); Handle<SHTexture> AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets);
/*******************************************************************************/ /*******************************************************************************/
/*! /*!
@ -236,7 +246,7 @@ namespace SHADE
*/ */
/*******************************************************************************/ /*******************************************************************************/
void Remove(Handle<SHTexture> tex); void RemoveTexture(Handle<SHTexture> tex);
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -252,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();
@ -269,7 +280,10 @@ namespace SHADE
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;}
#ifdef SHEDITOR
Handle<SHViewport> GetEditorViewport () const {return editorViewport;};
#endif
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;}; Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
//SHRenderGraph const& GetRenderGraph(void) const noexcept; //SHRenderGraph const& GetRenderGraph(void) const noexcept;
@ -278,6 +292,7 @@ namespace SHADE
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -298,13 +313,19 @@ namespace SHADE
SHWindow* window = nullptr; SHWindow* window = nullptr;
// Middle End Resources // Middle End Resources
ResourceManager resourceManager; SHResourceHub 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
@ -331,5 +352,7 @@ namespace SHADE
Handle<SHMousePickSystem> mousePickSystem; Handle<SHMousePickSystem> mousePickSystem;
Handle<SHPostOffscreenRenderSystem> postOffscreenRender; Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
uint32_t resizeWidth;
uint32_t resizeHeight;
}; };
} }

View File

@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes // STL Includes
#include <unordered_map> #include <unordered_map>
// Project Includes // Project Includes
#include "Resource/Handle.h" #include "Resource/SHHandle.h"
#include "SHCommonTypes.h" #include "SHCommonTypes.h"
namespace SHADE namespace SHADE

Some files were not shown because too many files have changed in this diff Show More