Merge branch 'main' into SP3-141-Camera-System
This commit is contained in:
commit
33b173ab9e
|
@ -362,3 +362,5 @@ MigrationBackup/
|
||||||
*.csproj
|
*.csproj
|
||||||
|
|
||||||
*.filters
|
*.filters
|
||||||
|
|
||||||
|
Assets/Editor/Layouts/UserLayout.ini
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: Cube.003
|
||||||
|
ID: 110152941
|
||||||
|
Type:
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: Cube.012
|
||||||
|
ID: 107348815
|
||||||
|
Type:
|
|
@ -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
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: RaccoonPreTexturedVer1_Base9
|
||||||
|
ID: 91918845
|
||||||
|
Type:
|
Binary file not shown.
|
@ -19,10 +19,11 @@ echo "L - yamlcpp"
|
||||||
echo "M - SDL"
|
echo "M - SDL"
|
||||||
echo "N - dotnet"
|
echo "N - dotnet"
|
||||||
echo "O - tinyddsloader"
|
echo "O - tinyddsloader"
|
||||||
|
echo "P - fmod"
|
||||||
echo ---------------------------------------------------
|
echo ---------------------------------------------------
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
choice /C ABCDEFGHIJKLMNO /T 10 /D A
|
choice /C ABCDEFGHIJKLMNOP /T 10 /D A
|
||||||
set _e=%ERRORLEVEL%
|
set _e=%ERRORLEVEL%
|
||||||
|
|
||||||
if %_e%==1 goto VMA
|
if %_e%==1 goto VMA
|
||||||
|
@ -40,6 +41,7 @@ if %_e%==12 goto yamlcpp
|
||||||
if %_e%==13 goto SDL
|
if %_e%==13 goto SDL
|
||||||
if %_e%==14 goto dotnet
|
if %_e%==14 goto dotnet
|
||||||
if %_e%==15 goto tinyddsloader
|
if %_e%==15 goto tinyddsloader
|
||||||
|
if %_e%==16 goto fmod
|
||||||
|
|
||||||
:VMA
|
:VMA
|
||||||
echo -----------------------VMA----------------------------
|
echo -----------------------VMA----------------------------
|
||||||
|
@ -145,6 +147,12 @@ if %_e%==14 (goto :done) else (goto :tinyddsloader)
|
||||||
echo --------------------tinyddsloader-------------------------
|
echo --------------------tinyddsloader-------------------------
|
||||||
rmdir "Dependencies/tinyddsloader" /S /Q
|
rmdir "Dependencies/tinyddsloader" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/tinyddsloader.git "Dependencies/tinyddsloader"
|
git clone https://github.com/SHADE-DP/tinyddsloader.git "Dependencies/tinyddsloader"
|
||||||
|
if %_e%==15 (goto :done) else (goto :fmod)
|
||||||
|
|
||||||
|
:fmod
|
||||||
|
echo --------------------fmod-------------------------
|
||||||
|
rmdir "Dependencies/fmod" /S /Q
|
||||||
|
git clone https://github.com/SHADE-DP/FMOD.git "Dependencies/fmod"
|
||||||
|
|
||||||
:done
|
:done
|
||||||
echo DONE!
|
echo DONE!
|
||||||
|
|
|
@ -15,3 +15,4 @@ IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
|
||||||
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
||||||
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
||||||
IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader"
|
IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader"
|
||||||
|
IncludeDir["fmod"] = "%{wks.location}\\Dependencies\\fmod"
|
|
@ -30,12 +30,14 @@ project "SHADE_Application"
|
||||||
|
|
||||||
externalincludedirs
|
externalincludedirs
|
||||||
{
|
{
|
||||||
"%{IncludeDir.spdlog}/include",
|
"%{IncludeDir.RTTR}\\include",
|
||||||
"%{IncludeDir.VULKAN}/include",
|
"%{IncludeDir.fmod}/include",
|
||||||
"%{IncludeDir.VMA}/include",
|
|
||||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||||
"%{IncludeDir.RTTR}/include",
|
"%{IncludeDir.VMA}/include",
|
||||||
"%{IncludeDir.tinyddsloader}"
|
"%{IncludeDir.VULKAN}/include",
|
||||||
|
"%{IncludeDir.spdlog}/include",
|
||||||
|
"%{IncludeDir.tinyddsloader}",
|
||||||
|
"%{IncludeDir.reactphysics3d}\\include"
|
||||||
}
|
}
|
||||||
|
|
||||||
externalwarnings "Off"
|
externalwarnings "Off"
|
||||||
|
@ -56,7 +58,7 @@ project "SHADE_Application"
|
||||||
libdirs
|
libdirs
|
||||||
{
|
{
|
||||||
"%{IncludeDir.spdlog}/lib",
|
"%{IncludeDir.spdlog}/lib",
|
||||||
"%{IncludeDir.SDL}/lib",
|
"%{IncludeDir.SDL}/lib"
|
||||||
}
|
}
|
||||||
|
|
||||||
defines
|
defines
|
||||||
|
@ -66,9 +68,16 @@ project "SHADE_Application"
|
||||||
|
|
||||||
disablewarnings
|
disablewarnings
|
||||||
{
|
{
|
||||||
"4251"
|
"4251",
|
||||||
|
"26812",
|
||||||
|
"26439",
|
||||||
|
"26451",
|
||||||
|
"26437",
|
||||||
|
"4275"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linkoptions { "-IGNORE:4006" }
|
||||||
|
|
||||||
warnings 'Extra'
|
warnings 'Extra'
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
|
@ -81,4 +90,4 @@ project "SHADE_Application"
|
||||||
|
|
||||||
filter "configurations:Publish"
|
filter "configurations:Publish"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE"}
|
defines{"_RELEASE", "_PUBLISH"}
|
||||||
|
|
|
@ -14,22 +14,34 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ratio>
|
#include <ratio>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#define SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN 1
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
#include "Scripting/SHScriptEngine.h"
|
|
||||||
#include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h"
|
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
|
||||||
#include "Scene/SHSceneManager.h"
|
|
||||||
#include "Math/Transform/SHTransformSystem.h"
|
|
||||||
#include "Input/SHInputManagerSystem.h"
|
|
||||||
|
|
||||||
#include "Scenes/SBTestScene.h"
|
#include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h"
|
||||||
|
|
||||||
|
// Managers
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
|
||||||
|
// Systems
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
#include "Physics/SHPhysicsSystem.h"
|
||||||
|
#include "Math/Transform/SHTransformSystem.h"
|
||||||
|
#include "Input/SHInputManager.h"
|
||||||
|
#include "FRC/SHFramerateController.h"
|
||||||
|
#include "AudioSystem/SHAudioSystem.h"
|
||||||
|
|
||||||
|
// Components
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
|
#include "Scenes/SBTestScene.h"
|
||||||
|
|
||||||
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
namespace Sandbox
|
namespace Sandbox
|
||||||
|
@ -44,93 +56,112 @@ namespace Sandbox
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Set working directory
|
// Set working directory
|
||||||
SHADE::SHFileUtilities::SetWorkDirToExecDir();
|
SHFileUtilities::SetWorkDirToExecDir();
|
||||||
|
|
||||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||||
|
|
||||||
// Create Systems
|
// Create Systems
|
||||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
SHSystemManager::CreateSystem<SHGraphicsSystem>();
|
||||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>();
|
SHSystemManager::CreateSystem<SHScriptEngine>();
|
||||||
// TODO(Diren): Create Physics System here
|
SHSystemManager::CreateSystem<SHPhysicsSystem>();
|
||||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
|
SHSystemManager::CreateSystem<SHTransformSystem>();
|
||||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
||||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>();
|
SHSystemManager::CreateSystem<SHAudioSystem>();
|
||||||
|
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||||
|
SHSystemManager::CreateSystem<SHEditor>();
|
||||||
|
SHSystemManager::GetSystem<SHEditor>()->SetSDLWindow(sdlWindow);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Create Routines
|
// Create Routines
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameSetUpRoutine>();
|
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameSetUpRoutine>();
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::UpdateRoutine>();
|
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::UpdateRoutine>();
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::LateUpdateRoutine>();
|
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::LateUpdateRoutine>();
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameCleanUpRoutine>();
|
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameCleanUpRoutine>();
|
||||||
|
|
||||||
// TODO(Diren): Register Physics System & Routines here
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
||||||
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
||||||
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
||||||
|
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHTransformSystem, SHADE::SHTransformSystem::TransformUpdateRoutine>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformUpdateRoutine>();
|
||||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
|
||||||
|
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BatcherDispatcherRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BeginRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>();
|
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>();
|
|
||||||
|
|
||||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
|
#ifdef SHEDITOR
|
||||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
SHSystemManager::RegisterRoutine<SHEditor, SHEditor::EditorRoutine>();
|
||||||
|
#endif
|
||||||
|
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHInputManagerSystem, SHADE::SHInputManagerSystem::InputManagerRoutine>();
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::RenderRoutine>();
|
||||||
|
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::EndRoutine>();
|
||||||
|
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHRigidBodyComponent>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHColliderComponent>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHTransformComponent>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHRenderable>();
|
||||||
|
|
||||||
//TODO: REMOVE AFTER PRESENTATION
|
//TODO: REMOVE AFTER PRESENTATION
|
||||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
//SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
||||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
|
//SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
|
||||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
|
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
|
||||||
|
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
|
||||||
|
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
|
||||||
//TODO: REMOVE AFTER PRESENTATION
|
//TODO: REMOVE AFTER PRESENTATION
|
||||||
|
|
||||||
|
|
||||||
|
auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||||
|
auto id2 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||||
|
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||||
|
|
||||||
|
SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>();
|
||||||
|
|
||||||
// Set up graphics system and windows
|
// Set up graphics system and windows
|
||||||
graphicsSystem->SetWindow(&window);
|
graphicsSystem->SetWindow(&window);
|
||||||
|
|
||||||
SHADE::SHSystemManager::Init();
|
SHSystemManager::Init();
|
||||||
#ifdef SHEDITOR
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
|
||||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
|
||||||
SHADE::SHEditor::Initialise(sdlWindow);
|
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
||||||
|
|
||||||
|
SHFrameRateController::UpdateFRC();
|
||||||
|
|
||||||
|
SHAssetManager::Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBApplication::Update(void)
|
void SBApplication::Update(void)
|
||||||
{
|
{
|
||||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::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();
|
||||||
|
SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime());
|
||||||
SHSceneManager::UpdateSceneManager();
|
SHSceneManager::UpdateSceneManager();
|
||||||
SHSceneManager::SceneUpdate(1/60.0f);
|
|
||||||
//#ifdef SHEDITOR
|
|
||||||
//#endif
|
|
||||||
graphicsSystem->BeginRender();
|
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SHADE::SHEditor::Update(0.16f);
|
if(editor->editorState == SHEditor::State::PLAY)
|
||||||
|
SHSceneManager::SceneUpdate(0.016f);
|
||||||
#endif
|
#endif
|
||||||
|
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
||||||
graphicsSystem->Run(1.0f);
|
editor->PollPicking();
|
||||||
graphicsSystem->EndRender();
|
|
||||||
|
|
||||||
SHADE::SHSystemManager::RunRoutines(false, 0.016f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finish all graphics jobs first
|
||||||
|
graphicsSystem->AwaitGraphicsExecution();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SBApplication::Exit(void)
|
void SBApplication::Exit(void)
|
||||||
{
|
{
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SHADE::SHEditor::Exit();
|
|
||||||
SDL_DestroyWindow(sdlWindow);
|
SDL_DestroyWindow(sdlWindow);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SHSceneManager::Exit();
|
SHSceneManager::Exit();
|
||||||
SHADE::SHSystemManager::Exit();
|
SHSystemManager::Exit();
|
||||||
|
SHAssetManager::Unload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
|
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
|
|
||||||
|
@ -35,12 +38,13 @@ namespace Sandbox
|
||||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||||
// Create temp meshes
|
// Create temp meshes
|
||||||
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
|
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
|
||||||
//graphicsSystem->BuildMeshBuffers();
|
|
||||||
|
|
||||||
//Test Racoon mesh
|
//Test Racoon mesh
|
||||||
auto meshes = SHADE::SHAssetManager::GetAllMeshes();
|
auto meshes = SHADE::SHAssetManager::GetAllMeshes();
|
||||||
std::vector<Handle<SHMesh>> handles;
|
std::vector<Handle<SHMesh>> handles;
|
||||||
for (auto const& mesh : meshes)
|
for (auto const& mesh : meshes)
|
||||||
|
{
|
||||||
|
if (mesh.header.meshName == "Cube.012")
|
||||||
{
|
{
|
||||||
handles.push_back(graphicsSystem->AddMesh(
|
handles.push_back(graphicsSystem->AddMesh(
|
||||||
mesh.header.vertexCount,
|
mesh.header.vertexCount,
|
||||||
|
@ -52,72 +56,132 @@ namespace Sandbox
|
||||||
mesh.indices.data()
|
mesh.indices.data()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
graphicsSystem->BuildMeshBuffers();
|
graphicsSystem->BuildMeshBuffers();
|
||||||
|
|
||||||
//Test Textures
|
// Load Textures
|
||||||
auto textures{ SHADE::SHAssetManager::GetAllTextures() };
|
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();
|
||||||
|
auto customMat = graphicsSystem->AddMaterialInstanceCopy(matInst);
|
||||||
|
customMat->SetProperty("data.color", SHVec4(0.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
customMat->SetProperty("data.textureIndex", 0);
|
||||||
|
customMat->SetProperty("data.alpha", 0.1f);
|
||||||
|
|
||||||
// Create Stress Test Objects
|
// Create Stress Test Objects
|
||||||
static const SHVec3 TEST_OBJ_SCALE = { 0.2f, 0.2f, 0.2f };
|
static const SHVec3 TEST_OBJ_SCALE = SHVec3::One * 0.5f;
|
||||||
constexpr int NUM_ROWS = 1;
|
constexpr int NUM_ROWS = 10;
|
||||||
constexpr int NUM_COLS = 1;
|
constexpr int NUM_COLS = 10;
|
||||||
static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f };
|
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 ), 0.0f, 0.0f };
|
static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f };
|
||||||
//for (int z = 0; z < NUM_ROWS; ++z)
|
|
||||||
//for (int x = 0; x < NUM_COLS; ++x)
|
|
||||||
//{
|
|
||||||
// auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
|
||||||
// auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
|
||||||
// auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
|
||||||
|
|
||||||
// renderable.Mesh = handles.front();
|
for (int y = 0; y < NUM_ROWS; ++y)
|
||||||
// renderable.SetMaterial(matInst);
|
for (int x = 0; x < NUM_COLS; ++x)
|
||||||
|
{
|
||||||
// // Set initial positions
|
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
|
||||||
// transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, 0.0f, z * TEST_OBJ_SPACING.z });
|
|
||||||
// //transform.SetLocalScale(TEST_OBJ_SCALE);
|
|
||||||
|
|
||||||
// stressTestObjects.emplace_back(entity);
|
|
||||||
//}
|
|
||||||
|
|
||||||
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
|
||||||
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||||
|
auto& collider = *SHComponentManager::GetComponent_s<SHColliderComponent>(entity);
|
||||||
|
|
||||||
renderable.Mesh = handles.front();
|
//renderable.Mesh = handles.front();
|
||||||
renderable.SetMaterial(matInst);
|
renderable.Mesh = CUBE_MESH;
|
||||||
|
renderable.SetMaterial(customMat);
|
||||||
|
|
||||||
//transform.SetLocalScale(TEST_OBJ_SCALE);
|
if (y == 50)
|
||||||
|
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
//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({-1.0f, -1.0f, -1.0f});
|
||||||
|
transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber());
|
||||||
|
transform.SetWorldScale(TEST_OBJ_SCALE);
|
||||||
|
|
||||||
|
if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN)
|
||||||
|
collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero);
|
||||||
|
else
|
||||||
|
collider.AddBoundingSphere(0.5f, SHVec3::Zero);
|
||||||
|
|
||||||
stressTestObjects.emplace_back(entity);
|
stressTestObjects.emplace_back(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto raccoonSpin = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin);
|
||||||
|
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonSpin);
|
||||||
|
|
||||||
|
renderable.Mesh = handles.front();
|
||||||
|
renderable.SetMaterial(customMat);
|
||||||
|
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
|
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||||
|
renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
||||||
|
|
||||||
|
transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f });
|
||||||
|
transform.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
||||||
|
|
||||||
|
auto floor = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
|
||||||
|
auto& floorRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(floor);
|
||||||
|
auto& floorTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(floor);
|
||||||
|
auto& floorRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(floor);
|
||||||
|
auto& floorCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(floor);
|
||||||
|
|
||||||
|
floorRenderable.Mesh = CUBE_MESH;
|
||||||
|
floorRenderable.SetMaterial(customMat);
|
||||||
|
floorRenderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
|
floorTransform.SetWorldScale({ 7.5f, 0.5f, 7.5 });
|
||||||
|
floorTransform.SetWorldPosition({ 0.0f, -3.0f, -5.0f });
|
||||||
|
|
||||||
|
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
|
||||||
|
|
||||||
|
auto* floorBox = floorCollider.AddBoundingBox();
|
||||||
|
floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f);
|
||||||
|
|
||||||
// Create blank entity with a script
|
// Create blank entity with a script
|
||||||
testObj = SHADE::SHEntityManager::CreateEntity();
|
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
//auto& testObjRenderable = *SHComponentManager::GetComponent<SHRenderable>(testObj);
|
||||||
|
//testObjRenderable.Mesh = CUBE_MESH;
|
||||||
|
//testObjRenderable.SetMaterial(matInst);
|
||||||
|
|
||||||
|
|
||||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||||
scriptEngine->AddScript(testObj, "TestScript");
|
scriptEngine->AddScript(raccoonSpin, "RaccoonSpin");
|
||||||
|
|
||||||
|
auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
|
||||||
|
auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
|
||||||
|
|
||||||
|
renderableShowcase.Mesh = handles.front();
|
||||||
|
renderableShowcase.SetMaterial(customMat);
|
||||||
|
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
|
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||||
|
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
||||||
|
|
||||||
|
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
|
||||||
|
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
||||||
|
scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBTestScene::Update(float dt)
|
void SBTestScene::Update(float dt)
|
||||||
{
|
{
|
||||||
/*static float rotation = 0.0f;
|
static float rotation = 0.0f;
|
||||||
|
|
||||||
auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(testObj);
|
//auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(testObj);
|
||||||
|
|
||||||
transform.SetLocalRotation(rotation, 0.0f, 0.0f);
|
//transform.SetWorldPosition({1.0f, 1.0f, -1.0f});
|
||||||
rotation += dt * 10.0f;*/
|
//transform.SetWorldRotation(0.0f, 0.0f + rotation, 0.0f);
|
||||||
/*static float rotation = 0.0f;
|
//rotation += dt * 0.2f;
|
||||||
|
|
||||||
auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(stressTestObjects[0]);
|
|
||||||
|
|
||||||
transform.SetWorldPosition({rotation, 0.0f, 0.0f});
|
|
||||||
rotation += dt * 10.0f;*/
|
|
||||||
|
|
||||||
// Destroy entity if space is pressed
|
// Destroy entity if space is pressed
|
||||||
if (GetKeyState(VK_SPACE) & 0x8000)
|
if (GetKeyState(VK_SPACE) & 0x8000)
|
||||||
{
|
{
|
||||||
|
rotation = 0.0f;
|
||||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||||
scriptEngine->RemoveAllScripts(testObj);
|
scriptEngine->RemoveAllScripts(testObj);
|
||||||
}
|
}
|
||||||
|
@ -125,6 +189,7 @@ namespace Sandbox
|
||||||
|
|
||||||
void SBTestScene::Render()
|
void SBTestScene::Render()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBTestScene::Unload()
|
void SBTestScene::Unload()
|
||||||
|
@ -135,8 +200,4 @@ namespace Sandbox
|
||||||
{
|
{
|
||||||
//SHSerialization::SerializeScene("resources/scenes/Scene01.SHADE");
|
//SHSerialization::SerializeScene("resources/scenes/Scene01.SHADE");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,8 @@ project "SHADE_Engine"
|
||||||
"%{IncludeDir.VULKAN}\\include",
|
"%{IncludeDir.VULKAN}\\include",
|
||||||
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
|
"%{IncludeDir.VULKAN}\\Source\\SPIRV-Reflect",
|
||||||
"%{IncludeDir.dotnet}\\include",
|
"%{IncludeDir.dotnet}\\include",
|
||||||
"%{IncludeDir.tinyddsloader}"
|
"%{IncludeDir.tinyddsloader}",
|
||||||
|
"%{IncludeDir.fmod}\\include"
|
||||||
}
|
}
|
||||||
|
|
||||||
externalwarnings "Off"
|
externalwarnings "Off"
|
||||||
|
@ -55,7 +56,8 @@ project "SHADE_Engine"
|
||||||
"%{IncludeDir.assimp}/lib/Release",
|
"%{IncludeDir.assimp}/lib/Release",
|
||||||
"%{IncludeDir.RTTR}/lib",
|
"%{IncludeDir.RTTR}/lib",
|
||||||
"%{IncludeDir.SDL}/lib",
|
"%{IncludeDir.SDL}/lib",
|
||||||
"%{IncludeDir.spdlog}/lib"
|
"%{IncludeDir.spdlog}/lib",
|
||||||
|
"%{IncludeDir.fmod}/lib"
|
||||||
}
|
}
|
||||||
|
|
||||||
links
|
links
|
||||||
|
@ -74,9 +76,16 @@ project "SHADE_Engine"
|
||||||
|
|
||||||
disablewarnings
|
disablewarnings
|
||||||
{
|
{
|
||||||
"4251"
|
"4251",
|
||||||
|
"26812",
|
||||||
|
"26439",
|
||||||
|
"26451",
|
||||||
|
"26437",
|
||||||
|
"4275"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linkoptions { "-IGNORE:4006" }
|
||||||
|
|
||||||
defines
|
defines
|
||||||
{
|
{
|
||||||
"_LIB",
|
"_LIB",
|
||||||
|
@ -108,9 +117,30 @@ project "SHADE_Engine"
|
||||||
}
|
}
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\""}
|
postbuildcommands
|
||||||
|
{
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\""
|
||||||
|
}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
|
postbuildcommands
|
||||||
|
{
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
|
||||||
|
}
|
||||||
|
|
||||||
|
filter "configurations:Publish"
|
||||||
|
postbuildcommands
|
||||||
|
{
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
|
||||||
|
}
|
||||||
|
|
||||||
|
filter "configurations:Publish"
|
||||||
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""}
|
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""}
|
||||||
|
|
||||||
warnings 'Extra'
|
warnings 'Extra'
|
||||||
|
@ -119,22 +149,22 @@ project "SHADE_Engine"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
defines {"_DEBUG", "SHEDITOR"}
|
defines {"_DEBUG", "SHEDITOR"}
|
||||||
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
||||||
--links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE", "SHEDITOR"}
|
defines{"_RELEASE", "SHEDITOR"}
|
||||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||||
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
||||||
|
|
||||||
filter "configurations:Publish"
|
filter "configurations:Publish"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE"}
|
defines{"_RELEASE", "_PUBLISH"}
|
||||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||||
excludes
|
excludes
|
||||||
{
|
{
|
||||||
"%{prj.location}/src/Editor/**.cpp",
|
-- "%{prj.location}/src/Editor/**.cpp",
|
||||||
"%{prj.location}/src/Editor/**.h",
|
-- "%{prj.location}/src/Editor/**.h",
|
||||||
"%{prj.location}/src/Editor/**.hpp",
|
-- "%{prj.location}/src/Editor/**.hpp",
|
||||||
}
|
}
|
||||||
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
|
@ -1,25 +1,37 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHMeshAsset.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Struct to contain ready data for loading into GPU. Also used for
|
||||||
|
* compilation into binary files
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Math/SHMath.h"
|
#include "Math/SHMath.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SHMeshAssetHeader
|
struct SH_API SHMeshAssetHeader
|
||||||
{
|
{
|
||||||
uint32_t vertexCount;
|
uint32_t vertexCount;
|
||||||
uint32_t indexCount;
|
uint32_t indexCount;
|
||||||
|
std::string meshName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHMeshAsset
|
struct SH_API SHMeshAsset
|
||||||
{
|
{
|
||||||
bool compiled;
|
bool compiled;
|
||||||
bool changed;
|
bool changed;
|
||||||
|
|
||||||
SHMeshAssetHeader header;
|
SHMeshAssetHeader header;
|
||||||
|
|
||||||
std::string meshName;
|
|
||||||
|
|
||||||
std::vector<SHVec3> vertexPosition;
|
std::vector<SHVec3> vertexPosition;
|
||||||
std::vector<SHVec3> vertexTangent;
|
std::vector<SHVec3> vertexTangent;
|
||||||
std::vector<SHVec3> vertexNormal;
|
std::vector<SHVec3> vertexNormal;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tinyddsloader.h"
|
#include "tinyddsloader.h"
|
||||||
|
|
||||||
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
struct SHTextureAsset
|
struct SHTextureAsset
|
||||||
{
|
{
|
||||||
|
bool compiled;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
uint32_t numBytes;
|
uint32_t numBytes;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
|
@ -18,7 +18,8 @@ namespace SHADE
|
||||||
SHTexture::PixelChannel const * pixelData;
|
SHTexture::PixelChannel const * pixelData;
|
||||||
|
|
||||||
SHTextureAsset()
|
SHTextureAsset()
|
||||||
: numBytes{ 0 },
|
: compiled{ false },
|
||||||
|
numBytes{ 0 },
|
||||||
width{ 0 },
|
width{ 0 },
|
||||||
height{ 0 },
|
height{ 0 },
|
||||||
format{ SHTexture::TextureFormat::eUndefined },
|
format{ SHTexture::TextureFormat::eUndefined },
|
||||||
|
@ -26,7 +27,8 @@ namespace SHADE
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHTextureAsset(SHTextureAsset const& rhs)
|
SHTextureAsset(SHTextureAsset const& rhs)
|
||||||
: numBytes{ rhs.numBytes },
|
: compiled{ false },
|
||||||
|
numBytes{ rhs.numBytes },
|
||||||
width{ rhs.width },
|
width{ rhs.width },
|
||||||
height{ rhs.height },
|
height{ rhs.height },
|
||||||
format{ rhs.format },
|
format{ rhs.format },
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHMeshCompiler.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Library to write data in SHMeshAsset into binary file for faster
|
||||||
|
* loading in the future
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "SHMeshCompiler.h"
|
||||||
|
#include "Graphics/MiddleEnd/Meshes/SHMeshData.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
std::string SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
|
||||||
|
{
|
||||||
|
std::string newPath{ path.string() };
|
||||||
|
newPath = newPath.substr(0, newPath.find_last_of('/') + 1);
|
||||||
|
newPath += asset.header.meshName + MESH_EXTENSION;
|
||||||
|
|
||||||
|
std::ofstream file{ newPath, std::ios::out | std::ios::binary | std::ios::trunc };
|
||||||
|
if (!file.is_open())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<const char*>(&(asset.header.indexCount)),
|
||||||
|
sizeof(uint32_t)
|
||||||
|
);
|
||||||
|
|
||||||
|
auto const vertexVec3Byte {sizeof(SHVec3) * asset.header.vertexCount};
|
||||||
|
auto const vertexVec2Byte {sizeof(SHVec2) * asset.header.vertexCount};
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.vertexPosition.data()),
|
||||||
|
vertexVec3Byte
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.vertexTangent.data()),
|
||||||
|
vertexVec3Byte
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.vertexNormal.data()),
|
||||||
|
vertexVec3Byte
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.texCoords.data()),
|
||||||
|
vertexVec2Byte
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.indices.data()),
|
||||||
|
sizeof(uint32_t) * asset.header.indexCount
|
||||||
|
);
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return newPath;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHMeshCompiler.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Library to write data in SHMeshAsset into binary file for faster
|
||||||
|
* loading in the future
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "../Asset Types/SHMeshAsset.h"
|
||||||
|
#include "../SHAssetMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHMeshCompiler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
static std::string CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,12 +1,25 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHMeshLoader.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Implementation for Mesh loader. Accounts for custom binary format
|
||||||
|
* as well as GLTF file format.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "SHpch.h"
|
||||||
#include "SHMeshLoader.h"
|
#include "SHMeshLoader.h"
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
Assimp::Importer SHMeshLoader::aiImporter;
|
Assimp::Importer SHMeshLoader::aiImporter;
|
||||||
|
|
||||||
void SHMeshLoader::ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes)
|
void SHMeshLoader::ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes) noexcept
|
||||||
{
|
{
|
||||||
for (size_t i {0}; i < node.mNumMeshes; ++i)
|
for (size_t i {0}; i < node.mNumMeshes; ++i)
|
||||||
{
|
{
|
||||||
|
@ -20,15 +33,14 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHMeshAsset SHMeshLoader::ProcessMesh(aiMesh const& mesh, aiScene const& scene)
|
SHMeshAsset SHMeshLoader::ProcessMesh(aiMesh const& mesh, aiScene const& scene) noexcept
|
||||||
{
|
{
|
||||||
(void)scene;
|
(void)scene;
|
||||||
|
|
||||||
SHMeshAsset result
|
SHMeshAsset result
|
||||||
{
|
{
|
||||||
.compiled { false},
|
.compiled { false},
|
||||||
.changed { false },
|
.changed { false }
|
||||||
.meshName { mesh.mName.C_Str() }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i{0}; i < mesh.mNumVertices; ++i)
|
for (size_t i{0}; i < mesh.mNumVertices; ++i)
|
||||||
|
@ -79,26 +91,22 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.header.vertexCount = result.vertexPosition.size();
|
result.header.vertexCount = static_cast<uint32_t>(result.vertexPosition.size());
|
||||||
result.header.indexCount = result.indices.size();
|
result.header.indexCount = static_cast<uint32_t>(result.indices.size());
|
||||||
|
result.header.meshName = mesh.mName.C_Str();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHMeshLoader::LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path)
|
void SHMeshLoader::LoadExternal(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept
|
||||||
{
|
{
|
||||||
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
|
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
|
||||||
aiProcess_Triangulate
|
aiProcess_Triangulate // Make sure we get triangles rather than nvert polygons
|
||||||
// Make sure we get triangles rather than nvert polygons
|
|
||||||
| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
|
| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
|
||||||
| aiProcess_TransformUVCoords
|
| aiProcess_TransformUVCoords // preprocess UV transformations (scaling, translation ...)
|
||||||
// preprocess UV transformations (scaling, translation ...)
|
| aiProcess_FindInstances // search for instanced meshes and remove them by references to one master
|
||||||
| aiProcess_FindInstances
|
| aiProcess_CalcTangentSpace // calculate tangents and bitangents if possible
|
||||||
// search for instanced meshes and remove them by references to one master
|
| aiProcess_JoinIdenticalVertices // join identical vertices/ optimize indexing
|
||||||
| aiProcess_CalcTangentSpace
|
|
||||||
// calculate tangents and bitangents if possible
|
|
||||||
| aiProcess_JoinIdenticalVertices
|
|
||||||
// join identical vertices/ optimize indexing
|
|
||||||
| aiProcess_RemoveRedundantMaterials // remove redundant materials
|
| aiProcess_RemoveRedundantMaterials // remove redundant materials
|
||||||
| aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors
|
| aiProcess_FindInvalidData // detect invalid model data, such as invalid normal vectors
|
||||||
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
|
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
|
||||||
|
@ -107,8 +115,9 @@ namespace SHADE
|
||||||
if (!scene || !scene->HasMeshes())
|
if (!scene || !scene->HasMeshes())
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string());
|
SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string());
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO MATERIALS FROM MESHES
|
//TODO MATERIALS FROM MESHES
|
||||||
//if (scene->HasMaterials())
|
//if (scene->HasMaterials())
|
||||||
//{
|
//{
|
||||||
|
@ -123,7 +132,100 @@ namespace SHADE
|
||||||
//}
|
//}
|
||||||
|
|
||||||
ProcessNode(*scene->mRootNode, *scene, meshes);
|
ProcessNode(*scene->mRootNode, *scene, meshes);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
void SHMeshLoader::LoadSHMesh(SHMeshAsset& mesh, AssetPath path) noexcept
|
||||||
|
{
|
||||||
|
std::ifstream file{ path.string(), std::ios::in | std::ios::binary };
|
||||||
|
if (!file.is_open())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string name{ path.stem().string() };
|
||||||
|
|
||||||
|
file.seekg(0);
|
||||||
|
|
||||||
|
uint32_t vertCount, indexCount;
|
||||||
|
std::vector<SHVec3> vertPos, vertTan, vertNorm;
|
||||||
|
std::vector<SHVec2> texCoord;
|
||||||
|
std::vector<uint32_t> indices;
|
||||||
|
|
||||||
|
file.read(reinterpret_cast<char*>(&vertCount), sizeof(uint32_t));
|
||||||
|
file.read(reinterpret_cast<char*>(&indexCount), sizeof(uint32_t));
|
||||||
|
|
||||||
|
auto const vertexVec3Byte{ sizeof(SHVec3) * vertCount };
|
||||||
|
auto const vertexVec2Byte{ sizeof(SHVec2) * vertCount };
|
||||||
|
|
||||||
|
vertPos.resize(vertCount);
|
||||||
|
vertTan.resize(vertCount);
|
||||||
|
vertNorm.resize(vertCount);
|
||||||
|
texCoord.resize(vertCount);
|
||||||
|
indices.resize(indexCount);
|
||||||
|
|
||||||
|
file.read(reinterpret_cast<char *>(vertPos.data()), vertexVec3Byte);
|
||||||
|
file.read(reinterpret_cast<char *>(vertTan.data()), vertexVec3Byte);
|
||||||
|
file.read(reinterpret_cast<char *>(vertNorm.data()), vertexVec3Byte);
|
||||||
|
file.read(reinterpret_cast<char *>(texCoord.data()), vertexVec2Byte);
|
||||||
|
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.changed = false;
|
||||||
|
|
||||||
|
mesh.header.indexCount = indexCount;
|
||||||
|
mesh.header.vertexCount = vertCount;
|
||||||
|
mesh.header.meshName = name;
|
||||||
|
|
||||||
|
mesh.vertexPosition = std::move(vertPos);
|
||||||
|
mesh.vertexTangent = std::move(vertTan);
|
||||||
|
mesh.vertexNormal = std::move(vertNorm);
|
||||||
|
mesh.texCoords = std::move(texCoord);
|
||||||
|
mesh.indices = std::move(indices);
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMeshLoader::LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept
|
||||||
|
{
|
||||||
|
if (path.extension().string() == GLTF_EXTENSION)
|
||||||
|
{
|
||||||
|
LoadExternal(meshes, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
meshes.emplace_back();
|
||||||
|
LoadSHMesh(meshes.back(), path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHMeshLoader.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Library to load gltf mesh files and custom binary format
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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
|
#pragma once
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
@ -12,10 +23,14 @@ namespace SHADE
|
||||||
private:
|
private:
|
||||||
static Assimp::Importer aiImporter;
|
static Assimp::Importer aiImporter;
|
||||||
|
|
||||||
static void ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes);
|
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 SHMeshAsset ProcessMesh(aiMesh const& mesh, aiScene const& scene);
|
|
||||||
public:
|
public:
|
||||||
static bool LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path);
|
static void LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
|
||||||
|
static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,48 +0,0 @@
|
||||||
#include "SHpch.h"
|
|
||||||
#include "SHMeshWriter.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
void SHADE::SHMeshWriter::WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
|
|
||||||
{
|
|
||||||
std::ofstream file{path, std::ios::out | std::ios::binary};
|
|
||||||
if (!file.is_open())
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
|
|
||||||
}
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
|
|
||||||
sizeof(uint32_t)
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<const char*>(&(asset.header.indexCount)),
|
|
||||||
sizeof(uint32_t)
|
|
||||||
);
|
|
||||||
|
|
||||||
auto const vertexVec3Byte {sizeof(SHVec3) * asset.header.vertexCount};
|
|
||||||
auto const vertexVec2Byte {sizeof(SHVec2) * asset.header.vertexCount};
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.vertexPosition.data()),
|
|
||||||
vertexVec3Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.vertexTangent.data()),
|
|
||||||
vertexVec3Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.vertexNormal.data()),
|
|
||||||
vertexVec3Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.write(
|
|
||||||
reinterpret_cast<char const*>(asset.texCoords.data()),
|
|
||||||
vertexVec2Byte
|
|
||||||
);
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../Asset Types/SHMeshAsset.h"
|
|
||||||
#include "../SHAssetMacros.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
class SHMeshWriter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
public:
|
|
||||||
static void WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHTextureCompiler.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Library to write data in SHTextureAsset into binary file for
|
||||||
|
* faster loading in the future
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "SHTextureCompiler.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
std::string SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path)
|
||||||
|
{
|
||||||
|
std::string newPath{ path.string() };
|
||||||
|
newPath = newPath.substr(0, newPath.find_last_of('.'));
|
||||||
|
newPath += TEXTURE_EXTENSION;
|
||||||
|
|
||||||
|
std::ofstream file{ newPath, std::ios::out | std::ios::binary };
|
||||||
|
if (!file.is_open())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Unable to open file for writing texture file: {}", path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const intBytes{sizeof(uint32_t)};
|
||||||
|
|
||||||
|
uint32_t mipOffsetCount{ static_cast<uint32_t>(asset.mipOffsets.size()) };
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&asset.numBytes),
|
||||||
|
intBytes
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&asset.width),
|
||||||
|
intBytes
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&asset.height),
|
||||||
|
intBytes
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&asset.format),
|
||||||
|
sizeof(SHTexture::TextureFormat)
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(&mipOffsetCount),
|
||||||
|
intBytes
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.mipOffsets.data()),
|
||||||
|
intBytes * asset.mipOffsets.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
file.write(
|
||||||
|
reinterpret_cast<char const*>(asset.pixelData),
|
||||||
|
asset.numBytes
|
||||||
|
);
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return newPath;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHTextureCompiler.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Library to write data in SHTextureAsset into binary file for
|
||||||
|
* faster loading in the future
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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/SHTextureAsset.h"
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHTextureCompiler
|
||||||
|
{
|
||||||
|
static std::string CompileTextureBinary(SHTextureAsset const& asset, AssetPath path);
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,3 +1,14 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHTextureLoader.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Library to load dds textures and custom binary format
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 "SHpch.h"
|
||||||
#include "SHTextureLoader.h"
|
#include "SHTextureLoader.h"
|
||||||
|
|
||||||
|
@ -58,7 +69,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset)
|
void SHTextureLoader::LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept
|
||||||
{
|
{
|
||||||
tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
|
tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
|
||||||
tinyddsloader::DDSFile file;
|
tinyddsloader::DDSFile file;
|
||||||
|
@ -72,21 +83,65 @@ namespace SHADE
|
||||||
|
|
||||||
std::vector<uint32_t> mipOff(file.GetMipCount());
|
std::vector<uint32_t> mipOff(file.GetMipCount());
|
||||||
|
|
||||||
for (auto i{0}; i < file.GetMipCount(); ++i)
|
for (size_t i{0}; i < file.GetMipCount(); ++i)
|
||||||
{
|
{
|
||||||
mipOff.push_back(totalBytes);
|
mipOff[i] = static_cast<uint32_t>(totalBytes);
|
||||||
totalBytes += file.GetImageData(i, 0)->m_memSlicePitch;
|
totalBytes += file.GetImageData(static_cast<uint32_t>(i), 0)->m_memSlicePitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
||||||
std::memcpy(pixel, file.GetDDSData(), 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.numBytes = totalBytes;
|
asset.name = path.stem().string();
|
||||||
|
asset.compiled = false;
|
||||||
|
asset.numBytes = static_cast<uint32_t>(totalBytes);
|
||||||
asset.width = file.GetWidth();
|
asset.width = file.GetWidth();
|
||||||
asset.height = file.GetHeight();
|
asset.height = file.GetHeight();
|
||||||
asset.format = ddsLoaderToVkFormat(file.GetFormat(), true);
|
asset.format = ddsLoaderToVkFormat(file.GetFormat(), true);
|
||||||
asset.mipOffsets = std::move(mipOff);
|
asset.mipOffsets = std::move(mipOff);
|
||||||
asset.pixelData = std::move(pixel);
|
asset.pixelData = std::move(pixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHTextureLoader::LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept
|
||||||
|
{
|
||||||
|
std::ifstream file{path.string(), std::ios::in | std::ios::binary};
|
||||||
|
if (!file.is_open())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Error opening SHTexture file: {}", path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const intBytes{ sizeof(uint32_t) };
|
||||||
|
uint32_t mipCount;
|
||||||
|
|
||||||
|
file.read(reinterpret_cast<char*>(&asset.numBytes), intBytes);
|
||||||
|
file.read(reinterpret_cast<char*>(&asset.width), intBytes);
|
||||||
|
file.read(reinterpret_cast<char*>(&asset.height), intBytes);
|
||||||
|
file.read(reinterpret_cast<char*>(&asset.format), sizeof(SHTexture::TextureFormat));
|
||||||
|
|
||||||
|
file.read(reinterpret_cast<char*>(&mipCount), intBytes);
|
||||||
|
std::vector<uint32_t> mips(mipCount);
|
||||||
|
file.read(reinterpret_cast<char*>(mips.data()), intBytes * mipCount);
|
||||||
|
|
||||||
|
auto pixel = new SHTexture::PixelChannel[asset.numBytes];
|
||||||
|
file.read(reinterpret_cast<char*>(pixel), asset.numBytes);
|
||||||
|
|
||||||
|
asset.mipOffsets = std::move(mips);
|
||||||
|
asset.pixelData = std::move( pixel );
|
||||||
|
|
||||||
|
asset.compiled = true;
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset)
|
||||||
|
{
|
||||||
|
if (path.extension().string() == DDS_EXTENSION)
|
||||||
|
{
|
||||||
|
LoadTinyDDS(path, asset);
|
||||||
|
}
|
||||||
|
else if (path.extension().string() == TEXTURE_EXTENSION)
|
||||||
|
{
|
||||||
|
LoadSHTexture(path, asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHTextureLoader.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Library to load dds textures and custom binary format
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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
|
#pragma once
|
||||||
#define TINYDDSLOADER_IMPLEMENTATION
|
#define TINYDDSLOADER_IMPLEMENTATION
|
||||||
|
|
||||||
|
@ -13,7 +24,10 @@ namespace SHADE
|
||||||
static std::string TinyDDSResultToString(tinyddsloader::Result value);
|
static std::string TinyDDSResultToString(tinyddsloader::Result value);
|
||||||
static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear);
|
static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear);
|
||||||
|
|
||||||
|
|
||||||
|
static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept;
|
||||||
public:
|
public:
|
||||||
static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
|
static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
|
||||||
|
static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
/*************************************************************************//**
|
||||||
|
* \file SHAsset.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 30 September 2022
|
||||||
|
* \brief Struct for asset identification and meta file writing
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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
|
#pragma once
|
||||||
|
|
||||||
#include "Filesystem/SHFileSystem.h"
|
#include "Filesystem/SHFileSystem.h"
|
||||||
|
|
|
@ -40,7 +40,7 @@ typedef FMOD::Sound* SHSound;
|
||||||
#define ASSET_META_VER "1.0"
|
#define ASSET_META_VER "1.0"
|
||||||
|
|
||||||
// Asset type enum
|
// Asset type enum
|
||||||
enum class AssetType : uint8_t
|
enum class AssetType : AssetTypeMeta
|
||||||
{
|
{
|
||||||
INVALID = 0,
|
INVALID = 0,
|
||||||
AUDIO = 1,
|
AUDIO = 1,
|
||||||
|
@ -57,7 +57,12 @@ enum class AssetType : uint8_t
|
||||||
};
|
};
|
||||||
|
|
||||||
//Directory
|
//Directory
|
||||||
#define ASSET_ROOT "./Assets/"
|
#ifdef _PUBLISH
|
||||||
|
#define ASSET_ROOT "Assets"
|
||||||
|
#else
|
||||||
|
#define ASSET_ROOT "../../Assets"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// ASSET EXTENSIONS
|
// ASSET EXTENSIONS
|
||||||
#define META_EXTENSION ".shmeta"
|
#define META_EXTENSION ".shmeta"
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
#include "Libraries/SHMeshLoader.h"
|
#include "Libraries/SHMeshLoader.h"
|
||||||
#include "Libraries/SHTextureLoader.h"
|
#include "Libraries/SHTextureLoader.h"
|
||||||
|
|
||||||
|
#include "Libraries/SHMeshCompiler.h"
|
||||||
|
#include "Libraries/SHTextureCompiler.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
FMOD::System* SHAssetManager::audioSystem;
|
FMOD::System* SHAssetManager::audioSystem;
|
||||||
|
@ -69,12 +72,13 @@ namespace SHADE
|
||||||
|
|
||||||
AssetType type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string().c_str());
|
AssetType type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string().c_str());
|
||||||
std::string folder;
|
std::string folder;
|
||||||
switch (type)
|
//TODO Implement asset type generation
|
||||||
{
|
//switch (type)
|
||||||
default:
|
//{
|
||||||
//TODO:ASSERT UNSUPPORTED FILE TYPE
|
//default:
|
||||||
return std::filesystem::path();
|
// //TODO:ASSERT UNSUPPORTED FILE TYPE
|
||||||
}
|
// return std::filesystem::path();
|
||||||
|
//}
|
||||||
|
|
||||||
return std::filesystem::path(ASSET_ROOT + folder + path.filename().string());
|
return std::filesystem::path(ASSET_ROOT + folder + path.filename().string());
|
||||||
}
|
}
|
||||||
|
@ -105,12 +109,13 @@ namespace SHADE
|
||||||
meta.type = type;
|
meta.type = type;
|
||||||
|
|
||||||
std::string folder;
|
std::string folder;
|
||||||
switch (type)
|
//TODO implement folder choosing
|
||||||
{
|
//switch (type)
|
||||||
default:
|
//{
|
||||||
folder = "";
|
//default:
|
||||||
break;
|
// folder = "";
|
||||||
}
|
// break;
|
||||||
|
//}
|
||||||
AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
|
AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
|
||||||
|
|
||||||
SHAssetMetaHandler::WriteMetaData(meta);
|
SHAssetMetaHandler::WriteMetaData(meta);
|
||||||
|
@ -199,7 +204,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
AssetPath path{ p };
|
AssetPath path{ p };
|
||||||
|
|
||||||
if (path.extension().string() == GLTF_EXTENSION)
|
if (path.extension().string() == FBX_EXTENSION
|
||||||
|
|| path.extension().string() == GLTF_EXTENSION
|
||||||
|
|| path.extension().string() == MESH_EXTENSION)
|
||||||
{
|
{
|
||||||
LoadGLTF(
|
LoadGLTF(
|
||||||
{
|
{
|
||||||
|
@ -211,7 +218,8 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (path.extension().string() == DDS_EXTENSION)
|
else if (path.extension().string() == DDS_EXTENSION
|
||||||
|
|| path.extension().string() == TEXTURE_EXTENSION)
|
||||||
{
|
{
|
||||||
LoadDDS(
|
LoadDDS(
|
||||||
{
|
{
|
||||||
|
@ -247,6 +255,26 @@ namespace SHADE
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHMeshAsset const* SHAssetManager::GetMesh(AssetID id) noexcept
|
||||||
|
{
|
||||||
|
if (meshCollection.find(id) == meshCollection.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &meshCollection[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
SHTextureAsset const* SHAssetManager::GetTexture(AssetID id) noexcept
|
||||||
|
{
|
||||||
|
if (textureCollection.find(id) == textureCollection.end())
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &textureCollection[id];
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \param Path for meta data file
|
* \param Path for meta data file
|
||||||
* \param Path for asset file
|
* \param Path for asset file
|
||||||
|
@ -299,7 +327,22 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto const& mesh : meshes)
|
for (auto const& mesh : meshes)
|
||||||
{
|
{
|
||||||
meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh);
|
auto id{ GenerateAssetID(AssetType::MESH) };
|
||||||
|
meshCollection.emplace(id, mesh);
|
||||||
|
|
||||||
|
AssetPath path;
|
||||||
|
if (!mesh.compiled)
|
||||||
|
{
|
||||||
|
path = SHMeshCompiler::CompileMeshBinary(mesh, asset.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
assetCollection.emplace_back(
|
||||||
|
mesh.header.meshName,
|
||||||
|
id,
|
||||||
|
AssetType::MESH,
|
||||||
|
path,
|
||||||
|
0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +352,21 @@ namespace SHADE
|
||||||
|
|
||||||
SHTextureLoader::LoadImageAsset(asset.path, image);
|
SHTextureLoader::LoadImageAsset(asset.path, image);
|
||||||
|
|
||||||
textureCollection.emplace(GenerateAssetID(AssetType::DDS), image);
|
if (!image.compiled)
|
||||||
|
{
|
||||||
|
auto id{ GenerateAssetID(AssetType::TEXTURE) };
|
||||||
|
textureCollection.emplace(id, image);
|
||||||
|
|
||||||
|
auto path{ SHTextureCompiler::CompileTextureBinary(image, asset.path) };
|
||||||
|
|
||||||
|
assetCollection.emplace_back(
|
||||||
|
image.name,
|
||||||
|
id,
|
||||||
|
AssetType::TEXTURE,
|
||||||
|
path,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -326,8 +383,24 @@ namespace SHADE
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void SHAssetManager::LoadAllData() noexcept
|
void SHAssetManager::LoadAllData() noexcept
|
||||||
{
|
{
|
||||||
|
//TODO Remove when on demand loading is done
|
||||||
for (auto const& asset : assetCollection)
|
for (auto const& asset : assetCollection)
|
||||||
{
|
{
|
||||||
|
switch (asset.type)
|
||||||
|
{
|
||||||
|
case AssetType::MESH:
|
||||||
|
meshCollection.emplace(asset.id, SHMeshAsset());
|
||||||
|
SHMeshLoader::LoadSHMesh(meshCollection[asset.id], asset.path);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AssetType::TEXTURE:
|
||||||
|
textureCollection.emplace(asset.id, SHTextureAsset());
|
||||||
|
SHTextureLoader::LoadSHTexture(asset.path, textureCollection[asset.id]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
void;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,40 +417,51 @@ namespace SHADE
|
||||||
std::vector<AssetPath> metaFiles;
|
std::vector<AssetPath> metaFiles;
|
||||||
std::vector<AssetPath> AssetFiles;
|
std::vector<AssetPath> AssetFiles;
|
||||||
|
|
||||||
//TODO: Write new function for file manager to loop through all files
|
for (auto const dir : std::filesystem::recursive_directory_iterator(ASSET_ROOT))
|
||||||
SHFileSystem::StartupFillDirectories(ASSET_ROOT);
|
{
|
||||||
FolderPointer rootFolder = SHFileSystem::GetRoot();
|
if (dir.path().extension().string() == META_EXTENSION)
|
||||||
|
{
|
||||||
|
auto meta{ SHAssetMetaHandler::RetrieveMetaData(dir.path()) };
|
||||||
|
|
||||||
for (auto const& meta : metaFiles)
|
assetCollection.push_back(meta);
|
||||||
{
|
assetRegistry.emplace(meta.id, meta);
|
||||||
for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() };
|
|
||||||
it != AssetFiles.cend();
|
|
||||||
++it)
|
|
||||||
{
|
|
||||||
// Asset exists for meta file
|
|
||||||
std::string fileExtCheck{ it->filename().string() };
|
|
||||||
fileExtCheck += META_EXTENSION;
|
|
||||||
if (meta.filename().string() == fileExtCheck)
|
|
||||||
{
|
|
||||||
RegisterAsset(meta, *it);
|
|
||||||
AssetFiles.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Write new function for file manager to loop through all files
|
||||||
|
//SHFileSystem::StartupFillDirectories(ASSET_ROOT);
|
||||||
|
//FolderPointer rootFolder = SHFileSystem::GetRoot();
|
||||||
|
|
||||||
|
//for (auto const& meta : metaFiles)
|
||||||
|
//{
|
||||||
|
// for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() };
|
||||||
|
// it != AssetFiles.cend();
|
||||||
|
// ++it)
|
||||||
|
// {
|
||||||
|
// // Asset exists for meta file
|
||||||
|
// std::string fileExtCheck{ it->filename().string() };
|
||||||
|
// fileExtCheck += META_EXTENSION;
|
||||||
|
// if (meta.filename().string() == fileExtCheck)
|
||||||
|
// {
|
||||||
|
// RegisterAsset(meta, *it);
|
||||||
|
// AssetFiles.erase(it);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
|
//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
|
||||||
for (auto const& file : AssetFiles)
|
//for (auto const& file : AssetFiles)
|
||||||
{
|
//{
|
||||||
if (IsRecognised(file.extension().string().c_str()))
|
// if (IsRecognised(file.extension().string().c_str()))
|
||||||
{
|
// {
|
||||||
SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file));
|
// SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file));
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
std::cout << "Unsupported File Format: " << file.filename() << "\n";
|
// std::cout << "Unsupported File Format: " << file.filename() << "\n";
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept
|
AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept
|
||||||
|
|
|
@ -75,6 +75,8 @@ namespace SHADE
|
||||||
static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
|
static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
|
||||||
static std::vector<SHTextureAsset> GetAllTextures() noexcept;
|
static std::vector<SHTextureAsset> GetAllTextures() noexcept;
|
||||||
|
|
||||||
|
static SHMeshAsset const* GetMesh(AssetID id) noexcept;
|
||||||
|
static SHTextureAsset const* GetTexture(AssetID id) noexcept;
|
||||||
private:
|
private:
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* \brief Load resource data into memory
|
* \brief Load resource data into memory
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,10 +108,11 @@ namespace SHADE
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
|
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
|
||||||
{
|
{
|
||||||
|
//TODO: Write into binary eventually
|
||||||
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())
|
||||||
{
|
{
|
||||||
|
@ -110,8 +120,20 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHAudioListenerComponent.cpp
|
||||||
|
* \author Glence Low
|
||||||
|
* \brief Definition of the SHAudioListenerComponent class.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction
|
||||||
|
or disclosure of this file or its contents without the prior written
|
||||||
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHAudioListenerComponent.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
const SHVec3 SHAudioListenerComponent::GetPos() const
|
||||||
|
{
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHVec3 SHAudioListenerComponent::GetVel() const
|
||||||
|
{
|
||||||
|
return vel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHVec3 SHAudioListenerComponent::GetForward() const
|
||||||
|
{
|
||||||
|
return forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHVec3 SHAudioListenerComponent::GetUp() const
|
||||||
|
{
|
||||||
|
return up;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioListenerComponent::SetPos(const SHVec3 p)
|
||||||
|
{
|
||||||
|
pos = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioListenerComponent::SetVel(const SHVec3 v)
|
||||||
|
{
|
||||||
|
vel = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioListenerComponent::SetForward(const SHVec3 f)
|
||||||
|
{
|
||||||
|
forward = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioListenerComponent::SetUp(const SHVec3 u)
|
||||||
|
{
|
||||||
|
up = u;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#pragma once
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHAudioListenerComponent.h
|
||||||
|
* \author Glence Low
|
||||||
|
* \brief Declaration of the SHAudioListenerComponent class.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction
|
||||||
|
or disclosure of this file or its contents without the prior written
|
||||||
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHAudioListenerComponent : public SHComponent
|
||||||
|
{
|
||||||
|
friend class SHAudioSystem;
|
||||||
|
public:
|
||||||
|
|
||||||
|
SHAudioListenerComponent() = default;
|
||||||
|
~SHAudioListenerComponent() = default;
|
||||||
|
|
||||||
|
const SHVec3 GetPos() const;
|
||||||
|
void SetPos(const SHVec3 p);
|
||||||
|
|
||||||
|
const SHVec3 GetVel() const;
|
||||||
|
const SHVec3 GetForward() const;
|
||||||
|
const SHVec3 GetUp() const;
|
||||||
|
|
||||||
|
void SetVel(const SHVec3 v);
|
||||||
|
void SetForward(const SHVec3 f);
|
||||||
|
void SetUp(const SHVec3 u);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SHVec3 pos{}, vel{}, forward{}, up{ 0.f,1.f,0.f };
|
||||||
|
};
|
||||||
|
}//namespace SHADE
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHAudioSourceComponet.cpp
|
||||||
|
* \author Glence Low
|
||||||
|
* \brief Definition of the SHAudioSourceComponet class.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction
|
||||||
|
or disclosure of this file or its contents without the prior written
|
||||||
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "AudioSystem/SHAudioSystem.h"
|
||||||
|
#include "SHAudioSourceComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief play the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void SHAudioSourceComponent::PlaySoundSFX(EntityID id, bool loop, bool spatial, float min , float max )
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHAudioSystem>()->PlaySFX(id, GetEID(),loop,spatial, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSourceComponent::PlaySoundBGM(EntityID id, bool loop, bool spatial, float min, float max)
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHAudioSystem>()->PlayBGM(id, GetEID(), loop, spatial, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void SHAudioSourceComponent::StopSound(EntityID id)
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHAudioSystem>()->StopSound(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mute the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void SHAudioSourceComponent::SetMute(EntityID id, bool mute)
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHAudioSystem>()->SetMute(id, mute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHAudioSourceComponet.h
|
||||||
|
* \author Glence Low
|
||||||
|
* \brief Declaration of the SHAudioSourceComponet class.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction
|
||||||
|
or disclosure of this file or its contents without the prior written
|
||||||
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHAudioSourceComponent : public SHComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief default constructor for the component
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
SHAudioSourceComponent() = default;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief default destructor for the component
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
~SHAudioSourceComponent() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief play the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void PlaySoundSFX(EntityID id, bool loop = false, bool spatial = false, float min = 5.0f, float max = 1000.f);
|
||||||
|
|
||||||
|
void PlaySoundBGM(EntityID id, bool loop = false, bool spatial = false, float min = 5.0f, float max = 1000.f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stop the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void StopSound(EntityID id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mute the sound
|
||||||
|
*
|
||||||
|
* @param index where the sound is in the index
|
||||||
|
*/
|
||||||
|
void SetMute(EntityID id, bool mute);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}//namespace SHADE
|
||||||
|
|
|
@ -0,0 +1,557 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHAudioSystem.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "AudioSystem/SHAudioListenerComponent.h"
|
||||||
|
#include "AudioSystem/SHAudioSourceComponent.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:26812) //disable warning about preference of enum class over enum as ImGuizmo uses enums
|
||||||
|
#include <FMOD/fmod_errors.h>
|
||||||
|
#include <FMOD/fmod.hpp>
|
||||||
|
#include <FMOD/fmod_studio.hpp>
|
||||||
|
#include <SDL_keyboard.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHAudioSystem::SHAudioSystem()
|
||||||
|
: fmodStudioSystem(nullptr)
|
||||||
|
, extraDriverData(nullptr)
|
||||||
|
, soundList()
|
||||||
|
, bgmChannelGroup(nullptr)
|
||||||
|
, sfxChannelGroup(nullptr)
|
||||||
|
, masterGroup(nullptr)
|
||||||
|
, audioChannels()
|
||||||
|
, result(FMOD_RESULT_FORCEINT)
|
||||||
|
, bgmVolume(1.F)
|
||||||
|
, sfxVolume(1.F)
|
||||||
|
, masterVolume(1.0F)
|
||||||
|
, version(0)
|
||||||
|
, speakerMode(FMOD_SPEAKERMODE_5POINT1)
|
||||||
|
, paused(false)
|
||||||
|
{
|
||||||
|
result = FMOD::Studio::System::create(&fmodStudioSystem);
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAudioSystem::~SHAudioSystem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHADE::SHAudioSystem::Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHAudioSourceComponent>();
|
||||||
|
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHAudioListenerComponent>();
|
||||||
|
|
||||||
|
denseListener = &SHComponentManager::GetDense<SHAudioListenerComponent>();
|
||||||
|
fmodStudioSystem->getCoreSystem(&fmodSystem);
|
||||||
|
|
||||||
|
result = fmodStudioSystem->initialize(AUDIO_SYS_MAX_CHANNELS, AUDIO_SYS_MAX_CHANNELS, FMOD_STUDIO_INIT_NORMAL, extraDriverData);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
fmodSystem->setSoftwareFormat(0, speakerMode, 0);
|
||||||
|
|
||||||
|
result = fmodSystem->createChannelGroup("SFX", &sfxChannelGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
result = fmodSystem->createChannelGroup("BGM", &bgmChannelGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
result = fmodSystem->getMasterChannelGroup(&masterGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
result = masterGroup->addGroup(bgmChannelGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
result = masterGroup->addGroup(sfxChannelGroup);
|
||||||
|
ErrorCheck();
|
||||||
|
|
||||||
|
bgmChannelGroup->setVolume(bgmVolume);
|
||||||
|
sfxChannelGroup->setVolume(sfxVolume);
|
||||||
|
masterGroup->setVolume(masterVolume);
|
||||||
|
|
||||||
|
//SHResourceManager::LoadAllAudio(system, soundList);
|
||||||
|
|
||||||
|
|
||||||
|
LoadBank("../../Assets/Audio/Master.bank");
|
||||||
|
LoadBank("../../Assets/Audio/Master.strings.bank");
|
||||||
|
//LoadBank("../../Assets/Audio/Music.bank");
|
||||||
|
LoadBank("../../Assets/Audio/footsteps.bank");
|
||||||
|
|
||||||
|
//auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
|
||||||
|
//clip->Play();
|
||||||
|
//PlayEventOnce("event:/Characters/sfx_footsteps_raccoon");
|
||||||
|
//PlayEventOnce("event:/SFX/Dawn/Dawn_Attack");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHADE::SHAudioSystem::Run(double dt)
|
||||||
|
{
|
||||||
|
static_cast<void>(dt);
|
||||||
|
//if (GetKeyState(VK_SPACE) & 0x8000)
|
||||||
|
// PlayEventOnce("event:/Characters/sfx_footsteps_raccoon");
|
||||||
|
|
||||||
|
fmodStudioSystem->update();
|
||||||
|
if (!denseListener->empty())
|
||||||
|
{
|
||||||
|
SHAudioListenerComponent& listener = denseListener->at(0);
|
||||||
|
SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(listener.GetEID());
|
||||||
|
if (listenerTransform)
|
||||||
|
{
|
||||||
|
listener.SetPos(listenerTransform->GetLocalPosition());
|
||||||
|
listener.SetForward({ (listenerTransform->GetLocalScale()[0] > 0.f) ? 1.f : -1.f, 0.f, 0.f });
|
||||||
|
FMOD_VECTOR pos = { listener.pos[0] ,listener.pos[1] ,0.f };
|
||||||
|
FMOD_VECTOR forward = { listener.forward[0] ,listener.forward[1] ,listener.forward[2] };
|
||||||
|
FMOD_VECTOR up = { listener.up[0] ,listener.up[1] ,listener.up[2] };
|
||||||
|
fmodSystem->set3DListenerAttributes(0, &pos, nullptr, &forward, &up);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAudioSystem::AudioRoutine::AudioRoutine()
|
||||||
|
: SHSystemRoutine("Audio Routine", false) {}
|
||||||
|
|
||||||
|
void SHAudioSystem::AudioRoutine::Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
reinterpret_cast<SHAudioSystem*>(system)->Run(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHADE::SHAudioSystem::Exit()
|
||||||
|
{
|
||||||
|
for (auto& event : eventMap)
|
||||||
|
{
|
||||||
|
result = event.second->releaseAllInstances();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& bank : bankMap)
|
||||||
|
{
|
||||||
|
result = bank.second->unload();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& sound : soundList)
|
||||||
|
{
|
||||||
|
result = sound.second->release();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bgmChannelGroup)
|
||||||
|
{
|
||||||
|
result = bgmChannelGroup->release();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sfxChannelGroup)
|
||||||
|
{
|
||||||
|
result = sfxChannelGroup->release();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fmodStudioSystem)
|
||||||
|
{
|
||||||
|
result = fmodStudioSystem->release();
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::ErrorCheck() const
|
||||||
|
{
|
||||||
|
if (result != FMOD_OK)
|
||||||
|
std::cerr << "Audio system error: " << FMOD_ErrorString(result) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::PlayEventOnce(const char* path, bool isSFX, EntityID eid, bool spatial)
|
||||||
|
{
|
||||||
|
if (paused)
|
||||||
|
return;
|
||||||
|
auto it = eventMap.find(path);
|
||||||
|
if (it != eventMap.end())
|
||||||
|
{
|
||||||
|
FMOD::Studio::EventInstance* event = nullptr;
|
||||||
|
it->second->createInstance(&event);
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
|
||||||
|
event->setVolume(masterVolume * (isSFX ? sfxVolume : bgmVolume));
|
||||||
|
if (spatial)
|
||||||
|
{
|
||||||
|
if (SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
FMOD_3D_ATTRIBUTES attributes{ {} };
|
||||||
|
attributes.forward.z = 1.0f;
|
||||||
|
attributes.up.y = 1.0f;
|
||||||
|
SHAudioListenerComponent& listener = denseListener->at(0);
|
||||||
|
SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(listener.GetEID());
|
||||||
|
if (listenerTransform)
|
||||||
|
{
|
||||||
|
attributes.position.z = listenerTransform->GetLocalPosition()[2];
|
||||||
|
}
|
||||||
|
attributes.position.x = audioTransform->GetLocalPosition()[0];
|
||||||
|
attributes.position.y = audioTransform->GetLocalPosition()[1];
|
||||||
|
event->set3DAttributes(&attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
event->start();
|
||||||
|
event->release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::PlaySFX(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min, float max)
|
||||||
|
{
|
||||||
|
SHSound sound = soundList[id];
|
||||||
|
int index = GetAvailableChannelIndex();
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
unsigned int mode{};
|
||||||
|
mode |= (loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
||||||
|
mode |= (spatial ? FMOD_3D : FMOD_2D);
|
||||||
|
sound->setMode(mode);
|
||||||
|
result = fmodSystem->playSound(sound, sfxChannelGroup, false, &audioChannels[index]);
|
||||||
|
if (spatial && SHComponentManager::HasComponent<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
|
||||||
|
FMOD_VECTOR fpos{ audioTransform->GetLocalPosition()[0],audioTransform->GetLocalPosition()[1] ,0.f};
|
||||||
|
audioChannels[index]->set3DAttributes(&fpos, nullptr);
|
||||||
|
audioChannels[index]->setMode(mode);
|
||||||
|
audioChannels[index]->set3DMinMaxDistance(min, max);
|
||||||
|
}
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::PlayBGM(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min, float max)
|
||||||
|
{
|
||||||
|
SHSound sound = soundList[id];
|
||||||
|
int index = GetAvailableChannelIndex();
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
unsigned int mode{};
|
||||||
|
mode |= (loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
||||||
|
mode |= (spatial ? FMOD_3D : FMOD_2D);
|
||||||
|
sound->setMode(mode);
|
||||||
|
result = fmodSystem->playSound(sound, bgmChannelGroup, false, &audioChannels[index]);
|
||||||
|
if (spatial && SHComponentManager::HasComponent<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
|
||||||
|
FMOD_VECTOR fpos{ audioTransform->GetLocalPosition()[0],audioTransform->GetLocalPosition()[1] ,0.f };
|
||||||
|
audioChannels[index]->set3DAttributes(&fpos, nullptr);
|
||||||
|
audioChannels[index]->setMode(mode);
|
||||||
|
audioChannels[index]->set3DMinMaxDistance(min, max);
|
||||||
|
}
|
||||||
|
ErrorCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::SetMute(EntityID id, bool mute)
|
||||||
|
{
|
||||||
|
SHSound sound;
|
||||||
|
for (auto& channel : audioChannels)
|
||||||
|
{
|
||||||
|
channel->getCurrentSound(&sound);
|
||||||
|
if (soundList.find(id)->second == sound) // tbc
|
||||||
|
{
|
||||||
|
channel->setMute(mute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::StopSound(EntityID id)
|
||||||
|
{
|
||||||
|
SHSound sound;
|
||||||
|
for (auto& channel : audioChannels)
|
||||||
|
{
|
||||||
|
channel->getCurrentSound(&sound);
|
||||||
|
if (soundList.find(id)->second == sound) // tbc
|
||||||
|
{
|
||||||
|
channel->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::StopAllSounds()
|
||||||
|
{
|
||||||
|
for (auto& channel : audioChannels)
|
||||||
|
{
|
||||||
|
bool isPlaying{ false };
|
||||||
|
if (channel->isPlaying(&isPlaying) == FMOD_OK && isPlaying)
|
||||||
|
channel->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FMOD_GUID> SHAudioSystem::GetEventGUID(const char* path)
|
||||||
|
{
|
||||||
|
FMOD_GUID guid;
|
||||||
|
FMOD::Studio::EventDescription* event;
|
||||||
|
result = fmodStudioSystem->getEvent(path, &event);
|
||||||
|
ErrorCheck();
|
||||||
|
if (result == FMOD_OK)
|
||||||
|
{
|
||||||
|
result = event->getID(&guid);
|
||||||
|
ErrorCheck();
|
||||||
|
if (result == FMOD_OK)
|
||||||
|
{
|
||||||
|
return guid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioClip* SHAudioSystem::CreateAudioClip(const char* path)
|
||||||
|
{
|
||||||
|
AudioClipID newID{};
|
||||||
|
AudioClip* clip = nullptr;
|
||||||
|
auto it = eventMap.find(path);
|
||||||
|
if (it != eventMap.end())
|
||||||
|
{
|
||||||
|
FMOD::Studio::EventInstance* event = nullptr;
|
||||||
|
it->second->createInstance(&event);
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
//event->start();
|
||||||
|
newID = clipID;
|
||||||
|
clipID++;
|
||||||
|
eventInstances.emplace(newID, AudioClip(newID, event));
|
||||||
|
clip = &eventInstances[newID];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clip;
|
||||||
|
}
|
||||||
|
|
||||||
|
//std::vector<const char*> SHAudioSystem::GetAllEvents()
|
||||||
|
//{
|
||||||
|
// int count{};
|
||||||
|
// stringsBank->getEventCount(&count);
|
||||||
|
|
||||||
|
// std::vector<FMOD::Studio::EventDescription*> events(count);
|
||||||
|
// auto eventData = events.data();
|
||||||
|
// int finalCount{};
|
||||||
|
// stringsBank->getEventList(eventData, count, &finalCount);
|
||||||
|
// std::vector<const char*> eventNames;
|
||||||
|
// std::transform(events.begin(), events.end(), std::back_inserter(eventNames), [](FMOD::Studio::EventDescription* event)
|
||||||
|
// {
|
||||||
|
// char path[256];
|
||||||
|
// event->getPath(path, 256, nullptr);
|
||||||
|
// return path;
|
||||||
|
// });
|
||||||
|
// return eventNames;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void SHAudioSystem::PlayEventInstance(FMOD::Studio::EventInstance* instance, bool isSFX, EntityID eid, bool spatial)
|
||||||
|
//{
|
||||||
|
// instance->setVolume(masterVolume * (isSFX ? sfxVolume : bgmVolume));
|
||||||
|
// FMOD::ChannelGroup* channelGroup;
|
||||||
|
// if (spatial)
|
||||||
|
// {
|
||||||
|
// if (SHTransformComponent* audioTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||||
|
// {
|
||||||
|
// FMOD_3D_ATTRIBUTES attributes{ {} };
|
||||||
|
// attributes.forward.z = 1.0f;
|
||||||
|
// attributes.up.y = 1.0f;
|
||||||
|
// SHAudioListenerComponent& listener = denseListener->at(0);
|
||||||
|
// SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(listener.GetEID());
|
||||||
|
// if (listenerTransform)
|
||||||
|
// {
|
||||||
|
// attributes.position.z = listenerTransform->GetTranslation()[2];
|
||||||
|
// }
|
||||||
|
// attributes.position.x = audioTransform->GetTranslation()[0];
|
||||||
|
// attributes.position.y = audioTransform->GetTranslation()[1];
|
||||||
|
// instance->set3DAttributes(&attributes);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// instance->start();
|
||||||
|
//}
|
||||||
|
|
||||||
|
int SHAudioSystem::GetAvailableChannelIndex()
|
||||||
|
{
|
||||||
|
bool isPlaying = false;
|
||||||
|
for (int i = 0; i < AUDIO_SYS_MAX_CHANNELS; ++i)
|
||||||
|
{
|
||||||
|
audioChannels[i]->isPlaying(&isPlaying);
|
||||||
|
if (!isPlaying)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHAudioSystem::GetBgmVolume()
|
||||||
|
{
|
||||||
|
return bgmVolume;
|
||||||
|
}
|
||||||
|
float SHAudioSystem::GetSfxVolume()
|
||||||
|
{
|
||||||
|
return sfxVolume;
|
||||||
|
}
|
||||||
|
float SHAudioSystem::GetMasterVolume()
|
||||||
|
{
|
||||||
|
return masterVolume;
|
||||||
|
}
|
||||||
|
void SHAudioSystem::SetBgmVolume(float const bgmvol)
|
||||||
|
{
|
||||||
|
bgmChannelGroup->setVolume(bgmvol);
|
||||||
|
}
|
||||||
|
void SHAudioSystem::SetSfxVolume(float const sfxvol)
|
||||||
|
{
|
||||||
|
sfxChannelGroup->setVolume(sfxvol);
|
||||||
|
}
|
||||||
|
void SHAudioSystem::SetMasterVolume(float const mastervol)
|
||||||
|
{
|
||||||
|
masterGroup->setVolume(mastervol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::SetPaused(bool pause)
|
||||||
|
{
|
||||||
|
paused = pause;
|
||||||
|
for (auto const& channel : audioChannels)
|
||||||
|
{
|
||||||
|
channel->setPaused(paused);
|
||||||
|
}
|
||||||
|
for (auto const& event : eventMap)
|
||||||
|
{
|
||||||
|
int instanceCount = 0;
|
||||||
|
event.second->getInstanceCount(&instanceCount);
|
||||||
|
std::vector<FMOD::Studio::EventInstance*> instances(instanceCount);
|
||||||
|
event.second->getInstanceList(instances.data(), static_cast<int>(instances.size()), &instanceCount);
|
||||||
|
for (auto const& instance : instances)
|
||||||
|
{
|
||||||
|
instance->setPaused(pause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHAudioSystem::GetPaused() const
|
||||||
|
{
|
||||||
|
return paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHAudioSystem::GetListenerPosition()
|
||||||
|
{
|
||||||
|
auto &listener = denseListener->at(0);
|
||||||
|
SHTransformComponent* listenerTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(listener.GetEID());
|
||||||
|
if (listenerTransform)
|
||||||
|
{
|
||||||
|
return listenerTransform->GetLocalPosition();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAudioSystem::LoadBank(const char* path)
|
||||||
|
{
|
||||||
|
FMOD::Studio::Bank* bank = nullptr;
|
||||||
|
result = fmodStudioSystem->loadBankFile(path, FMOD_STUDIO_LOAD_BANK_NORMAL, &bank);
|
||||||
|
ErrorCheck();
|
||||||
|
if (result != FMOD_OK)
|
||||||
|
return;
|
||||||
|
bankMap.emplace(path, bank);
|
||||||
|
bank->loadSampleData();
|
||||||
|
int numOfEvents;
|
||||||
|
bank->getEventCount(&numOfEvents);
|
||||||
|
if (numOfEvents > 0)
|
||||||
|
{
|
||||||
|
std::vector<FMOD::Studio::EventDescription*> events(numOfEvents);
|
||||||
|
bank->getEventList(events.data(), numOfEvents, &numOfEvents);
|
||||||
|
char eventName[512];
|
||||||
|
for (int i{}; i < numOfEvents; ++i)
|
||||||
|
{
|
||||||
|
FMOD::Studio::EventDescription* event = events[i];
|
||||||
|
event->getPath(eventName, 512, nullptr);
|
||||||
|
eventMap.emplace(eventName, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioClip::AudioClip(AudioClipID clipID, FMOD::Studio::EventInstance* inst)
|
||||||
|
:instance(inst), id(clipID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioClip::~AudioClip()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClip::Play(bool isSfx)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->start();
|
||||||
|
auto audioSystem = SHSystemManager::GetSystem<SHADE::SHAudioSystem>();
|
||||||
|
instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClip::Play(SHVec3 position, bool isSfx)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->start();
|
||||||
|
FMOD_3D_ATTRIBUTES attributes{ {} };
|
||||||
|
attributes.forward.z = 1.0f;
|
||||||
|
attributes.up.y = 1.0f;
|
||||||
|
|
||||||
|
auto audioSystem = SHSystemManager::GetSystem<SHADE::SHAudioSystem>();
|
||||||
|
SHVec3 listenerPos = audioSystem->GetListenerPosition();
|
||||||
|
attributes.position.x = position[0];
|
||||||
|
attributes.position.y = position[1];
|
||||||
|
attributes.position.z = listenerPos[2];
|
||||||
|
instance->set3DAttributes(&attributes);
|
||||||
|
instance->setVolume(audioSystem->GetMasterVolume() * (isSfx ? audioSystem->GetSfxVolume() : audioSystem->GetBgmVolume()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClip::Stop(bool fadeOut)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->stop(fadeOut ? FMOD_STUDIO_STOP_ALLOWFADEOUT : FMOD_STUDIO_STOP_IMMEDIATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClip::SetPause(bool pause)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->setPaused(pause);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioClip::IsPaused()
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool paused{};
|
||||||
|
instance->getPaused(&paused);
|
||||||
|
return paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AudioClip::SetParameter(const char* paramName, float value)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->setParameterByName(paramName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioClip::SetParameterLabel(const char* paramName, const char* label)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return;
|
||||||
|
instance->setParameterByNameWithLabel(paramName, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
float AudioClip::GetParameterValue(const char* paramName)
|
||||||
|
{
|
||||||
|
if (!instance)
|
||||||
|
return {};
|
||||||
|
float value{};
|
||||||
|
instance->getParameterByName(paramName, &value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
#include <optional>
|
||||||
|
#include <FMOD/fmod_studio.hpp>
|
||||||
|
#include "SH_API.h"
|
||||||
|
#define AUDIO_SYS_MAX_CHANNELS 1024
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
typedef FMOD::Sound* SHSound;
|
||||||
|
typedef FMOD::Studio::Bank* SHBank;
|
||||||
|
|
||||||
|
class SHAudioListenerComponent;
|
||||||
|
|
||||||
|
typedef uint64_t AudioClipID;
|
||||||
|
|
||||||
|
class AudioClip
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AudioClip() = default;
|
||||||
|
AudioClip(AudioClipID clipID, FMOD::Studio::EventInstance* inst);
|
||||||
|
~AudioClip();
|
||||||
|
void Play(bool isSfx = true);
|
||||||
|
void Play(SHVec3 position, bool isSfx = true);
|
||||||
|
void Stop(bool fadeOut = true);
|
||||||
|
|
||||||
|
void SetPause(bool pause);
|
||||||
|
bool IsPaused();
|
||||||
|
void SetParameter(const char* paramName, float value);
|
||||||
|
void SetParameterLabel(const char* paramName, const char* label);
|
||||||
|
float GetParameterValue(const char* paramName);
|
||||||
|
friend class SHAudioSystem;
|
||||||
|
private:
|
||||||
|
FMOD::Studio::EventInstance* instance;
|
||||||
|
AudioClipID id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SH_API SHAudioSystem : public SHSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHAudioSystem();
|
||||||
|
~SHAudioSystem();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Run(double dt);
|
||||||
|
class SH_API AudioRoutine final : public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AudioRoutine();
|
||||||
|
void Execute(double dt) noexcept override final;
|
||||||
|
};
|
||||||
|
void Exit();
|
||||||
|
|
||||||
|
int GetAvailableChannelIndex();
|
||||||
|
/*std::vector<SHSound>::size_type CreateSound(const char* filepath, bool loop = false);*/
|
||||||
|
void PlaySFX(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f);
|
||||||
|
void PlayBGM(EntityID id, EntityID eid, const bool& loop, const bool& spatial, float min = 5.0f, float max = 1000.0f);
|
||||||
|
void PlayEventOnce(const char* path, bool isSFX = true, EntityID eid = MAX_EID, bool spatial = false);
|
||||||
|
void SetMute(EntityID id, bool);
|
||||||
|
void StopSound(EntityID id);
|
||||||
|
void StopAllSounds();
|
||||||
|
|
||||||
|
std::optional<FMOD_GUID> GetEventGUID(const char* path);
|
||||||
|
AudioClip* CreateAudioClip(const char* path);
|
||||||
|
//std::vector<const char*> GetAllEvents();
|
||||||
|
|
||||||
|
float GetBgmVolume();
|
||||||
|
float GetSfxVolume();
|
||||||
|
float GetMasterVolume();
|
||||||
|
void SetBgmVolume(float const bgmvol);
|
||||||
|
void SetSfxVolume(float const sfxvol);
|
||||||
|
void SetMasterVolume(float const mastervol);
|
||||||
|
void SetPaused(bool pause);
|
||||||
|
bool GetPaused() const;
|
||||||
|
SHVec3 GetListenerPosition();
|
||||||
|
void LoadBank(const char* path);
|
||||||
|
private:
|
||||||
|
FMOD::Studio::System* fmodStudioSystem;
|
||||||
|
FMOD::System* fmodSystem;
|
||||||
|
bool paused;
|
||||||
|
void ErrorCheck() const;
|
||||||
|
|
||||||
|
void* extraDriverData;
|
||||||
|
std::unordered_map<EntityID, SHSound> soundList;
|
||||||
|
//std::unordered_map<ResourceID, SHBank> bankMap;
|
||||||
|
std::unordered_map<std::string, SHBank> bankMap;
|
||||||
|
std::unordered_map<std::string, FMOD::Studio::EventDescription*> eventMap;
|
||||||
|
std::unordered_map<AudioClipID, AudioClip> eventInstances;
|
||||||
|
FMOD::ChannelGroup* bgmChannelGroup, * sfxChannelGroup, * masterGroup;
|
||||||
|
FMOD::Channel* audioChannels[AUDIO_SYS_MAX_CHANNELS];
|
||||||
|
FMOD_RESULT result;
|
||||||
|
float bgmVolume, sfxVolume, masterVolume;
|
||||||
|
unsigned int version;
|
||||||
|
FMOD_SPEAKERMODE speakerMode;
|
||||||
|
SHBank masterBank, stringsBank, musicBank, sfxBank; //To do: change to map of banks loaded by resource manager
|
||||||
|
|
||||||
|
std::vector<SHAudioListenerComponent>* denseListener;
|
||||||
|
AudioClipID clipID = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "ECS_Base/General/SHFamily.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -120,4 +121,7 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template class SH_API SHFamilyID<SHComponent>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHComponentAddedEvent
|
||||||
|
{
|
||||||
|
EntityID eid;
|
||||||
|
ComponentTypeID addedComponentType;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHComponentRemovedEvent
|
||||||
|
{
|
||||||
|
EntityID eid;
|
||||||
|
ComponentTypeID removedComponentType;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
#include "SHFamily.h"
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//initialize currentID as 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -14,16 +14,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename BaseClass>
|
template<typename BaseClass>
|
||||||
class SHFamilyID
|
class SH_API SHFamilyID
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
//this is used to keep track of the new current ID to be assign to a new Derived class type.
|
|
||||||
static ComponentTypeID currentID;
|
|
||||||
|
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
* \brief Construct a new SHFamilyID object
|
* \brief Construct a new SHFamilyID object
|
||||||
|
@ -46,6 +47,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
//this is used to keep track of the new current ID to be assign to a new Derived class type.
|
||||||
|
static inline ComponentTypeID currentID = 0;
|
||||||
|
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
* Checks if this identifier is cuurrently in use / valid.
|
* Checks if this identifier is cuurrently in use / valid.
|
||||||
|
@ -59,7 +63,6 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return(id < currentID);
|
return(id < currentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
* Get the ID of a derived class type.
|
* Get the ID of a derived class type.
|
||||||
|
@ -68,16 +71,27 @@ namespace SHADE
|
||||||
* @tparam DerivedClass
|
* @tparam DerivedClass
|
||||||
* The derived class type that we are trying to get the ID of.
|
* The derived class type that we are trying to get the ID of.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
#ifdef SH_API_EXPORT
|
||||||
template<typename DerivedClass>
|
template<typename DerivedClass>
|
||||||
static ENABLE_IF_DERIVED(ComponentTypeID, BaseClass, DerivedClass) GetID() noexcept
|
static SH_API ENABLE_IF_DERIVED(ComponentTypeID, BaseClass, DerivedClass) GetID() noexcept
|
||||||
{
|
{
|
||||||
//The first time a new derived class type call this get id, it will initialize id using the currentID from familyID class.
|
//The first time a new derived class type call this get id, it will initialize id using the currentID from familyID class.
|
||||||
static ComponentTypeID id = currentID++;
|
static ComponentTypeID id = SHFamilyID<BaseClass>::currentID++;
|
||||||
return id;
|
return id;
|
||||||
|
//return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
template<typename DerivedClass>
|
||||||
|
static SH_API ENABLE_IF_DERIVED(ComponentTypeID, BaseClass, DerivedClass) GetID() noexcept;
|
||||||
|
#endif // SH_API_EXPORT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
//initialize currentID as 0
|
|
||||||
template<typename BaseClass>
|
|
||||||
ComponentTypeID SHFamilyID<BaseClass>::currentID = 0;
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -17,8 +17,11 @@
|
||||||
#include "../General/SHSparseSetContainer.h"
|
#include "../General/SHSparseSetContainer.h"
|
||||||
#include "../Components/SHComponent.h"
|
#include "../Components/SHComponent.h"
|
||||||
#include "../Components/SHComponentGroup.h"
|
#include "../Components/SHComponentGroup.h"
|
||||||
|
#include "../Events/SHComponentAddedEvent.h"
|
||||||
|
#include "../Events/SHComponentRemovedEvent.h"
|
||||||
//#include "Scene/SHSceneNode.h"
|
//#include "Scene/SHSceneNode.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "Events/SHEventManager.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -216,6 +219,11 @@ namespace SHADE
|
||||||
comp->OnCreate();
|
comp->OnCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHComponentAddedEvent eventData;
|
||||||
|
eventData.eid = entityID;
|
||||||
|
eventData.addedComponentType = ComponentFamily::GetID<T>();
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHComponentAddedEvent>(eventData, SH_COMPONENT_ADDED_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -247,6 +255,13 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
comp->OnCreate();
|
comp->OnCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHComponentAddedEvent eventData;
|
||||||
|
eventData.eid = entityID;
|
||||||
|
eventData.addedComponentType = componentTypeID;
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHComponentAddedEvent>(eventData, SH_COMPONENT_ADDED_EVENT);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -313,6 +328,12 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
componentSet.GetSparseSet<T>()->Remove(EntityHandleGenerator::GetIndex(entityID));
|
componentSet.GetSparseSet<T>()->Remove(EntityHandleGenerator::GetIndex(entityID));
|
||||||
|
|
||||||
|
SHComponentRemovedEvent eventData;
|
||||||
|
eventData.eid = entityID;
|
||||||
|
eventData.removedComponentType = ComponentFamily::GetID<T>();
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHComponentRemovedEvent>(eventData, SH_COMPONENT_REMOVED_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
|
@ -464,11 +485,6 @@ namespace SHADE
|
||||||
return componentGroups[index];
|
return componentGroups[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddScriptComponent(EntityID eid, std::string const& scriptClassName) noexcept;
|
|
||||||
|
|
||||||
static void RemoveScriptComponent(EntityID eid, std::string const& scriptClassName) noexcept;
|
|
||||||
|
|
||||||
|
|
||||||
};// end SHComponentManager
|
};// end SHComponentManager
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,9 @@ namespace SHADE
|
||||||
id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID;
|
id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID;
|
||||||
}
|
}
|
||||||
systemContainer.emplace(id, std::make_unique<T>());
|
systemContainer.emplace(id, std::make_unique<T>());
|
||||||
|
|
||||||
|
auto size = systemContainer.size();
|
||||||
|
|
||||||
systemContainer[id].get()->systemID = id;
|
systemContainer[id].get()->systemID = id;
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -26,4 +26,6 @@ const EntityIndex MAX_EID = 51000;
|
||||||
#define ENABLE_IF_UINT(_TYPE, _RETURN)\
|
#define ENABLE_IF_UINT(_TYPE, _RETURN)\
|
||||||
typename std::enable_if<(std::is_integral<_TYPE>::value && !std::is_signed<_TYPE>::value),_RETURN>::type
|
typename std::enable_if<(std::is_integral<_TYPE>::value && !std::is_signed<_TYPE>::value),_RETURN>::type
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -8,23 +8,19 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
class SHFixedSystemRoutine: public SHSystemRoutine
|
class SHFixedSystemRoutine: public SHSystemRoutine
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
double accumulatedTime;
|
double accumulatedTime;
|
||||||
double fixedTimeStep;
|
double fixedTimeStep;
|
||||||
|
|
||||||
protected:
|
|
||||||
SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false)
|
SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false)
|
||||||
:SHSystemRoutine(routineName, editorPause), accumulatedTime(0.0), fixedTimeStep(timeStep){}
|
:SHSystemRoutine(routineName, editorPause), accumulatedTime(0.0), fixedTimeStep(timeStep){}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~SHFixedSystemRoutine() = default;
|
~SHFixedSystemRoutine() = default;
|
||||||
|
|
||||||
virtual void Execute(double dt) noexcept;
|
virtual void Execute(double dt) noexcept override;
|
||||||
|
|
||||||
virtual void FixedExecute(double dt) noexcept {};
|
|
||||||
|
|
||||||
|
virtual void FixedExecute(double dt) noexcept {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "ECS_Base/General/SHFamily.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -69,5 +70,9 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template class SH_API SHFamilyID<SHSystem>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Components/SHComponent.h"
|
#include "../Components/SHComponent.h"
|
||||||
|
#include <rttr/registration>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -27,4 +28,50 @@ namespace SHADE
|
||||||
std::string value{};
|
std::string value{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SHComponent_ENUM : public SHComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Option
|
||||||
|
{
|
||||||
|
OPT_A,
|
||||||
|
OPT_B,
|
||||||
|
OPT_C
|
||||||
|
};
|
||||||
|
|
||||||
|
bool boolTest{};
|
||||||
|
int intTest{};
|
||||||
|
float floatTest{};
|
||||||
|
double doubleTest{};
|
||||||
|
long longTest{};
|
||||||
|
uint8_t uint8Test{};
|
||||||
|
uint16_t uint16Test{};
|
||||||
|
uint32_t uint32Test{};
|
||||||
|
uint64_t uint64Test{};
|
||||||
|
|
||||||
|
|
||||||
|
Option option;
|
||||||
|
RTTR_ENABLE()
|
||||||
|
};
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace rttr;
|
||||||
|
registration::enumeration<SHComponent_ENUM::Option>("Option")
|
||||||
|
(
|
||||||
|
value("Option A", SHComponent_ENUM::Option::OPT_A),
|
||||||
|
value("Option B", SHComponent_ENUM::Option::OPT_B),
|
||||||
|
value("Option C", SHComponent_ENUM::Option::OPT_C)
|
||||||
|
);
|
||||||
|
rttr::registration::class_<SHComponent_ENUM>("Enum Component")
|
||||||
|
.property("Option", &SHComponent_ENUM::option)
|
||||||
|
.property("boolTest", &SHComponent_ENUM::boolTest)
|
||||||
|
.property("intTest", &SHComponent_ENUM::intTest)( metadata("MIN", 0.0f), metadata("MAX", 1.f))
|
||||||
|
.property("floatTest", &SHComponent_ENUM::floatTest)(metadata("MIN", 0.0f), metadata("MAX", 1.f))
|
||||||
|
.property("doubleTest", &SHComponent_ENUM::doubleTest)(metadata("MIN", 0.0f), metadata("MAX", 1.f))
|
||||||
|
.property("uint8Test", &SHComponent_ENUM::uint8Test)(metadata("MIN", 0.0f), metadata("MAX", 1.f))
|
||||||
|
.property("uint16Test", &SHComponent_ENUM::uint16Test)(metadata("MIN", 0.0f), metadata("MAX", 1.f))
|
||||||
|
.property("uint32Test", &SHComponent_ENUM::uint32Test)(metadata("MIN", 0.0f), metadata("MAX", 1.f))
|
||||||
|
.property("uint64Test", &SHComponent_ENUM::uint64Test)(metadata("MIN", 0.0f), metadata("MAX", 1.f));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,9 +5,13 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHBaseCommand
|
class SH_API SHBaseCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~SHBaseCommand() = default;
|
virtual ~SHBaseCommand() = default;
|
||||||
|
@ -48,4 +52,20 @@ namespace SHADE
|
||||||
T newValue;
|
T newValue;
|
||||||
SetterFunction set;
|
SetterFunction set;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SH_API SHCLICommand : SHBaseCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHCLICommand() = default;
|
||||||
|
void Execute() override
|
||||||
|
{
|
||||||
|
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->RedoScriptInspectorChanges();
|
||||||
|
}
|
||||||
|
void Undo() override
|
||||||
|
{
|
||||||
|
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->UndoScriptInspectorChanges();
|
||||||
|
}
|
||||||
|
};
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -27,6 +27,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::RegisterCommand(CommandPtr commandPtr)
|
||||||
|
{
|
||||||
|
undoStack.push(commandPtr);
|
||||||
|
}
|
||||||
|
|
||||||
void SHCommandManager::UndoCommand()
|
void SHCommandManager::UndoCommand()
|
||||||
{
|
{
|
||||||
if (undoStack.empty())
|
if (undoStack.empty())
|
||||||
|
|
|
@ -9,10 +9,11 @@
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "SHCommand.hpp"
|
#include "SHCommand.hpp"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHCommandManager
|
class SH_API SHCommandManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -22,6 +23,7 @@ namespace SHADE
|
||||||
using CommandStack = std::stack<CommandPtr>;
|
using CommandStack = std::stack<CommandPtr>;
|
||||||
|
|
||||||
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false);
|
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false);
|
||||||
|
static void RegisterCommand(CommandPtr commandPtr);
|
||||||
static void UndoCommand();
|
static void UndoCommand();
|
||||||
static void RedoCommand();
|
static void RedoCommand();
|
||||||
static std::size_t GetUndoStackSize();
|
static std::size_t GetUndoStackSize();
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
#include "SHHierarchyPanel.h"
|
#include "SHHierarchyPanel.h"
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Editor/DragDrop/SHDragDrop.hpp"
|
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||||
#include "Tools/SHException.h"
|
#include "Tools/SHException.h"
|
||||||
|
@ -21,6 +21,8 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
|
#include "Serialization/SHSerialization.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -62,11 +64,12 @@ namespace SHADE
|
||||||
|
|
||||||
if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
{
|
{
|
||||||
SHEditor::selectedEntities.clear();
|
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||||
|
editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
||||||
ImGui::End();
|
|
||||||
}
|
}
|
||||||
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHHierarchyPanel::Exit()
|
void SHHierarchyPanel::Exit()
|
||||||
|
@ -74,6 +77,11 @@ namespace SHADE
|
||||||
SHEditorWindow::Exit();
|
SHEditorWindow::Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::SetScrollTo(EntityID eid)
|
||||||
|
{
|
||||||
|
scrollTo = eid;
|
||||||
|
}
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Private Member Functions ||
|
//|| Private Member Functions ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -81,7 +89,20 @@ 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))
|
||||||
|
{
|
||||||
|
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))
|
||||||
{
|
{
|
||||||
SHEntityManager::CreateEntity();
|
SHEntityManager::CreateEntity();
|
||||||
}
|
}
|
||||||
|
@ -102,7 +123,16 @@ 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();
|
||||||
const bool isSelected = (std::ranges::find(SHEditor::selectedEntities, eid) != SHEditor::selectedEntities.end());
|
|
||||||
|
if(scrollTo != MAX_EID && eid == scrollTo)
|
||||||
|
{
|
||||||
|
ImGui::SetScrollHereY();
|
||||||
|
scrollTo = MAX_EID;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
|
||||||
|
const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
|
||||||
|
|
||||||
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
||||||
|
|
||||||
|
@ -114,7 +144,7 @@ namespace SHADE
|
||||||
|
|
||||||
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
||||||
//Draw Node
|
//Draw Node
|
||||||
bool isNodeOpen = ImGui::TreeNodeEx((void*)eid, nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str());
|
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(entity), nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(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
|
||||||
|
@ -140,8 +170,12 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if(!isSelected)
|
if(!isSelected)
|
||||||
{
|
{
|
||||||
SHEditor::selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
SHEditor::selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
|
}
|
||||||
|
if(ImGui::Selectable("Copy"))
|
||||||
|
{
|
||||||
|
SHLOG_INFO(SHSerialization::SerializeEntitiesToString(editor->selectedEntities))
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||||
{
|
{
|
||||||
|
@ -163,19 +197,19 @@ namespace SHADE
|
||||||
if (!isSelected)
|
if (!isSelected)
|
||||||
{
|
{
|
||||||
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||||
SHEditor::selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
SHEditor::selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
}//if not selected
|
}//if not selected
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||||
{
|
{
|
||||||
auto it = std::ranges::remove(SHEditor::selectedEntities, eid).begin();
|
auto it = std::ranges::remove(editor->selectedEntities, eid).begin();
|
||||||
}//if mod ctrl is not pressed
|
}//if mod ctrl is not pressed
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SHEditor::selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
SHEditor::selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
}
|
}
|
||||||
}//if selected
|
}//if selected
|
||||||
}//if left mouse button released
|
}//if left mouse button released
|
||||||
|
|
|
@ -23,11 +23,13 @@ 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;
|
||||||
std::string filter;
|
std::string filter;
|
||||||
bool isAnyNodeSelected = false;
|
bool isAnyNodeSelected = false;
|
||||||
|
EntityID scrollTo = MAX_EID;
|
||||||
};//class SHHierarchyPanel
|
};//class SHHierarchyPanel
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.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 "Reflection/SHReflectionMetadata.h"
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
||||||
|
@ -44,8 +46,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (!component)
|
if (!component)
|
||||||
return;
|
return;
|
||||||
auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
{
|
{
|
||||||
|
@ -55,14 +57,208 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
auto const& type = property.get_type();
|
auto const& type = property.get_type();
|
||||||
|
|
||||||
if (type == rttr::type::get<SHVec4>())
|
if (type.is_enumeration())
|
||||||
{
|
{
|
||||||
DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); });
|
auto enumAlign = type.get_enumeration();
|
||||||
|
auto names = enumAlign.get_names();
|
||||||
|
std::vector<const char*> list;
|
||||||
|
for (auto const& name : names)
|
||||||
|
list.push_back(name.data());
|
||||||
|
SHEditorWidgets::ComboBox(property.get_name().data(), list, [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& idx)
|
||||||
|
{
|
||||||
|
auto enumAlign = property.get_enumeration();
|
||||||
|
auto values = enumAlign.get_values();
|
||||||
|
auto it = std::next(values.begin(), idx);
|
||||||
|
property.set_value(component, *it);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (type.is_arithmetic())
|
||||||
|
{
|
||||||
|
if (type == rttr::type::get<bool>())
|
||||||
|
{
|
||||||
|
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property] {return property.get_value(component).to_bool(); }, [component, property](bool const& result) {property.set_value(component, result); });
|
||||||
|
}
|
||||||
|
//else if (type == rttr::type::get<char>())
|
||||||
|
//{
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
else if (type == rttr::type::get<int8_t>() || type == rttr::type::get<int16_t>() || type == rttr::type::get<int32_t>() || type == rttr::type::get<int64_t>())
|
||||||
|
{
|
||||||
|
auto metaMin = property.get_metadata(META::min);
|
||||||
|
auto metaMax = property.get_metadata(META::max);
|
||||||
|
if (metaMin && metaMax)
|
||||||
|
{
|
||||||
|
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMin.template get_value<int>(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditorWidgets::DragInt(property.get_name().data(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == rttr::type::get<uint8_t>())
|
||||||
|
{
|
||||||
|
auto metaMin = property.get_metadata(META::min);
|
||||||
|
auto metaMax = property.get_metadata(META::max);
|
||||||
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
|
{
|
||||||
|
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, "%zu");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == rttr::type::get<uint16_t>())
|
||||||
|
{
|
||||||
|
auto metaMin = property.get_metadata(META::min);
|
||||||
|
auto metaMax = property.get_metadata(META::max);
|
||||||
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
|
{
|
||||||
|
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMin.template get_value<uint16_t>(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, "%zu");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == rttr::type::get<uint32_t>())
|
||||||
|
{
|
||||||
|
auto metaMin = property.get_metadata(META::min);
|
||||||
|
auto metaMax = property.get_metadata(META::max);
|
||||||
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
|
{
|
||||||
|
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMin.template get_value<uint32_t>(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, "%zu");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == rttr::type::get<uint64_t>())
|
||||||
|
{
|
||||||
|
auto metaMin = property.get_metadata(META::min);
|
||||||
|
auto metaMax = property.get_metadata(META::max);
|
||||||
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
|
{
|
||||||
|
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMin.template get_value<uint64_t>(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, "%zu");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, 0.1f, 0, 0, "%zu");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == rttr::type::get<float>())
|
||||||
|
{
|
||||||
|
auto metaMin = property.get_metadata(META::min);
|
||||||
|
auto metaMax = property.get_metadata(META::max);
|
||||||
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
|
{
|
||||||
|
SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value<float>(), metaMin.template get_value<float>(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == rttr::type::get<double>())
|
||||||
|
{
|
||||||
|
auto metaMin = property.get_metadata(META::min);
|
||||||
|
auto metaMax = property.get_metadata(META::max);
|
||||||
|
if (metaMin.is_valid() && metaMax.is_valid())
|
||||||
|
{
|
||||||
|
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMin.template get_value<double>(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }, 0.1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == rttr::type::get<SHVec4>())
|
||||||
|
{
|
||||||
|
SHEditorWidgets::DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); });
|
||||||
}
|
}
|
||||||
else if (type == rttr::type::get<SHVec3>())
|
else if (type == rttr::type::get<SHVec3>())
|
||||||
{
|
{
|
||||||
DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); });
|
SHEditorWidgets::DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); });
|
||||||
}
|
}
|
||||||
|
else if (type == rttr::type::get<SHVec2>())
|
||||||
|
{
|
||||||
|
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y" }, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else DrawContextMenu(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
static void DrawComponent(SHColliderComponent* component)
|
||||||
|
{
|
||||||
|
if (!component)
|
||||||
|
return;
|
||||||
|
const auto componentType = rttr::type::get(*component);
|
||||||
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||||
|
{
|
||||||
|
DrawContextMenu(component);
|
||||||
|
|
||||||
|
auto& colliders = component->GetColliders();
|
||||||
|
int const size = static_cast<int>(colliders.size());
|
||||||
|
ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true);
|
||||||
|
std::optional<int> colliderToDelete{std::nullopt};
|
||||||
|
for (int i{}; i < size; ++i)
|
||||||
|
{
|
||||||
|
ImGui::PushID(i);
|
||||||
|
SHCollider& collider = component->GetCollider(i);
|
||||||
|
auto cursorPos = ImGui::GetCursorPos();
|
||||||
|
|
||||||
|
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 });
|
||||||
|
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);});
|
||||||
|
}
|
||||||
|
else if (collider.GetType() == SHCollider::Type::SPHERE)
|
||||||
|
{
|
||||||
|
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
|
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
|
||||||
|
SHEditorWidgets::DragFloat("Radius", [sphere] {return sphere->GetRadius(); }, [sphere](float const& value) {sphere->SetRadius(value);});
|
||||||
|
}
|
||||||
|
else if (collider.GetType() == SHCollider::Type::CAPSULE)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
{
|
||||||
|
SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f });
|
||||||
|
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider.GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider.SetPositionOffset(vec); });
|
||||||
|
SHEditorWidgets::EndPanel();
|
||||||
|
}
|
||||||
|
if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
||||||
|
{
|
||||||
|
colliderToDelete = i;
|
||||||
|
}
|
||||||
|
SHEditorWidgets::EndPanel();
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
if(colliderToDelete.has_value())
|
||||||
|
{
|
||||||
|
component->RemoveCollider(colliderToDelete.value());
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu("Add Collider"))
|
||||||
|
{
|
||||||
|
if(ImGui::Selectable("Box Collider"))
|
||||||
|
{
|
||||||
|
component->AddBoundingBox();
|
||||||
|
}
|
||||||
|
if(ImGui::Selectable("Sphere Collider"))
|
||||||
|
{
|
||||||
|
component->AddBoundingSphere();
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else DrawContextMenu(component);
|
else DrawContextMenu(component);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
#include "SHEditorInspector.h"
|
#include "SHEditorInspector.h"
|
||||||
|
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
@ -7,21 +8,31 @@
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
#include "Editor/SHEditor.hpp"
|
|
||||||
#include "Editor/SHImGuiHelpers.hpp"
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
#include "SHEditorComponentView.hpp"
|
#include "SHEditorComponentView.hpp"
|
||||||
|
#include "ECS_Base/UnitTesting/SHTestComponents.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "AudioSystem/SHAudioSystem.h"
|
||||||
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
void DrawAddComponentButton(EntityID const& eid)
|
bool DrawAddComponentButton(EntityID const& eid)
|
||||||
{
|
{
|
||||||
if(!SHComponentManager::HasComponent<ComponentType>(eid) && ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()))
|
bool selected = false;
|
||||||
|
if(!SHComponentManager::HasComponent<ComponentType>(eid))
|
||||||
{
|
{
|
||||||
|
if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()); selected)
|
||||||
SHComponentManager::AddComponent<ComponentType>(eid);
|
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||||
}
|
}
|
||||||
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHEditorInspector::SHEditorInspector()
|
SHEditorInspector::SHEditorInspector()
|
||||||
|
@ -39,13 +50,14 @@ namespace SHADE
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
if (!SHEditor::selectedEntities.empty())
|
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (editor && !editor->selectedEntities.empty())
|
||||||
{
|
{
|
||||||
EntityID const& eid = SHEditor::selectedEntities[0];
|
EntityID const& eid = editor->selectedEntities[0];
|
||||||
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
|
||||||
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
||||||
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();
|
||||||
|
|
||||||
ImGui::InputText("##EntityName", &entity->name);
|
ImGui::InputText("##EntityName", &entity->name);
|
||||||
|
@ -54,17 +66,42 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawComponent(transformComponent);
|
DrawComponent(transformComponent);
|
||||||
}
|
}
|
||||||
|
if(auto renderableComponent = SHComponentManager::GetComponent_s<SHRenderable>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(renderableComponent);
|
||||||
|
}
|
||||||
|
if(auto colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(colliderComponent);
|
||||||
|
}
|
||||||
|
if(auto rigidbodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(rigidbodyComponent);
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
// Render Scripts
|
||||||
|
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->RenderScriptsInInspector(eid);
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
||||||
{
|
{
|
||||||
DrawAddComponentButton<SHTransformComponent>(eid);
|
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||||
DrawAddComponentButton<SHRenderable>(eid);
|
DrawAddComponentButton<SHRenderable>(eid);
|
||||||
|
DrawAddComponentButton<SHColliderComponent>(eid);
|
||||||
|
if(DrawAddComponentButton<SHRigidBodyComponent>(eid))
|
||||||
|
{
|
||||||
|
if(SHComponentManager::GetComponent_s<SHTransformComponent>(eid) == nullptr)
|
||||||
|
{
|
||||||
|
SHComponentManager::AddComponent<SHTransformComponent>(eid);
|
||||||
|
}
|
||||||
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void SHEditorInspector::Exit()
|
void SHEditorInspector::Exit()
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,9 +3,12 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
#include "SHEditorMenuBar.h"
|
#include "SHEditorMenuBar.h"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "Editor/Command/SHCommandManager.h"
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -14,8 +17,7 @@
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
#include <rttr/type>
|
#include <rttr/type>
|
||||||
|
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Serialization/SHSerialization.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -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,15 +101,56 @@ namespace SHADE
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
if (ImGui::BeginMenu("Scripts"))
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable("Generate Visual Studio Project"))
|
||||||
|
{
|
||||||
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->GenerateScriptsCsProjFile();
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable("Build Scripts - Debug"))
|
||||||
|
{
|
||||||
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->BuildScriptAssembly(true, true);
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable("Build Scripts - Release"))
|
||||||
|
{
|
||||||
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->BuildScriptAssembly(false, true);
|
||||||
|
}
|
||||||
|
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"))
|
if (ImGui::BeginMenu("Theme"))
|
||||||
{
|
{
|
||||||
auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
|
const auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
|
||||||
auto values = styles.get_values();
|
auto values = styles.get_values();
|
||||||
for (auto style : values)
|
for (auto style : values)
|
||||||
{
|
{
|
||||||
if (ImGui::Selectable(style.to_string().c_str()))
|
if (ImGui::Selectable(style.to_string().c_str()))
|
||||||
{
|
{
|
||||||
SHEditor::SetStyle(style.convert<SHEditor::Style>());
|
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::EndMenu();
|
||||||
|
@ -103,15 +158,41 @@ namespace SHADE
|
||||||
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
|
||||||
|
@ -122,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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHEditorProfiler.h"
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "FRC/SHFramerateController.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHEditorProfiler::SHEditorProfiler()
|
||||||
|
:SHEditorWindow("Profiler", ImGuiWindowFlags_None)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorProfiler::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorProfiler::Update()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Update();
|
||||||
|
|
||||||
|
const float dt = static_cast<float>(SHFrameRateController::GetRawDeltaTime());
|
||||||
|
if(frames.size() > MaxFramesDisplayed)
|
||||||
|
{
|
||||||
|
for (size_t i = 1; i < frames.size(); i++)
|
||||||
|
{
|
||||||
|
frames[i-1] = frames[i];
|
||||||
|
}
|
||||||
|
frames[frames.size() - 1] = dt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frames.push_back(dt);
|
||||||
|
}
|
||||||
|
if(Begin())
|
||||||
|
{
|
||||||
|
ImGui::PlotLines("DT", frames.data(), static_cast<int>(frames.size()), 0, nullptr, 0.0f, 16.0f);
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorProfiler::Exit()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Exit();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
#include <vector>
|
||||||
|
constexpr uint32_t MaxFramesDisplayed = 100;
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHEditorProfiler final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHEditorProfiler();
|
||||||
|
void Init() override;
|
||||||
|
void Update() override;
|
||||||
|
void Exit() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<float> frames;
|
||||||
|
};
|
||||||
|
}
|
|
@ -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,30 @@ 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();
|
||||||
|
if(windowSize.x != wndSize.x || windowSize.y != wndSize.y)
|
||||||
|
{
|
||||||
|
windowSize = {wndSize.x, wndSize.y};
|
||||||
|
OnResize();
|
||||||
|
}
|
||||||
|
auto wndPos = ImGui::GetWindowPos();
|
||||||
|
if(windowPos.x != wndPos.x || windowPos.y != wndPos.y)
|
||||||
|
{
|
||||||
|
windowPos = {wndPos.x, wndPos.y};
|
||||||
|
OnPosChange();
|
||||||
|
}
|
||||||
|
isWindowHovered = ImGui::IsWindowHovered();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorWindow::OnResize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorWindow::OnPosChange()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Forward Declarations ||
|
//|| Forward Declarations ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -21,11 +23,18 @@ 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;
|
||||||
protected:
|
protected:
|
||||||
virtual bool Begin();
|
virtual bool Begin();
|
||||||
|
virtual void OnResize();
|
||||||
|
virtual void OnPosChange();
|
||||||
|
|
||||||
ImGuiWindowFlags windowFlags = 0;
|
ImGuiWindowFlags windowFlags = 0;
|
||||||
ImGuiIO& io;
|
ImGuiIO& io;
|
||||||
|
SHVec2 windowSize;
|
||||||
|
SHVec2 windowPos;
|
||||||
|
SHVec2 viewportMousePos;
|
||||||
};//class SHEditorWindow
|
};//class SHEditorWindow
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -2,3 +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 "ViewportWindow/SHEditorViewport.h" //Editor Viewport
|
|
@ -0,0 +1,84 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHEditorViewport.h"
|
||||||
|
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
|
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHEditorViewport::SHEditorViewport()
|
||||||
|
:SHEditorWindow("Viewport", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorViewport::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorViewport::Update()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Update();
|
||||||
|
if(Begin())
|
||||||
|
{
|
||||||
|
DrawMenuBar();
|
||||||
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
|
||||||
|
auto mousePos = ImGui::GetMousePos();
|
||||||
|
auto cursorPos = ImGui::GetCursorScreenPos();
|
||||||
|
viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y};
|
||||||
|
gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos);
|
||||||
|
//if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
|
//{
|
||||||
|
// auto eid = gfxSystem->GetMousePickSystem ()->GetPickedEntity();
|
||||||
|
// if(eid != MAX_EID)
|
||||||
|
// {
|
||||||
|
// auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
// editor->selectedEntities.clear();
|
||||||
|
// editor->selectedEntities.push_back(eid);
|
||||||
|
// if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>())
|
||||||
|
// {
|
||||||
|
// hierarchyPanel->SetScrollTo(eid);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize());
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = {}
|
||||||
|
gfxSystem->PrepareResize(static_cast<uint32_t>(windowSize.x), static_cast<uint32_t>(windowSize.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorViewport::OnPosChange()
|
||||||
|
{
|
||||||
|
SHEditorWindow::OnPosChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorViewport::DrawMenuBar() const noexcept
|
||||||
|
{
|
||||||
|
if(ImGui::BeginMenuBar())
|
||||||
|
{
|
||||||
|
ImGui::EndMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "imgui_internal.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHEditorViewport final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHEditorViewport();
|
||||||
|
void Init() override;
|
||||||
|
void Update() override;
|
||||||
|
void Exit() override;
|
||||||
|
protected:
|
||||||
|
void OnResize() override;
|
||||||
|
void OnPosChange() override;
|
||||||
|
private:
|
||||||
|
void DrawMenuBar() const noexcept;
|
||||||
|
};//class SHEditorViewport
|
||||||
|
}//namespace SHADE
|
|
@ -843,7 +843,7 @@
|
||||||
#define ICON_MD_FLIP_TO_FRONT "\xee\xa2\x83" // U+e883
|
#define ICON_MD_FLIP_TO_FRONT "\xee\xa2\x83" // U+e883
|
||||||
#define ICON_MD_FLOOD "\xee\xaf\xa6" // U+ebe6
|
#define ICON_MD_FLOOD "\xee\xaf\xa6" // U+ebe6
|
||||||
#define ICON_MD_FLOURESCENT "\xee\xb0\xb1" // U+ec31
|
#define ICON_MD_FLOURESCENT "\xee\xb0\xb1" // U+ec31
|
||||||
#define ICON_MD_FLOURESCENT "\xef\x80\x8d" // U+f00d
|
#define ICON_MD_FLOURESCENT2 "\xef\x80\x8d" // U+f00d
|
||||||
#define ICON_MD_FLUORESCENT "\xee\xb0\xb1" // U+ec31
|
#define ICON_MD_FLUORESCENT "\xee\xb0\xb1" // U+ec31
|
||||||
#define ICON_MD_FLUTTER_DASH "\xee\x80\x8b" // U+e00b
|
#define ICON_MD_FLUTTER_DASH "\xee\x80\x8b" // U+e00b
|
||||||
#define ICON_MD_FMD_BAD "\xef\x80\x8e" // U+f00e
|
#define ICON_MD_FMD_BAD "\xef\x80\x8e" // U+f00e
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "SHEditor.hpp"
|
#include "SHEditor.hpp"
|
||||||
#include "SHEditorWidgets.hpp"
|
#include "SHEditorWidgets.hpp"
|
||||||
|
|
||||||
|
#include "Math/Transform/SHTransformSystem.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Editor Window Includes ||
|
//|| Editor Window Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -41,6 +43,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;
|
||||||
|
@ -58,19 +62,20 @@ RTTR_REGISTRATION
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Initialise static members ||
|
//|| Init static members ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
//Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
||||||
Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
|
//Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
|
||||||
SHEditor::EditorWindowMap SHEditor::editorWindows{};
|
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
|
||||||
SHEditor::EditorWindowID SHEditor::windowCount{};
|
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
|
||||||
std::vector<EntityID> SHEditor::selectedEntities;
|
//std::vector<EntityID> SHEditor::selectedEntities;
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Public Member Functions ||
|
//|| Public Member Functions ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
void SHEditor::Initialise(SDL_Window* const sdlWindow)
|
void SHEditor::Init()
|
||||||
{
|
{
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
if(auto context = ImGui::CreateContext())
|
if(auto context = ImGui::CreateContext())
|
||||||
{
|
{
|
||||||
|
@ -80,32 +85,48 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
//Add editor windows
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
||||||
|
|
||||||
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";
|
||||||
|
|
||||||
|
InitLayout();
|
||||||
|
|
||||||
InitFonts();
|
InitFonts();
|
||||||
InitBackend(sdlWindow);
|
|
||||||
|
auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||||
|
auto id2 = SHFamilyID<SHSystem>::GetID<SHTransformSystem>();
|
||||||
|
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||||
|
|
||||||
|
InitBackend();
|
||||||
|
|
||||||
SetStyle(Style::SHADE);
|
SetStyle(Style::SHADE);
|
||||||
|
|
||||||
//Add editor windows
|
|
||||||
CreateEditorWindow<SHEditorMenuBar>();
|
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||||
CreateEditorWindow<SHHierarchyPanel>();
|
{
|
||||||
CreateEditorWindow<SHEditorInspector>();
|
window->Init();
|
||||||
|
}
|
||||||
|
|
||||||
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::Update(float const dt)
|
void SHEditor::Update(double const dt)
|
||||||
{
|
{
|
||||||
(void)dt;
|
(void)dt;
|
||||||
NewFrame();
|
NewFrame();
|
||||||
|
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||||
for (const auto& window : editorWindows | std::views::values)
|
|
||||||
{
|
{
|
||||||
|
if(window->isOpen)
|
||||||
window->Update();
|
window->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,35 +139,45 @@ 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 };
|
constexpr ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
||||||
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.PixelSnapH = true;
|
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
||||||
ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path
|
ImFont* UIFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path
|
||||||
|
|
||||||
io.Fonts->Build();
|
io->Fonts->Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::Exit()
|
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();
|
||||||
|
@ -252,7 +283,7 @@ namespace SHADE
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Private Member Functions ||
|
//|| Private Member Functions ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
void SHEditor::InitBackend(SDL_Window* sdlWindow)
|
void SHEditor::InitBackend()
|
||||||
{
|
{
|
||||||
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
|
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
|
||||||
{
|
{
|
||||||
|
@ -273,10 +304,11 @@ namespace SHADE
|
||||||
imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||||
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
|
||||||
auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
//auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||||
|
auto const& renderers = gfxSystem->GetEditorViewport()->GetRenderers();
|
||||||
|
|
||||||
SHASSERT(!renderers.empty(), "No Renderers available")
|
SHASSERT(!renderers.empty(), "No Renderers available")
|
||||||
auto renderGraph = renderers[0]->GetRenderGraph();
|
auto renderGraph = renderers[SHGraphicsConstants::RenderGraphIndices::EDITOR]->GetRenderGraph();
|
||||||
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
|
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
|
||||||
|
|
||||||
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
||||||
|
@ -292,6 +324,8 @@ namespace SHADE
|
||||||
imguiCommandBuffer->EndRecording();
|
imguiCommandBuffer->EndRecording();
|
||||||
gfxSystem->GetQueue()->SubmitCommandBuffer({ imguiCommandBuffer }, {}, {}, vk::PipelineStageFlagBits::eNone, {});
|
gfxSystem->GetQueue()->SubmitCommandBuffer({ imguiCommandBuffer }, {}, {}, vk::PipelineStageFlagBits::eNone, {});
|
||||||
|
|
||||||
|
gfxSystem->GetDevice()->WaitIdle();
|
||||||
|
|
||||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||||
|
|
||||||
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
||||||
|
@ -299,6 +333,29 @@ namespace SHADE
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::PollPicking()
|
||||||
|
{
|
||||||
|
if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
|
||||||
|
{
|
||||||
|
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
|
||||||
|
if (viewportWindow->isWindowHovered && 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;
|
||||||
|
@ -312,4 +369,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHEditor::EditorRoutine::Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
reinterpret_cast<SHEditor*>(system)->Update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
#include "Resource/Handle.h"
|
#include "Resource/Handle.h"
|
||||||
#include "EditorWindow/SHEditorWindow.h"
|
#include "EditorWindow/SHEditorWindow.h"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
|
@ -28,11 +30,7 @@ namespace SHADE
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
class SHVkCommandPool;
|
class SHVkCommandPool;
|
||||||
|
|
||||||
/**
|
class SHEditorWindowManager
|
||||||
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class SH_API SHEditor
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -41,46 +39,6 @@ namespace SHADE
|
||||||
using EditorWindowID = uint8_t;
|
using EditorWindowID = uint8_t;
|
||||||
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
||||||
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Style options
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
enum class Style : uint8_t
|
|
||||||
{
|
|
||||||
SHADE,
|
|
||||||
DARK,
|
|
||||||
LIGHT,
|
|
||||||
CLASSIC
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialise the editor
|
|
||||||
*
|
|
||||||
* @param sdlWindow pointer to SDL_Window object created in application
|
|
||||||
*/
|
|
||||||
static void Initialise(SDL_Window* sdlWindow);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update the editor and add to ImGui DrawList
|
|
||||||
*
|
|
||||||
* @param dt Delta-time of the frame
|
|
||||||
*/
|
|
||||||
static void Update(float dt);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Safely shutdown the editor
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void Exit();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the Style for the editor
|
|
||||||
*
|
|
||||||
* @param style Desired style
|
|
||||||
*/
|
|
||||||
static void SetStyle(Style style);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get ID for the Editor Window Type
|
* @brief Get ID for the Editor Window Type
|
||||||
*
|
*
|
||||||
|
@ -100,39 +58,6 @@ namespace SHADE
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get pointer to the Editor Window
|
|
||||||
*
|
|
||||||
* @tparam T Type of editor window to retrieve
|
|
||||||
* @return T* Pointer to the editor window
|
|
||||||
*/
|
|
||||||
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
|
||||||
static T* GetEditorWindow()
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
|
|
||||||
}
|
|
||||||
|
|
||||||
// List of selected entities
|
|
||||||
static std::vector<EntityID> selectedEntities;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief Initialise Backend for ImGui (SDL and Vulkan backend)
|
|
||||||
*
|
|
||||||
* @param sdlWindow Pointer to SDL_Window
|
|
||||||
*/
|
|
||||||
static void InitBackend(SDL_Window* sdlWindow);
|
|
||||||
/**
|
|
||||||
* @brief Start new frame for editor
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void NewFrame();
|
|
||||||
/**
|
|
||||||
* @brief Perform ImGui and ImGui Backend Render
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void Render();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create an Editor Window
|
* @brief Create an Editor Window
|
||||||
*
|
*
|
||||||
|
@ -153,16 +78,127 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void InitFonts() noexcept;
|
/**
|
||||||
|
* @brief Get pointer to the Editor Window
|
||||||
// Handle to command pool used for ImGui Vulkan Backend
|
*
|
||||||
static Handle<SHVkCommandPool> imguiCommandPool;
|
* @tparam T Type of editor window to retrieve
|
||||||
// Handle to command buffer used for ImGui Vulkan Backend
|
* @return T* Pointer to the editor window
|
||||||
static Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||||
|
static T* GetEditorWindow()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
|
||||||
|
}
|
||||||
|
|
||||||
|
static EditorWindowMap editorWindows;
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class SH_API SHEditor final : public SHSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
class SH_API EditorRoutine final : public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorRoutine():SHSystemRoutine("Editor routine", true) {};
|
||||||
|
void Execute(double dt) noexcept override final;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class State : uint8_t
|
||||||
|
{
|
||||||
|
PLAY,
|
||||||
|
PAUSE,
|
||||||
|
STOP
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Style options
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
enum class Style : uint8_t
|
||||||
|
{
|
||||||
|
SHADE,
|
||||||
|
DARK,
|
||||||
|
LIGHT,
|
||||||
|
CLASSIC
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialise the editor
|
||||||
|
*
|
||||||
|
* @param sdlWindow pointer to SDL_Window object created in application
|
||||||
|
*/
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update the editor and add to ImGui DrawList
|
||||||
|
*
|
||||||
|
* @param dt Delta-time of the frame
|
||||||
|
*/
|
||||||
|
void Update(double dt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Safely shutdown the editor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Exit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the Style for the editor
|
||||||
|
*
|
||||||
|
* @param style Desired style
|
||||||
|
*/
|
||||||
|
void SetStyle(Style style);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialise Backend for ImGui (SDL and Vulkan backend)
|
||||||
|
*
|
||||||
|
* @param sdlWindow Pointer to SDL_Window
|
||||||
|
*/
|
||||||
|
void InitBackend();
|
||||||
|
|
||||||
|
void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
|
||||||
|
|
||||||
|
void PollPicking();
|
||||||
|
|
||||||
|
// List of selected entities
|
||||||
|
std::vector<EntityID> selectedEntities;
|
||||||
|
|
||||||
|
State editorState = State::STOP;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Start new frame for editor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void NewFrame();
|
||||||
|
/**
|
||||||
|
* @brief Perform ImGui and ImGui Backend Render
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Render();
|
||||||
|
|
||||||
|
void InitLayout() noexcept;
|
||||||
|
|
||||||
|
void InitFonts() noexcept;
|
||||||
|
|
||||||
|
// Handle to command pool used for ImGui Vulkan Backend
|
||||||
|
Handle<SHVkCommandPool> imguiCommandPool;
|
||||||
|
// Handle to command buffer used for ImGui Vulkan Backend
|
||||||
|
Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
||||||
|
|
||||||
|
SDL_Window* sdlWindow {nullptr};
|
||||||
|
|
||||||
|
ImGuiIO* io{nullptr};
|
||||||
};//class SHEditor
|
};//class SHEditor
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -0,0 +1,292 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file EditorUI.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Nov 7, 2021
|
||||||
|
\brief Contains the implementation of the EditorUI class.
|
||||||
|
|
||||||
|
Copyright (C) 2021 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
// Precompiled Header
|
||||||
|
#include "SHpch.h"
|
||||||
|
// Primary Header
|
||||||
|
#include "SHEditorUI.h"
|
||||||
|
// External Dependencies
|
||||||
|
#include <imgui.h>
|
||||||
|
#include "SHEditorWidgets.hpp"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - ID Stack */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
void SHEditorUI::PushID(const std::string& id)
|
||||||
|
{
|
||||||
|
ImGui::PushID(id.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::PushID(int id)
|
||||||
|
{
|
||||||
|
ImGui::PushID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::PopID()
|
||||||
|
{
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Indent */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
void SHEditorUI::Indent()
|
||||||
|
{
|
||||||
|
ImGui::Indent();
|
||||||
|
}
|
||||||
|
void SHEditorUI::Unindent()
|
||||||
|
{
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Organizers */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
bool SHEditorUI::CollapsingHeader(const std::string& title)
|
||||||
|
{
|
||||||
|
return ImGui::CollapsingHeader(title.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::SameLine()
|
||||||
|
{
|
||||||
|
ImGui::SameLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::Separator()
|
||||||
|
{
|
||||||
|
ImGui::Separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::IsItemHovered()
|
||||||
|
{
|
||||||
|
return ImGui::IsItemHovered();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::BeginMenu(const std::string& label)
|
||||||
|
{
|
||||||
|
return ImGui::BeginMenu(label.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::BeginMenu(const std::string& label, const char* icon)
|
||||||
|
{
|
||||||
|
return ImGui::BeginMenu(std::format("{} {}", icon, label.data()).data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::EndMenu()
|
||||||
|
{
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::BeginTooltip()
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::EndTooltip()
|
||||||
|
{
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Pop Ups */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
bool SHEditorUI::BeginPopup(const std::string& label)
|
||||||
|
{
|
||||||
|
return ImGui::BeginPopup(label.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::BeginPopupContextItem(const std::string& label)
|
||||||
|
{
|
||||||
|
return ImGui::BeginPopupContextItem(label.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorUI::EndPopup()
|
||||||
|
{
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
void SHEditorUI::OpenPopup(const std::string& label)
|
||||||
|
{
|
||||||
|
ImGui::OpenPopup(label.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::MenuItem(const std::string& label)
|
||||||
|
{
|
||||||
|
return ImGui::MenuItem(label.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Widgets */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
void SHEditorUI::Text(const std::string& title)
|
||||||
|
{
|
||||||
|
ImGui::Text(title.c_str());
|
||||||
|
}
|
||||||
|
bool SHEditorUI::SmallButton(const std::string& title)
|
||||||
|
{
|
||||||
|
return ImGui::SmallButton(title.c_str());
|
||||||
|
}
|
||||||
|
bool SHEditorUI::Button(const std::string& title)
|
||||||
|
{
|
||||||
|
return ImGui::Button(title.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::Selectable(const std::string& label)
|
||||||
|
{
|
||||||
|
return ImGui::Selectable(label.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::Selectable(const std::string& label, const char* icon)
|
||||||
|
{
|
||||||
|
return ImGui::Selectable(std::format("{} {}", icon, label).data());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
return ImGui::Checkbox("#", &value);
|
||||||
|
}
|
||||||
|
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
return ImGui::InputInt("#", &value,
|
||||||
|
1, 10,
|
||||||
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
|
}
|
||||||
|
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
int signedVal = static_cast<int>(value);
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
const bool CHANGED = InputInt("#", signedVal);
|
||||||
|
if (CHANGED)
|
||||||
|
{
|
||||||
|
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
|
||||||
|
value = static_cast<unsigned int>(signedVal);
|
||||||
|
}
|
||||||
|
return CHANGED;
|
||||||
|
}
|
||||||
|
bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
return ImGui::InputFloat("#", &value,
|
||||||
|
0.1f, 1.0f, "%.3f",
|
||||||
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
|
}
|
||||||
|
bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
return ImGui::InputDouble("#", &value,
|
||||||
|
0.1, 1.0, "%.3f",
|
||||||
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
|
}
|
||||||
|
bool SHEditorUI::InputAngle(const std::string& label, double& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
return ImGui::InputDouble("#", &value,
|
||||||
|
1.0, 45.0, "%.3f",
|
||||||
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
float val = static_cast<float>(value);
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
const bool CHANGED = ImGui::SliderFloat("#", &val,
|
||||||
|
static_cast<float>(min), static_cast<float>(max), "%.3f",
|
||||||
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
|
|
||||||
|
if (CHANGED)
|
||||||
|
{
|
||||||
|
value = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
static const std::vector<std::string> COMPONENT_LABELS = { "X", "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, bool* isHovered, float speed)
|
||||||
|
{
|
||||||
|
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", float{}, float{}, 0, isHovered);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::InputTextField(const std::string& label, std::string& value, bool* isHovered)
|
||||||
|
{
|
||||||
|
std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' };
|
||||||
|
strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str());
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
||||||
|
if (CHANGED)
|
||||||
|
{
|
||||||
|
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
|
||||||
|
}
|
||||||
|
return CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered)
|
||||||
|
{
|
||||||
|
// Clamp input value
|
||||||
|
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
|
||||||
|
bool b = false;
|
||||||
|
|
||||||
|
ImGui::Text(label.c_str());
|
||||||
|
if (isHovered)
|
||||||
|
*isHovered = ImGui::IsItemHovered();
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < enumNames.size(); ++i)
|
||||||
|
{
|
||||||
|
const bool IS_SELECTED = v == i;
|
||||||
|
if (ImGui::Selectable(enumNames[i].c_str(), IS_SELECTED))
|
||||||
|
{
|
||||||
|
v = i;
|
||||||
|
b = true;
|
||||||
|
}
|
||||||
|
if (IS_SELECTED)
|
||||||
|
{
|
||||||
|
ImGui::SetItemDefaultFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,305 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHEditorUI.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\par email: t.yanchongclarence\@digipen.edu
|
||||||
|
\date Sep 27, 2022
|
||||||
|
\brief Defines a class that contains wrapper functions for ImGui.
|
||||||
|
|
||||||
|
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
|
||||||
|
// Standard Library
|
||||||
|
#include <functional> // std::function
|
||||||
|
#include <string> // std::string
|
||||||
|
// Project Includes
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
#include "Math/SHMatrix.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Static class that contains useful functions for Editor UI using ImGui.
|
||||||
|
/// </summary>
|
||||||
|
class SH_API SHEditorUI final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Constants */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum length of a string supported by InputTextField()
|
||||||
|
/// </summary>
|
||||||
|
static constexpr size_t TEXT_FIELD_MAX_LENGTH = 256;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - ID Stack */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Marks the start of a stack of ImGui widgets with the specified id.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::PushID().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">String-based ID.</param>
|
||||||
|
static void PushID(const std::string& id);
|
||||||
|
/// <summary>
|
||||||
|
/// Marks the start of a stack of ImGui widgets with the specified id.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::PushID().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Integer-based ID.</param>
|
||||||
|
static void PushID(int id);
|
||||||
|
/// <summary>
|
||||||
|
/// Marks the end of a stack of ImGui widgets from the last PushID() call.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::PopID().
|
||||||
|
/// </summary>
|
||||||
|
static void PopID();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Indent */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Indents the widgets rendered after this call.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::Indent().
|
||||||
|
/// </summary>
|
||||||
|
static void Indent();
|
||||||
|
/// <summary>
|
||||||
|
/// Unindents the widgets rendered after this call.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::Unindent().
|
||||||
|
/// </summary>
|
||||||
|
static void Unindent();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Organizers */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a collapsing title header.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::CollapsingHeader().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="title">Label for the header.</param>
|
||||||
|
/// <returns>True if the header is open, false otherwise.</returns>
|
||||||
|
static bool CollapsingHeader(const std::string& title);
|
||||||
|
static void SameLine();
|
||||||
|
static void Separator();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Queries */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static bool IsItemHovered();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Menu */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static bool BeginMenu(const std::string& label);
|
||||||
|
static bool BeginMenu(const std::string& label, const char* icon);
|
||||||
|
static void EndMenu();
|
||||||
|
static void BeginTooltip();
|
||||||
|
static void EndTooltip();
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Pop Ups */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Marks the start of a definition of a mini pop up that can show options.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::BeginPopup().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
|
/// <returns>Whether or not the pop up is open.</returns>
|
||||||
|
static bool BeginPopup(const std::string& label);
|
||||||
|
static bool BeginPopupContextItem(const std::string& label);
|
||||||
|
/// <summary>
|
||||||
|
/// Marks the end of a definition of a mini pop up that can show options.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::EndPopup().
|
||||||
|
/// </summary>
|
||||||
|
static void EndPopup();
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the popup that was defined with the specified label.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::OpenPopup().
|
||||||
|
/// </summary>
|
||||||
|
static void OpenPopup(const std::string& label);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a menu item in the list of items for a mini popup.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::MenuItem().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</param>
|
||||||
|
/// <returns>Whether or not the menu item was selected.</returns>
|
||||||
|
static bool MenuItem(const std::string& label);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Widgets */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a visual text widget.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::Text().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="title">Text to display.</param>
|
||||||
|
static void Text(const std::string& title);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a small inline button widget.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::SmallButton().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="title">Text to display.</param>
|
||||||
|
/// <returns>True if button was pressed.</returns>
|
||||||
|
static bool SmallButton(const std::string& title);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a inline button widget.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::Button().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="title">Text to display.</param>
|
||||||
|
/// <returns>True if button was pressed.</returns>
|
||||||
|
static bool Button(const std::string& title);
|
||||||
|
static bool Selectable(const std::string& label);
|
||||||
|
static bool Selectable(const std::string& label, const char* icon);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a checkbox widget for boolean input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::Checkbox().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</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 InputCheckbox(const std::string& label, bool& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a integer field widget for integer input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::InputInt().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</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 InputInt(const std::string& label, int& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a integer field widget for unsigned integer input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::InputInt() with an additional clamping of values.
|
||||||
|
/// <br/>
|
||||||
|
/// Note: As a result, the range of this function limits it to the maximum
|
||||||
|
/// value of a 32-bit signed integer instead of a 32-bit unsigned integer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</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 InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a decimal field widget for single precision float input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::InputFloat().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</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 InputFloat(const std::string& label, float& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a decimal field widget for double precision float input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::InputDouble().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</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 InputDouble(const std::string& label, double& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a decimal field widget for double input with increments of higher
|
||||||
|
/// steps meant for angle variables.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::InputDouble().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</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 InputAngle(const std::string& label, double& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a double slider field widget for double input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::InputSliderFloat().
|
||||||
|
/// </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>
|
||||||
|
/// Creates a 2x double field widget for Vector2 input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::InputFloat2().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</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 InputVec2(const std::string& label, SHVec2& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a 3x double field widget for Vector3 input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::InputFloat3().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</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 InputVec3(const std::string& label, SHVec3& value, bool* isHovered = nullptr, float speed = 0.1f);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a text field widget for string input.
|
||||||
|
/// <br/>
|
||||||
|
/// Wraps up ImGui::InputText().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">Label used to identify this widget.</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 InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a combo box for enumeration input.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="Enum">The type of enum to input.</typeparam>
|
||||||
|
/// <param name="label">The name of the input.</param>
|
||||||
|
/// <param name="v">The reference to the value to modify.</param>
|
||||||
|
/// <param name="maxVal">The maximum value of the enum.</param>
|
||||||
|
/// <param name="toStrFn">
|
||||||
|
/// Conversion function from the type of enum to C-style string.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
|
/// <returns>Whether the value was modified.</returns>
|
||||||
|
template<typename Enum>
|
||||||
|
static bool InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char*(Enum)> toStrFn, bool* isHovered = nullptr);
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a combo box for enumeration input using a specified list of names.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="label">The name of the input.</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="isHovered>If set, stores the hover state of this widget.</param>
|
||||||
|
/// <returns>Whether the value was modified.</returns>
|
||||||
|
static bool InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered = nullptr);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Prevent instantiation of this static class
|
||||||
|
SHEditorUI() = delete;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "SHEditorUI.hpp"
|
|
@ -0,0 +1,56 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHEditorUI.hpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 27, 2022
|
||||||
|
\brief Contains the implementation of editor inspector template functions.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
// Primary Header
|
||||||
|
#include "SHEditorUI.h"
|
||||||
|
// External Dependencies
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* ImGui Wrapper Functions - Widgets */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
template<typename Enum>
|
||||||
|
inline bool SHEditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char* (Enum)> toStrFn, bool* isHovered)
|
||||||
|
{
|
||||||
|
std::vector<Enum> values;
|
||||||
|
for (int i = 0; i <= maxVal; ++i)
|
||||||
|
{
|
||||||
|
values.emplace_back(static_cast<Enum>(i));
|
||||||
|
}
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= maxVal; ++i)
|
||||||
|
{
|
||||||
|
const auto VALUE = values[i];
|
||||||
|
const bool IS_SELECTED = v == VALUE;
|
||||||
|
if (ImGui::Selectable(toStrFn(VALUE), IS_SELECTED))
|
||||||
|
{
|
||||||
|
v = VALUE;
|
||||||
|
b = true;
|
||||||
|
}
|
||||||
|
if (IS_SELECTED)
|
||||||
|
{
|
||||||
|
ImGui::SetItemDefaultFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
#include "Math/SHMath.h"
|
#include "Math/SHMath.h"
|
||||||
#include "Command/SHCommandManager.h"
|
#include "Command/SHCommandManager.h"
|
||||||
#include "SHImGuiHelpers.hpp"
|
#include "SHImGuiHelpers.hpp"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -23,9 +24,129 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
class SH_API SHEditorWidgets
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Constructor ||
|
||||||
|
//#==============================================================#
|
||||||
|
SHEditorWidgets() = delete;
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Custom Widgets ||
|
//|| Custom Widgets ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
inline static ImVector<ImRect> panelStack{};
|
||||||
|
static void BeginPanel(std::string_view const& name, const ImVec2& size)
|
||||||
|
{
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
|
auto cursorPos = ImGui::GetCursorScreenPos();
|
||||||
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
|
ImVec2 effectiveSize = size;
|
||||||
|
if (size.x < 0.0f)
|
||||||
|
effectiveSize.x = ImGui::GetContentRegionAvail().x;
|
||||||
|
else
|
||||||
|
effectiveSize.x = size.x;
|
||||||
|
ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f));
|
||||||
|
|
||||||
|
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
ImGui::TextUnformatted(name.data());
|
||||||
|
auto labelMin = ImGui::GetItemRectMin();
|
||||||
|
auto labelMax = ImGui::GetItemRectMax();
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
|
||||||
|
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f;
|
||||||
|
|
||||||
|
ImGui::GetCurrentWindow()->Size.x -= frameHeight;
|
||||||
|
|
||||||
|
auto itemWidth = ImGui::CalcItemWidth();
|
||||||
|
ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
|
||||||
|
|
||||||
|
panelStack.push_back(ImRect(labelMin, labelMax));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void EndPanel()
|
||||||
|
{
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
auto frameHeight = ImGui::GetFrameHeight();
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||||
|
ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y));
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
auto itemMin = ImGui::GetItemRectMin();
|
||||||
|
auto itemMax = ImGui::GetItemRectMax();
|
||||||
|
|
||||||
|
auto labelRect = panelStack.back();
|
||||||
|
panelStack.pop_back();
|
||||||
|
|
||||||
|
ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
|
||||||
|
ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
|
||||||
|
labelRect.Min.x -= itemSpacing.x;
|
||||||
|
labelRect.Max.x += itemSpacing.x;
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
// left half-plane
|
||||||
|
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break;
|
||||||
|
// right half-plane
|
||||||
|
case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
|
||||||
|
// top
|
||||||
|
case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, -FLT_MAX), ImVec2(labelRect.Max.x, labelRect.Min.y), true); break;
|
||||||
|
// bottom
|
||||||
|
case 3: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::GetWindowDrawList()->AddRect(
|
||||||
|
frameRect.Min, frameRect.Max,
|
||||||
|
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Button)),
|
||||||
|
halfFrame.x);
|
||||||
|
|
||||||
|
ImGui::PopClipRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
|
||||||
|
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f;
|
||||||
|
ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f;
|
||||||
|
|
||||||
|
ImGui::GetCurrentWindow()->Size.x += frameHeight;
|
||||||
|
|
||||||
|
ImGui::Dummy(ImVec2(0.0f, 0.0f));
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f)
|
static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f)
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
|
@ -39,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)
|
||||||
|
@ -53,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)
|
||||||
{
|
{
|
||||||
|
@ -182,6 +305,148 @@ namespace SHADE
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool InputText(const std::string& label, const std::function<std::string(void)> get,
|
||||||
|
const std::function<void(std::string)> set, ImGuiInputTextFlags flag = 0,
|
||||||
|
ImGuiInputTextCallback callback = (ImGuiInputTextCallback)0, void* userData = (void*)0)
|
||||||
|
{
|
||||||
|
std::string text = get();
|
||||||
|
if (ImGui::InputText(label.c_str(), &text, flag, callback, userData))
|
||||||
|
{
|
||||||
|
if (ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static bool DragScalar(const std::string& fieldLabel, ImGuiDataType data_type, std::function<T(void)> get, std::function<void(T const&)> set,
|
||||||
|
float speed = 1.0f, T p_min = T(), T p_max = T(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
T value = get();
|
||||||
|
std::cout << value << " \n";
|
||||||
|
//bool hasChange = ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags);
|
||||||
|
|
||||||
|
if (ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags))
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||||
|
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
|
||||||
|
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DragFloat(const std::string& fieldLabel, std::function<float(void)> get, std::function<void(float const&)> set,
|
||||||
|
float speed = 0.1f, float p_min = float(), float p_max = float(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
float value = get();
|
||||||
|
//bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags);
|
||||||
|
if (ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags))
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
|
||||||
|
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
|
||||||
|
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DragInt(const std::string& fieldLabel, std::function<int(void)> get, std::function<void(int const&)> set,
|
||||||
|
float speed = 1.0f, int p_min = int(), int p_max = int(), const char* displayFormat = "%d", ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
int value = get();
|
||||||
|
//bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags);
|
||||||
|
if (ImGui::DragInt(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags))
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
|
||||||
|
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
|
||||||
|
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function<T(void)> get, std::function<void(T const&)> set,
|
||||||
|
const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
T value = get();
|
||||||
|
if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags))
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||||
|
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function<float(void)> get, std::function<void(float const&)> set,
|
||||||
|
const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
float value = get();
|
||||||
|
if (ImGui::SliderFloat(fieldLabel.c_str(), &value, min, max, displayFormat, flags))
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
|
||||||
|
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function<int(void)> get, std::function<void(int const&)> set,
|
||||||
|
const char* displayFormat = "%d", ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
int value = get();
|
||||||
|
if (ImGui::SliderInt(fieldLabel.c_str(), &value, min, max, displayFormat, flags))
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
|
||||||
|
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ComboBox(const std::string& fieldLabel, std::vector<const char*> list, std::function<int(void)> get, std::function<void(int const&)> set)
|
||||||
|
{
|
||||||
|
bool edited = false;
|
||||||
|
int selected = get();
|
||||||
|
ImGui::PushID(fieldLabel.c_str());
|
||||||
|
ImGui::Text(fieldLabel.c_str()); ImGui::SameLine();
|
||||||
|
|
||||||
|
if (edited = ImGui::Combo("##Combo", &selected, list.data(), static_cast<int>(list.size())))
|
||||||
|
{
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), selected, set)), false);
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
return edited;
|
||||||
|
}
|
||||||
|
};
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -8,3 +8,5 @@ typedef uint32_t SHEventHandle;
|
||||||
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_REMOVED_EVENT{ 4 };
|
||||||
|
|
|
@ -9,12 +9,31 @@
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
//TODO Legacy code. Delete soon
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <SHpch.h>
|
#include <SHpch.h>
|
||||||
#include "SHFramerateController.h"
|
#include "SHFramerateController.h"
|
||||||
#include "../Tools/SHLogger.h"
|
#include "../Tools/SHLogger.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
double SHFrameRateController::rawDeltaTime = 0.0;
|
||||||
|
std::chrono::steady_clock::time_point SHFrameRateController::prevFrameTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
void SHFrameRateController::UpdateFRC() noexcept
|
||||||
|
{
|
||||||
|
std::chrono::duration<double> deltaTime;
|
||||||
|
deltaTime = std::chrono::high_resolution_clock::now() - prevFrameTime;
|
||||||
|
prevFrameTime = std::chrono::high_resolution_clock::now();
|
||||||
|
rawDeltaTime = deltaTime.count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO Legacy code. Delete soon
|
||||||
|
#if 0
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
//Init statics
|
//Init statics
|
||||||
|
@ -132,3 +151,4 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
|
@ -13,6 +13,38 @@
|
||||||
#define SH_FRAMERATECONTROLLER_H
|
#define SH_FRAMERATECONTROLLER_H
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SH_API SHFrameRateController
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//Varying delta time. The actual time it took for every frame
|
||||||
|
static double rawDeltaTime;
|
||||||
|
static std::chrono::steady_clock::time_point prevFrameTime;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Gets the raw delta time
|
||||||
|
static inline double GetRawDeltaTime() noexcept
|
||||||
|
{
|
||||||
|
return rawDeltaTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Updates the raw delta time accordingly
|
||||||
|
static void UpdateFRC() noexcept;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//TODO Legacy code. Delete soon
|
||||||
|
#if 0
|
||||||
#include "../Scene/SHScene.h"
|
#include "../Scene/SHScene.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -56,7 +88,19 @@ namespace SHADE
|
||||||
//halt execution of the current scene and prepare
|
//halt execution of the current scene and prepare
|
||||||
//execution of the next
|
//execution of the next
|
||||||
static inline void SetNextScene(SHScene* const next) { nextScene = next; }
|
static inline void SetNextScene(SHScene* const next) { nextScene = next; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -2,7 +2,6 @@
|
||||||
#include "SHFileSystem.h"
|
#include "SHFileSystem.h"
|
||||||
#include "fileapi.h"
|
#include "fileapi.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <cassert>
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -28,7 +27,10 @@ namespace SHADE
|
||||||
|
|
||||||
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
||||||
|
|
||||||
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
|
if (count >= FOLDER_MAX_COUNT)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Max subfolder reached: {}\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
auto const location = static_cast<FolderLocation>(count);
|
auto const location = static_cast<FolderLocation>(count);
|
||||||
|
|
||||||
|
@ -37,7 +39,10 @@ namespace SHADE
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(folders.contains(here), "Folder creation location does not exist/invalid\n");
|
if (!folders.contains(here))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Folder creation location does not exist/invalid: {}\n", here);
|
||||||
|
}
|
||||||
|
|
||||||
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
||||||
|
|
||||||
|
@ -45,7 +50,11 @@ namespace SHADE
|
||||||
location <<= FOLDER_BIT_ALLOCATE;
|
location <<= FOLDER_BIT_ALLOCATE;
|
||||||
location |= count;
|
location |= count;
|
||||||
|
|
||||||
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
|
if (count >= FOLDER_MAX_COUNT)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Max subfolder reached: {}\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
CreateFolder(folders[0]->path, here, location, name);
|
CreateFolder(folders[0]->path, here, location, name);
|
||||||
|
|
||||||
return location;
|
return location;
|
||||||
|
@ -53,7 +62,10 @@ namespace SHADE
|
||||||
|
|
||||||
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
|
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
|
||||||
{
|
{
|
||||||
assert(folders.contains(location->id), "Delete target does not exist/invalid.\n");
|
if (!folders.contains(location->id))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Delete target does not exist/invalid: {}\n", location->name);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto const& subFolder : folders[location->id]->subFolders)
|
for (auto const& subFolder : folders[location->id]->subFolders)
|
||||||
{
|
{
|
||||||
|
@ -116,10 +128,11 @@ namespace SHADE
|
||||||
|
|
||||||
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
|
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
|
||||||
{
|
{
|
||||||
assert(
|
|
||||||
CreateDirectoryA(path.c_str(), nullptr),
|
if (!CreateDirectoryA(path.c_str(), nullptr))
|
||||||
"Failed to create folder\n"
|
{
|
||||||
);
|
SHLOG_ERROR("Failed to create folder: {}\n", path);
|
||||||
|
}
|
||||||
|
|
||||||
folders[location] = std::make_unique<SHFolder>(location, name);
|
folders[location] = std::make_unique<SHFolder>(location, name);
|
||||||
folders[location]->path = path;
|
folders[location]->path = path;
|
||||||
|
|
|
@ -105,6 +105,17 @@ namespace SHADE
|
||||||
vk::Buffer GetVkBuffer (void) const noexcept;
|
vk::Buffer GetVkBuffer (void) const noexcept;
|
||||||
vk::BufferUsageFlags GetUsageBits(void) const noexcept;
|
vk::BufferUsageFlags GetUsageBits(void) const noexcept;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T GetDataFromMappedPointer(uint32_t index) const noexcept
|
||||||
|
{
|
||||||
|
if (mappedPtr && index < sizeStored / sizeof (T))
|
||||||
|
{
|
||||||
|
return (static_cast<T*>(mappedPtr))[index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkCommandBuffer::~SHVkCommandBuffer(void) noexcept
|
SHVkCommandBuffer::~SHVkCommandBuffer(void) noexcept
|
||||||
{
|
{
|
||||||
if (vkCommandBuffer)
|
if (vkCommandBuffer && parentPool)
|
||||||
parentPool->GetLogicalDevice()->GetVkLogicalDevice().freeCommandBuffers(parentPool->GetVkCommandPool(), commandBufferCount, &vkCommandBuffer);
|
parentPool->GetLogicalDevice()->GetVkLogicalDevice().freeCommandBuffers(parentPool->GetVkCommandPool(), commandBufferCount, &vkCommandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,6 +461,11 @@ namespace SHADE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::CopyImageToBuffer(const vk::Image& src, const vk::Buffer& dst, const std::vector<vk::BufferImageCopy>& copyInfo)
|
||||||
|
{
|
||||||
|
vkCommandBuffer.copyImageToBuffer (src, vk::ImageLayout::eTransferSrcOptimal, dst, copyInfo);
|
||||||
|
}
|
||||||
|
|
||||||
void SHVkCommandBuffer::PipelineBarrier(
|
void SHVkCommandBuffer::PipelineBarrier(
|
||||||
vk::PipelineStageFlags srcStage,
|
vk::PipelineStageFlags srcStage,
|
||||||
vk::PipelineStageFlags dstStage,
|
vk::PipelineStageFlags dstStage,
|
||||||
|
|
|
@ -121,6 +121,7 @@ namespace SHADE
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
// memory barriers
|
// memory barriers
|
||||||
void PipelineBarrier (
|
void PipelineBarrier (
|
||||||
|
|
|
@ -102,8 +102,6 @@ namespace SHADE
|
||||||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
||||||
transient = rhs.transient;
|
transient = rhs.transient;
|
||||||
|
|
||||||
static_cast<ISelfHandle<SHVkCommandPool>&>(*this) = static_cast<ISelfHandle<SHVkCommandPool>&>(rhs);
|
|
||||||
|
|
||||||
rhs.vkCommandPool = VK_NULL_HANDLE;
|
rhs.vkCommandPool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
|
@ -40,7 +40,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
{ vk::DescriptorType::eCombinedImageSampler, 100 },
|
{ vk::DescriptorType::eCombinedImageSampler, 100 },
|
||||||
{ vk::DescriptorType::eUniformBuffer, 100 },
|
{ vk::DescriptorType::eUniformBuffer, 100 },
|
||||||
{ vk::DescriptorType::eUniformBufferDynamic, 100 }
|
{ vk::DescriptorType::eUniformBufferDynamic, 100 },
|
||||||
|
{ vk::DescriptorType::eStorageImage, 100},
|
||||||
|
{ vk::DescriptorType::eStorageBufferDynamic, 100 }
|
||||||
};
|
};
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum number of descriptor sets allowed
|
/// Maximum number of descriptor sets allowed
|
||||||
|
|
|
@ -155,7 +155,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::pair<Handle<SHVkImageView>, Handle<SHVkSampler>>> const& imageViewsAndSamplers) noexcept
|
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept
|
||||||
{
|
{
|
||||||
// Find the target writeDescSet
|
// Find the target writeDescSet
|
||||||
BindingAndSetHash writeHash = binding;
|
BindingAndSetHash writeHash = binding;
|
||||||
|
@ -170,9 +170,10 @@ namespace SHADE
|
||||||
for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i)
|
for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i)
|
||||||
{
|
{
|
||||||
// write sampler and image view
|
// write sampler and image view
|
||||||
auto& ivs = imageViewsAndSamplers[i];
|
auto& [view, sampler, layout] = imageViewsAndSamplers[i];
|
||||||
writeInfo.descImageInfos[i].imageView = ivs.first->GetImageView();
|
writeInfo.descImageInfos[i].imageView = view->GetImageView();
|
||||||
writeInfo.descImageInfos[i].sampler = ivs.second->GetVkSampler();
|
writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
||||||
|
writeInfo.descImageInfos[i].imageLayout = layout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +208,7 @@ namespace SHADE
|
||||||
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||||
|
|
||||||
// to index a set
|
// to index a set
|
||||||
uint32_t setIndex = setIndexing[bsHash];
|
uint32_t setIndex = setIndexing[set];
|
||||||
|
|
||||||
// to index a write for a binding
|
// to index a write for a binding
|
||||||
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||||
|
@ -232,7 +233,7 @@ namespace SHADE
|
||||||
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||||
|
|
||||||
// to index a set
|
// to index a set
|
||||||
uint32_t setIndex = setIndexing[bsHash];
|
uint32_t setIndex = setIndexing[set];
|
||||||
|
|
||||||
// to index a write for a binding
|
// to index a write for a binding
|
||||||
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Graphics/SHVulkanIncludes.h"
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
#include "Resource/Handle.h"
|
#include "Resource/Handle.h"
|
||||||
|
@ -63,7 +65,7 @@ namespace SHADE
|
||||||
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
||||||
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
||||||
|
|
||||||
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::pair<Handle<SHVkImageView>, Handle<SHVkSampler>>> const& imageViewsAndSamplers) noexcept;
|
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept;
|
||||||
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
@ -76,6 +97,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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
||||||
#include "Graphics/Images/SHVkImageView.h"
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -85,6 +86,17 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SHVkLogicalDevice::ComputeAlignedBufferSize(uint32_t originalSize, size_t alignmentSize) const noexcept
|
||||||
|
{
|
||||||
|
uint32_t alignedSize = originalSize;
|
||||||
|
//uint32_t minBuffer
|
||||||
|
if (alignmentSize > 0)
|
||||||
|
{
|
||||||
|
alignedSize = (alignedSize + static_cast<uint32_t>(alignmentSize) - 1) & ~(alignmentSize - 1);
|
||||||
|
}
|
||||||
|
return alignedSize;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -176,12 +188,15 @@ namespace SHADE
|
||||||
// point and lines fill mode
|
// point and lines fill mode
|
||||||
features.fillModeNonSolid = true;
|
features.fillModeNonSolid = true;
|
||||||
features.samplerAnisotropy = VK_TRUE;
|
features.samplerAnisotropy = VK_TRUE;
|
||||||
|
features.multiDrawIndirect = true;
|
||||||
|
|
||||||
// for wide lines
|
// for wide lines
|
||||||
features.wideLines = true;
|
features.wideLines = true;
|
||||||
|
|
||||||
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
|
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
|
||||||
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
|
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
|
||||||
|
descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true;
|
||||||
|
descIndexingFeature.runtimeDescriptorArray = true;
|
||||||
|
|
||||||
// Prepare to create the device
|
// Prepare to create the device
|
||||||
vk::DeviceCreateInfo deviceCreateInfo
|
vk::DeviceCreateInfo deviceCreateInfo
|
||||||
|
@ -236,6 +251,22 @@ namespace SHADE
|
||||||
vkLogicalDevice.destroy(nullptr);
|
vkLogicalDevice.destroy(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHVkLogicalDevice& SHVkLogicalDevice::operator=(SHVkLogicalDevice&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
vkLogicalDevice = std::move (rhs.vkLogicalDevice);
|
||||||
|
queueFamilyIndices = std::move (rhs.queueFamilyIndices);
|
||||||
|
vmaAllocator = rhs.vmaAllocator;
|
||||||
|
nonDedicatedBestIndex = 0;
|
||||||
|
parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl;
|
||||||
|
|
||||||
|
rhs.vkLogicalDevice = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -288,13 +319,12 @@ namespace SHADE
|
||||||
|
|
||||||
uint32_t SHVkLogicalDevice::PadUBOSize(uint32_t originalSize) const noexcept
|
uint32_t SHVkLogicalDevice::PadUBOSize(uint32_t originalSize) const noexcept
|
||||||
{
|
{
|
||||||
uint32_t alignedSize = originalSize;
|
return ComputeAlignedBufferSize(originalSize, uboBufferMemoryAlignment);
|
||||||
//uint32_t minBuffer
|
|
||||||
if (uboBufferMemoryAlignment > 0)
|
|
||||||
{
|
|
||||||
alignedSize = (alignedSize + uboBufferMemoryAlignment - 1) & ~(uboBufferMemoryAlignment - 1);
|
|
||||||
}
|
}
|
||||||
return alignedSize;
|
|
||||||
|
uint32_t SHVkLogicalDevice::PadSSBOSize(uint32_t originalSize) const noexcept
|
||||||
|
{
|
||||||
|
return ComputeAlignedBufferSize(originalSize, ssboBufferMemoryAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -499,6 +529,11 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHVkSampler> SHVkLogicalDevice::CreateSampler(const SHVkSamplerParams& params) noexcept
|
||||||
|
{
|
||||||
|
return SHVkInstance::GetResourceManager().Create <SHVkSampler>(GetHandle(), params);
|
||||||
|
}
|
||||||
|
|
||||||
Handle<SHVkRenderpass> SHVkLogicalDevice::CreateRenderpass(std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept
|
Handle<SHVkRenderpass> SHVkLogicalDevice::CreateRenderpass(std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create <SHVkRenderpass>(GetHandle(), vkDescriptions, subpasses);
|
return SHVkInstance::GetResourceManager().Create <SHVkRenderpass>(GetHandle(), vkDescriptions, subpasses);
|
||||||
|
@ -515,10 +550,9 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept
|
Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers/* = false*/) noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex, bindings);
|
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex, bindings, genImmutableSamplers);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkDescriptorPool> SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept
|
Handle<SHVkDescriptorPool> SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||||
#include "Graphics/Images/SHVkImage.h"
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -41,6 +40,8 @@ namespace SHADE
|
||||||
class SHShaderBlockInterface;
|
class SHShaderBlockInterface;
|
||||||
class SHVkDescriptorSetGroup;
|
class SHVkDescriptorSetGroup;
|
||||||
class SHSubpass;
|
class SHSubpass;
|
||||||
|
class SHVkSampler;
|
||||||
|
struct SHVkSamplerParams;
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -102,6 +103,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void InitializeVMA (void) noexcept;
|
void InitializeVMA (void) noexcept;
|
||||||
void InitializeQueues (std::initializer_list<SHQueueParams> queueCreateParams) noexcept;
|
void InitializeQueues (std::initializer_list<SHQueueParams> queueCreateParams) noexcept;
|
||||||
|
uint32_t ComputeAlignedBufferSize(uint32_t originalSize, size_t typeSize) const noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -113,7 +115,7 @@ namespace SHADE
|
||||||
~SHVkLogicalDevice (void) noexcept;
|
~SHVkLogicalDevice (void) noexcept;
|
||||||
|
|
||||||
SHVkLogicalDevice& operator= (SHVkLogicalDevice const& rhs) noexcept = default;
|
SHVkLogicalDevice& operator= (SHVkLogicalDevice const& rhs) noexcept = default;
|
||||||
SHVkLogicalDevice& operator= (SHVkLogicalDevice&& rhs) noexcept = default;
|
SHVkLogicalDevice& operator= (SHVkLogicalDevice&& rhs) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER VARIABLES */
|
/* PUBLIC MEMBER VARIABLES */
|
||||||
|
@ -122,6 +124,7 @@ namespace SHADE
|
||||||
void WaitIdle (void) noexcept;
|
void WaitIdle (void) noexcept;
|
||||||
uint32_t FindMemoryType (uint32_t typeFilter, vk::MemoryPropertyFlags properties);
|
uint32_t FindMemoryType (uint32_t typeFilter, vk::MemoryPropertyFlags properties);
|
||||||
uint32_t PadUBOSize(uint32_t originalSize) const noexcept;
|
uint32_t PadUBOSize(uint32_t originalSize) const noexcept;
|
||||||
|
uint32_t PadSSBOSize(uint32_t originalSize) const noexcept;
|
||||||
|
|
||||||
// creation functions
|
// creation functions
|
||||||
Handle<SHVkSurface> CreateSurface (HWND const& windowHandle) const noexcept;
|
Handle<SHVkSurface> CreateSurface (HWND const& windowHandle) const noexcept;
|
||||||
|
@ -178,11 +181,12 @@ namespace SHADE
|
||||||
Handle<SHVkRenderpass> const& renderpassHdl,
|
Handle<SHVkRenderpass> const& renderpassHdl,
|
||||||
Handle<SHSubpass> subpass
|
Handle<SHSubpass> subpass
|
||||||
) noexcept;
|
) 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,
|
||||||
|
|
|
@ -98,6 +98,51 @@ namespace SHADE
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkFramebuffer::HandleResize(Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept
|
||||||
|
{
|
||||||
|
width = inWidth;
|
||||||
|
height = inHeight;
|
||||||
|
|
||||||
|
for (auto& attachment : attachments)
|
||||||
|
{
|
||||||
|
// Not sure if its an error to pass in diff dimension images.
|
||||||
|
if (attachment->GetParentImage()->GetWidth() != (*attachments.begin())->GetParentImage()->GetWidth() || attachment->GetParentImage()->GetHeight() != (*attachments.begin())->GetParentImage()->GetHeight())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Dimensions of images not same as each other. Cannot create framebuffer.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<vk::ImageView> vkAttachments(attachments.size());
|
||||||
|
|
||||||
|
uint32_t i = 0;
|
||||||
|
for(auto const& attachment : attachments)
|
||||||
|
{
|
||||||
|
vkAttachments[i] = attachment->GetImageView();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::FramebufferCreateInfo createInfo
|
||||||
|
{
|
||||||
|
.renderPass = renderpassHdl->GetVkRenderpass(),
|
||||||
|
.attachmentCount = static_cast<uint32_t>(vkAttachments.size()),
|
||||||
|
.pAttachments = vkAttachments.data(),
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.layers = 1 // TODO: Find out why this is 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createFramebuffer(&createInfo, nullptr, &vkFramebuffer); result != vk::Result::eSuccess)
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkError(result, "Failed to create framebuffer. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created framebuffer. ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ namespace SHADE
|
||||||
SHVkFramebuffer(SHVkFramebuffer&& rhs) noexcept;
|
SHVkFramebuffer(SHVkFramebuffer&& rhs) noexcept;
|
||||||
SHVkFramebuffer& operator=(SHVkFramebuffer&& rhs) noexcept;
|
SHVkFramebuffer& operator=(SHVkFramebuffer&& rhs) noexcept;
|
||||||
|
|
||||||
|
void HandleResize (Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkImage::PrepStagingBuffer(void* data, uint32_t srcSize) noexcept
|
void SHVkImage::PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept
|
||||||
{
|
{
|
||||||
// For creation of buffer
|
// For creation of buffer
|
||||||
vk::BufferCreateInfo bufferInfo{};
|
vk::BufferCreateInfo bufferInfo{};
|
||||||
|
@ -70,7 +70,7 @@ namespace SHADE
|
||||||
vmaMapMemory(*vmaAllocator, stagingAlloc, &stagingBufferMappedPtr);
|
vmaMapMemory(*vmaAllocator, stagingAlloc, &stagingBufferMappedPtr);
|
||||||
|
|
||||||
if (stagingBufferMappedPtr)
|
if (stagingBufferMappedPtr)
|
||||||
std::memcpy(static_cast<uint8_t*>(stagingBufferMappedPtr), static_cast<uint8_t*>(data), srcSize);
|
std::memcpy(static_cast<uint8_t*>(stagingBufferMappedPtr), static_cast<const uint8_t*>(data), srcSize);
|
||||||
|
|
||||||
const VkDeviceSize offsets = 0;
|
const VkDeviceSize offsets = 0;
|
||||||
const VkDeviceSize sizes = srcSize;
|
const VkDeviceSize sizes = srcSize;
|
||||||
|
@ -79,10 +79,45 @@ namespace SHADE
|
||||||
vmaUnmapMemory(*vmaAllocator, stagingAlloc);
|
vmaUnmapMemory(*vmaAllocator, stagingAlloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkImage::CreateFramebufferImage(void) noexcept
|
||||||
|
{
|
||||||
|
vk::ImageCreateInfo imageCreateInfo{};
|
||||||
|
imageCreateInfo.imageType = vk::ImageType::e2D;
|
||||||
|
imageCreateInfo.extent.width = width;
|
||||||
|
imageCreateInfo.extent.height = height;
|
||||||
|
imageCreateInfo.extent.depth = depth;
|
||||||
|
imageCreateInfo.mipLevels = mipLevelCount;
|
||||||
|
imageCreateInfo.arrayLayers = layerCount;
|
||||||
|
imageCreateInfo.format = imageFormat;
|
||||||
|
imageCreateInfo.tiling = vk::ImageTiling::eOptimal;
|
||||||
|
imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
|
||||||
|
imageCreateInfo.usage = usageFlags;
|
||||||
|
imageCreateInfo.sharingMode = vk::SharingMode::eExclusive;
|
||||||
|
imageCreateInfo.samples = vk::SampleCountFlagBits::e1;
|
||||||
|
imageCreateInfo.flags = createFlags;
|
||||||
|
|
||||||
|
|
||||||
|
// Prepare allocation parameters for call to create images later
|
||||||
|
VmaAllocationCreateInfo allocCreateInfo{};
|
||||||
|
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||||
|
allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set
|
||||||
|
|
||||||
|
VmaAllocationInfo allocInfo{};
|
||||||
|
|
||||||
|
VkImage tempImage;
|
||||||
|
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||||
|
vkImage = tempImage;
|
||||||
|
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
||||||
|
else
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
|
||||||
|
}
|
||||||
|
|
||||||
SHVkImage::SHVkImage(
|
SHVkImage::SHVkImage(
|
||||||
VmaAllocator const* allocator,
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
unsigned char* data,
|
const unsigned char* data,
|
||||||
uint32_t dataSize,
|
uint32_t dataSize,
|
||||||
std::span<uint32_t> inMipOffsets,
|
std::span<uint32_t> inMipOffsets,
|
||||||
VmaMemoryUsage memUsage,
|
VmaMemoryUsage memUsage,
|
||||||
|
@ -196,37 +231,7 @@ namespace SHADE
|
||||||
, createFlags {create}
|
, createFlags {create}
|
||||||
, vmaAllocator {allocator}
|
, vmaAllocator {allocator}
|
||||||
{
|
{
|
||||||
vk::ImageCreateInfo imageCreateInfo{};
|
CreateFramebufferImage();
|
||||||
imageCreateInfo.imageType = vk::ImageType::e2D;
|
|
||||||
imageCreateInfo.extent.width = width;
|
|
||||||
imageCreateInfo.extent.height = height;
|
|
||||||
imageCreateInfo.extent.depth = depth;
|
|
||||||
imageCreateInfo.mipLevels = mipLevelCount;
|
|
||||||
imageCreateInfo.arrayLayers = layerCount;
|
|
||||||
imageCreateInfo.format = imageFormat;
|
|
||||||
imageCreateInfo.tiling = vk::ImageTiling::eOptimal;
|
|
||||||
imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
|
|
||||||
imageCreateInfo.usage = usageFlags;
|
|
||||||
imageCreateInfo.sharingMode = vk::SharingMode::eExclusive;
|
|
||||||
imageCreateInfo.samples = vk::SampleCountFlagBits::e1;
|
|
||||||
imageCreateInfo.flags = createFlags;
|
|
||||||
|
|
||||||
|
|
||||||
// Prepare allocation parameters for call to create images later
|
|
||||||
VmaAllocationCreateInfo allocCreateInfo{};
|
|
||||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
|
||||||
allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set
|
|
||||||
|
|
||||||
VmaAllocationInfo allocInfo{};
|
|
||||||
|
|
||||||
VkImage tempImage;
|
|
||||||
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
|
||||||
vkImage = tempImage;
|
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
|
||||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
|
||||||
else
|
|
||||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
|
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
|
||||||
|
@ -288,6 +293,16 @@ namespace SHADE
|
||||||
barrier.subresourceRange.layerCount = layerCount;
|
barrier.subresourceRange.layerCount = layerCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkImage::HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept
|
||||||
|
{
|
||||||
|
vmaDestroyImage(*vmaAllocator, vkImage, alloc);
|
||||||
|
|
||||||
|
width = newWidth;
|
||||||
|
height = newHeight;
|
||||||
|
|
||||||
|
CreateFramebufferImage();
|
||||||
|
}
|
||||||
|
|
||||||
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
||||||
{
|
{
|
||||||
vkImage = inVkImage;
|
vkImage = inVkImage;
|
||||||
|
|
|
@ -107,8 +107,8 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void PrepStagingBuffer(void* data, uint32_t srcSize) noexcept;
|
void PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept;
|
||||||
|
void CreateFramebufferImage (void) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -119,7 +119,7 @@ namespace SHADE
|
||||||
SHVkImage(
|
SHVkImage(
|
||||||
VmaAllocator const* allocator,
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
unsigned char* data,
|
const unsigned char* data,
|
||||||
uint32_t dataSize,
|
uint32_t dataSize,
|
||||||
std::span<uint32_t> inMipOffsets,
|
std::span<uint32_t> inMipOffsets,
|
||||||
VmaMemoryUsage memUsage,
|
VmaMemoryUsage memUsage,
|
||||||
|
@ -137,6 +137,7 @@ namespace SHADE
|
||||||
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
||||||
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
|
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
|
||||||
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
||||||
|
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
|
|
|
@ -6,27 +6,13 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
void SHVkImageView::Create(void) noexcept
|
||||||
Non-default ctor. Initializes image view with image that it is a view of.
|
|
||||||
|
|
||||||
\param parent
|
|
||||||
Parent image the view is a view of.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHVkImageView::SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
|
|
||||||
: parentImage{ }
|
|
||||||
, vkImageView{}
|
|
||||||
, imageViewDetails{}
|
|
||||||
, logicalDeviceHdl {inLogicalDeviceHdl}
|
|
||||||
{
|
{
|
||||||
auto parentImageCreateFlags = parent->GetImageeCreateFlags();
|
auto parentImageCreateFlags = parentImage->GetImageeCreateFlags();
|
||||||
|
|
||||||
// 2D array image type means parent image must be 2D array compatible
|
// 2D array image type means parent image must be 2D array compatible
|
||||||
if (createParams.viewType == vk::ImageViewType::e2DArray)
|
if (imageViewDetails.viewType == vk::ImageViewType::e2DArray)
|
||||||
{
|
{
|
||||||
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible))
|
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible))
|
||||||
{
|
{
|
||||||
|
@ -36,7 +22,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if its possible for the image view to have different format than parent image
|
// Check if its possible for the image view to have different format than parent image
|
||||||
if (createParams.format != parent->GetImageFormat())
|
if (imageViewDetails.format != parentImage->GetImageFormat())
|
||||||
{
|
{
|
||||||
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat))
|
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat))
|
||||||
{
|
{
|
||||||
|
@ -49,9 +35,9 @@ namespace SHADE
|
||||||
vk::ImageViewCreateInfo viewCreateInfo
|
vk::ImageViewCreateInfo viewCreateInfo
|
||||||
{
|
{
|
||||||
.pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information
|
.pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information
|
||||||
.image = parent->GetVkImage(),
|
.image = parentImage->GetVkImage(),
|
||||||
.viewType = createParams.viewType,
|
.viewType = imageViewDetails.viewType,
|
||||||
.format = createParams.format,
|
.format = imageViewDetails.format,
|
||||||
.components
|
.components
|
||||||
{
|
{
|
||||||
.r = vk::ComponentSwizzle::eR,
|
.r = vk::ComponentSwizzle::eR,
|
||||||
|
@ -61,15 +47,15 @@ namespace SHADE
|
||||||
},
|
},
|
||||||
.subresourceRange
|
.subresourceRange
|
||||||
{
|
{
|
||||||
.aspectMask = createParams.imageAspectFlags,
|
.aspectMask = imageViewDetails.imageAspectFlags,
|
||||||
.baseMipLevel = createParams.baseMipLevel,
|
.baseMipLevel = imageViewDetails.baseMipLevel,
|
||||||
.levelCount = createParams.mipLevelCount,
|
.levelCount = imageViewDetails.mipLevelCount,
|
||||||
.baseArrayLayer = createParams.baseArrayLayer,
|
.baseArrayLayer = imageViewDetails.baseArrayLayer,
|
||||||
.layerCount = createParams.layerCount,
|
.layerCount = imageViewDetails.layerCount,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auto result = inLogicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess)
|
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess)
|
||||||
{
|
{
|
||||||
SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! ");
|
SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! ");
|
||||||
return;
|
return;
|
||||||
|
@ -79,9 +65,26 @@ namespace SHADE
|
||||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. ");
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// After success, THEN assign variables
|
}
|
||||||
parentImage = parent;
|
|
||||||
imageViewDetails = createParams;
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Non-default ctor. Initializes image view with image that it is a view of.
|
||||||
|
|
||||||
|
\param parent
|
||||||
|
Parent image the view is a view of.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHVkImageView::SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
|
||||||
|
: parentImage{ parent }
|
||||||
|
, vkImageView{}
|
||||||
|
, imageViewDetails{createParams}
|
||||||
|
, logicalDeviceHdl {inLogicalDeviceHdl}
|
||||||
|
{
|
||||||
|
Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVkImageView::SHVkImageView(SHVkImageView&& rhs) noexcept
|
SHVkImageView::SHVkImageView(SHVkImageView&& rhs) noexcept
|
||||||
|
@ -94,6 +97,17 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHVkImageView::ViewNewImage(Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
|
||||||
|
{
|
||||||
|
imageViewDetails = createParams;
|
||||||
|
parentImage = parent;
|
||||||
|
|
||||||
|
if (vkImageView)
|
||||||
|
logicalDeviceHdl->GetVkLogicalDevice().destroyImageView(vkImageView, nullptr);
|
||||||
|
|
||||||
|
Create();
|
||||||
|
}
|
||||||
|
|
||||||
Handle<SHVkImage> const& SHVkImageView::GetParentImage(void) const noexcept
|
Handle<SHVkImage> const& SHVkImageView::GetParentImage(void) const noexcept
|
||||||
{
|
{
|
||||||
return parentImage;
|
return parentImage;
|
||||||
|
|
|
@ -25,12 +25,17 @@ namespace SHADE
|
||||||
//! Logical Device needed for creation and destruction
|
//! Logical Device needed for creation and destruction
|
||||||
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
||||||
|
|
||||||
|
//! Create new image view
|
||||||
|
void Create (void) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
|
SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
|
||||||
~SHVkImageView(void) noexcept;
|
~SHVkImageView(void) noexcept;
|
||||||
SHVkImageView(SHVkImageView&& rhs) noexcept;
|
SHVkImageView(SHVkImageView&& rhs) noexcept;
|
||||||
SHVkImageView& operator=(SHVkImageView&& rhs) noexcept;
|
SHVkImageView& operator=(SHVkImageView&& rhs) noexcept;
|
||||||
|
|
||||||
|
void ViewNewImage (Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -1,12 +1,65 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHVkSampler.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 26, 2022
|
||||||
|
\brief Contains definitions for all of the functions of the SHVkSampler class.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHVkSampler.h"
|
#include "SHVkSampler.h"
|
||||||
|
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
vk::Sampler SHVkSampler::GetVkSampler(void) const noexcept
|
/* Constructors */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHVkSampler::SHVkSampler(Handle<SHVkLogicalDevice> logicalDevice, const SHVkSamplerParams& params) noexcept
|
||||||
|
: device { logicalDevice }
|
||||||
{
|
{
|
||||||
return vkSampler;
|
const vk::SamplerCreateInfo SAMPLER_CREATE_INFO
|
||||||
|
{
|
||||||
|
.magFilter = params.magFilter,
|
||||||
|
.minFilter = params.minFilter,
|
||||||
|
.mipmapMode = params.mipmapMode,
|
||||||
|
.addressModeU = params.addressMode,
|
||||||
|
.addressModeV = params.addressMode,
|
||||||
|
.addressModeW = params.addressMode,
|
||||||
|
.maxAnisotropy = 1.0f,
|
||||||
|
.minLod = params.minLod,
|
||||||
|
.maxLod = params.maxLod,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create the sampler
|
||||||
|
vkSampler = device->GetVkLogicalDevice().createSampler(SAMPLER_CREATE_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHVkSampler::SHVkSampler(SHVkSampler&& rhs) noexcept
|
||||||
|
: vkSampler{ rhs.vkSampler }
|
||||||
|
, device{ rhs.device }
|
||||||
|
{
|
||||||
|
rhs.vkSampler = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVkSampler::~SHVkSampler() noexcept
|
||||||
|
{
|
||||||
|
if (vkSampler)
|
||||||
|
device->GetVkLogicalDevice().destroySampler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Overloaded Operators */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHADE::SHVkSampler& SHVkSampler::operator=(SHVkSampler&& rhs) noexcept
|
||||||
|
{
|
||||||
|
vkSampler = rhs.vkSampler;
|
||||||
|
device = rhs.device;
|
||||||
|
rhs.vkSampler = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,28 +1,80 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHVkSampler.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 26, 2022
|
||||||
|
\brief Contains definitions of the SHVkSampler class.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// STL Includes
|
||||||
|
#include <vector>
|
||||||
|
// Project Includes
|
||||||
#include "Graphics/SHVulkanIncludes.h"
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Holds parameters for constructing the SHVkSampler.
|
||||||
|
*/
|
||||||
|
/*************************************************************************************/
|
||||||
struct SHVkSamplerParams
|
struct SHVkSamplerParams
|
||||||
{
|
{
|
||||||
vk::Filter minFilter;
|
vk::Filter minFilter = vk::Filter::eLinear;
|
||||||
vk::Filter maxFilter;
|
vk::Filter magFilter = vk::Filter::eLinear;
|
||||||
//vk::Filter maxFilter;
|
vk::SamplerAddressMode addressMode = vk::SamplerAddressMode::eClampToEdge;
|
||||||
|
vk::SamplerMipmapMode mipmapMode = vk::SamplerMipmapMode::eLinear;
|
||||||
|
float minLod = 0;
|
||||||
|
float maxLod = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*************************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Wrapper for a VkSampler.
|
||||||
|
*/
|
||||||
|
/*************************************************************************************/
|
||||||
class SHVkSampler
|
class SHVkSampler
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
//! The vulkan sampler handler
|
|
||||||
vk::Sampler vkSampler;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHVkSampler () noexcept;
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHVkSampler(Handle<SHVkLogicalDevice> logicalDevice, const SHVkSamplerParams& params = {}) noexcept;
|
||||||
SHVkSampler(SHVkSampler&& rhs) noexcept;
|
SHVkSampler(SHVkSampler&& rhs) noexcept;
|
||||||
SHVkSampler&& operator=(SHVkSampler&& rhs) noexcept;
|
~SHVkSampler() noexcept;
|
||||||
|
|
||||||
vk::Sampler GetVkSampler (void) const noexcept;
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Overloaded Operators */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHVkSampler& operator=(SHVkSampler&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
vk::Sampler GetVkSampler(void) const noexcept { return vkSampler; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
vk::Sampler vkSampler; //! The Vulkan sampler handler
|
||||||
|
Handle<SHVkLogicalDevice> device; //! Stored device for deallocating the object
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,11 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/Pipeline/SHVkPipeline.h"
|
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -107,6 +110,7 @@ namespace SHADE
|
||||||
// Clear CPU buffers
|
// Clear CPU buffers
|
||||||
drawData.clear();
|
drawData.clear();
|
||||||
transformData.clear();
|
transformData.clear();
|
||||||
|
eidData.clear();
|
||||||
matPropsData.reset();
|
matPropsData.reset();
|
||||||
matPropsDataSize = 0;
|
matPropsDataSize = 0;
|
||||||
|
|
||||||
|
@ -116,11 +120,12 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
drawDataBuffer[i].Free();
|
drawDataBuffer[i].Free();
|
||||||
transformDataBuffer[i].Free();
|
transformDataBuffer[i].Free();
|
||||||
|
eidBuffer[i].Free();
|
||||||
matPropsBuffer[i].Free();
|
matPropsBuffer[i].Free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatch::UpdateMaterialBuffer(uint32_t frameIndex)
|
void SHBatch::UpdateMaterialBuffer(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
{
|
{
|
||||||
|
@ -154,21 +159,17 @@ namespace SHADE
|
||||||
if (!matBufferDirty[frameIndex])
|
if (!matBufferDirty[frameIndex])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Build CPI Buffer
|
// Build CPU Buffer
|
||||||
char* propsCurrPtr = matPropsData.get();
|
char* propsCurrPtr = matPropsData.get();
|
||||||
for (auto& subBatch : subBatches)
|
for (auto& subBatch : subBatches)
|
||||||
for (const SHRenderable* renderable : subBatch.Renderables)
|
for (const SHRenderable* renderable : subBatch.Renderables)
|
||||||
{
|
{
|
||||||
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
||||||
propsCurrPtr += singleMatPropSize;
|
propsCurrPtr += singleMatPropAlignedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer to GPU
|
// Transfer to GPU
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
rebuildMaterialBuffers(frameIndex, descPool);
|
||||||
(
|
|
||||||
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
|
||||||
vk::BufferUsageFlagBits::eStorageBuffer
|
|
||||||
);
|
|
||||||
|
|
||||||
// This frame is updated
|
// This frame is updated
|
||||||
matBufferDirty[frameIndex] = false;
|
matBufferDirty[frameIndex] = false;
|
||||||
|
@ -207,7 +208,31 @@ namespace SHADE
|
||||||
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0);
|
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatch::Build(Handle<SHVkLogicalDevice> _device, uint32_t frameIndex)
|
void SHBatch::UpdateEIDBuffer(uint32_t frameIndex)
|
||||||
|
{
|
||||||
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHBatch] Attempted to update eid buffers with an invalid frame index.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset Transform Data
|
||||||
|
eidData.clear();
|
||||||
|
|
||||||
|
// Populate on the CPU
|
||||||
|
for (auto& subBatch : subBatches)
|
||||||
|
for (const SHRenderable* renderable : subBatch.Renderables)
|
||||||
|
{
|
||||||
|
eidData.emplace_back(renderable->GetEID());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer to GPU
|
||||||
|
if (eidBuffer[frameIndex])
|
||||||
|
eidBuffer[frameIndex]->WriteToMemory(eidData.data(), static_cast<EntityID>(eidData.size() * sizeof(EntityID)), 0, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBatch::Build(Handle<SHVkLogicalDevice> _device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
{
|
{
|
||||||
|
@ -215,6 +240,9 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save logical device
|
||||||
|
device = _device;
|
||||||
|
|
||||||
// No need to build as there are no changes
|
// No need to build as there are no changes
|
||||||
if (!isDirty[frameIndex])
|
if (!isDirty[frameIndex])
|
||||||
return;
|
return;
|
||||||
|
@ -235,6 +263,11 @@ namespace SHADE
|
||||||
// - Transform data
|
// - Transform data
|
||||||
transformData.reserve(numTotalElements);
|
transformData.reserve(numTotalElements);
|
||||||
transformData.clear();
|
transformData.clear();
|
||||||
|
// - EID data
|
||||||
|
eidData.reserve(numTotalElements);
|
||||||
|
eidData.clear();
|
||||||
|
|
||||||
|
|
||||||
// - Material Properties Data
|
// - Material Properties Data
|
||||||
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
|
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
|
||||||
(
|
(
|
||||||
|
@ -247,7 +280,8 @@ namespace SHADE
|
||||||
if (!EMPTY_MAT_PROPS)
|
if (!EMPTY_MAT_PROPS)
|
||||||
{
|
{
|
||||||
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
||||||
matPropTotalBytes = drawData.size() * singleMatPropSize;
|
singleMatPropAlignedSize = device->PadSSBOSize(static_cast<uint32_t>(singleMatPropSize));
|
||||||
|
matPropTotalBytes = numTotalElements * singleMatPropAlignedSize;
|
||||||
if (matPropsDataSize < matPropTotalBytes)
|
if (matPropsDataSize < matPropTotalBytes)
|
||||||
{
|
{
|
||||||
matPropsData.reset(new char[matPropTotalBytes]);
|
matPropsData.reset(new char[matPropTotalBytes]);
|
||||||
|
@ -267,14 +301,15 @@ namespace SHADE
|
||||||
.instanceCount = static_cast<uint32_t>(subBatch.Renderables.size()),
|
.instanceCount = static_cast<uint32_t>(subBatch.Renderables.size()),
|
||||||
.firstIndex = subBatch.Mesh->FirstIndex,
|
.firstIndex = subBatch.Mesh->FirstIndex,
|
||||||
.vertexOffset = subBatch.Mesh->FirstVertex,
|
.vertexOffset = subBatch.Mesh->FirstVertex,
|
||||||
.firstInstance = nextInstanceIndex
|
.firstInstance = nextInstanceIndex++
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fill in buffers (CPU)
|
// Fill in buffers (CPU)
|
||||||
for (const SHRenderable* renderable : subBatch.Renderables)
|
for (const SHRenderable* renderable : subBatch.Renderables)
|
||||||
{
|
{
|
||||||
// Transform
|
// Transform
|
||||||
auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(renderable->GetEID());
|
EntityID eid = renderable->GetEID();
|
||||||
|
auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
|
||||||
if (!transform)
|
if (!transform)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!");
|
SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!");
|
||||||
|
@ -285,11 +320,13 @@ namespace SHADE
|
||||||
transformData.emplace_back(transform->GetTRS());
|
transformData.emplace_back(transform->GetTRS());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eidData.emplace_back(eid);
|
||||||
|
|
||||||
// Material Properties
|
// Material Properties
|
||||||
if (!EMPTY_MAT_PROPS)
|
if (!EMPTY_MAT_PROPS)
|
||||||
{
|
{
|
||||||
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
||||||
propsCurrPtr += singleMatPropSize;
|
propsCurrPtr += singleMatPropAlignedSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,30 +341,27 @@ namespace SHADE
|
||||||
const uint32_t DRAW_DATA_BYTES = static_cast<uint32_t>(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand));
|
const uint32_t DRAW_DATA_BYTES = static_cast<uint32_t>(drawData.size() * sizeof(vk::DrawIndexedIndirectCommand));
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
_device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
|
device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
|
||||||
BuffUsage::eIndirectBuffer
|
BuffUsage::eIndirectBuffer
|
||||||
);
|
);
|
||||||
// - Transform Buffer
|
// - Transform Buffer
|
||||||
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
|
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
_device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
|
device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
|
||||||
|
BuffUsage::eVertexBuffer
|
||||||
|
);
|
||||||
|
const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(eidData.size() * sizeof(EntityID));
|
||||||
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
|
(
|
||||||
|
device, eidBuffer[frameIndex], eidData.data(), EID_DATA_BYTES,
|
||||||
BuffUsage::eVertexBuffer
|
BuffUsage::eVertexBuffer
|
||||||
);
|
);
|
||||||
// - Material Properties Buffer
|
// - Material Properties Buffer
|
||||||
if (matPropsData)
|
rebuildMaterialBuffers(frameIndex, descPool);
|
||||||
{
|
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
|
||||||
(
|
|
||||||
_device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
|
||||||
BuffUsage::eStorageBuffer
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Mark this frame as no longer dirty
|
||||||
isDirty[frameIndex] = false;
|
isDirty[frameIndex] = false;
|
||||||
|
|
||||||
// Save logical device
|
|
||||||
this->device = _device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -341,8 +375,21 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind all required objects before drawing
|
||||||
|
static std::array<uint32_t, 1> dynamicOffset { 0 };
|
||||||
cmdBuffer->BindPipeline(pipeline);
|
cmdBuffer->BindPipeline(pipeline);
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||||
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::EID, eidBuffer[frameIndex], 0);
|
||||||
|
if (matPropsDescSet[frameIndex])
|
||||||
|
{
|
||||||
|
cmdBuffer->BindDescriptorSet
|
||||||
|
(
|
||||||
|
matPropsDescSet[frameIndex],
|
||||||
|
vk::PipelineBindPoint::eGraphics,
|
||||||
|
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||||
|
dynamicOffset
|
||||||
|
);
|
||||||
|
}
|
||||||
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
|
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,4 +402,39 @@ namespace SHADE
|
||||||
dirt = true;
|
dirt = true;
|
||||||
isCPUBuffersDirty = true;
|
isCPUBuffersDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHBatch::rebuildMaterialBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)
|
||||||
|
{
|
||||||
|
if (matPropsData)
|
||||||
|
{
|
||||||
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
|
(
|
||||||
|
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
||||||
|
vk::BufferUsageFlagBits::eStorageBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!matPropsDescSet[frameIndex])
|
||||||
|
{
|
||||||
|
matPropsDescSet[frameIndex] = descPool->Allocate
|
||||||
|
(
|
||||||
|
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] },
|
||||||
|
{ 0 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
|
||||||
|
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer
|
||||||
|
(
|
||||||
|
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||||
|
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||||
|
bufferList,
|
||||||
|
0, static_cast<uint32_t>(matPropsDataSize)
|
||||||
|
);
|
||||||
|
matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
||||||
|
(
|
||||||
|
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||||
|
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue