Merge remote-tracking branch 'origin/main' into SP3-12-SceneGraph
This commit is contained in:
commit
b0d3d3a6c5
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -18,10 +18,11 @@ echo "K - RTTR"
|
||||||
echo "L - yamlcpp"
|
echo "L - yamlcpp"
|
||||||
echo "M - SDL"
|
echo "M - SDL"
|
||||||
echo "N - dotnet"
|
echo "N - dotnet"
|
||||||
|
echo "O - tinyddsloader"
|
||||||
echo ---------------------------------------------------
|
echo ---------------------------------------------------
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
choice /C ABCDEFGHIJKLMN /T 10 /D A
|
choice /C ABCDEFGHIJKLMNO /T 10 /D A
|
||||||
set _e=%ERRORLEVEL%
|
set _e=%ERRORLEVEL%
|
||||||
|
|
||||||
if %_e%==1 goto VMA
|
if %_e%==1 goto VMA
|
||||||
|
@ -38,6 +39,7 @@ if %_e%==11 goto RTTR
|
||||||
if %_e%==12 goto yamlcpp
|
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
|
||||||
|
|
||||||
:VMA
|
:VMA
|
||||||
echo -----------------------VMA----------------------------
|
echo -----------------------VMA----------------------------
|
||||||
|
@ -136,6 +138,13 @@ robocopy "Dependencies/dotnet/tmp/shared/Microsoft.NETCore.App/6.0.8/" "Dependen
|
||||||
rmdir "Dependencies/dotnet/tmp/" /s /q
|
rmdir "Dependencies/dotnet/tmp/" /s /q
|
||||||
del "Dependencies/dotnet/dotnet.zip"
|
del "Dependencies/dotnet/dotnet.zip"
|
||||||
powershell -Command "& {Remove-Item "Dependencies/dotnet/dotnet.zip"}"
|
powershell -Command "& {Remove-Item "Dependencies/dotnet/dotnet.zip"}"
|
||||||
|
if %_e%==14 (goto :done) else (goto :tinyddsloader)
|
||||||
|
|
||||||
|
|
||||||
|
:tinyddsloader
|
||||||
|
echo --------------------tinyddsloader-------------------------
|
||||||
|
rmdir "Dependencies/tinyddsloader" /S /Q
|
||||||
|
git clone https://github.com/SHADE-DP/tinyddsloader.git "Dependencies/tinyddsloader"
|
||||||
|
|
||||||
:done
|
:done
|
||||||
echo DONE!
|
echo DONE!
|
||||||
|
|
|
@ -14,3 +14,4 @@ IncludeDir["reactphysics3d"] = "%{wks.location}\\Dependencies\\reactphysics3d"
|
||||||
IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL"
|
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"
|
||||||
|
|
|
@ -30,10 +30,12 @@ project "SHADE_Application"
|
||||||
|
|
||||||
externalincludedirs
|
externalincludedirs
|
||||||
{
|
{
|
||||||
"%{IncludeDir.spdlog}/include",
|
"%{IncludeDir.spdlog}/include",
|
||||||
"%{IncludeDir.VULKAN}/include",
|
"%{IncludeDir.VULKAN}/include",
|
||||||
"%{IncludeDir.VMA}/include",
|
"%{IncludeDir.VMA}/include",
|
||||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect"
|
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||||
|
"%{IncludeDir.RTTR}/include",
|
||||||
|
"%{IncludeDir.tinyddsloader}"
|
||||||
}
|
}
|
||||||
|
|
||||||
externalwarnings "Off"
|
externalwarnings "Off"
|
||||||
|
@ -71,8 +73,12 @@ project "SHADE_Application"
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
defines {"_DEBUG"}
|
defines {"_DEBUG", "SHEDITOR"}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
|
optimize "On"
|
||||||
|
defines{"_RELEASE", "SHEDITOR"}
|
||||||
|
|
||||||
|
filter "configurations:Publish"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE"}
|
defines{"_RELEASE"}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//#define SHEDITOR
|
//#define SHEDITOR
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
#include "Editor/SHEditor.h"
|
#include "Editor/SHEditor.hpp"
|
||||||
//#include "Scenes/SBEditorScene.h"
|
//#include "Scenes/SBEditorScene.h"
|
||||||
#endif // SHEDITOR
|
#endif // SHEDITOR
|
||||||
|
|
||||||
|
@ -22,8 +22,13 @@
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Math/Transform/SHTransformSystem.h"
|
||||||
|
#include "Input/SHInputManagerSystem.h"
|
||||||
|
|
||||||
#include "Scenes/SBTestScene.h"
|
#include "Scenes/SBTestScene.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
|
@ -41,30 +46,53 @@ namespace Sandbox
|
||||||
// Set working directory
|
// Set working directory
|
||||||
SHADE::SHFileUtilities::SetWorkDirToExecDir();
|
SHADE::SHFileUtilities::SetWorkDirToExecDir();
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_EVERYTHING);
|
|
||||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||||
|
|
||||||
|
// Create Systems
|
||||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
||||||
|
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>();
|
||||||
|
// TODO(Diren): Create Physics System here
|
||||||
|
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
|
||||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||||
|
SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>();
|
||||||
|
|
||||||
|
// Create Routines
|
||||||
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameSetUpRoutine>();
|
||||||
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::UpdateRoutine>();
|
||||||
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::LateUpdateRoutine>();
|
||||||
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameCleanUpRoutine>();
|
||||||
|
|
||||||
|
// TODO(Diren): Register Physics System & Routines here
|
||||||
|
|
||||||
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHTransformSystem, SHADE::SHTransformSystem::TransformUpdateRoutine>();
|
||||||
|
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
||||||
|
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BatcherDispatcherRoutine>();
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BatcherDispatcherRoutine>();
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BeginRoutine>();
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BeginRoutine>();
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>();
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>();
|
||||||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>();
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>();
|
||||||
|
|
||||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
|
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
|
||||||
|
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
||||||
|
|
||||||
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHInputManagerSystem, SHADE::SHInputManagerSystem::InputManagerRoutine>();
|
||||||
|
|
||||||
|
//TODO: REMOVE AFTER PRESENTATION
|
||||||
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
||||||
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
|
||||||
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
|
||||||
|
//TODO: REMOVE AFTER PRESENTATION
|
||||||
|
|
||||||
|
// Set up graphics system and windows
|
||||||
graphicsSystem->SetWindow(&window);
|
graphicsSystem->SetWindow(&window);
|
||||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
|
||||||
//auto [w, h] = window.GetWindowSize();
|
|
||||||
//SDL_SetWindowSize(sdlWindow, w, h);
|
|
||||||
|
|
||||||
SHADE::SHSystemManager::Init();
|
SHADE::SHSystemManager::Init();
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||||
SHADE::SHEditor::Initialise(sdlWindow);
|
SHADE::SHEditor::Initialise(sdlWindow);
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set up scripting
|
|
||||||
SHADE::SHScriptEngine::Init();
|
|
||||||
|
|
||||||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
||||||
}
|
}
|
||||||
|
@ -82,13 +110,9 @@ namespace Sandbox
|
||||||
graphicsSystem->BeginRender();
|
graphicsSystem->BeginRender();
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SHADE::SHEditor::PreRender();
|
SHADE::SHEditor::Update(0.16f);
|
||||||
//SHADE::SHEditor::Render();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
|
||||||
SHADE::SHEditor::Render();
|
|
||||||
#endif
|
|
||||||
graphicsSystem->Run(1.0f);
|
graphicsSystem->Run(1.0f);
|
||||||
graphicsSystem->EndRender();
|
graphicsSystem->EndRender();
|
||||||
|
|
||||||
|
@ -99,14 +123,14 @@ namespace Sandbox
|
||||||
|
|
||||||
void SBApplication::Exit(void)
|
void SBApplication::Exit(void)
|
||||||
{
|
{
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SHADE::SHEditor::Exit();
|
SHADE::SHEditor::Exit();
|
||||||
#endif
|
|
||||||
SHSceneManager::Exit();
|
|
||||||
SHADE::SHScriptEngine::Exit();
|
|
||||||
SHADE::SHSystemManager::Exit();
|
|
||||||
SDL_DestroyWindow(sdlWindow);
|
SDL_DestroyWindow(sdlWindow);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SHSceneManager::Exit();
|
||||||
|
SHADE::SHSystemManager::Exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
|
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
|
@ -31,22 +35,92 @@ 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
|
||||||
|
auto meshes = SHADE::SHAssetManager::GetAllMeshes();
|
||||||
|
std::vector<Handle<SHMesh>> handles;
|
||||||
|
for (auto const& mesh : meshes)
|
||||||
|
{
|
||||||
|
handles.push_back(graphicsSystem->AddMesh(
|
||||||
|
mesh.header.vertexCount,
|
||||||
|
mesh.vertexPosition.data(),
|
||||||
|
mesh.texCoords.data(),
|
||||||
|
mesh.vertexTangent.data(),
|
||||||
|
mesh.vertexNormal.data(),
|
||||||
|
mesh.header.indexCount,
|
||||||
|
mesh.indices.data()
|
||||||
|
));
|
||||||
|
}
|
||||||
graphicsSystem->BuildMeshBuffers();
|
graphicsSystem->BuildMeshBuffers();
|
||||||
|
|
||||||
// Create Materials
|
//Test Textures
|
||||||
auto matInst = graphicsSystem->AddMaterialInstance();
|
auto textures{ SHADE::SHAssetManager::GetAllTextures() };
|
||||||
|
|
||||||
// Create entity and add mesh
|
// Create Materials
|
||||||
auto entity = SHADE::SHEntityManager::CreateEntity<SHADE::SHRenderable>();
|
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
|
||||||
auto& renderable = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHRenderable>(entity);
|
|
||||||
renderable.Mesh = CUBE_MESH;
|
// Create Stress Test Objects
|
||||||
renderable.SetMaterial(matInst);
|
static const SHVec3 TEST_OBJ_SCALE = { 0.2f, 0.2f, 0.2f };
|
||||||
renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f);
|
constexpr int NUM_ROWS = 1;
|
||||||
|
constexpr int NUM_COLS = 1;
|
||||||
|
static const SHVec3 TEST_OBJ_SPACING = { 1.0f, 1.0f, 1.0f };
|
||||||
|
static const SHVec3 TEST_OBJ_START_POS = { - (NUM_COLS / 2 * TEST_OBJ_SPACING.x ), 0.0f, 0.0f };
|
||||||
|
//for (int z = 0; z < NUM_ROWS; ++z)
|
||||||
|
//for (int x = 0; x < NUM_COLS; ++x)
|
||||||
|
//{
|
||||||
|
// auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
// auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||||
|
// auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||||
|
|
||||||
|
// renderable.Mesh = handles.front();
|
||||||
|
// renderable.SetMaterial(matInst);
|
||||||
|
|
||||||
|
// // Set initial positions
|
||||||
|
// transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, 0.0f, z * TEST_OBJ_SPACING.z });
|
||||||
|
// //transform.SetLocalScale(TEST_OBJ_SCALE);
|
||||||
|
|
||||||
|
// stressTestObjects.emplace_back(entity);
|
||||||
|
//}
|
||||||
|
|
||||||
|
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||||
|
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||||
|
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||||
|
|
||||||
|
renderable.Mesh = handles.front();
|
||||||
|
renderable.SetMaterial(matInst);
|
||||||
|
|
||||||
|
//transform.SetLocalScale(TEST_OBJ_SCALE);
|
||||||
|
|
||||||
|
stressTestObjects.emplace_back(entity);
|
||||||
|
|
||||||
|
// Create blank entity with a script
|
||||||
|
testObj = SHADE::SHEntityManager::CreateEntity();
|
||||||
|
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||||
|
scriptEngine->AddScript(testObj, "TestScript");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBTestScene::Update(float dt)
|
void SBTestScene::Update(float dt)
|
||||||
{
|
{
|
||||||
(void)dt;
|
/*static float rotation = 0.0f;
|
||||||
|
|
||||||
|
auto& transform = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHTransformComponent>(testObj);
|
||||||
|
|
||||||
|
transform.SetLocalRotation(rotation, 0.0f, 0.0f);
|
||||||
|
rotation += dt * 10.0f;*/
|
||||||
|
/*static float rotation = 0.0f;
|
||||||
|
|
||||||
|
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
|
||||||
|
if (GetKeyState(VK_SPACE) & 0x8000)
|
||||||
|
{
|
||||||
|
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||||
|
scriptEngine->RemoveAllScripts(testObj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBTestScene::Render()
|
void SBTestScene::Render()
|
||||||
|
|
|
@ -9,7 +9,8 @@ namespace Sandbox
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
EntityID camera;
|
EntityID camera;
|
||||||
|
EntityID testObj;
|
||||||
|
std::vector<EntityID> stressTestObjects;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void Load();
|
virtual void Load();
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||||
|
<Type Name="SHADE::Handle<*>">
|
||||||
|
<DisplayString Condition="library==nullptr">NULL</DisplayString>
|
||||||
|
<DisplayString>ID = {id.Data.Index} Version = {id.Data.Version} Type = {"$T1"} </DisplayString>
|
||||||
|
<Expand>
|
||||||
|
<ExpandedItem>(*library).objects.denseArray[(*library).objects.sparseArray[id.Data.Index]]</ExpandedItem>
|
||||||
|
</Expand>
|
||||||
|
</Type>
|
||||||
|
</AutoVisualizer>
|
|
@ -15,7 +15,8 @@ project "SHADE_Engine"
|
||||||
"%{prj.location}/src/**.hpp",
|
"%{prj.location}/src/**.hpp",
|
||||||
"%{prj.location}/src/**.c",
|
"%{prj.location}/src/**.c",
|
||||||
"%{prj.location}/src/**.cpp",
|
"%{prj.location}/src/**.cpp",
|
||||||
"%{prj.location}/src/**.glsl"
|
"%{prj.location}/src/**.glsl",
|
||||||
|
"%{prj.location}/**.natvis"
|
||||||
}
|
}
|
||||||
|
|
||||||
includedirs
|
includedirs
|
||||||
|
@ -41,6 +42,7 @@ 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}"
|
||||||
}
|
}
|
||||||
|
|
||||||
externalwarnings "Off"
|
externalwarnings "Off"
|
||||||
|
@ -102,19 +104,37 @@ project "SHADE_Engine"
|
||||||
{
|
{
|
||||||
"xcopy /s /r /y /q \"%{IncludeDir.spdlog}\\bin\" \"$(OutDir)\"",
|
"xcopy /s /r /y /q \"%{IncludeDir.spdlog}\\bin\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.SDL}\\lib\\SDL2.dll\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.SDL}\\lib\\SDL2.dll\" \"$(OutDir)\"",
|
||||||
"xcopy /s /r /y /q \"%{IncludeDir.dotnet}\\bin\" \"$(OutDir)\""
|
"xcopy /s /r /y /q \"%{IncludeDir.dotnet}\\bin\" \"$(OutDir)\""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter "configurations:Debug"
|
||||||
|
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Debug\\assimp-vc142-mtd.dll\" \"$(OutDir)\""}
|
||||||
|
|
||||||
|
filter "configurations:Release"
|
||||||
|
postbuildcommands {"xcopy /r /y /q \"%{IncludeDir.assimp}\\bin\\Release\\assimp-vc142-mt.dll\" \"$(OutDir)\""}
|
||||||
|
|
||||||
warnings 'Extra'
|
warnings 'Extra'
|
||||||
|
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
defines {"_DEBUG"}
|
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"
|
||||||
|
defines{"_RELEASE", "SHEDITOR"}
|
||||||
|
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||||
|
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
||||||
|
|
||||||
|
filter "configurations:Publish"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE"}
|
defines{"_RELEASE"}
|
||||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||||
|
excludes
|
||||||
|
{
|
||||||
|
"%{prj.location}/src/Editor/**.cpp",
|
||||||
|
"%{prj.location}/src/Editor/**.h",
|
||||||
|
"%{prj.location}/src/Editor/**.hpp",
|
||||||
|
}
|
||||||
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHMeshAssetHeader
|
||||||
|
{
|
||||||
|
uint32_t vertexCount;
|
||||||
|
uint32_t indexCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHMeshAsset
|
||||||
|
{
|
||||||
|
bool compiled;
|
||||||
|
bool changed;
|
||||||
|
|
||||||
|
SHMeshAssetHeader header;
|
||||||
|
|
||||||
|
std::string meshName;
|
||||||
|
|
||||||
|
std::vector<SHVec3> vertexPosition;
|
||||||
|
std::vector<SHVec3> vertexTangent;
|
||||||
|
std::vector<SHVec3> vertexNormal;
|
||||||
|
std::vector<SHVec2> texCoords;
|
||||||
|
std::vector<uint32_t> indices;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tinyddsloader.h"
|
||||||
|
|
||||||
|
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHTextureAsset
|
||||||
|
{
|
||||||
|
uint32_t numBytes;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
SHTexture::TextureFormat format;
|
||||||
|
std::vector<uint32_t> mipOffsets;
|
||||||
|
SHTexture::PixelChannel const * pixelData;
|
||||||
|
|
||||||
|
SHTextureAsset()
|
||||||
|
: numBytes{ 0 },
|
||||||
|
width{ 0 },
|
||||||
|
height{ 0 },
|
||||||
|
format{ SHTexture::TextureFormat::eUndefined },
|
||||||
|
pixelData{ nullptr }
|
||||||
|
{}
|
||||||
|
|
||||||
|
SHTextureAsset(SHTextureAsset const& rhs)
|
||||||
|
: numBytes{ rhs.numBytes },
|
||||||
|
width{ rhs.width },
|
||||||
|
height{ rhs.height },
|
||||||
|
format{ rhs.format },
|
||||||
|
mipOffsets{ rhs.mipOffsets },
|
||||||
|
pixelData(rhs.pixelData)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//SHTextureAsset(SHTextureAsset&& rhs)
|
||||||
|
// : numBytes{ rhs.numBytes },
|
||||||
|
// width{ rhs.width },
|
||||||
|
// height{ rhs.height },
|
||||||
|
// format{ rhs.format },
|
||||||
|
// mipOffsets{ rhs.mipOffsets },
|
||||||
|
// pixelData(std::move(rhs.pixelData))
|
||||||
|
//{}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHMeshLoader.h"
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
Assimp::Importer SHMeshLoader::aiImporter;
|
||||||
|
|
||||||
|
void SHMeshLoader::ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes)
|
||||||
|
{
|
||||||
|
for (size_t i {0}; i < node.mNumMeshes; ++i)
|
||||||
|
{
|
||||||
|
aiMesh* mesh = scene.mMeshes[node.mMeshes[i]];
|
||||||
|
meshes.push_back(ProcessMesh(*mesh, scene));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i{ 0 }; i < node.mNumChildren; ++i)
|
||||||
|
{
|
||||||
|
ProcessNode(*node.mChildren[i], scene, meshes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHMeshAsset SHMeshLoader::ProcessMesh(aiMesh const& mesh, aiScene const& scene)
|
||||||
|
{
|
||||||
|
(void)scene;
|
||||||
|
|
||||||
|
SHMeshAsset result
|
||||||
|
{
|
||||||
|
.compiled { false},
|
||||||
|
.changed { false },
|
||||||
|
.meshName { mesh.mName.C_Str() }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i{0}; i < mesh.mNumVertices; ++i)
|
||||||
|
{
|
||||||
|
// Vertex position
|
||||||
|
SHVec3 vertex;
|
||||||
|
vertex.x = mesh.mVertices[i].x;
|
||||||
|
vertex.y = mesh.mVertices[i].y;
|
||||||
|
vertex.z = mesh.mVertices[i].z;
|
||||||
|
result.vertexPosition.push_back(vertex);
|
||||||
|
|
||||||
|
// Tex coords
|
||||||
|
SHVec2 texCoord{0.f, 0.f};
|
||||||
|
if (mesh.mTextureCoords[0])
|
||||||
|
{
|
||||||
|
texCoord.x = mesh.mTextureCoords[0][i].x;
|
||||||
|
texCoord.y = mesh.mTextureCoords[0][i].y;
|
||||||
|
}
|
||||||
|
result.texCoords.push_back(texCoord);
|
||||||
|
|
||||||
|
// Normals
|
||||||
|
SHVec3 normal{0.f, 0.f, 0.f};
|
||||||
|
if (mesh.mNormals)
|
||||||
|
{
|
||||||
|
normal.x = mesh.mNormals[i].x;
|
||||||
|
normal.y = mesh.mNormals[i].y;
|
||||||
|
normal.z = mesh.mNormals[i].z;
|
||||||
|
}
|
||||||
|
result.vertexNormal.push_back(normal);
|
||||||
|
|
||||||
|
// Tangent
|
||||||
|
SHVec3 tangent{0.f, 0.f, 0.f};
|
||||||
|
if (mesh.mTangents)
|
||||||
|
{
|
||||||
|
tangent.x = mesh.mTangents[i].x;
|
||||||
|
tangent.y = mesh.mTangents[i].y;
|
||||||
|
tangent.z = mesh.mTangents[i].z;
|
||||||
|
}
|
||||||
|
result.vertexTangent.push_back(tangent);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i {0}; i < mesh.mNumFaces; ++i)
|
||||||
|
{
|
||||||
|
aiFace face = mesh.mFaces[i];
|
||||||
|
for (size_t j{0}; j < face.mNumIndices; ++j)
|
||||||
|
{
|
||||||
|
result.indices.push_back(face.mIndices[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.header.vertexCount = result.vertexPosition.size();
|
||||||
|
result.header.indexCount = result.indices.size();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHMeshLoader::LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path)
|
||||||
|
{
|
||||||
|
const aiScene* scene = aiImporter.ReadFile(path.string().c_str(),
|
||||||
|
aiProcess_Triangulate
|
||||||
|
// Make sure we get triangles rather than nvert polygons
|
||||||
|
| aiProcess_GenUVCoords // Convert any type of mapping to uv mapping
|
||||||
|
| aiProcess_TransformUVCoords
|
||||||
|
// preprocess UV transformations (scaling, translation ...)
|
||||||
|
| aiProcess_FindInstances
|
||||||
|
// search for instanced meshes and remove them by references to one master
|
||||||
|
| aiProcess_CalcTangentSpace
|
||||||
|
// calculate tangents and bitangents if possible
|
||||||
|
| aiProcess_JoinIdenticalVertices
|
||||||
|
// join identical vertices/ optimize indexing
|
||||||
|
| aiProcess_RemoveRedundantMaterials // remove redundant materials
|
||||||
|
| aiProcess_FindInvalidData// detect invalid model data, such as invalid normal vectors
|
||||||
|
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!scene || !scene->HasMeshes())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("ERROR in GLTF::ASSIMP: {}\nFile: {}", aiImporter.GetErrorString(), path.string());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//TODO MATERIALS FROM MESHES
|
||||||
|
//if (scene->HasMaterials())
|
||||||
|
//{
|
||||||
|
// for (int i{0}; i < scene->mNumMaterials; ++i)
|
||||||
|
// {
|
||||||
|
// if (scene->mMaterials[i]->mNumProperties > 0)
|
||||||
|
// {
|
||||||
|
// for (int j{0}; j < scene->mMaterials[i]->mProperties[j].)
|
||||||
|
// }
|
||||||
|
//std::cout << scene->mMaterials[i]->;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
ProcessNode(*scene->mRootNode, *scene, meshes);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#pragma once
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include "../SHAssetMacros.h"
|
||||||
|
#include "../Asset Types/SHMeshAsset.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHMeshLoader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static Assimp::Importer aiImporter;
|
||||||
|
|
||||||
|
static void ProcessNode(aiNode const& node, aiScene const& scene, std::vector<SHMeshAsset>& meshes);
|
||||||
|
|
||||||
|
static SHMeshAsset ProcessMesh(aiMesh const& mesh, aiScene const& scene);
|
||||||
|
public:
|
||||||
|
static bool LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path);
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#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();
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#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,92 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHTextureLoader.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
std::string SHTextureLoader::TinyDDSResultToString(tinyddsloader::Result value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case tinyddsloader::Result::ErrorFileOpen:
|
||||||
|
return "File open err";
|
||||||
|
case tinyddsloader::Result::ErrorRead:
|
||||||
|
return "File read err";
|
||||||
|
case tinyddsloader::Result::ErrorMagicWord:
|
||||||
|
return "File header magic word err";
|
||||||
|
case tinyddsloader::Result::ErrorSize:
|
||||||
|
return "File size err";
|
||||||
|
case tinyddsloader::Result::ErrorVerify:
|
||||||
|
return "Pixel format err";
|
||||||
|
case tinyddsloader::Result::ErrorNotSupported:
|
||||||
|
return "Unsupported format";
|
||||||
|
case tinyddsloader::Result::ErrorInvalidData:
|
||||||
|
return "Invalid data";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::Format SHTextureLoader::ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eBc1RgbaUnormBlock : vk::Format::eBc1RgbaSrgbBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eBc2UnormBlock : vk::Format::eBc2SrgbBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eBc3UnormBlock : vk::Format::eBc3SrgbBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC5_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::BC5_SNorm:
|
||||||
|
return isLinear ? vk::Format::eBc5UnormBlock : vk::Format::eBc5SnormBlock;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eR8G8B8A8Unorm : vk::Format::eR8G8B8A8Srgb;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_SNorm:
|
||||||
|
return vk::Format::eR8G8B8A8Snorm;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8A8Srgb;
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8X8_UNorm:
|
||||||
|
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8X8_UNorm_SRGB:
|
||||||
|
return isLinear ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8Srgb;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unsupported DDS format.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset)
|
||||||
|
{
|
||||||
|
tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
|
||||||
|
tinyddsloader::DDSFile file;
|
||||||
|
loadResult = file.Load(path.string().c_str());
|
||||||
|
if (loadResult != tinyddsloader::Result::Success)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Unable to load Texture file: {} at {}", TinyDDSResultToString(loadResult), path.string());
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t totalBytes{ 0 };
|
||||||
|
|
||||||
|
std::vector<uint32_t> mipOff(file.GetMipCount());
|
||||||
|
|
||||||
|
for (auto i{0}; i < file.GetMipCount(); ++i)
|
||||||
|
{
|
||||||
|
mipOff.push_back(totalBytes);
|
||||||
|
totalBytes += file.GetImageData(i, 0)->m_memSlicePitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
||||||
|
std::memcpy(pixel, file.GetDDSData(), totalBytes);
|
||||||
|
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
|
||||||
|
|
||||||
|
asset.numBytes = totalBytes;
|
||||||
|
asset.width = file.GetWidth();
|
||||||
|
asset.height = file.GetHeight();
|
||||||
|
asset.format = ddsLoaderToVkFormat(file.GetFormat(), true);
|
||||||
|
asset.mipOffsets = std::move(mipOff);
|
||||||
|
asset.pixelData = std::move(pixel);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
#define TINYDDSLOADER_IMPLEMENTATION
|
||||||
|
|
||||||
|
#include "../SHAssetMacros.h"
|
||||||
|
#include "../Asset Types/SHTextureAsset.h"
|
||||||
|
#include "tinyddsloader.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHTextureLoader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static std::string TinyDDSResultToString(tinyddsloader::Result value);
|
||||||
|
static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Filesystem/SHFileSystem.h"
|
||||||
|
#include "SHAssetMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHAsset
|
||||||
|
{
|
||||||
|
AssetName name;
|
||||||
|
AssetID id;
|
||||||
|
AssetType type;
|
||||||
|
AssetPath path;
|
||||||
|
FolderLocation location;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetMacros.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Macros and typedefs for assets
|
||||||
|
*
|
||||||
|
* \copyright 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
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef SH_ASSET_MACROS_H
|
||||||
|
#define SH_ASSET_MACROS_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
// FMOD Fwd Declare
|
||||||
|
namespace FMOD
|
||||||
|
{
|
||||||
|
class Sound;
|
||||||
|
class System;
|
||||||
|
class ChannelGroup;
|
||||||
|
class Channel;
|
||||||
|
}
|
||||||
|
enum FMOD_RESULT : int;
|
||||||
|
enum FMOD_SPEAKERMODE : int;
|
||||||
|
|
||||||
|
// Typedefs
|
||||||
|
typedef uint32_t AssetID;
|
||||||
|
typedef std::string AssetName;
|
||||||
|
typedef std::filesystem::path AssetPath;
|
||||||
|
typedef unsigned char* AssetData;
|
||||||
|
typedef std::string AssetMetaVersion;
|
||||||
|
typedef std::string AssetExtension;
|
||||||
|
typedef unsigned char AssetTypeMeta;
|
||||||
|
|
||||||
|
typedef FMOD::Sound* SHSound;
|
||||||
|
|
||||||
|
// Asset Meta Version
|
||||||
|
#define ASSET_META_VER "1.0"
|
||||||
|
|
||||||
|
// Asset type enum
|
||||||
|
enum class AssetType : uint8_t
|
||||||
|
{
|
||||||
|
INVALID = 0,
|
||||||
|
AUDIO = 1,
|
||||||
|
SHADER,
|
||||||
|
MATERIAL,
|
||||||
|
IMAGE,
|
||||||
|
TEXTURE,
|
||||||
|
MESH,
|
||||||
|
SCRIPT,
|
||||||
|
SCENE,
|
||||||
|
PREFAB,
|
||||||
|
AUDIO_WAV,
|
||||||
|
DDS
|
||||||
|
};
|
||||||
|
|
||||||
|
//Directory
|
||||||
|
#define ASSET_ROOT "./Assets/"
|
||||||
|
|
||||||
|
// ASSET EXTENSIONS
|
||||||
|
#define META_EXTENSION ".shmeta"
|
||||||
|
#define IMAGE_EXTENSION ".png"
|
||||||
|
#define AUDIO_EXTENSION ".ogg"
|
||||||
|
#define AUDIO_WAV_EXTENSION ".wav"
|
||||||
|
#define SHADER_EXTENSION ".glsl"
|
||||||
|
#define SCRIPT_EXTENSION ".cs"
|
||||||
|
#define SCENE_EXTENSION ".SHADE"
|
||||||
|
#define PREFAB_EXTENSION ".SHPrefab"
|
||||||
|
#define MATERIAL_EXTENSION ".SHMat"
|
||||||
|
#define TEXTURE_EXTENSION ".shtex"
|
||||||
|
#define DDS_EXTENSION ".dds"
|
||||||
|
#define FBX_EXTENSION ".fbx"
|
||||||
|
#define GLTF_EXTENSION ".gltf"
|
||||||
|
#define MESH_EXTENSION ".shmesh"
|
||||||
|
|
||||||
|
std::string const EXTENSIONS[] = {
|
||||||
|
AUDIO_EXTENSION,
|
||||||
|
SHADER_EXTENSION,
|
||||||
|
MATERIAL_EXTENSION,
|
||||||
|
IMAGE_EXTENSION,
|
||||||
|
TEXTURE_EXTENSION,
|
||||||
|
DDS_EXTENSION,
|
||||||
|
MESH_EXTENSION,
|
||||||
|
SCRIPT_EXTENSION,
|
||||||
|
SCENE_EXTENSION,
|
||||||
|
PREFAB_EXTENSION,
|
||||||
|
AUDIO_WAV_EXTENSION,
|
||||||
|
FBX_EXTENSION,
|
||||||
|
GLTF_EXTENSION
|
||||||
|
};
|
||||||
|
|
||||||
|
// Error flags
|
||||||
|
#define FILE_NOT_FOUND_ERR "FILE NOT FOUND"
|
||||||
|
#define META_NOT_FOUND_ERR "META NOT FOUND"
|
||||||
|
#define ASSET_NOT_FOUND_ERR "ASSET NOT FOUND"
|
||||||
|
#define EXT_DOES_NOT_EXIST "TYPE DOES NOT HAVE EXTENSION DEFINED"
|
||||||
|
|
||||||
|
#endif // !SH_ASSET_MACROS_H
|
|
@ -0,0 +1,441 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetManager.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Implementations for SHAssetManager.h
|
||||||
|
*
|
||||||
|
* \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 <random>
|
||||||
|
#include <chrono>
|
||||||
|
#include "SHAssetManager.h"
|
||||||
|
#include "SHAssetMetaHandler.h"
|
||||||
|
#include "Filesystem/SHFileSystem.h"
|
||||||
|
|
||||||
|
#include "Libraries/SHMeshLoader.h"
|
||||||
|
#include "Libraries/SHTextureLoader.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
FMOD::System* SHAssetManager::audioSystem;
|
||||||
|
std::unordered_map<AssetID, SHSound >* SHAssetManager::audioSoundList;
|
||||||
|
|
||||||
|
std::vector<SHAsset> SHAssetManager::assetCollection;
|
||||||
|
std::unordered_map<AssetID, SHAsset> SHAssetManager::assetRegistry;
|
||||||
|
|
||||||
|
std::unordered_map<AssetID, SHMeshAsset> SHAssetManager::meshCollection;
|
||||||
|
std::unordered_map<AssetID, SHTextureAsset> SHAssetManager::textureCollection;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Static function to generate asset ID.
|
||||||
|
****************************************************************************/
|
||||||
|
AssetID SHAssetManager::GenerateAssetID(AssetType type) noexcept
|
||||||
|
{
|
||||||
|
std::default_random_engine randEngine{
|
||||||
|
static_cast<unsigned int>(std::chrono::system_clock::now().time_since_epoch().count()) };
|
||||||
|
std::mt19937 idGen{ randEngine() };
|
||||||
|
AssetID result{ static_cast<AssetID>(type) << 24};
|
||||||
|
AssetID unique{ idGen() & ((1 << 24) - 1) };
|
||||||
|
|
||||||
|
result |= unique;
|
||||||
|
|
||||||
|
while (result == 0)
|
||||||
|
{
|
||||||
|
result = GenerateAssetID(type);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Deallocate all memory used by asset data
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::Unload() noexcept
|
||||||
|
{
|
||||||
|
for (auto const& asset : assetCollection)
|
||||||
|
{
|
||||||
|
SHAssetMetaHandler::WriteMetaData(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept
|
||||||
|
{
|
||||||
|
if (!IsRecognised(path.extension().string().c_str()))
|
||||||
|
{
|
||||||
|
//TODO:ASSERT UNRECOGNISED FILE TYPE
|
||||||
|
return std::filesystem::path();
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetType type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string().c_str());
|
||||||
|
std::string folder;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
//TODO:ASSERT UNSUPPORTED FILE TYPE
|
||||||
|
return std::filesystem::path();
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::filesystem::path(ASSET_ROOT + folder + path.filename().string());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Get record of all assets currently loaded with name and id.
|
||||||
|
*
|
||||||
|
* \return const& to unordered_map<AssetName, AssetID>
|
||||||
|
****************************************************************************/
|
||||||
|
std::vector<SHAsset> const& SHAssetManager::GetAllAssets() noexcept
|
||||||
|
{
|
||||||
|
return assetCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Create record for new asset. CAN ONLY CREATE FOR CUSTOM
|
||||||
|
* ASSETS CREATED BY THE ENGINE.
|
||||||
|
*
|
||||||
|
* \param type of asset
|
||||||
|
* \param name of asset
|
||||||
|
* \return asset id generated for new asset
|
||||||
|
****************************************************************************/
|
||||||
|
AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
|
||||||
|
{
|
||||||
|
AssetID id{ GenerateAssetID(type) };
|
||||||
|
SHAsset meta;
|
||||||
|
meta.id = id;
|
||||||
|
meta.type = type;
|
||||||
|
|
||||||
|
std::string folder;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
folder = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
|
||||||
|
|
||||||
|
SHAssetMetaHandler::WriteMetaData(meta);
|
||||||
|
|
||||||
|
assetCollection.push_back(meta);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Import new asset from outside editor window.
|
||||||
|
*
|
||||||
|
* \param path - c style string to full path
|
||||||
|
* \return asset if generated for new
|
||||||
|
****************************************************************************/
|
||||||
|
AssetID SHAssetManager::ImportNewAsset(char const* p) noexcept
|
||||||
|
{
|
||||||
|
std::filesystem::path const path{ p };
|
||||||
|
|
||||||
|
std::filesystem::path const newPath{ GenerateLocalPath(path) };
|
||||||
|
if (newPath.empty())
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Unsupported file format for asset: {}", path.string());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::copy(path, newPath);
|
||||||
|
|
||||||
|
AssetID id{ RetrieveAsset(newPath.string().c_str()) };
|
||||||
|
if (id != 0)
|
||||||
|
{
|
||||||
|
LoadData(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Search through assets folder for new unregistered assets.
|
||||||
|
* Takes in no params and returns nothing. Only updates internally.
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::RefreshAllAssets() noexcept
|
||||||
|
{
|
||||||
|
std::vector<AssetPath> metaFiles;
|
||||||
|
std::vector<AssetPath> AssetFiles;
|
||||||
|
|
||||||
|
//SHFileSystem::LoadAllFiles(metaFiles, AssetFiles);
|
||||||
|
//std::vector<AssetPath> AssetFilesVerified;
|
||||||
|
std::vector<AssetPath> AssetFilesNew;
|
||||||
|
|
||||||
|
for (auto const& asset : AssetFiles)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for (auto it {metaFiles.begin()}; it != metaFiles.end(); ++it)
|
||||||
|
{
|
||||||
|
std::string fileExtCheck{ asset.filename().string() };
|
||||||
|
fileExtCheck += META_EXTENSION;
|
||||||
|
if (it->filename().string() == fileExtCheck)
|
||||||
|
{
|
||||||
|
metaFiles.erase(it);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found && IsRecognised(asset.extension().string().c_str()))
|
||||||
|
{
|
||||||
|
AssetFilesNew.push_back(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SHAsset> newLoad;
|
||||||
|
newLoad.reserve(AssetFilesNew.size());
|
||||||
|
|
||||||
|
//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
|
||||||
|
for (auto const& file : AssetFilesNew)
|
||||||
|
{
|
||||||
|
newLoad.push_back(RegisterAssetNew(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
//UpdateAllSpriteSets();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::LoadDataTemp(std::string p) noexcept
|
||||||
|
{
|
||||||
|
AssetPath path{ p };
|
||||||
|
|
||||||
|
if (path.extension().string() == GLTF_EXTENSION)
|
||||||
|
{
|
||||||
|
LoadGLTF(
|
||||||
|
{
|
||||||
|
.name {path.filename().string()},
|
||||||
|
.id {0},
|
||||||
|
.type {AssetType::MESH},
|
||||||
|
.path {path},
|
||||||
|
.location {0}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (path.extension().string() == DDS_EXTENSION)
|
||||||
|
{
|
||||||
|
LoadDDS(
|
||||||
|
{
|
||||||
|
.name {path.filename().string()},
|
||||||
|
.id {0},
|
||||||
|
.type {AssetType::DDS},
|
||||||
|
.path {path},
|
||||||
|
.location {0}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SHMeshAsset> SHAssetManager::GetAllMeshes() noexcept
|
||||||
|
{
|
||||||
|
std::vector<SHMeshAsset> result;
|
||||||
|
for (auto const& mesh : meshCollection)
|
||||||
|
{
|
||||||
|
result.push_back(mesh.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SHTextureAsset> SHAssetManager::GetAllTextures() noexcept
|
||||||
|
{
|
||||||
|
std::vector<SHTextureAsset> result;
|
||||||
|
for (auto const& dds : textureCollection)
|
||||||
|
{
|
||||||
|
result.push_back(dds.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Path for meta data file
|
||||||
|
* \param Path for asset file
|
||||||
|
|
||||||
|
* \brief Links meta data to asset in registries. Meta data should
|
||||||
|
* already exist
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::RegisterAsset(AssetPath const& metaPath, AssetPath const& path) noexcept
|
||||||
|
{
|
||||||
|
SHAsset const meta = SHAssetMetaHandler::RetrieveMetaData(metaPath);
|
||||||
|
|
||||||
|
assetCollection.push_back(meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Path for asset file
|
||||||
|
|
||||||
|
* \brief Creates new meta data for new asset.
|
||||||
|
****************************************************************************/
|
||||||
|
SHAsset SHAssetManager::RegisterAssetNew(AssetPath const& asset) noexcept
|
||||||
|
{
|
||||||
|
SHAsset meta;
|
||||||
|
meta.type = SHAssetMetaHandler::GetTypeFromExtension(asset.extension().string());
|
||||||
|
meta.id = GenerateAssetID(meta.type);
|
||||||
|
|
||||||
|
assetCollection.push_back(meta);
|
||||||
|
|
||||||
|
SHAssetMetaHandler::WriteMetaData(meta);
|
||||||
|
return assetCollection.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHAssetManager::IsRecognised(char const* ext) noexcept
|
||||||
|
{
|
||||||
|
for (auto const& e : EXTENSIONS)
|
||||||
|
{
|
||||||
|
if (strcmp(ext, e.c_str()) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::LoadGLTF(SHAsset asset) noexcept
|
||||||
|
{
|
||||||
|
std::vector<SHMeshAsset> meshes;
|
||||||
|
|
||||||
|
SHMeshLoader::LoadMesh(meshes, asset.path);
|
||||||
|
|
||||||
|
for (auto const& mesh : meshes)
|
||||||
|
{
|
||||||
|
meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::LoadDDS(SHAsset asset) noexcept
|
||||||
|
{
|
||||||
|
SHTextureAsset image;
|
||||||
|
|
||||||
|
SHTextureLoader::LoadImageAsset(asset.path, image);
|
||||||
|
|
||||||
|
textureCollection.emplace(GenerateAssetID(AssetType::DDS), image);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Load all assets that are in the folder
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::Load() noexcept
|
||||||
|
{
|
||||||
|
RetrieveAssets();
|
||||||
|
LoadAllData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Load asset data into memory
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::LoadAllData() noexcept
|
||||||
|
{
|
||||||
|
for (auto const& asset : assetCollection)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAssetManager::LoadData(AssetID id) noexcept
|
||||||
|
{
|
||||||
|
(void)id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Retrieve all asset files and meta files from filesystem
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetManager::RetrieveAssets() noexcept
|
||||||
|
{
|
||||||
|
std::vector<AssetPath> metaFiles;
|
||||||
|
std::vector<AssetPath> AssetFiles;
|
||||||
|
|
||||||
|
//TODO: Write new function for file manager to loop through all files
|
||||||
|
SHFileSystem::StartupFillDirectories(ASSET_ROOT);
|
||||||
|
FolderPointer rootFolder = SHFileSystem::GetRoot();
|
||||||
|
|
||||||
|
for (auto const& meta : metaFiles)
|
||||||
|
{
|
||||||
|
for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() };
|
||||||
|
it != AssetFiles.cend();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
// Asset exists for meta file
|
||||||
|
std::string fileExtCheck{ it->filename().string() };
|
||||||
|
fileExtCheck += META_EXTENSION;
|
||||||
|
if (meta.filename().string() == fileExtCheck)
|
||||||
|
{
|
||||||
|
RegisterAsset(meta, *it);
|
||||||
|
AssetFiles.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
|
||||||
|
for (auto const& file : AssetFiles)
|
||||||
|
{
|
||||||
|
if (IsRecognised(file.extension().string().c_str()))
|
||||||
|
{
|
||||||
|
SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Unsupported File Format: " << file.filename() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept
|
||||||
|
{
|
||||||
|
std::filesystem::path p{ path };
|
||||||
|
if (IsRecognised(p.extension().string().c_str()))
|
||||||
|
{
|
||||||
|
SHAsset const& meta{ RegisterAssetNew(p) };
|
||||||
|
SHAssetMetaHandler::WriteMetaData(meta);
|
||||||
|
return meta.id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Unsupported File Format: " << p.filename() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert that file imported is not recognised
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Full path of file
|
||||||
|
|
||||||
|
* \brief Extracts file name from path. Formats file name into readable
|
||||||
|
* with spaces and capitalises first letter of every word
|
||||||
|
****************************************************************************/
|
||||||
|
AssetName SHAssetManager::GetNameFromPath(AssetPath filepath) noexcept
|
||||||
|
{
|
||||||
|
std::string name{ filepath.filename().string() };
|
||||||
|
name = name.substr(0, name.find_last_of('.'));
|
||||||
|
|
||||||
|
//if (name[0] <= 122 && name[0] >= 97)
|
||||||
|
//{
|
||||||
|
// name[0] -= 32;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//for (size_t i{ 1 }; i < name.length(); ++i)
|
||||||
|
//{
|
||||||
|
// // Replace all underscores with spaces
|
||||||
|
// if (name[i] == '_')
|
||||||
|
// {
|
||||||
|
// name[i] = ' ';
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (name[i + 1] <= 'Z' && name[i + 1] >= 'A'
|
||||||
|
// && name[i] <= 'z' && name[i] >= 'a')
|
||||||
|
// {
|
||||||
|
// name.insert(i + 1, 1, ' ');
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (name[i - 1] == ' ' && name[i] <= 'z' && name[i] >= 'a')
|
||||||
|
// {
|
||||||
|
// name[i] -= 32;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetManager.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Interface for resource manager, to be used by engine side
|
||||||
|
* operations.
|
||||||
|
*
|
||||||
|
* \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 "tinyddsloader.h"
|
||||||
|
#include "SHAsset.h"
|
||||||
|
|
||||||
|
#include "Asset Types/SHMeshAsset.h"
|
||||||
|
#include "Asset Types/SHTextureAsset.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SH_API SHAssetManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Static function to generate resource ID.
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetID GenerateAssetID(AssetType type) noexcept;
|
||||||
|
|
||||||
|
static AssetPath GenerateLocalPath(AssetPath path) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Deallocate all memory used by resource data
|
||||||
|
****************************************************************************/
|
||||||
|
static void Unload() noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Load all resources that are in the folder
|
||||||
|
****************************************************************************/
|
||||||
|
static void Load() noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Get record of all resources currently loaded with name and id.
|
||||||
|
*
|
||||||
|
* \return const& to unordered_map<AssetName, AssetID>
|
||||||
|
****************************************************************************/
|
||||||
|
static std::vector<SHAsset> const& GetAllAssets() noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Create record for new resource. CAN ONLY CREATE FOR CUSTOM
|
||||||
|
* RESOURCES CREATED BY THE ENGINE.
|
||||||
|
*
|
||||||
|
* \param type of resource
|
||||||
|
* \param name of resource
|
||||||
|
* \return resource id generated for new asset
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetID CreateNewAsset(AssetType, AssetName) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Import new resource from outside editor window.
|
||||||
|
*
|
||||||
|
* \param path - c style string to full path
|
||||||
|
* \return resource if generated for new
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetID ImportNewAsset(char const* path) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Search through resources folder for new unregistered assets.
|
||||||
|
* Takes in no params and returns nothing. Only updates internally.
|
||||||
|
****************************************************************************/
|
||||||
|
static void RefreshAllAssets() noexcept;
|
||||||
|
// -------------------------------------------------------------------------/
|
||||||
|
|
||||||
|
//TODO: TEMPORARY FOR TESTING GLTF & DDS
|
||||||
|
static void LoadDataTemp(std::string path) noexcept;
|
||||||
|
static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
|
||||||
|
static std::vector<SHTextureAsset> GetAllTextures() noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Load resource data into memory
|
||||||
|
****************************************************************************/
|
||||||
|
static void LoadAllData() noexcept;
|
||||||
|
|
||||||
|
static void LoadData(AssetID id) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \brief Retrieve all resource files and meta files from filesystem
|
||||||
|
****************************************************************************/
|
||||||
|
static void RetrieveAssets() noexcept;
|
||||||
|
|
||||||
|
static AssetID RetrieveAsset(char const* path) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Full path of file
|
||||||
|
|
||||||
|
* \brief Extracts file name from path. Formats file name into readable
|
||||||
|
* with spaces and capitalises first letter of every word
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetName GetNameFromPath(AssetPath) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Path for meta data file
|
||||||
|
* \param Path for resource file
|
||||||
|
|
||||||
|
* \brief Links meta data to resource in registries. Meta data should
|
||||||
|
* already exist
|
||||||
|
****************************************************************************/
|
||||||
|
static void RegisterAsset(AssetPath const&, AssetPath const&) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Path for resource file
|
||||||
|
|
||||||
|
* \brief Creates new meta data for new resource.
|
||||||
|
****************************************************************************/
|
||||||
|
static SHAsset RegisterAssetNew(AssetPath const&) noexcept;
|
||||||
|
|
||||||
|
static bool IsRecognised(char const*) noexcept;
|
||||||
|
|
||||||
|
// Specialised load calls
|
||||||
|
static void LoadGLTF(SHAsset asset) noexcept;
|
||||||
|
static void LoadDDS(SHAsset asset) noexcept;
|
||||||
|
|
||||||
|
static FMOD::System* audioSystem;
|
||||||
|
static std::unordered_map<AssetID,SHSound>* audioSoundList;
|
||||||
|
|
||||||
|
// For all resources
|
||||||
|
static std::vector<SHAsset> assetCollection;
|
||||||
|
static std::unordered_map<AssetID, SHAsset> assetRegistry;
|
||||||
|
|
||||||
|
static std::unordered_map<AssetID, SHMeshAsset> meshCollection;
|
||||||
|
static std::unordered_map<AssetID, SHTextureAsset> textureCollection;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetMetaHandler.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Implementations for SHAssetMetaHandler.h
|
||||||
|
*
|
||||||
|
* \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 "SHAssetMetaHandler.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/****************************************************************************
|
||||||
|
* \param reference to ifstream file to read line from
|
||||||
|
* \param reference to string to store line into
|
||||||
|
|
||||||
|
* \brief Helper function to retrieve field value from meta data file
|
||||||
|
* for processing
|
||||||
|
****************************************************************************/
|
||||||
|
void GetFieldValue(std::ifstream& file, std::string& line) noexcept
|
||||||
|
{
|
||||||
|
line = "";
|
||||||
|
std::getline(file, line);
|
||||||
|
line = line.substr(line.find_last_of(':') + 2, line.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param String containing extension of resource file
|
||||||
|
|
||||||
|
* \brief Get correct resource type from file extension of resource.
|
||||||
|
****************************************************************************/
|
||||||
|
AssetType SHAssetMetaHandler::GetTypeFromExtension(AssetExtension ext) noexcept
|
||||||
|
{
|
||||||
|
for (int i{0}; i < EXTENSIONS->size(); ++i)
|
||||||
|
{
|
||||||
|
if (ext == EXTENSIONS[i])
|
||||||
|
{
|
||||||
|
return static_cast<AssetType>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AssetType::INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param String containing extension of resource file
|
||||||
|
|
||||||
|
* \brief Get correct resource type from file extension of resource.
|
||||||
|
****************************************************************************/
|
||||||
|
AssetExtension SHAssetMetaHandler::GetExtensionFromType(AssetType type) noexcept
|
||||||
|
{
|
||||||
|
return EXTENSIONS[static_cast<size_t>(type)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Create class containing meta data from meta file
|
||||||
|
|
||||||
|
* \brief path to meta data file
|
||||||
|
****************************************************************************/
|
||||||
|
SHAsset SHAssetMetaHandler::RetrieveMetaData(AssetPath const& path) noexcept
|
||||||
|
{
|
||||||
|
std::ifstream metaFile{ path.string(), std::ios_base::in };
|
||||||
|
if (!metaFile.is_open())
|
||||||
|
{
|
||||||
|
// Error unable to open
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
SHAsset meta;
|
||||||
|
|
||||||
|
// Get resource id
|
||||||
|
GetFieldValue(metaFile, line);
|
||||||
|
std::stringstream idStream{ line };
|
||||||
|
AssetID id;
|
||||||
|
idStream >> id;
|
||||||
|
meta.id = id;
|
||||||
|
|
||||||
|
// Get resource type
|
||||||
|
GetFieldValue(metaFile, line);
|
||||||
|
std::stringstream typeStream{ line };
|
||||||
|
AssetTypeMeta type;
|
||||||
|
typeStream >> type;
|
||||||
|
meta.type = static_cast<AssetType>(type);
|
||||||
|
|
||||||
|
metaFile.close();
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Asset meta data to be written into
|
||||||
|
* \param Path to be written into
|
||||||
|
|
||||||
|
* \brief Writes meta data into text file
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAssetMetaHandler::WriteMetaData(SHAsset const& meta) noexcept
|
||||||
|
{
|
||||||
|
std::string path{ meta.path.string() };
|
||||||
|
path.append(META_EXTENSION);
|
||||||
|
|
||||||
|
std::ofstream metaFile{ path, std::ios_base::out };
|
||||||
|
|
||||||
|
if (!metaFile.is_open())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Asset write path is invalid: {}", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
metaFile << "ID: " << meta.id << "\n";
|
||||||
|
metaFile << "Type: " << static_cast<int>(meta.type) << std::endl;
|
||||||
|
metaFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAssetMetaHandler.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Handler classes for meta data for all resources
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef SH_RESOURCE_META_HANDLER_H
|
||||||
|
#define SH_RESOURCE_META_HANDLER_H
|
||||||
|
|
||||||
|
#include "SHAssetMacros.h"
|
||||||
|
#include "SHAsset.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHAssetMetaHandler
|
||||||
|
{
|
||||||
|
/****************************************************************************
|
||||||
|
* \param String containing extension of resource file
|
||||||
|
|
||||||
|
* \brief Get correct resource type from file extension of resource.
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetType GetTypeFromExtension(AssetExtension) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param String containing extension of resource file
|
||||||
|
|
||||||
|
* \brief Get correct resource type from file extension of resource.
|
||||||
|
****************************************************************************/
|
||||||
|
static AssetExtension GetExtensionFromType(AssetType) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Create class containing meta data from meta file
|
||||||
|
|
||||||
|
* \brief path to meta data file
|
||||||
|
****************************************************************************/
|
||||||
|
static SHAsset RetrieveMetaData(AssetPath const&) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param Asset meta data to be written into
|
||||||
|
* \param Path to be written into
|
||||||
|
|
||||||
|
* \brief Writes meta data into text file
|
||||||
|
****************************************************************************/
|
||||||
|
static void WriteMetaData(SHAsset const&) noexcept;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !SH_RESOURCE_META_HANDLER_H
|
|
@ -0,0 +1,51 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHBaseCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~SHBaseCommand() = default;
|
||||||
|
virtual void Execute() {}
|
||||||
|
virtual void Undo() {}
|
||||||
|
virtual void Merge(std::shared_ptr<SHBaseCommand>) {}
|
||||||
|
};//struct SHBaseCommand
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class SHCommand : SHBaseCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::function<void(T const&)> SetterFunction;
|
||||||
|
|
||||||
|
SHCommand(T const& oldVal, T const& value, SetterFunction setFnc)
|
||||||
|
: oldValue(oldVal), newValue(value), set(setFnc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Execute() override
|
||||||
|
{
|
||||||
|
set(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Undo() override
|
||||||
|
{
|
||||||
|
set(oldValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Merge(std::shared_ptr<SHBaseCommand> newCommand) override
|
||||||
|
{
|
||||||
|
newValue = std::reinterpret_pointer_cast<SHCommand>(newCommand)->newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
T oldValue;
|
||||||
|
T newValue;
|
||||||
|
SetterFunction set;
|
||||||
|
};
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,57 @@
|
||||||
|
//#==============================================================#
|
||||||
|
//|| PCH Include ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHCommandManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHCommandManager::CommandStack SHCommandManager::undoStack{};
|
||||||
|
SHCommandManager::CommandStack SHCommandManager::redoStack{};
|
||||||
|
|
||||||
|
void SHCommandManager::PerformCommand(CommandPtr commandPtr, bool const& overrideValue)
|
||||||
|
{
|
||||||
|
redoStack = CommandStack();
|
||||||
|
commandPtr->Execute();
|
||||||
|
if (overrideValue && !undoStack.empty())
|
||||||
|
{
|
||||||
|
undoStack.top()->Merge(commandPtr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
undoStack.push(commandPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::UndoCommand()
|
||||||
|
{
|
||||||
|
if (undoStack.empty())
|
||||||
|
return;
|
||||||
|
undoStack.top()->Undo();
|
||||||
|
redoStack.push(undoStack.top());
|
||||||
|
undoStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::RedoCommand()
|
||||||
|
{
|
||||||
|
if (redoStack.empty())
|
||||||
|
return;
|
||||||
|
redoStack.top()->Execute();
|
||||||
|
undoStack.push(redoStack.top());
|
||||||
|
redoStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t SHCommandManager::GetUndoStackSize()
|
||||||
|
{
|
||||||
|
return undoStack.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t SHCommandManager::GetRedoStackSize()
|
||||||
|
{
|
||||||
|
return redoStack.size();
|
||||||
|
}
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHCommand.hpp"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHCommandManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Type Aliases ||
|
||||||
|
//#==============================================================#
|
||||||
|
using CommandPtr = std::shared_ptr<SHBaseCommand>;
|
||||||
|
using CommandStack = std::stack<CommandPtr>;
|
||||||
|
|
||||||
|
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false);
|
||||||
|
static void UndoCommand();
|
||||||
|
static void RedoCommand();
|
||||||
|
static std::size_t GetUndoStackSize();
|
||||||
|
static std::size_t GetRedoStackSize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static CommandStack undoStack;
|
||||||
|
static CommandStack redoStack;
|
||||||
|
};
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
#include "SHDragDrop.hpp"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
bool SHDragDrop::hasDragDrop = false;
|
||||||
|
|
||||||
|
bool SHDragDrop::BeginSource(ImGuiDragDropFlags const flags)
|
||||||
|
{ return ImGui::BeginDragDropSource(flags); }
|
||||||
|
|
||||||
|
void SHDragDrop::EndSource()
|
||||||
|
{ ImGui::EndDragDropSource();}
|
||||||
|
|
||||||
|
bool SHDragDrop::BeginTarget()
|
||||||
|
{ return ImGui::BeginDragDropTarget(); }
|
||||||
|
|
||||||
|
void SHDragDrop::EndTarget()
|
||||||
|
{ ImGui::EndDragDropTarget(); hasDragDrop = false;}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//TODO: Convert to RTTR?
|
||||||
|
constexpr auto DRAG_EID = "DragEID";
|
||||||
|
constexpr auto DRAG_RESOURCE = "DragResource";
|
||||||
|
|
||||||
|
|
||||||
|
struct SHDragDrop
|
||||||
|
{
|
||||||
|
static bool BeginSource(ImGuiDragDropFlags const flags = 0);
|
||||||
|
/**
|
||||||
|
* \brief Ends the DragDrop Source. ONLY CALL IF BeginSource returns true
|
||||||
|
*/
|
||||||
|
static void EndSource();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool SetPayload(std::string_view const type, T* object, ImGuiCond const cond = 0)
|
||||||
|
{
|
||||||
|
hasDragDrop = ImGui::SetDragDropPayload(type.data(), static_cast<void*>(object), sizeof(T), cond);
|
||||||
|
return hasDragDrop;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool BeginTarget();
|
||||||
|
/**
|
||||||
|
* \brief Ends the DragDrop Target. ONLY CALL IF BeginTarget returns true
|
||||||
|
*/
|
||||||
|
static void EndTarget();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static T* AcceptPayload(std::string_view const type, ImGuiDragDropFlags const flags = 0)
|
||||||
|
{
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(type.data(), flags))
|
||||||
|
return static_cast<T*>(payload->Data);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool hasDragDrop;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,212 @@
|
||||||
|
//#==============================================================#
|
||||||
|
//|| PCH Include ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
#include "SHHierarchyPanel.h"
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||||
|
#include "Tools/SHException.h"
|
||||||
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Public Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
SHHierarchyPanel::SHHierarchyPanel()
|
||||||
|
:SHEditorWindow("Hierarchy Panel", ImGuiWindowFlags_MenuBar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::Update()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Update();
|
||||||
|
|
||||||
|
isAnyNodeSelected = false;
|
||||||
|
|
||||||
|
if (Begin())
|
||||||
|
{
|
||||||
|
DrawMenuBar();
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
if(const auto root = sceneGraph.GetRoot())
|
||||||
|
{
|
||||||
|
auto const& children = root->GetChildren();
|
||||||
|
for (const auto child : children)
|
||||||
|
{
|
||||||
|
RecursivelyDrawEntityNode(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Scene Graph root is null! Unable to render hierarchy.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
|
{
|
||||||
|
SHEditor::selectedEntities.clear();
|
||||||
|
}
|
||||||
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::Exit()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Private Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
void SHHierarchyPanel::DrawMenuBar() const noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui::SmallButton(ICON_MD_ADD))
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity();
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Add Entity");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
ImGui::EndMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* currentNode)
|
||||||
|
{
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
|
||||||
|
//Get node data (Children, eid, selected)
|
||||||
|
auto& children = currentNode->GetChildren();
|
||||||
|
EntityID eid = currentNode->GetEntityID();
|
||||||
|
const bool isSelected = (std::ranges::find(SHEditor::selectedEntities, eid) != SHEditor::selectedEntities.end());
|
||||||
|
|
||||||
|
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
||||||
|
|
||||||
|
//bool highlighted = false;
|
||||||
|
//if(highlighted)
|
||||||
|
//{
|
||||||
|
// ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
|
||||||
|
//}
|
||||||
|
|
||||||
|
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
||||||
|
//Draw Node
|
||||||
|
bool isNodeOpen = ImGui::TreeNodeEx((void*)eid, nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str());
|
||||||
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
|
||||||
|
//Check For Begin Drag
|
||||||
|
if (SHDragDrop::BeginSource())
|
||||||
|
{
|
||||||
|
ImGui::Text("Moving EID: %zu", eid);
|
||||||
|
SHDragDrop::SetPayload<EntityID>(DRAG_EID, &eid);
|
||||||
|
SHDragDrop::EndSource();
|
||||||
|
}
|
||||||
|
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
||||||
|
{
|
||||||
|
if (const EntityID* eidPayload = SHDragDrop::AcceptPayload<EntityID>(DRAG_EID)) //If payload is valid
|
||||||
|
{
|
||||||
|
EntityID const dropEID = *eidPayload;
|
||||||
|
if(!sceneGraph.GetChild(dropEID, eid))
|
||||||
|
sceneGraph.SetParent(dropEID, eid); //Set dropEID parent to eid (belonging to current Node)
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Context menu
|
||||||
|
if(ImGui::BeginPopupContextItem(std::to_string(eid).c_str()))
|
||||||
|
{
|
||||||
|
if(!isSelected)
|
||||||
|
{
|
||||||
|
SHEditor::selectedEntities.clear();
|
||||||
|
SHEditor::selectedEntities.push_back(eid);
|
||||||
|
}
|
||||||
|
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||||
|
{
|
||||||
|
SHEntityManager::DestroyEntity(eid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
|
||||||
|
{
|
||||||
|
sceneGraph.SetParent(currentNode->GetEntityID(), nullptr);
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Handle node selection
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
|
{
|
||||||
|
if (!isSelected)
|
||||||
|
{
|
||||||
|
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||||
|
SHEditor::selectedEntities.clear();
|
||||||
|
SHEditor::selectedEntities.push_back(eid);
|
||||||
|
}//if not selected
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||||
|
{
|
||||||
|
auto it = std::ranges::remove(SHEditor::selectedEntities, eid).begin();
|
||||||
|
}//if mod ctrl is not pressed
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditor::selectedEntities.clear();
|
||||||
|
SHEditor::selectedEntities.push_back(eid);
|
||||||
|
}
|
||||||
|
}//if selected
|
||||||
|
}//if left mouse button released
|
||||||
|
}//if item hovered
|
||||||
|
|
||||||
|
if (isNodeOpen)
|
||||||
|
{
|
||||||
|
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||||
|
const float horizontalOffset = 0.0f;
|
||||||
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||||
|
|
||||||
|
ImVec2 vertLineStart = ImGui::GetCursorScreenPos();
|
||||||
|
vertLineStart.x += horizontalOffset;
|
||||||
|
ImVec2 vertLineEnd = vertLineStart;
|
||||||
|
|
||||||
|
for (const auto child : children)
|
||||||
|
{
|
||||||
|
const float horizontalLineSize = 8.0f;
|
||||||
|
const ImRect childRect = RecursivelyDrawEntityNode(child);
|
||||||
|
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||||
|
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 2);
|
||||||
|
vertLineEnd.y = midPoint;
|
||||||
|
}
|
||||||
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 2);
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
return nodeRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::CreateChildEntity(EntityID parentEID) const noexcept
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
|
||||||
|
}
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,33 @@
|
||||||
|
#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 SHSceneNode;
|
||||||
|
constexpr ImVec4 highlightedColor = ImVec4(0.f, 0.7f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
class SHHierarchyPanel final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHHierarchyPanel();
|
||||||
|
void Init() override;
|
||||||
|
void Update() override;
|
||||||
|
void Exit() override;
|
||||||
|
private:
|
||||||
|
void DrawMenuBar() const noexcept;
|
||||||
|
ImRect RecursivelyDrawEntityNode(SHSceneNode*);
|
||||||
|
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||||
|
std::string filter;
|
||||||
|
bool isAnyNodeSelected = false;
|
||||||
|
};//class SHHierarchyPanel
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,70 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <rttr/type>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
||||||
|
static void DrawContextMenu(T* component)
|
||||||
|
{
|
||||||
|
if(!component)
|
||||||
|
return;
|
||||||
|
rttr::string_view componentName = rttr::type::get<T>().get_name();
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupContextItem(componentName.data()))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ImGui::Selectable(std::format("{} Copy {}", ICON_MD_CONTENT_COPY, componentName.data()).data()))
|
||||||
|
{
|
||||||
|
//SHClipboardUtil::WriteStringToClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT, SHComponentToString(component));
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable(std::format("{} Paste {}", ICON_MD_CONTENT_PASTE, componentName.data()).data()))
|
||||||
|
{
|
||||||
|
//SHStringToComponent(component, SHClipboardUtil::ReadStringFromClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT));
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable(std::format("{} Delete {}", ICON_MD_DELETE, componentName.data()).data()))
|
||||||
|
{
|
||||||
|
SHComponentManager::RemoveComponent<T>(component->GetEID());
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T, std::enable_if_t<std::is_base_of_v<SHComponent, T>, bool> = true>
|
||||||
|
static void DrawComponent(T* component)
|
||||||
|
{
|
||||||
|
if (!component)
|
||||||
|
return;
|
||||||
|
auto componentType = rttr::type::get(*component);
|
||||||
|
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 const& properties = componentType.get_properties();
|
||||||
|
for (auto const& property : properties)
|
||||||
|
{
|
||||||
|
auto const& type = property.get_type();
|
||||||
|
|
||||||
|
if (type == rttr::type::get<SHVec4>())
|
||||||
|
{
|
||||||
|
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>())
|
||||||
|
{
|
||||||
|
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 DrawContextMenu(component);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
#include "SHEditorInspector.h"
|
||||||
|
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
#include "SHEditorComponentView.hpp"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
void DrawAddComponentButton(EntityID const& eid)
|
||||||
|
{
|
||||||
|
if(!SHComponentManager::HasComponent<ComponentType>(eid) && ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()))
|
||||||
|
{
|
||||||
|
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHEditorInspector::SHEditorInspector()
|
||||||
|
:SHEditorWindow("Inspector", ImGuiWindowFlags_MenuBar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorInspector::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorInspector::Update()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Update();
|
||||||
|
if (Begin())
|
||||||
|
{
|
||||||
|
if (!SHEditor::selectedEntities.empty())
|
||||||
|
{
|
||||||
|
EntityID const& eid = SHEditor::selectedEntities[0];
|
||||||
|
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
|
||||||
|
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
||||||
|
CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
ImGui::InputText("##EntityName", &entity->name);
|
||||||
|
|
||||||
|
if (auto transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(transformComponent);
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
||||||
|
{
|
||||||
|
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||||
|
DrawAddComponentButton<SHRenderable>(eid);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorInspector::Exit()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Exit();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <rttr/type>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHComponent;
|
||||||
|
|
||||||
|
class SHEditorInspector final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHEditorInspector();
|
||||||
|
void Init() override;
|
||||||
|
void Update() override;
|
||||||
|
void Exit() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHEditorMenuBar.h"
|
||||||
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
#include <rttr/type>
|
||||||
|
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||||
|
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking |
|
||||||
|
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||||
|
|
||||||
|
constexpr ImGuiWindowFlags dockspaceFlags = ImGuiDockNodeFlags_PassthruCentralNode;
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Public Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
SHEditorMenuBar::SHEditorMenuBar()
|
||||||
|
:SHEditorWindow("SHEditorMenuBar", editorMenuBarFlags | ImGuiWindowFlags_NoBackground)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::Update()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Update();
|
||||||
|
DrawMainMenuBar();
|
||||||
|
DrawSecondaryBar();
|
||||||
|
DrawStatusBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Private Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
void SHEditorMenuBar::DrawMainMenuBar() noexcept
|
||||||
|
{
|
||||||
|
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||||
|
|
||||||
|
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||||
|
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||||
|
ImGui::SetNextWindowViewport(viewport->ID);
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { ImVec2(0.0f, 0.0f) });
|
||||||
|
if (Begin())
|
||||||
|
{
|
||||||
|
ImGui::PopStyleVar(3);
|
||||||
|
|
||||||
|
if (ImGui::BeginMainMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("File"))
|
||||||
|
{
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
if(ImGui::BeginMenu("Edit"))
|
||||||
|
{
|
||||||
|
ImGui::BeginDisabled(!SHCommandManager::GetUndoStackSize());
|
||||||
|
if(ImGui::Button(std::format("{} Undo", ICON_MD_UNDO).data()))
|
||||||
|
{
|
||||||
|
SHCommandManager::UndoCommand();
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::BeginDisabled(!SHCommandManager::GetRedoStackSize());
|
||||||
|
if(ImGui::Button(std::format("{} Redo", ICON_MD_REDO).data()))
|
||||||
|
{
|
||||||
|
SHCommandManager::RedoCommand();
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
if(ImGui::BeginMenu("Theme"))
|
||||||
|
{
|
||||||
|
auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
|
||||||
|
auto values = styles.get_values();
|
||||||
|
for (auto style : values)
|
||||||
|
{
|
||||||
|
if(ImGui::Selectable(style.to_string().c_str()))
|
||||||
|
{
|
||||||
|
SHEditor::SetStyle(style.convert<SHEditor::Style>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMainMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ImGuiID dockspace_id = ImGui::GetID("DockSpace");
|
||||||
|
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspaceFlags);
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::DrawSecondaryBar() const noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::DrawStatusBar() const noexcept
|
||||||
|
{
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { ImVec2(0.0f, 0.0f) });
|
||||||
|
if (ImGui::BeginViewportSideBar("MainStatusBar", ImGui::GetMainViewport(), ImGuiDir_Down, menuBarHeight, editorMenuBarFlags))
|
||||||
|
{
|
||||||
|
ImGui::Text("Entity count: ");
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar(3);
|
||||||
|
|
||||||
|
}
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHEditorMenuBar final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHEditorMenuBar();
|
||||||
|
virtual void Init() override;
|
||||||
|
virtual void Update() override;
|
||||||
|
private:
|
||||||
|
void DrawMainMenuBar() noexcept;
|
||||||
|
void DrawSecondaryBar() const noexcept;
|
||||||
|
void DrawStatusBar() const noexcept;
|
||||||
|
float menuBarHeight = 20.0f;
|
||||||
|
};//class SHEditorMenuBar
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,46 @@
|
||||||
|
//#==============================================================#
|
||||||
|
//|| PCH Include ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SHEditorWindow.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Public Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
|
||||||
|
: isOpen(true), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorWindow::Init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorWindow::Update()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorWindow::Exit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Protected Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
bool SHEditorWindow::Begin()
|
||||||
|
{
|
||||||
|
return ImGui::Begin(windowName.data(), &isOpen, windowFlags);
|
||||||
|
}
|
||||||
|
}//namespace SHADE
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Forward Declarations ||
|
||||||
|
//#==============================================================#
|
||||||
|
struct ImGuiIO;
|
||||||
|
typedef int ImGuiWindowFlags;
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags);
|
||||||
|
virtual ~SHEditorWindow() = default;
|
||||||
|
virtual void Init();
|
||||||
|
virtual void Update();
|
||||||
|
virtual void Exit();
|
||||||
|
bool isOpen = false;
|
||||||
|
std::string_view windowName;
|
||||||
|
protected:
|
||||||
|
virtual bool Begin();
|
||||||
|
ImGuiWindowFlags windowFlags = 0;
|
||||||
|
ImGuiIO& io;
|
||||||
|
};//class SHEditorWindow
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,4 @@
|
||||||
|
#pragma once
|
||||||
|
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar
|
||||||
|
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
|
||||||
|
#include "Inspector/SHEditorInspector.h" //Inspector
|
File diff suppressed because it is too large
Load Diff
|
@ -1,79 +1,125 @@
|
||||||
|
//#==============================================================#
|
||||||
|
//|| PCH Include ||
|
||||||
|
//#==============================================================#
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHEditor.h"
|
|
||||||
|
|
||||||
#include <imgui.h>
|
#include "IconsMaterialDesign.h"
|
||||||
|
#include "DragDrop/SHDragDrop.hpp"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "Tools/SHException.h"
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
#include "Graphics/Instance/SHVkInstance.h"
|
#include "Graphics/Instance/SHVkInstance.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
|
||||||
//IMGUI Backend includes
|
#include "SHEditor.hpp"
|
||||||
|
#include "SHEditorWidgets.hpp"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Editor Window Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "EditorWindow/SHEditorWindowIncludes.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <rttr/registration>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| ImGui Backend Includes ||
|
||||||
|
//#==============================================================#
|
||||||
#include <backends/imgui_impl_sdl.h>
|
#include <backends/imgui_impl_sdl.h>
|
||||||
#include <backends/imgui_impl_vulkan.h>
|
#include <backends/imgui_impl_vulkan.h>
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace SHADE;
|
||||||
|
using namespace rttr;
|
||||||
|
registration::enumeration<SHEditor::Style>("Style")
|
||||||
|
(
|
||||||
|
value("SHADE", SHEditor::Style::SHADE),
|
||||||
|
value("DARK", SHEditor::Style::DARK),
|
||||||
|
value("LIGHT", SHEditor::Style::LIGHT),
|
||||||
|
value("CLASSIC", SHEditor::Style::CLASSIC)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Initialise static members ||
|
||||||
|
//#==============================================================#
|
||||||
Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
||||||
Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
|
Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
|
||||||
|
SHEditor::EditorWindowMap SHEditor::editorWindows{};
|
||||||
|
SHEditor::EditorWindowID SHEditor::windowCount{};
|
||||||
|
std::vector<EntityID> SHEditor::selectedEntities;
|
||||||
|
|
||||||
void SHEditor::Initialise(SDL_Window* sdlWindow)
|
//#==============================================================#
|
||||||
|
//|| Public Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
void SHEditor::Initialise(SDL_Window* const sdlWindow)
|
||||||
{
|
{
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
if(auto context = ImGui::CreateContext())
|
||||||
|
{
|
||||||
|
if(context == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_CRITICAL("Failed to create ImGui Context")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||||
|
|
||||||
ImGui_ImplSDL2_InitForVulkan(sdlWindow);
|
InitFonts();
|
||||||
|
InitBackend(sdlWindow);
|
||||||
|
|
||||||
auto* gfxSystem = reinterpret_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
SetStyle(Style::SHADE);
|
||||||
|
|
||||||
|
//Add editor windows
|
||||||
|
CreateEditorWindow<SHEditorMenuBar>();
|
||||||
|
CreateEditorWindow<SHHierarchyPanel>();
|
||||||
|
CreateEditorWindow<SHEditorInspector>();
|
||||||
|
|
||||||
ImGui_ImplVulkan_InitInfo initInfo{};
|
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
||||||
initInfo.Instance = SHVkInstance::GetVkInstance();
|
|
||||||
initInfo.PhysicalDevice = gfxSystem->GetPhysicalDevice()->GetVkPhysicalDevice();
|
|
||||||
initInfo.Device = gfxSystem->GetDevice()->GetVkLogicalDevice();
|
|
||||||
initInfo.Queue = gfxSystem->GetQueue()->GetVkQueue();
|
|
||||||
initInfo.DescriptorPool = gfxSystem->GetDescriptorPool()->GetVkHandle();
|
|
||||||
initInfo.MinImageCount = initInfo.ImageCount = gfxSystem->GetSwapchain()->GetNumImages();
|
|
||||||
initInfo.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
|
|
||||||
imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
|
||||||
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
|
||||||
|
|
||||||
/*auto renderPass = gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetRenderpass();
|
|
||||||
ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass());*/
|
|
||||||
|
|
||||||
imguiCommandBuffer->BeginRecording();
|
|
||||||
ImGui_ImplVulkan_CreateFontsTexture(imguiCommandBuffer->GetVkCommandBuffer());
|
|
||||||
imguiCommandBuffer->EndRecording();
|
|
||||||
gfxSystem->GetQueue()->SubmitCommandBuffer({imguiCommandBuffer}, {}, {}, vk::PipelineStageFlagBits::eNone, {});
|
|
||||||
|
|
||||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
|
||||||
|
|
||||||
/*gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
|
||||||
});*/
|
|
||||||
|
|
||||||
//ImGuiIO& io = ImGui::GetIO();
|
|
||||||
//int w, h;
|
|
||||||
//SDL_GetWindowSize(sdlWindow, &w, &h);
|
|
||||||
//io.DisplaySize = { static_cast<float>(w),static_cast<float>(h)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::PreRender()
|
void SHEditor::Update(float const dt)
|
||||||
{
|
{
|
||||||
|
(void)dt;
|
||||||
NewFrame();
|
NewFrame();
|
||||||
|
|
||||||
ImGui::ShowDemoWindow();
|
for (const auto& window : editorWindows | std::views::values)
|
||||||
ImGui::Begin("Your mom");
|
|
||||||
if (ImGui::Button("OP"))
|
|
||||||
{
|
{
|
||||||
std::cout << "HEHEHEOHEIOHIEOH\n";
|
window->Update();
|
||||||
}
|
}
|
||||||
ImGui::End();
|
|
||||||
|
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||||
|
{
|
||||||
|
SHCommandManager::RedoCommand();
|
||||||
|
}
|
||||||
|
else if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||||
|
{
|
||||||
|
SHCommandManager::UndoCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::Render()
|
void SHEditor::Render()
|
||||||
|
@ -87,6 +133,18 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
||||||
|
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.PixelSnapH = true;
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
void SHEditor::Exit()
|
void SHEditor::Exit()
|
||||||
{
|
{
|
||||||
ImGui_ImplVulkan_Shutdown();
|
ImGui_ImplVulkan_Shutdown();
|
||||||
|
@ -94,19 +152,164 @@ namespace SHADE
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::SetStyle(Style style)
|
||||||
void SHEditor::InitBackend()
|
|
||||||
{
|
{
|
||||||
|
switch (style)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case Style::SHADE:
|
||||||
|
{
|
||||||
|
ImGuiStyle& imStyle = ImGui::GetStyle();
|
||||||
|
ImVec4* colors = imStyle.Colors;
|
||||||
|
colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f);
|
||||||
|
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
|
||||||
|
colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f);
|
||||||
|
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||||
|
colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f);
|
||||||
|
colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f);
|
||||||
|
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
|
||||||
|
colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||||
|
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
|
||||||
|
colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||||
|
colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f);
|
||||||
|
colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f);
|
||||||
|
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
|
||||||
|
colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
|
||||||
|
colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
|
||||||
|
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
|
||||||
|
colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||||
|
colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f);
|
||||||
|
colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||||
|
colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f);
|
||||||
|
colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f);
|
||||||
|
colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg];
|
||||||
|
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
|
||||||
|
colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
|
||||||
|
colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
|
||||||
|
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
|
||||||
|
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
|
||||||
|
colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
|
||||||
|
colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f);
|
||||||
|
colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg];
|
||||||
|
colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
|
||||||
|
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||||
|
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||||
|
colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
|
||||||
|
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||||
|
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
|
||||||
|
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||||
|
colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
|
||||||
|
colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f);
|
||||||
|
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.141f, 0.141f, 0.141f, 0.70f);
|
||||||
|
colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight];
|
||||||
|
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f);
|
||||||
|
|
||||||
|
imStyle.WindowPadding = ImVec2(8.00f, 8.00f);
|
||||||
|
imStyle.FramePadding = ImVec2(5.00f, 2.00f);
|
||||||
|
imStyle.CellPadding = ImVec2(6.00f, 8.00f);
|
||||||
|
imStyle.ItemSpacing = ImVec2(6.00f, 6.00f);
|
||||||
|
imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f);
|
||||||
|
imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f);
|
||||||
|
imStyle.IndentSpacing = 25;
|
||||||
|
imStyle.ScrollbarSize = 15;
|
||||||
|
imStyle.GrabMinSize = 10;
|
||||||
|
imStyle.WindowBorderSize = 0.6f;
|
||||||
|
imStyle.ChildBorderSize = 1;
|
||||||
|
imStyle.PopupBorderSize = 1;
|
||||||
|
imStyle.FrameBorderSize = 1;
|
||||||
|
imStyle.TabBorderSize = 1;
|
||||||
|
imStyle.WindowRounding = 7;
|
||||||
|
imStyle.ChildRounding = 4;
|
||||||
|
imStyle.FrameRounding = 3;
|
||||||
|
imStyle.PopupRounding = 4;
|
||||||
|
imStyle.ScrollbarRounding = 9;
|
||||||
|
imStyle.GrabRounding = 3;
|
||||||
|
imStyle.LogSliderDeadzone = 4;
|
||||||
|
imStyle.TabRounding = 4;
|
||||||
|
imStyle.WindowMenuButtonPosition = ImGuiDir_None;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Style::DARK: ImGui::StyleColorsDark(); break;
|
||||||
|
case Style::LIGHT: ImGui::StyleColorsLight(); break;
|
||||||
|
case Style::CLASSIC: ImGui::StyleColorsClassic(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Private Member Functions ||
|
||||||
|
//#==============================================================#
|
||||||
|
void SHEditor::InitBackend(SDL_Window* sdlWindow)
|
||||||
|
{
|
||||||
|
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
|
||||||
|
{
|
||||||
|
SHLOG_CRITICAL("Editor backend initialisation; Failed to perform SDL initialisation for Vulkan")
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_InitInfo initInfo{};
|
||||||
|
initInfo.Instance = SHVkInstance::GetVkInstance();
|
||||||
|
initInfo.PhysicalDevice = gfxSystem->GetPhysicalDevice()->GetVkPhysicalDevice();
|
||||||
|
initInfo.Device = gfxSystem->GetDevice()->GetVkLogicalDevice();
|
||||||
|
initInfo.Queue = gfxSystem->GetQueue()->GetVkQueue();
|
||||||
|
initInfo.DescriptorPool = gfxSystem->GetDescriptorPool()->GetVkHandle();
|
||||||
|
initInfo.MinImageCount = initInfo.ImageCount = gfxSystem->GetSwapchain()->GetNumImages();
|
||||||
|
initInfo.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
|
imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||||
|
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
|
||||||
|
auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||||
|
|
||||||
|
SHASSERT(!renderers.empty(), "No Renderers available")
|
||||||
|
auto renderGraph = renderers[0]->GetRenderGraph();
|
||||||
|
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
|
||||||
|
|
||||||
|
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
||||||
|
{
|
||||||
|
SHLOG_CRITICAL("Editor backend initialisation; Failed to initialise Vulkan backend")
|
||||||
|
}
|
||||||
|
|
||||||
|
imguiCommandBuffer->BeginRecording();
|
||||||
|
if(ImGui_ImplVulkan_CreateFontsTexture(imguiCommandBuffer->GetVkCommandBuffer()) == false)
|
||||||
|
{
|
||||||
|
SHLOG_CRITICAL("Editor backend initialisation; Failed to create fonts texture for Vulkan backend")
|
||||||
|
}
|
||||||
|
imguiCommandBuffer->EndRecording();
|
||||||
|
gfxSystem->GetQueue()->SubmitCommandBuffer({ imguiCommandBuffer }, {}, {}, vk::PipelineStageFlagBits::eNone, {});
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||||
|
|
||||||
|
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
||||||
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::NewFrame()
|
void SHEditor::NewFrame()
|
||||||
{
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event) != 0)
|
||||||
|
{
|
||||||
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
|
}
|
||||||
ImGui_ImplVulkan_NewFrame();
|
ImGui_ImplVulkan_NewFrame();
|
||||||
ImGui_ImplSDL2_NewFrame();
|
ImGui_ImplSDL2_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHEditor::EndFrame()
|
}//namespace SHADE
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "SH_API.h"
|
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
#include "Resource/Handle.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
class SHVkCommandBuffer;
|
|
||||||
class SHVkCommandPool;
|
|
||||||
|
|
||||||
class SH_API SHEditor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static void Initialise(SDL_Window* sdlWindow);
|
|
||||||
static void PreRender();
|
|
||||||
static void Render();
|
|
||||||
static void Exit();
|
|
||||||
private:
|
|
||||||
static void InitBackend();
|
|
||||||
static void NewFrame();
|
|
||||||
static void EndFrame();
|
|
||||||
|
|
||||||
static Handle<SHVkCommandPool> imguiCommandPool;
|
|
||||||
static Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
#include "EditorWindow/SHEditorWindow.h"
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <SDL_video.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Forward Declarations ||
|
||||||
|
//#==============================================================#
|
||||||
|
class SHVkCommandBuffer;
|
||||||
|
class SHVkCommandPool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class SH_API SHEditor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Type Aliases ||
|
||||||
|
//#==============================================================#
|
||||||
|
using EditorWindowID = uint8_t;
|
||||||
|
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
||||||
|
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
|
||||||
|
*
|
||||||
|
* @tparam T Type of Editor Window
|
||||||
|
* @return EditorWindowID ID of Editor Window Type
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||||
|
static EditorWindowID GetEditorWindowID()
|
||||||
|
{
|
||||||
|
static EditorWindowID id;
|
||||||
|
static bool idCreated = false;
|
||||||
|
if (!idCreated)
|
||||||
|
{
|
||||||
|
id = windowCount++;
|
||||||
|
idCreated = true;
|
||||||
|
}
|
||||||
|
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
|
||||||
|
*
|
||||||
|
* @tparam T Type of Editor Window to create
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||||
|
static void CreateEditorWindow()
|
||||||
|
{
|
||||||
|
static bool isCreated = false;
|
||||||
|
if (!isCreated)
|
||||||
|
{
|
||||||
|
editorWindows[GetEditorWindowID<T>()] = std::make_unique<T>();
|
||||||
|
isCreated = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Attempt to create duplicate of Editor window type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InitFonts() noexcept;
|
||||||
|
|
||||||
|
// Handle to command pool used for ImGui Vulkan Backend
|
||||||
|
static Handle<SHVkCommandPool> imguiCommandPool;
|
||||||
|
// Handle to command buffer used for ImGui Vulkan Backend
|
||||||
|
static Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
||||||
|
|
||||||
|
// Number of windows; used for Editor Window ID Generation
|
||||||
|
static EditorWindowID windowCount;
|
||||||
|
// Map of Editor Windows
|
||||||
|
static EditorWindowMap editorWindows;
|
||||||
|
};//class SHEditor
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,187 @@
|
||||||
|
#pragma once
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
#include "Command/SHCommandManager.h"
|
||||||
|
#include "SHImGuiHelpers.hpp"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
#include <misc/cpp/imgui_stdlib.h>
|
||||||
|
#include <rttr/type.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Custom Widgets ||
|
||||||
|
//#==============================================================#
|
||||||
|
static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
|
const ImGuiID id = window->GetID("##Splitter");
|
||||||
|
ImRect bb;
|
||||||
|
bb.Min = window->DC.CursorPos + (verticalSplit ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
|
||||||
|
bb.Max = bb.Min + (verticalSplit ? ImVec2(thickness, splitterAxisSize) : ImVec2(splitterAxisSize, thickness));
|
||||||
|
return ImGui::SplitterBehavior(bb, id, verticalSplit ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, minSize1, minSize2, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
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(),
|
||||||
|
ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
||||||
|
if (window->SkipItems)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const ImGuiContext& g = *GImGui;
|
||||||
|
bool valueChanged = false;
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::PushID(fieldLabel.c_str());
|
||||||
|
PushMultiItemsWidthsAndLabels(componentLabels, 0.0f);
|
||||||
|
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
|
||||||
|
ImGui::SetColumnWidth(-1, 80.0f);
|
||||||
|
ImGui::Text(fieldLabel.c_str());
|
||||||
|
ImGui::NextColumn();
|
||||||
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
|
{
|
||||||
|
ImGui::PushID(static_cast<int>(i));
|
||||||
|
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str())); ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(80.0f);
|
||||||
|
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
|
||||||
|
|
||||||
|
const ImVec2 min = ImGui::GetItemRectMin();
|
||||||
|
const ImVec2 max = ImGui::GetItemRectMax();
|
||||||
|
const float spacing = g.Style.FrameRounding;
|
||||||
|
const float halfSpacing = spacing / 2;
|
||||||
|
|
||||||
|
window->DrawList->AddLine({ min.x + spacing, max.y - halfSpacing }, { max.x - spacing, max.y - halfSpacing },
|
||||||
|
ImGuiColors::colors[i], 4);
|
||||||
|
|
||||||
|
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
}
|
||||||
|
ImGui::EndColumns();
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
return valueChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DragVec2(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
|
||||||
|
std::function<void(SHVec2)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
|
ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
SHVec2 values = get();
|
||||||
|
bool changed = false;
|
||||||
|
if (DragN<float, 2>(fieldLabel, componentLabels, {&values.x, &values.y}, speed, displayFormat, valueMin, valueMax, flags))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||||
|
else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), true);
|
||||||
|
else if(ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DragVec3(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
|
||||||
|
std::function<void(SHVec3)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
|
ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
SHVec3 values = get();
|
||||||
|
bool changed = false;
|
||||||
|
if (DragN<float, 3>(fieldLabel, componentLabels, {&values.x, &values.y, &values.z}, speed, displayFormat, valueMin, valueMax, flags))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||||
|
else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), true);
|
||||||
|
else if(ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DragVec4(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
|
||||||
|
std::function<void(SHVec4)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||||
|
ImGuiSliderFlags flags = 0)
|
||||||
|
{
|
||||||
|
SHVec4 values = get();
|
||||||
|
bool changed = false;
|
||||||
|
if (DragN<float, 4>(fieldLabel, componentLabels, {&values.x, &values.y, &values.z, &values.w}, speed, displayFormat, valueMin, valueMax, flags))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||||
|
else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), true);
|
||||||
|
else if(ImGui::IsItemDeactivatedAfterEdit())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Widget Extensions ||
|
||||||
|
//#==============================================================#
|
||||||
|
|
||||||
|
static bool CheckBox(std::string const& label, std::function<bool(void)> get, std::function<void(bool const&)> set)
|
||||||
|
{
|
||||||
|
bool value = get();
|
||||||
|
if (ImGui::Checkbox(label.c_str(), &value))
|
||||||
|
{
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool RadioButton(std::vector<std::string> const& listLabels, std::vector<T> const& listTypes, std::function<T(void)> get, std::function<void(T const&)> set)
|
||||||
|
{
|
||||||
|
T type = get();
|
||||||
|
for (size_t i = 0; i < listTypes.size(); i++)
|
||||||
|
{
|
||||||
|
if (ImGui::RadioButton(listLabels[i].c_str(), type == listTypes[i]))
|
||||||
|
{
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), listTypes[i], set)), false);
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}//namespace SHADE
|
|
@ -0,0 +1,69 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| SHADE-ImGui Math Conversions ||
|
||||||
|
//#==============================================================#
|
||||||
|
#ifndef SH_IM_MATH
|
||||||
|
#define IM_VEC2_CLASS_EXTRA \
|
||||||
|
ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \
|
||||||
|
operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);}
|
||||||
|
#define IM_VEC3_CLASS_EXTRA \
|
||||||
|
ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \
|
||||||
|
operator SHADE::SHVec3() const {return SHADE::SHVec3(x,y,z);}
|
||||||
|
#define IM_VEC4_CLASS_EXTRA \
|
||||||
|
ImVec4(const SHADE::SHVec4& vec) {x = vec.x; y = vec.y; z = vec.z; w = vec.w;} \
|
||||||
|
operator SHADE::SHVec4() const {return SHADE::SHVec4(x,y,z,w);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui_internal.h>
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
namespace ImGuiColors
|
||||||
|
{
|
||||||
|
constexpr ImVec4 red = {1.0f, 0.0f, 0.0f, 1.f};
|
||||||
|
constexpr ImVec4 green = {0.0f, 1.0f, 0.0f, 1.f};
|
||||||
|
constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f};
|
||||||
|
constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f};
|
||||||
|
|
||||||
|
constexpr ImU32 colors[] = {
|
||||||
|
0xBB0000FF, // red
|
||||||
|
0xBB00FF00, // green
|
||||||
|
0xBBFF0000, // blue
|
||||||
|
0xBBFFFFFF, // white
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PushMultiItemsWidthsAndLabels(const std::vector<std::string>& labels, float wFull)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
|
const ImGuiStyle& style = GImGui->Style;
|
||||||
|
if (wFull <= 0.0f)
|
||||||
|
wFull = ImGui::GetContentRegionAvail().x;
|
||||||
|
const auto size = labels.size();
|
||||||
|
const float w_item_one =
|
||||||
|
ImMax(1.0f, (wFull - (static_cast<float>(size) - 1.0f) * (style.ItemInnerSpacing.x * 2.0f)) / static_cast<float>(
|
||||||
|
size)) -
|
||||||
|
style.ItemInnerSpacing.x;
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
window->DC.ItemWidthStack.push_back(w_item_one - ImGui::CalcTextSize(labels[i].c_str()).x);
|
||||||
|
window->DC.ItemWidth = window->DC.ItemWidthStack.back();
|
||||||
|
}
|
||||||
|
} //namespace SHADE
|
|
@ -19,7 +19,7 @@ namespace SHADE
|
||||||
SHEventHandle(T::*callback)(SHEventPtr);
|
SHEventHandle(T::*callback)(SHEventPtr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventPtr))
|
SHEventReceiverSpec(T* obj, SHEventHandle(T::* cb)(SHEventPtr))
|
||||||
:SHEventReceiver(), object{ obj }, callback{ cb }
|
:SHEventReceiver(), object{ obj }, callback{ cb }
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,12 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (!dirEntry.is_directory())
|
if (!dirEntry.is_directory())
|
||||||
{
|
{
|
||||||
|
folder->files.emplace_back(
|
||||||
|
dirEntry.path().filename().string(),
|
||||||
|
dirEntry.path().string(),
|
||||||
|
dirEntry.path().extension().string()
|
||||||
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +109,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FolderPointer SHFileSystem::GetRoot() noexcept
|
||||||
|
{
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
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(
|
assert(
|
||||||
|
|
|
@ -14,12 +14,22 @@ namespace SHADE
|
||||||
typedef uint64_t FolderLocation;
|
typedef uint64_t FolderLocation;
|
||||||
typedef uint64_t FolderHandle;
|
typedef uint64_t FolderHandle;
|
||||||
typedef std::string FolderName;
|
typedef std::string FolderName;
|
||||||
|
typedef std::string FileName;
|
||||||
typedef std::string FolderPath;
|
typedef std::string FolderPath;
|
||||||
|
typedef std::string FilePath;
|
||||||
|
typedef std::string FileExt;
|
||||||
typedef SHFolder* FolderPointer;
|
typedef SHFolder* FolderPointer;
|
||||||
|
|
||||||
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
|
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
|
||||||
constexpr char FOLDER_MAX_DEPTH{ 16 };
|
constexpr char FOLDER_MAX_DEPTH{ 16 };
|
||||||
|
|
||||||
|
struct SHFile
|
||||||
|
{
|
||||||
|
FileName name;
|
||||||
|
FilePath path;
|
||||||
|
FileExt ext;
|
||||||
|
};
|
||||||
|
|
||||||
class SHFolder
|
class SHFolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -28,6 +38,7 @@ namespace SHADE
|
||||||
FolderHandle id;
|
FolderHandle id;
|
||||||
FolderName name;
|
FolderName name;
|
||||||
std::vector<FolderPointer> subFolders;
|
std::vector<FolderPointer> subFolders;
|
||||||
|
std::vector<SHFile> files;
|
||||||
|
|
||||||
bool folded;
|
bool folded;
|
||||||
|
|
||||||
|
@ -45,6 +56,8 @@ namespace SHADE
|
||||||
|
|
||||||
static void StartupFillDirectories(FolderPath path) noexcept;
|
static void StartupFillDirectories(FolderPath path) noexcept;
|
||||||
|
|
||||||
|
static FolderPointer GetRoot() noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static FolderPointer root;
|
static FolderPointer root;
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,11 @@ namespace SHADE
|
||||||
Init(newSize, data, srcSize, bufferUsageFlags, allocCreateInfo.usage, allocCreateInfo.flags);
|
Init(newSize, data, srcSize, bufferUsageFlags, allocCreateInfo.usage, allocCreateInfo.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkBuffer::FlushAllocation(uint32_t srcOffset, uint32_t dstOffset) noexcept
|
||||||
|
{
|
||||||
|
vmaFlushAllocation(vmaAllocator, alloc, srcOffset, dstOffset);
|
||||||
|
}
|
||||||
|
|
||||||
vk::Buffer SHVkBuffer::GetVkBuffer(void) const noexcept
|
vk::Buffer SHVkBuffer::GetVkBuffer(void) const noexcept
|
||||||
{
|
{
|
||||||
return vkBuffer;
|
return vkBuffer;
|
||||||
|
@ -72,8 +77,7 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkBuffer::Map(void) noexcept
|
void SHVkBuffer::Map(void) noexcept
|
||||||
{
|
{
|
||||||
if (!boundToCoherent)
|
vmaMapMemory(vmaAllocator, alloc, &mappedPtr);
|
||||||
vmaMapMemory(vmaAllocator, alloc, &mappedPtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -90,11 +94,8 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkBuffer::Unmap(void) noexcept
|
void SHVkBuffer::Unmap(void) noexcept
|
||||||
{
|
{
|
||||||
if (!boundToCoherent)
|
vmaUnmapMemory(vmaAllocator, alloc);
|
||||||
{
|
mappedPtr = nullptr;
|
||||||
vmaUnmapMemory(vmaAllocator, alloc);
|
|
||||||
mappedPtr = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -132,9 +133,7 @@ namespace SHADE
|
||||||
Otherwise, only the copying is carried out.
|
Otherwise, only the copying is carried out.
|
||||||
|
|
||||||
In the instance where memory is non-coherent but HOST_VISIBLE, we want to
|
In the instance where memory is non-coherent but HOST_VISIBLE, we want to
|
||||||
write to data and then unmap and flush it immediately. If you want to write
|
write to data and then unmap and flush it immediately.
|
||||||
to memory in random-access fashion, consider, mapping, writing a few
|
|
||||||
things, unmapping then flushing.
|
|
||||||
|
|
||||||
\param vmaAllocator
|
\param vmaAllocator
|
||||||
The VMA allocator object.
|
The VMA allocator object.
|
||||||
|
@ -155,18 +154,11 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkBuffer::MapWriteUnmap(void* data, uint32_t sizeToWrite, uint32_t srcOffset, uint32_t dstOffset) noexcept
|
void SHVkBuffer::MapWriteUnmap(void* data, uint32_t sizeToWrite, uint32_t srcOffset, uint32_t dstOffset) noexcept
|
||||||
{
|
{
|
||||||
if (!boundToCoherent)
|
// map from host visible memory to pointer, do a DMA, and then unmap
|
||||||
{
|
Map();
|
||||||
// map from host visible memory to pointer, do a DMA, and then unmap
|
WriteToMemory(data, sizeToWrite, srcOffset, dstOffset);
|
||||||
Map();
|
Unmap();
|
||||||
WriteToMemory(data, sizeToWrite, srcOffset, dstOffset);
|
FlushAllocation(srcOffset, dstOffset);
|
||||||
Unmap();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mappedPtr)
|
|
||||||
std::memcpy(static_cast<uint8_t*>(mappedPtr) + dstOffset, static_cast<uint8_t*>(data) + srcOffset, sizeToWrite);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -279,7 +271,6 @@ namespace SHADE
|
||||||
, mappedPtr{ nullptr }
|
, mappedPtr{ nullptr }
|
||||||
, alloc {nullptr}
|
, alloc {nullptr}
|
||||||
, randomAccessOptimized{false}
|
, randomAccessOptimized{false}
|
||||||
, boundToCoherent {false}
|
|
||||||
, vmaAllocator{allocator}
|
, vmaAllocator{allocator}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -304,7 +295,6 @@ namespace SHADE
|
||||||
, mappedPtr{ std::move(rhs.mappedPtr) }
|
, mappedPtr{ std::move(rhs.mappedPtr) }
|
||||||
, alloc{ std::move (rhs.alloc) }
|
, alloc{ std::move (rhs.alloc) }
|
||||||
, randomAccessOptimized{ rhs.randomAccessOptimized }
|
, randomAccessOptimized{ rhs.randomAccessOptimized }
|
||||||
, boundToCoherent{ rhs.boundToCoherent}
|
|
||||||
, vmaAllocator{ rhs.vmaAllocator }
|
, vmaAllocator{ rhs.vmaAllocator }
|
||||||
, bufferUsageFlags {rhs.bufferUsageFlags}
|
, bufferUsageFlags {rhs.bufferUsageFlags}
|
||||||
, bufferCreateInfo { rhs.bufferCreateInfo }
|
, bufferCreateInfo { rhs.bufferCreateInfo }
|
||||||
|
@ -325,7 +315,6 @@ namespace SHADE
|
||||||
mappedPtr = std::move(rhs.mappedPtr);
|
mappedPtr = std::move(rhs.mappedPtr);
|
||||||
alloc = std::move(rhs.alloc);
|
alloc = std::move(rhs.alloc);
|
||||||
randomAccessOptimized = rhs.randomAccessOptimized;
|
randomAccessOptimized = rhs.randomAccessOptimized;
|
||||||
boundToCoherent = rhs.boundToCoherent;
|
|
||||||
vmaAllocator = std::move (rhs.vmaAllocator);
|
vmaAllocator = std::move (rhs.vmaAllocator);
|
||||||
rhs.vkBuffer = VK_NULL_HANDLE;
|
rhs.vkBuffer = VK_NULL_HANDLE;
|
||||||
bufferCreateInfo = rhs.bufferCreateInfo;
|
bufferCreateInfo = rhs.bufferCreateInfo;
|
||||||
|
@ -430,18 +419,20 @@ namespace SHADE
|
||||||
// mainly host visible. Can be cached (need to flush/invalidate), uncached (always coherent) and coherent (virtual).
|
// mainly host visible. Can be cached (need to flush/invalidate), uncached (always coherent) and coherent (virtual).
|
||||||
if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
|
if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
|
||||||
{
|
{
|
||||||
// If memory is marked to be coherent between CPU and GPU (no need flush/invalidate) (TODO: Verify if VMA_ALLOCATION_CREATE_MAPPED_BIT is used when VMA_MEMORY_USAGE_AUTO is set)
|
const bool CREATE_MAPPED = allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||||
// TODO: also verify that coherent bit = pointer is already mapped
|
|
||||||
if (memPropFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
if (CREATE_MAPPED)
|
||||||
{
|
|
||||||
boundToCoherent = true;
|
|
||||||
mappedPtr = allocInfo.pMappedData;
|
mappedPtr = allocInfo.pMappedData;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
mappedPtr = nullptr;
|
mappedPtr = nullptr;
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
MapWriteUnmap(data, srcSize, 0, 0);
|
{
|
||||||
|
if (CREATE_MAPPED)
|
||||||
|
WriteToMemory(data, srcSize, 0, 0);
|
||||||
|
else
|
||||||
|
MapWriteUnmap(data, srcSize, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,9 +41,6 @@ namespace SHADE
|
||||||
//! If initialized with vma random access flag, this is true
|
//! If initialized with vma random access flag, this is true
|
||||||
bool randomAccessOptimized;
|
bool randomAccessOptimized;
|
||||||
|
|
||||||
//! Whether or not this buffer is bound to coherent memory
|
|
||||||
bool boundToCoherent;
|
|
||||||
|
|
||||||
//! buffer usage info flags
|
//! buffer usage info flags
|
||||||
vk::BufferUsageFlags bufferUsageFlags;
|
vk::BufferUsageFlags bufferUsageFlags;
|
||||||
|
|
||||||
|
@ -100,6 +97,7 @@ namespace SHADE
|
||||||
void TransferToDeviceResource(Handle<SHVkCommandBuffer> const& cmdBufferHdl) noexcept;
|
void TransferToDeviceResource(Handle<SHVkCommandBuffer> const& cmdBufferHdl) noexcept;
|
||||||
void ResizeNoCopy (uint32_t newSize);
|
void ResizeNoCopy (uint32_t newSize);
|
||||||
void ResizeReplace (uint32_t newSize, void* data, uint32_t srcSize);
|
void ResizeReplace (uint32_t newSize, void* data, uint32_t srcSize);
|
||||||
|
void FlushAllocation (uint32_t srcOffset, uint32_t dstOffset) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
||||||
#include "Graphics/Pipeline/SHVkPipeline.h"
|
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Frees the command buffer.
|
Frees the command buffer.
|
||||||
|
|
||||||
|
@ -29,13 +30,13 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Only the command buffer is allocated using
|
Only the command buffer is allocated using
|
||||||
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit, is resetting
|
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit, is resetting
|
||||||
individually permitted. Otherwise, throw exception. IMPORTANT NOTE:
|
individually permitted. Otherwise, throw exception. IMPORTANT NOTE:
|
||||||
the command buffer cannot be in the pending state!!!
|
the command buffer cannot be in the pending state!!!
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::Reset(void)
|
void SHVkCommandBuffer::Reset(void)
|
||||||
|
@ -66,10 +67,10 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Begins the command buffer.
|
Begins the command buffer.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::BeginRecording(void) noexcept
|
void SHVkCommandBuffer::BeginRecording(void) noexcept
|
||||||
|
@ -107,10 +108,10 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
End the recording of a command buffer.
|
End the recording of a command buffer.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::EndRecording(void) noexcept
|
void SHVkCommandBuffer::EndRecording(void) noexcept
|
||||||
|
@ -120,21 +121,21 @@ namespace SHADE
|
||||||
SHLOG_ERROR("Command Buffer not in recording state, cannot end recording. ");
|
SHLOG_ERROR("Command Buffer not in recording state, cannot end recording. ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vkCommandBuffer.end();
|
vkCommandBuffer.end();
|
||||||
cmdBufferState = SH_CMD_BUFFER_STATE::EXECUTABLE;
|
cmdBufferState = SH_CMD_BUFFER_STATE::EXECUTABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Begins a renderpass in the command buffer. 2 important things to note
|
Begins a renderpass in the command buffer. 2 important things to note
|
||||||
here, the command buffer used MUST be a primary command buffer and
|
here, the command buffer used MUST be a primary command buffer and
|
||||||
command buffer MUST be in a recording state.
|
command buffer MUST be in a recording state.
|
||||||
|
|
||||||
\param renderpassHdl
|
\param renderpassHdl
|
||||||
Renderpass for obvious reasons.
|
Renderpass for obvious reasons.
|
||||||
|
|
||||||
\param framebufferHdl
|
\param framebufferHdl
|
||||||
Framebuffer required in the begin info.
|
Framebuffer required in the begin info.
|
||||||
|
@ -144,7 +145,7 @@ namespace SHADE
|
||||||
|
|
||||||
\param extent
|
\param extent
|
||||||
Extent of the render area in the framebuffer.
|
Extent of the render area in the framebuffer.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::BeginRenderpass(Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset, vk::Extent2D extent) noexcept
|
void SHVkCommandBuffer::BeginRenderpass(Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset, vk::Extent2D extent) noexcept
|
||||||
|
@ -169,7 +170,7 @@ namespace SHADE
|
||||||
vk::RenderPassBeginInfo renderPassInfo{};
|
vk::RenderPassBeginInfo renderPassInfo{};
|
||||||
renderPassInfo.renderPass = renderpassHdl->GetVkRenderpass();
|
renderPassInfo.renderPass = renderpassHdl->GetVkRenderpass();
|
||||||
renderPassInfo.framebuffer = framebufferHdl->GetVkFramebuffer();
|
renderPassInfo.framebuffer = framebufferHdl->GetVkFramebuffer();
|
||||||
|
|
||||||
// If the extent passed in is 0, use the framebuffer dimensions instead.
|
// If the extent passed in is 0, use the framebuffer dimensions instead.
|
||||||
if (extent.width == 0 && extent.height == 0)
|
if (extent.width == 0 && extent.height == 0)
|
||||||
renderPassInfo.renderArea.extent = framebufferExtent;
|
renderPassInfo.renderArea.extent = framebufferExtent;
|
||||||
|
@ -191,16 +192,16 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin the render pass
|
// Begin the render pass
|
||||||
vkCommandBuffer.beginRenderPass (&renderPassInfo, vk::SubpassContents::eInline);
|
vkCommandBuffer.beginRenderPass(&renderPassInfo, vk::SubpassContents::eInline);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Ends a renderpass.
|
Ends a renderpass.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::EndRenderpass(void) noexcept
|
void SHVkCommandBuffer::EndRenderpass(void) noexcept
|
||||||
|
@ -215,14 +216,14 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Sets the viewport dynamically for the command buffer. #NoteToSelf:
|
Sets the viewport dynamically for the command buffer. #NoteToSelf:
|
||||||
Dynamic state will not affect pipelines that don't use dynamic state
|
Dynamic state will not affect pipelines that don't use dynamic state
|
||||||
so there isn't a need to do any checks. Also, setting dynamic state like
|
so there isn't a need to do any checks. Also, setting dynamic state like
|
||||||
this only needs to happen ONCE per command buffer UNLESS a different
|
this only needs to happen ONCE per command buffer UNLESS a different
|
||||||
viewport is to be used for different drawing commands.
|
viewport is to be used for different drawing commands.
|
||||||
|
|
||||||
\param vpWidth
|
\param vpWidth
|
||||||
viewport width
|
viewport width
|
||||||
|
|
||||||
|
@ -253,7 +254,7 @@ namespace SHADE
|
||||||
\param vpMaxDepth
|
\param vpMaxDepth
|
||||||
viewport maximum depth value
|
viewport maximum depth value
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::SetViewportScissor(float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX /*= 0.0f*/, float vpY /*= 0.0f*/, int32_t sX /*= 0.0f*/, int32_t sY /*= 0.0f*/, float vpMinDepth /*= 0.0f*/, float vpMaxDepth /*= 1.0f*/) noexcept
|
void SHVkCommandBuffer::SetViewportScissor(float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX /*= 0.0f*/, float vpY /*= 0.0f*/, int32_t sX /*= 0.0f*/, int32_t sY /*= 0.0f*/, float vpMinDepth /*= 0.0f*/, float vpMaxDepth /*= 1.0f*/) noexcept
|
||||||
|
@ -282,13 +283,13 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Binds a pipeline object to the command buffer.
|
Binds a pipeline object to the command buffer.
|
||||||
|
|
||||||
\param pipelineHdl
|
\param pipelineHdl
|
||||||
The pipeline to bind.
|
The pipeline to bind.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::BindPipeline(Handle<SHVkPipeline> const& pipelineHdl) noexcept
|
void SHVkCommandBuffer::BindPipeline(Handle<SHVkPipeline> const& pipelineHdl) noexcept
|
||||||
|
@ -306,7 +307,7 @@ namespace SHADE
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Binds a buffer to the vertex buffer binding point specified in
|
Binds a buffer to the vertex buffer binding point specified in
|
||||||
bindingPoint.
|
bindingPoint.
|
||||||
|
|
||||||
\param bindingPoint
|
\param bindingPoint
|
||||||
|
@ -320,29 +321,32 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept
|
void SHVkCommandBuffer::BindVertexBuffer(uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept
|
||||||
{
|
{
|
||||||
if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING)
|
if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING)
|
||||||
{
|
{
|
||||||
auto bufferHandle = buffer->GetVkBuffer();
|
if (buffer)
|
||||||
vkCommandBuffer.bindVertexBuffers (bindingPoint, 1, &bufferHandle, &offset);
|
{
|
||||||
|
auto bufferHandle = buffer->GetVkBuffer();
|
||||||
|
vkCommandBuffer.bindVertexBuffers(bindingPoint, 1, &bufferHandle, &offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Binds an index buffer to the pipeline.
|
Binds an index buffer to the pipeline.
|
||||||
|
|
||||||
\param buffer
|
\param buffer
|
||||||
The buffer to bind.
|
The buffer to bind.
|
||||||
|
|
||||||
\param startingIndex
|
\param startingIndex
|
||||||
The starting index in the index buffer. For example, 0 would mean
|
The starting index in the index buffer. For example, 0 would mean
|
||||||
starting at the beginning. 5 would mean starting at byte offset
|
starting at the beginning. 5 would mean starting at byte offset
|
||||||
size(uint32_t) * 5.
|
size(uint32_t) * 5.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::BindIndexBuffer(Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept
|
void SHVkCommandBuffer::BindIndexBuffer(Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept
|
||||||
|
@ -350,33 +354,33 @@ namespace SHADE
|
||||||
if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING)
|
if (cmdBufferState == SH_CMD_BUFFER_STATE::RECORDING)
|
||||||
{
|
{
|
||||||
auto bufferHandle = buffer->GetVkBuffer();
|
auto bufferHandle = buffer->GetVkBuffer();
|
||||||
vkCommandBuffer.bindIndexBuffer (bufferHandle, sizeof (uint32_t) * startingIndex, vk::IndexType::eUint32);
|
vkCommandBuffer.bindIndexBuffer(bufferHandle, sizeof(uint32_t) * startingIndex, vk::IndexType::eUint32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets)
|
void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets)
|
||||||
{
|
{
|
||||||
vkCommandBuffer.bindDescriptorSets (bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets);
|
vkCommandBuffer.bindDescriptorSets(bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Calls vkCmdDraw.
|
Calls vkCmdDraw.
|
||||||
|
|
||||||
\param vertexCount
|
\param vertexCount
|
||||||
How many vertices to draw
|
How many vertices to draw
|
||||||
|
|
||||||
\param instanceCount
|
\param instanceCount
|
||||||
Number of instances to draw
|
Number of instances to draw
|
||||||
|
|
||||||
\param firstVertex
|
\param firstVertex
|
||||||
First vertex in the buffer of vertices to start from
|
First vertex in the buffer of vertices to start from
|
||||||
|
|
||||||
\param firstInstance
|
\param firstInstance
|
||||||
First instance to start from.
|
First instance to start from.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::DrawArrays(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept
|
void SHVkCommandBuffer::DrawArrays(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept
|
||||||
|
@ -386,30 +390,30 @@ namespace SHADE
|
||||||
SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. ");
|
SHLOG_ERROR("Command buffer must have started recording before a pipeline can be bound. ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vkCommandBuffer.draw (vertexCount, instanceCount, firstVertex, firstInstance);
|
vkCommandBuffer.draw(vertexCount, instanceCount, firstVertex, firstInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Issues a non-instanced indexed draw call.
|
Issues a non-instanced indexed draw call.
|
||||||
|
|
||||||
\param indexCount
|
\param indexCount
|
||||||
Number of indices to draw.
|
Number of indices to draw.
|
||||||
|
|
||||||
\param firstIndex
|
\param firstIndex
|
||||||
Starting index. if the array was 0, 2, 5, 4, and we indicated this to be
|
Starting index. if the array was 0, 2, 5, 4, and we indicated this to be
|
||||||
1. The draw call would start from index 2.
|
1. The draw call would start from index 2.
|
||||||
|
|
||||||
\param vertexOffset
|
\param vertexOffset
|
||||||
Starting vertex offset. This would indicate that vertex pulling should
|
Starting vertex offset. This would indicate that vertex pulling should
|
||||||
start from a certain vertex. So a vertex offset of 3 (for example) would
|
start from a certain vertex. So a vertex offset of 3 (for example) would
|
||||||
mean an index of 0 would mean the 3rd vertex.
|
mean an index of 0 would mean the 3rd vertex.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept
|
void SHVkCommandBuffer::DrawIndexed(uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept
|
||||||
{
|
{
|
||||||
if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING)
|
if (cmdBufferState != SH_CMD_BUFFER_STATE::RECORDING)
|
||||||
{
|
{
|
||||||
|
@ -422,41 +426,6 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHVkCommandBuffer::PipelineBarrier (
|
|
||||||
vk::PipelineStageFlags srcStage,
|
|
||||||
vk::PipelineStageFlags dstStage,
|
|
||||||
vk::DependencyFlags deps,
|
|
||||||
std::vector<vk::MemoryBarrier> const& memoryBarriers,
|
|
||||||
std::vector<vk::BufferMemoryBarrier> const& bufferMemoryBarriers,
|
|
||||||
std::vector<vk::ImageMemoryBarrier> const& imageMemoryBarriers
|
|
||||||
) const noexcept
|
|
||||||
{
|
|
||||||
vkCommandBuffer.pipelineBarrier (
|
|
||||||
srcStage,
|
|
||||||
dstStage,
|
|
||||||
deps,
|
|
||||||
memoryBarriers,
|
|
||||||
bufferMemoryBarriers,
|
|
||||||
imageMemoryBarriers
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHVkCommandBuffer::IsReadyToSubmit(void) const noexcept
|
|
||||||
{
|
|
||||||
return cmdBufferState == SH_CMD_BUFFER_STATE::EXECUTABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHVkCommandBuffer::HandlePostSubmit(void) noexcept
|
|
||||||
{
|
|
||||||
SetState(SH_CMD_BUFFER_STATE::PENDING);
|
|
||||||
}
|
|
||||||
|
|
||||||
//void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
|
|
||||||
//{
|
|
||||||
// //vkCommandBuffer.pipelineBarrier()
|
|
||||||
//}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -479,17 +448,64 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
|
if (indirectDrawData)
|
||||||
|
vkCommandBuffer.drawIndexedIndirect(indirectDrawData->GetVkBuffer(), 0, drawCount, sizeof(vk::DrawIndexedIndirectCommand));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::CopyBufferToImage(const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo)
|
||||||
|
{
|
||||||
|
vkCommandBuffer.copyBufferToImage
|
||||||
|
(
|
||||||
|
src, dst, vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
static_cast<uint32_t>(copyInfo.size()), copyInfo.data()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::PipelineBarrier(
|
||||||
|
vk::PipelineStageFlags srcStage,
|
||||||
|
vk::PipelineStageFlags dstStage,
|
||||||
|
vk::DependencyFlags deps,
|
||||||
|
std::vector<vk::MemoryBarrier> const& memoryBarriers,
|
||||||
|
std::vector<vk::BufferMemoryBarrier> const& bufferMemoryBarriers,
|
||||||
|
std::vector<vk::ImageMemoryBarrier> const& imageMemoryBarriers
|
||||||
|
) const noexcept
|
||||||
|
{
|
||||||
|
vkCommandBuffer.pipelineBarrier(
|
||||||
|
srcStage,
|
||||||
|
dstStage,
|
||||||
|
deps,
|
||||||
|
memoryBarriers,
|
||||||
|
bufferMemoryBarriers,
|
||||||
|
imageMemoryBarriers
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHVkCommandBuffer::IsReadyToSubmit(void) const noexcept
|
||||||
|
{
|
||||||
|
return cmdBufferState == SH_CMD_BUFFER_STATE::EXECUTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::HandlePostSubmit(void) noexcept
|
||||||
|
{
|
||||||
|
SetState(SH_CMD_BUFFER_STATE::PENDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
|
||||||
|
//{
|
||||||
|
// //vkCommandBuffer.pipelineBarrier()
|
||||||
|
//}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::ForceSetPipelineLayout(Handle<SHVkPipelineLayout> pipelineLayout) noexcept
|
||||||
|
{
|
||||||
|
boundPipelineLayoutHdl = pipelineLayout;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Calls vkCmdPushConstants and submits data stored in command buffer.
|
Calls vkCmdPushConstants and submits data stored in command buffer.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::SubmitPushConstants(void) const noexcept
|
void SHVkCommandBuffer::SubmitPushConstants(void) const noexcept
|
||||||
|
@ -502,13 +518,13 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Simply returns the command buffer handle.
|
Simply returns the command buffer handle.
|
||||||
|
|
||||||
\return
|
\return
|
||||||
The command buffer handle.
|
The command buffer handle.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
vk::CommandBuffer const& SHVkCommandBuffer::GetVkCommandBuffer(void) const noexcept
|
vk::CommandBuffer const& SHVkCommandBuffer::GetVkCommandBuffer(void) const noexcept
|
||||||
|
@ -518,11 +534,11 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
See https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetRenderAreaGranularity.html
|
See https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetRenderAreaGranularity.html
|
||||||
or look up vkGetRenderAreaGranularity.
|
or look up vkGetRenderAreaGranularity.
|
||||||
|
|
||||||
\param renderpassHdl
|
\param renderpassHdl
|
||||||
Renderpass to get info from.
|
Renderpass to get info from.
|
||||||
|
|
||||||
|
@ -532,9 +548,9 @@ namespace SHADE
|
||||||
\param renderArea
|
\param renderArea
|
||||||
For the comparison. Again, look it up on the webpage.
|
For the comparison. Again, look it up on the webpage.
|
||||||
|
|
||||||
\return
|
\return
|
||||||
If optimal, true. otherwise false.
|
If optimal, true. otherwise false.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
bool SHVkCommandBuffer::IsRenderAreaOptimal(Handle<SHVkRenderpass> const& renderpassHdl, vk::Extent2D const& framebufferExtent, vk::Rect2D const& renderArea) const noexcept
|
bool SHVkCommandBuffer::IsRenderAreaOptimal(Handle<SHVkRenderpass> const& renderpassHdl, vk::Extent2D const& framebufferExtent, vk::Rect2D const& renderArea) const noexcept
|
||||||
|
@ -546,14 +562,14 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Setter for the state of the command buffer.
|
Setter for the state of the command buffer.
|
||||||
|
|
||||||
\param state
|
\param state
|
||||||
|
|
||||||
\return
|
\return
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkCommandBuffer::SetState(SH_CMD_BUFFER_STATE state) noexcept
|
void SHVkCommandBuffer::SetState(SH_CMD_BUFFER_STATE state) noexcept
|
||||||
|
@ -563,12 +579,12 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Returns the state of the command buffer.
|
Returns the state of the command buffer.
|
||||||
|
|
||||||
\return
|
\return
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SH_CMD_BUFFER_STATE SHVkCommandBuffer::GetState(void) const noexcept
|
SH_CMD_BUFFER_STATE SHVkCommandBuffer::GetState(void) const noexcept
|
||||||
|
@ -578,14 +594,14 @@ namespace SHADE
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Creates a command buffer. Cmd buffer can be primary or secondary. If
|
Creates a command buffer. Cmd buffer can be primary or secondary. If
|
||||||
secondary, flags will automatically have renderpass continue bit. Command
|
secondary, flags will automatically have renderpass continue bit. Command
|
||||||
pool used to create this command buffer will determine whether or not
|
pool used to create this command buffer will determine whether or not
|
||||||
this buffer will be allocated with
|
this buffer will be allocated with
|
||||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT using the reset mode.
|
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT using the reset mode.
|
||||||
|
|
||||||
\param logicalDevice
|
\param logicalDevice
|
||||||
Need a logical device to create a buffer.
|
Need a logical device to create a buffer.
|
||||||
|
|
||||||
|
@ -594,7 +610,7 @@ namespace SHADE
|
||||||
|
|
||||||
\param type
|
\param type
|
||||||
Type of the command buffer; primary or secondary.
|
Type of the command buffer; primary or secondary.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkCommandBuffer::SHVkCommandBuffer(Handle<SHVkCommandPool> const& commandPool, SH_CMD_BUFFER_TYPE type) noexcept
|
SHVkCommandBuffer::SHVkCommandBuffer(Handle<SHVkCommandPool> const& commandPool, SH_CMD_BUFFER_TYPE type) noexcept
|
||||||
|
@ -604,7 +620,7 @@ namespace SHADE
|
||||||
, parentPoolResetMode{ SH_CMD_POOL_RESET::POOL_BASED }
|
, parentPoolResetMode{ SH_CMD_POOL_RESET::POOL_BASED }
|
||||||
, usageFlags{}
|
, usageFlags{}
|
||||||
, commandBufferCount{ 0 }
|
, commandBufferCount{ 0 }
|
||||||
, parentPool{commandPool}
|
, parentPool{ commandPool }
|
||||||
, pushConstantData{}
|
, pushConstantData{}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -645,54 +661,54 @@ namespace SHADE
|
||||||
commandBufferType = type;
|
commandBufferType = type;
|
||||||
commandBufferCount = allocateInfo.commandBufferCount;
|
commandBufferCount = allocateInfo.commandBufferCount;
|
||||||
|
|
||||||
if (parentPool->GetIsTransient ())
|
if (parentPool->GetIsTransient())
|
||||||
usageFlags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
|
usageFlags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
|
||||||
|
|
||||||
if (commandBufferType == SH_CMD_BUFFER_TYPE::SECONDARY)
|
if (commandBufferType == SH_CMD_BUFFER_TYPE::SECONDARY)
|
||||||
usageFlags |= vk::CommandBufferUsageFlagBits::eRenderPassContinue;
|
usageFlags |= vk::CommandBufferUsageFlagBits::eRenderPassContinue;
|
||||||
|
|
||||||
// Reset all the push constant data to 0
|
// Reset all the push constant data to 0
|
||||||
memset (pushConstantData, 0, PUSH_CONSTANT_SIZE);
|
memset(pushConstantData, 0, PUSH_CONSTANT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Move ctor. Invalidates Vulkan handles.
|
Move ctor. Invalidates Vulkan handles.
|
||||||
|
|
||||||
\param rhs
|
\param rhs
|
||||||
the other command buffer.
|
the other command buffer.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkCommandBuffer::SHVkCommandBuffer(SHVkCommandBuffer&& rhs) noexcept
|
SHVkCommandBuffer::SHVkCommandBuffer(SHVkCommandBuffer&& rhs) noexcept
|
||||||
: vkCommandBuffer {std::move (rhs.vkCommandBuffer)}
|
: vkCommandBuffer{ std::move(rhs.vkCommandBuffer) }
|
||||||
, cmdBufferState {rhs.cmdBufferState}
|
, cmdBufferState{ rhs.cmdBufferState }
|
||||||
, commandBufferType {rhs.commandBufferType}
|
, commandBufferType{ rhs.commandBufferType }
|
||||||
, parentPoolResetMode {rhs.parentPoolResetMode}
|
, parentPoolResetMode{ rhs.parentPoolResetMode }
|
||||||
, usageFlags {rhs.usageFlags}
|
, usageFlags{ rhs.usageFlags }
|
||||||
, commandBufferCount {rhs.commandBufferCount}
|
, commandBufferCount{ rhs.commandBufferCount }
|
||||||
, parentPool {rhs.parentPool}
|
, parentPool{ rhs.parentPool }
|
||||||
, boundPipelineLayoutHdl{rhs.boundPipelineLayoutHdl }
|
, boundPipelineLayoutHdl{ rhs.boundPipelineLayoutHdl }
|
||||||
{
|
{
|
||||||
memcpy (pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
|
memcpy(pushConstantData, rhs.pushConstantData, PUSH_CONSTANT_SIZE);
|
||||||
|
|
||||||
rhs.vkCommandBuffer = VK_NULL_HANDLE;
|
rhs.vkCommandBuffer = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Move assignment operator. Invalidates Vulkan handles.
|
Move assignment operator. Invalidates Vulkan handles.
|
||||||
|
|
||||||
\param rhs
|
\param rhs
|
||||||
The other Vulkan Handle.
|
The other Vulkan Handle.
|
||||||
|
|
||||||
\return
|
\return
|
||||||
a reference itself.
|
a reference itself.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkCommandBuffer& SHVkCommandBuffer::operator=(SHVkCommandBuffer&& rhs) noexcept
|
SHVkCommandBuffer& SHVkCommandBuffer::operator=(SHVkCommandBuffer&& rhs) noexcept
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace SHADE
|
||||||
class SHVkFramebuffer;
|
class SHVkFramebuffer;
|
||||||
class SHVkPipeline;
|
class SHVkPipeline;
|
||||||
class SHVkBuffer;
|
class SHVkBuffer;
|
||||||
|
class SHVkImage;
|
||||||
class SHVkDescriptorSetGroup;
|
class SHVkDescriptorSetGroup;
|
||||||
|
|
||||||
enum class SH_CMD_BUFFER_TYPE
|
enum class SH_CMD_BUFFER_TYPE
|
||||||
|
@ -116,6 +117,10 @@ namespace SHADE
|
||||||
// Draw Commands
|
// Draw Commands
|
||||||
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;
|
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;
|
||||||
void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept;
|
void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept;
|
||||||
|
void DrawMultiIndirect (Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount);
|
||||||
|
|
||||||
|
// Buffer Copy
|
||||||
|
void CopyBufferToImage (const vk::Buffer& src, const vk::Image& dst, const std::vector<vk::BufferImageCopy>& copyInfo);
|
||||||
|
|
||||||
// memory barriers
|
// memory barriers
|
||||||
void PipelineBarrier (
|
void PipelineBarrier (
|
||||||
|
@ -129,7 +134,6 @@ namespace SHADE
|
||||||
|
|
||||||
bool IsReadyToSubmit (void) const noexcept;
|
bool IsReadyToSubmit (void) const noexcept;
|
||||||
void HandlePostSubmit (void) noexcept;
|
void HandlePostSubmit (void) noexcept;
|
||||||
void DrawMultiIndirect (Handle<SHVkBuffer> indirectDrawData, uint32_t drawCount);
|
|
||||||
|
|
||||||
// Push Constant variable setting
|
// Push Constant variable setting
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -137,6 +141,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
memcpy (static_cast<uint8_t*>(pushConstantData) + boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T));
|
memcpy (static_cast<uint8_t*>(pushConstantData) + boundPipelineLayoutHdl->GetPushConstantInterface().GetOffset(variableName), &data, sizeof (T));
|
||||||
};
|
};
|
||||||
|
void ForceSetPipelineLayout (Handle<SHVkPipelineLayout> pipelineLayout) noexcept;
|
||||||
|
|
||||||
void SubmitPushConstants (void) const noexcept;
|
void SubmitPushConstants (void) const noexcept;
|
||||||
|
|
||||||
|
|
|
@ -20,23 +20,6 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
Links the write infos to the vulkan write descriptor sets.
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
void SHDescriptorSetUpdater::LinkInfoToWriteDescSet(void) noexcept
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < writeInfos.size(); ++i)
|
|
||||||
{
|
|
||||||
writeDescSets[i].pImageInfo = writeInfos[i].descImageInfos.data();
|
|
||||||
writeDescSets[i].pBufferInfo = writeInfos[i].descBufferInfos.data();
|
|
||||||
writeDescSets[i].pTexelBufferView = writeInfos[i].descTexelBufferInfos.data();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SHDescriptorWriteInfo& SHDescriptorWriteInfo::operator=(SHDescriptorWriteInfo&& rhs) noexcept
|
SHDescriptorWriteInfo& SHDescriptorWriteInfo::operator=(SHDescriptorWriteInfo&& rhs) noexcept
|
||||||
{
|
{
|
||||||
|
@ -65,11 +48,6 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<vk::WriteDescriptorSet> const& SHDescriptorSetUpdater::GetWriteDescriptorSets(void) const noexcept
|
|
||||||
{
|
|
||||||
return writeDescSets;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHDescriptorSetUpdater& SHDescriptorSetUpdater::operator=(SHDescriptorSetUpdater&& rhs) noexcept
|
SHDescriptorSetUpdater& SHDescriptorSetUpdater::operator=(SHDescriptorSetUpdater&& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (&rhs == this)
|
if (&rhs == this)
|
||||||
|
|
|
@ -41,10 +41,6 @@ namespace SHADE
|
||||||
//! When we want to update a write, we need to use this to identify the index of the write.
|
//! When we want to update a write, we need to use this to identify the index of the write.
|
||||||
std::unordered_map<BindingAndSetHash, uint32_t> writeHashMap;
|
std::unordered_map<BindingAndSetHash, uint32_t> writeHashMap;
|
||||||
|
|
||||||
//! We keep this here because we want this to be immediately passable to vkUpdateDescriptorSets
|
|
||||||
std::vector<vk::WriteDescriptorSet> writeDescSets;
|
|
||||||
|
|
||||||
void LinkInfoToWriteDescSet(void) noexcept;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHDescriptorSetUpdater (void) noexcept;
|
SHDescriptorSetUpdater (void) noexcept;
|
||||||
|
@ -52,8 +48,6 @@ namespace SHADE
|
||||||
SHDescriptorSetUpdater& operator= (SHDescriptorSetUpdater&& rhs) noexcept;
|
SHDescriptorSetUpdater& operator= (SHDescriptorSetUpdater&& rhs) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<vk::WriteDescriptorSet> const& GetWriteDescriptorSets (void) const noexcept;
|
|
||||||
|
|
||||||
friend class SHVkDescriptorSetGroup;
|
friend class SHVkDescriptorSetGroup;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,9 +50,8 @@ namespace SHADE
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Handle<SHVkDescriptorSetGroup>> SHVkDescriptorPool::Allocate(const std::vector<Handle<SHVkDescriptorSetLayout>>& layouts, std::vector<uint32_t> const& variableDescCounts)
|
Handle<SHVkDescriptorSetGroup> SHVkDescriptorPool::Allocate(const std::vector<Handle<SHVkDescriptorSetLayout>>& layouts, std::vector<uint32_t> const& variableDescCounts)
|
||||||
{
|
{
|
||||||
SHVkInstance::GetResourceManager().Create<SHVkDescriptorSetGroup>(device, GetHandle(), layouts, variableDescCounts);
|
return SHVkInstance::GetResourceManager().Create<SHVkDescriptorSetGroup>(device, GetHandle(), layouts, variableDescCounts);
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ namespace SHADE
|
||||||
std::vector<vk::DescriptorPoolSize> Limits =
|
std::vector<vk::DescriptorPoolSize> Limits =
|
||||||
{
|
{
|
||||||
{ vk::DescriptorType::eCombinedImageSampler, 100 },
|
{ vk::DescriptorType::eCombinedImageSampler, 100 },
|
||||||
{ vk::DescriptorType::eUniformBuffer, 100 }
|
{ vk::DescriptorType::eUniformBuffer, 100 },
|
||||||
|
{ vk::DescriptorType::eUniformBufferDynamic, 100 }
|
||||||
};
|
};
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum number of descriptor sets allowed
|
/// Maximum number of descriptor sets allowed
|
||||||
|
@ -101,7 +102,7 @@ namespace SHADE
|
||||||
/// Handles to the created Descriptor Sets. If this DescriptorPool has run out of
|
/// Handles to the created Descriptor Sets. If this DescriptorPool has run out of
|
||||||
/// space, lesser number of Handles will be returned.
|
/// space, lesser number of Handles will be returned.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
std::vector<Handle<SHVkDescriptorSetGroup>> Allocate(const std::vector<Handle<SHVkDescriptorSetLayout>>& layouts, std::vector<uint32_t> const& variableDescCounts);
|
Handle<SHVkDescriptorSetGroup> Allocate(const std::vector<Handle<SHVkDescriptorSetLayout>>& layouts, std::vector<uint32_t> const& variableDescCounts);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -7,6 +7,11 @@
|
||||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -39,6 +44,7 @@ namespace SHADE
|
||||||
: device{deviceHdl}
|
: device{deviceHdl}
|
||||||
, descPool {pool}
|
, descPool {pool}
|
||||||
, descSets{}
|
, descSets{}
|
||||||
|
, layoutsUsed {layouts}
|
||||||
{
|
{
|
||||||
// Create the layout for each concurrent frame
|
// Create the layout for each concurrent frame
|
||||||
std::vector<vk::DescriptorSetLayout> vkLayouts{ layouts.size() };
|
std::vector<vk::DescriptorSetLayout> vkLayouts{ layouts.size() };
|
||||||
|
@ -47,6 +53,7 @@ namespace SHADE
|
||||||
for (uint32_t i = 0; i < layouts.size(); ++i)
|
for (uint32_t i = 0; i < layouts.size(); ++i)
|
||||||
{
|
{
|
||||||
vkLayouts[i] = layouts[i]->GetVkHandle();
|
vkLayouts[i] = layouts[i]->GetVkHandle();
|
||||||
|
setIndexing.emplace(layouts[i]->GetSetIndex(), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for variable descriptor count
|
// Check for variable descriptor count
|
||||||
|
@ -73,34 +80,22 @@ namespace SHADE
|
||||||
// allocate descriptor sets
|
// allocate descriptor sets
|
||||||
descSets = device->GetVkLogicalDevice().allocateDescriptorSets(DESC_SET_LAYOUT_CREATE_INFO);
|
descSets = device->GetVkLogicalDevice().allocateDescriptorSets(DESC_SET_LAYOUT_CREATE_INFO);
|
||||||
|
|
||||||
|
// Now we want to prepare the write descriptor sets info for writing later.
|
||||||
|
|
||||||
// Now we want to prepare the write descriptor sets for writing later.
|
|
||||||
for (uint32_t i = 0; i < layouts.size(); ++i)
|
for (uint32_t i = 0; i < layouts.size(); ++i)
|
||||||
{
|
{
|
||||||
auto const& bindings = layouts[i]->GetBindings();
|
auto const& bindings = layouts[i]->GetBindings();
|
||||||
for (auto& binding : bindings)
|
for (auto& binding : bindings)
|
||||||
{
|
{
|
||||||
BindingAndSetHash writeHash = binding.BindPoint;
|
BindingAndSetHash writeHash = binding.BindPoint;
|
||||||
writeHash |= static_cast<uint64_t>(i) << 32;
|
writeHash |= static_cast<uint64_t>(layouts[i]->GetSetIndex()) << 32;
|
||||||
|
|
||||||
// new write for the binding
|
// new write for the binding
|
||||||
updater.writeInfos.emplace_back();
|
updater.writeInfos.emplace_back();
|
||||||
updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1);
|
updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1);
|
||||||
auto& writeInfo = updater.writeInfos.back();
|
auto& writeInfo = updater.writeInfos.back();
|
||||||
|
|
||||||
updater.writeDescSets.emplace_back();
|
|
||||||
auto& writeDescSet = updater.writeDescSets.back();
|
|
||||||
|
|
||||||
// Initialize info for write
|
|
||||||
writeDescSet.descriptorType = binding.Type;
|
|
||||||
writeDescSet.dstArrayElement = 0;
|
|
||||||
writeDescSet.dstSet = descSets[i];
|
|
||||||
writeDescSet.dstBinding = binding.BindPoint;
|
|
||||||
|
|
||||||
// Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in
|
// Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in
|
||||||
uint32_t descriptorCount = (binding.flags & vk::DescriptorBindingFlagBits::eVariableDescriptorCount) ? variableDescCounts[i] : 1;
|
uint32_t descriptorCount = (binding.flags & vk::DescriptorBindingFlagBits::eVariableDescriptorCount) ? variableDescCounts[i] : 1;
|
||||||
writeDescSet.descriptorCount = descriptorCount;
|
|
||||||
|
|
||||||
switch (binding.Type)
|
switch (binding.Type)
|
||||||
{
|
{
|
||||||
|
@ -114,8 +109,10 @@ namespace SHADE
|
||||||
case vk::DescriptorType::eUniformTexelBuffer:
|
case vk::DescriptorType::eUniformTexelBuffer:
|
||||||
case vk::DescriptorType::eStorageTexelBuffer:
|
case vk::DescriptorType::eStorageTexelBuffer:
|
||||||
case vk::DescriptorType::eUniformBuffer:
|
case vk::DescriptorType::eUniformBuffer:
|
||||||
|
case vk::DescriptorType::eUniformBufferDynamic:
|
||||||
case vk::DescriptorType::eStorageBuffer:
|
case vk::DescriptorType::eStorageBuffer:
|
||||||
writeInfo.descImageInfos.resize (descriptorCount);
|
case vk::DescriptorType::eStorageBufferDynamic:
|
||||||
|
writeInfo.descBufferInfos.resize (descriptorCount);
|
||||||
break;
|
break;
|
||||||
//case vk::DescriptorType::eUniformBufferDynamic:
|
//case vk::DescriptorType::eUniformBufferDynamic:
|
||||||
// break;
|
// break;
|
||||||
|
@ -130,8 +127,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Link all the writeDescSet data for vkUpdateDescriptorSets to write to the linked descriptors
|
|
||||||
updater.LinkInfoToWriteDescSet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -160,7 +155,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::vector<std::pair<vk::ImageView, vk::Sampler>> const& imageViewsAndSamplers) noexcept
|
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::pair<Handle<SHVkImageView>, Handle<SHVkSampler>>> const& imageViewsAndSamplers) noexcept
|
||||||
{
|
{
|
||||||
// Find the target writeDescSet
|
// Find the target writeDescSet
|
||||||
BindingAndSetHash writeHash = binding;
|
BindingAndSetHash writeHash = binding;
|
||||||
|
@ -176,32 +171,83 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
// write sampler and image view
|
// write sampler and image view
|
||||||
auto& ivs = imageViewsAndSamplers[i];
|
auto& ivs = imageViewsAndSamplers[i];
|
||||||
writeInfo.descImageInfos[i].imageView = ivs.first;
|
writeInfo.descImageInfos[i].imageView = ivs.first->GetImageView();
|
||||||
writeInfo.descImageInfos[i].sampler = ivs.second;
|
writeInfo.descImageInfos[i].sampler = ivs.second->GetVkSampler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
|
||||||
void SHVkDescriptorSetGroup::UpdateDescriptorSet(void) noexcept
|
|
||||||
{
|
{
|
||||||
device->UpdateDescriptorSets(updater.GetWriteDescriptorSets());
|
// Find the target writeDescSet
|
||||||
|
BindingAndSetHash writeHash = binding;
|
||||||
|
writeHash |= static_cast<uint64_t>(set) << 32;
|
||||||
|
auto& writeInfo = updater.writeInfos[updater.writeHashMap.at(writeHash)];
|
||||||
|
|
||||||
|
if (buffers.size() > writeInfo.descBufferInfos.size())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < buffers.size(); ++i)
|
||||||
|
{
|
||||||
|
// write sampler and image view
|
||||||
|
auto& buffer = buffers[i];
|
||||||
|
writeInfo.descBufferInfos[i].buffer = buffer->GetVkBuffer();
|
||||||
|
writeInfo.descBufferInfos[i].offset = offset;
|
||||||
|
writeInfo.descBufferInfos[i].range = range;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept
|
||||||
void SHVkDescriptorSetGroup::UpdateSingleDescriptorSetImages(uint32_t set, uint32_t binding) noexcept
|
|
||||||
{
|
{
|
||||||
vk::WriteDescriptorSet writeDescSet{};
|
vk::WriteDescriptorSet writeDescSet{};
|
||||||
|
|
||||||
|
// Get binding + set hash
|
||||||
|
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||||
|
|
||||||
|
// to index a set
|
||||||
|
uint32_t setIndex = setIndexing[bsHash];
|
||||||
|
|
||||||
|
// to index a write for a binding
|
||||||
|
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||||
|
|
||||||
// Initialize info for write
|
// Initialize info for write
|
||||||
writeDescSet.descriptorType = vk::DescriptorType::eCombinedImageSampler;
|
writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type;
|
||||||
writeDescSet.dstArrayElement = 0;
|
writeDescSet.dstArrayElement = 0;
|
||||||
writeDescSet.dstSet = descSets[set];
|
writeDescSet.dstSet = descSets[setIndex];
|
||||||
writeDescSet.dstBinding = binding;
|
writeDescSet.dstBinding = binding;
|
||||||
|
|
||||||
writeDescSet.pImageInfo = updater.writeInfos[set].descImageInfos.data();
|
writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data();
|
||||||
writeDescSet.descriptorCount = static_cast<uint32_t>(updater.writeInfos[set].descImageInfos.size());
|
writeDescSet.descriptorCount = static_cast<uint32_t>(updater.writeInfos[writeInfoIndex].descImageInfos.size());
|
||||||
|
|
||||||
device->UpdateDescriptorSet(writeDescSet);
|
device->UpdateDescriptorSet(writeDescSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept
|
||||||
|
{
|
||||||
|
vk::WriteDescriptorSet writeDescSet{};
|
||||||
|
|
||||||
|
// Get binding + set hash
|
||||||
|
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||||
|
|
||||||
|
// to index a set
|
||||||
|
uint32_t setIndex = setIndexing[bsHash];
|
||||||
|
|
||||||
|
// to index a write for a binding
|
||||||
|
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||||
|
|
||||||
|
// Initialize info for write
|
||||||
|
writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type;
|
||||||
|
writeDescSet.dstArrayElement = 0;
|
||||||
|
writeDescSet.dstSet = descSets[setIndex];
|
||||||
|
writeDescSet.dstBinding = binding;
|
||||||
|
|
||||||
|
writeDescSet.pBufferInfo = updater.writeInfos[writeInfoIndex].descBufferInfos.data();
|
||||||
|
writeDescSet.descriptorCount = static_cast<uint32_t>(updater.writeInfos[writeInfoIndex].descBufferInfos.size());
|
||||||
|
|
||||||
|
device->UpdateDescriptorSet(writeDescSet);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,6 +14,10 @@ namespace SHADE
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
class SHVkDescriptorSetLayout;
|
class SHVkDescriptorSetLayout;
|
||||||
|
class SHVkSampler;
|
||||||
|
class SHVkImage;
|
||||||
|
class SHVkImageView;
|
||||||
|
class SHVkBuffer;
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -54,12 +58,14 @@ namespace SHADE
|
||||||
SHVkDescriptorSetGroup& operator=(SHVkDescriptorSetGroup&& rhs) noexcept = default;
|
SHVkDescriptorSetGroup& operator=(SHVkDescriptorSetGroup&& rhs) noexcept = default;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Descriptor set writing */
|
/* Public member functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::vector<std::pair<vk::ImageView, vk::Sampler>> const& imageViewsAndSamplers) noexcept;
|
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
||||||
void UpdateDescriptorSet(void) 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 ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||||
|
|
||||||
void UpdateSingleDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
@ -81,9 +87,17 @@ namespace SHADE
|
||||||
//! Descriptor pool to allocate descriptor sets
|
//! Descriptor pool to allocate descriptor sets
|
||||||
Handle<SHVkDescriptorPool> descPool;
|
Handle<SHVkDescriptorPool> descPool;
|
||||||
|
|
||||||
|
//! Sometimes when we pass in a layout, the set of the layout used in the
|
||||||
|
//! shader cannot be used to index into descSets. This is to mitigate that issue
|
||||||
|
//! when we update descriptor sets.
|
||||||
|
std::unordered_map<SetIndex, uint32_t> setIndexing;
|
||||||
|
|
||||||
//! Descriptor sets
|
//! Descriptor sets
|
||||||
std::vector<vk::DescriptorSet> descSets;
|
std::vector<vk::DescriptorSet> descSets;
|
||||||
|
|
||||||
|
//! Layouts used to create this descriptor set group
|
||||||
|
std::vector<Handle<SHVkDescriptorSetLayout>> layoutsUsed;
|
||||||
|
|
||||||
//! for updating descriptor sets. We want to cache this so that we don't create the
|
//! for updating descriptor sets. We want to cache this so that we don't create the
|
||||||
//! write structs at runtime.
|
//! write structs at runtime.
|
||||||
SHDescriptorSetUpdater updater;
|
SHDescriptorSetUpdater updater;
|
||||||
|
|
|
@ -7,9 +7,10 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constructor/Destructor */
|
/* Constructor/Destructor */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, const std::vector<Binding>& bindings)
|
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex set, const std::vector<Binding>& bindings)
|
||||||
: device { device }
|
: device { device }
|
||||||
, layoutDesc { bindings }
|
, layoutDesc { bindings }
|
||||||
|
, setIndex {set}
|
||||||
{
|
{
|
||||||
// Check if auto-binding point calculation configuration is valid
|
// Check if auto-binding point calculation configuration is valid
|
||||||
bool autoCalc = false;
|
bool autoCalc = false;
|
||||||
|
@ -74,6 +75,7 @@ namespace SHADE
|
||||||
: device {rhs.device}
|
: device {rhs.device}
|
||||||
, setLayout {rhs.setLayout}
|
, setLayout {rhs.setLayout}
|
||||||
, layoutDesc{std::move (rhs.layoutDesc)}
|
, layoutDesc{std::move (rhs.layoutDesc)}
|
||||||
|
, setIndex {rhs.setIndex}
|
||||||
{
|
{
|
||||||
rhs.setLayout = VK_NULL_HANDLE;
|
rhs.setLayout = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
@ -90,6 +92,11 @@ namespace SHADE
|
||||||
return layoutDesc;
|
return layoutDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetIndex SHVkDescriptorSetLayout::GetSetIndex(void) const noexcept
|
||||||
|
{
|
||||||
|
return setIndex;
|
||||||
|
}
|
||||||
|
|
||||||
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (&rhs == this)
|
if (&rhs == this)
|
||||||
|
@ -98,6 +105,7 @@ namespace SHADE
|
||||||
device = rhs.device;
|
device = rhs.device;
|
||||||
setLayout = rhs.setLayout;
|
setLayout = rhs.setLayout;
|
||||||
layoutDesc = std::move(rhs.layoutDesc);
|
layoutDesc = std::move(rhs.layoutDesc);
|
||||||
|
setIndex = rhs.setIndex;
|
||||||
|
|
||||||
rhs.setLayout = VK_NULL_HANDLE;
|
rhs.setLayout = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,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, const std::vector<Binding>& bindings);
|
SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex setIndex, const std::vector<Binding>& bindings);
|
||||||
SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete;
|
SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete;
|
||||||
SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept;
|
SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -97,6 +97,7 @@ namespace SHADE
|
||||||
/// <returns>Handle to the Vulkan Descriptor Set Layout handle.</returns>
|
/// <returns>Handle to the Vulkan Descriptor Set Layout handle.</returns>
|
||||||
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
||||||
std::vector<Binding> const& GetBindings (void) const noexcept;
|
std::vector<Binding> const& GetBindings (void) const noexcept;
|
||||||
|
SetIndex GetSetIndex (void) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -105,5 +106,6 @@ namespace SHADE
|
||||||
Handle<SHVkLogicalDevice> device;
|
Handle<SHVkLogicalDevice> device;
|
||||||
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
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -467,7 +467,12 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
Handle<SHVkPipelineLayout> SHVkLogicalDevice::CreatePipelineLayout(SHPipelineLayoutParams& pipelineLayoutParams) noexcept
|
Handle<SHVkPipelineLayout> SHVkLogicalDevice::CreatePipelineLayout(SHPipelineLayoutParams const& pipelineLayoutParams) noexcept
|
||||||
|
{
|
||||||
|
return SHVkInstance::GetResourceManager().Create <SHVkPipelineLayout>(GetHandle(), pipelineLayoutParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHVkPipelineLayout> SHVkLogicalDevice::CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create <SHVkPipelineLayout>(GetHandle(), pipelineLayoutParams);
|
return SHVkInstance::GetResourceManager().Create <SHVkPipelineLayout>(GetHandle(), pipelineLayoutParams);
|
||||||
}
|
}
|
||||||
|
@ -488,9 +493,9 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
Handle<SHVkPipeline> SHVkLogicalDevice::CreatePipeline(Handle<SHVkPipelineLayout> const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHSubpass> subpass, SH_PIPELINE_TYPE type) noexcept
|
Handle<SHVkPipeline> SHVkLogicalDevice::CreateGraphicsPipeline(Handle<SHVkPipelineLayout> const& pipelineLayoutHdl, SHVkPipelineState const* const state, Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHSubpass> subpass) noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create <SHVkPipeline>(GetHandle(), pipelineLayoutHdl, state, renderpassHdl, subpass, type);
|
return SHVkInstance::GetResourceManager().Create <SHVkPipeline>(GetHandle(), pipelineLayoutHdl, state, renderpassHdl, subpass);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,9 +515,9 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept
|
Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), bindings);
|
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex, bindings);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||||
#include "Graphics/Images/SHVkImage.h"
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -171,23 +172,23 @@ namespace SHADE
|
||||||
std::string const& shaderName
|
std::string const& shaderName
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
Handle<SHVkPipeline> CreatePipeline (
|
Handle<SHVkPipeline> CreateGraphicsPipeline (
|
||||||
Handle<SHVkPipelineLayout> const& pipelineLayoutHdl,
|
Handle<SHVkPipelineLayout> const& pipelineLayoutHdl,
|
||||||
SHVkPipelineState const* const state,
|
SHVkPipelineState const* const state,
|
||||||
Handle<SHVkRenderpass> const& renderpassHdl,
|
Handle<SHVkRenderpass> const& renderpassHdl,
|
||||||
Handle<SHSubpass> subpass,
|
Handle<SHSubpass> subpass
|
||||||
SH_PIPELINE_TYPE type
|
|
||||||
) noexcept;
|
) 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 (std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept;
|
Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) 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,
|
||||||
std::vector<uint32_t> const& variableDescCounts) noexcept;
|
std::vector<uint32_t> const& variableDescCounts) noexcept;
|
||||||
Handle<SHVkPipelineLayout> CreatePipelineLayout (SHPipelineLayoutParams& pipelineLayoutParams) noexcept;
|
Handle<SHVkPipelineLayout> CreatePipelineLayout(SHPipelineLayoutParams const& pipelineLayoutParams) noexcept;
|
||||||
|
Handle<SHVkPipelineLayout> CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept;
|
||||||
Handle<SHVkFence> CreateFence (void) const noexcept;
|
Handle<SHVkFence> CreateFence (void) const noexcept;
|
||||||
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
|
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,7 @@ namespace SHADE
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
|
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVkImage::TransferToDeviceResource(void) noexcept
|
void SHVkImage::TransferToDeviceResource(Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept
|
||||||
{
|
{
|
||||||
// prepare copy regions
|
// prepare copy regions
|
||||||
std::vector<vk::BufferImageCopy> copyRegions{mipOffsets.size()};
|
std::vector<vk::BufferImageCopy> copyRegions{mipOffsets.size()};
|
||||||
|
@ -252,7 +252,7 @@ namespace SHADE
|
||||||
copyRegions[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 };
|
copyRegions[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
//PrepareImageTransition();
|
cmdBufferHdl->CopyBufferToImage(stagingBuffer, vkImage, copyRegions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -274,7 +274,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVkImage::PrepareImageTransition(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept
|
void SHVkImage::PrepareImageTransitionInfo(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept
|
||||||
{
|
{
|
||||||
barrier.oldLayout = oldLayout;
|
barrier.oldLayout = oldLayout;
|
||||||
barrier.newLayout = newLayout;
|
barrier.newLayout = newLayout;
|
||||||
|
@ -286,33 +286,6 @@ namespace SHADE
|
||||||
barrier.subresourceRange.levelCount = mipLevelCount;
|
barrier.subresourceRange.levelCount = mipLevelCount;
|
||||||
barrier.subresourceRange.baseArrayLayer = 0;
|
barrier.subresourceRange.baseArrayLayer = 0;
|
||||||
barrier.subresourceRange.layerCount = layerCount;
|
barrier.subresourceRange.layerCount = layerCount;
|
||||||
|
|
||||||
vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
|
||||||
vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
|
||||||
|
|
||||||
if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal)
|
|
||||||
{
|
|
||||||
srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
|
||||||
dstStage = vk::PipelineStageFlagBits::eTransfer;
|
|
||||||
|
|
||||||
barrier.srcAccessMask = vk::AccessFlagBits::eNone;
|
|
||||||
barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
|
|
||||||
}
|
|
||||||
else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal)
|
|
||||||
{
|
|
||||||
srcStage = vk::PipelineStageFlagBits::eTransfer;
|
|
||||||
|
|
||||||
// TODO, what if we want to access in compute shader
|
|
||||||
dstStage = vk::PipelineStageFlagBits::eFragmentShader;
|
|
||||||
|
|
||||||
barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
|
|
||||||
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Image layouts are invalid. ");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
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
|
||||||
|
|
|
@ -135,8 +135,8 @@ namespace SHADE
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
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 (void) noexcept;
|
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
|
||||||
void PrepareImageTransition (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
|
|
|
@ -4,4 +4,9 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
|
vk::Sampler SHVkSampler::GetVkSampler(void) const noexcept
|
||||||
|
{
|
||||||
|
return vkSampler;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,6 +22,7 @@ namespace SHADE
|
||||||
SHVkSampler (SHVkSampler&& rhs) noexcept;
|
SHVkSampler (SHVkSampler&& rhs) noexcept;
|
||||||
SHVkSampler&& operator=(SHVkSampler&& rhs) noexcept;
|
SHVkSampler&& operator=(SHVkSampler&& rhs) noexcept;
|
||||||
|
|
||||||
|
vk::Sampler GetVkSampler (void) const noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ 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 "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -33,6 +35,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (!pipeline)
|
if (!pipeline)
|
||||||
throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!");
|
throw std::invalid_argument("Attempted to create a SHBatch with an invalid SHPipeline!");
|
||||||
|
|
||||||
|
// Mark all as dirty
|
||||||
|
setAllDirtyFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatch::Add(const SHRenderable* renderable)
|
void SHBatch::Add(const SHRenderable* renderable)
|
||||||
|
@ -52,6 +57,12 @@ namespace SHADE
|
||||||
|
|
||||||
// Add renderable in
|
// Add renderable in
|
||||||
subBatch->Renderables.insert(renderable);
|
subBatch->Renderables.insert(renderable);
|
||||||
|
|
||||||
|
// Also add material instance in
|
||||||
|
referencedMatInstances.insert(renderable->GetMaterial());
|
||||||
|
|
||||||
|
// Mark all as dirty
|
||||||
|
setAllDirtyFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatch::Remove(const SHRenderable* renderable)
|
void SHBatch::Remove(const SHRenderable* renderable)
|
||||||
|
@ -59,14 +70,34 @@ namespace SHADE
|
||||||
// Check if we have a SubBatch with the same mesh yet
|
// Check if we have a SubBatch with the same mesh yet
|
||||||
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
|
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
|
||||||
{
|
{
|
||||||
return batch.Mesh == renderable->Mesh;
|
return batch.Mesh == renderable->Mesh;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Attempt to remove if it exists
|
// Attempt to remove if it exists
|
||||||
if (subBatch == subBatches.end())
|
if (subBatch == subBatches.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
subBatch->Renderables.erase(renderable);
|
subBatch->Renderables.erase(renderable);
|
||||||
|
|
||||||
|
// Check if other renderables in subBatches contain the same material instance
|
||||||
|
bool matUnused = true;
|
||||||
|
for (const auto& sb : subBatches)
|
||||||
|
for (const auto& rend : sb.Renderables)
|
||||||
|
{
|
||||||
|
if (rend->GetMaterial() == renderable->GetMaterial())
|
||||||
|
{
|
||||||
|
matUnused = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Material is no longer in this library, so we remove it
|
||||||
|
if (matUnused)
|
||||||
|
referencedMatInstances.erase(renderable->GetMaterial());
|
||||||
|
|
||||||
|
// Mark all as dirty
|
||||||
|
for (bool& dirt : isDirty)
|
||||||
|
dirt = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatch::Clear()
|
void SHBatch::Clear()
|
||||||
|
@ -81,15 +112,111 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
// Clear GPU buffers
|
// Clear GPU buffers
|
||||||
drawDataBuffer.Free();
|
for (int i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||||
transformDataBuffer.Free();
|
{
|
||||||
matPropsBuffer.Free();
|
drawDataBuffer[i].Free();
|
||||||
|
transformDataBuffer[i].Free();
|
||||||
|
matPropsBuffer[i].Free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatch::Build(Handle<SHVkLogicalDevice> device)
|
void SHBatch::UpdateMaterialBuffer(uint32_t frameIndex)
|
||||||
|
{
|
||||||
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHBatch] Attempted to update transform buffers with an invalid frame index.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there are even material properties to update
|
||||||
|
if (!matPropsData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if any materials have changed
|
||||||
|
bool hasChanged = false;
|
||||||
|
for (const auto& material : referencedMatInstances)
|
||||||
|
{
|
||||||
|
if (material->HasChanged())
|
||||||
|
{
|
||||||
|
hasChanged = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to update all the material buffers if the materials have changed
|
||||||
|
if (hasChanged)
|
||||||
|
{
|
||||||
|
for (auto& dirt : matBufferDirty)
|
||||||
|
dirt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this frame's buffer is dirty
|
||||||
|
if (!matBufferDirty[frameIndex])
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Build CPI Buffer
|
||||||
|
char* propsCurrPtr = matPropsData.get();
|
||||||
|
for (auto& subBatch : subBatches)
|
||||||
|
for (const SHRenderable* renderable : subBatch.Renderables)
|
||||||
|
{
|
||||||
|
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
||||||
|
propsCurrPtr += singleMatPropSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer to GPU
|
||||||
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
|
(
|
||||||
|
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
||||||
|
vk::BufferUsageFlagBits::eStorageBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
// This frame is updated
|
||||||
|
matBufferDirty[frameIndex] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBatch::UpdateTransformBuffer(uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHBatch] Attempted to update transform buffers with an invalid frame index.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset Transform Data
|
||||||
|
transformData.clear();
|
||||||
|
|
||||||
|
// Populate on the CPU
|
||||||
|
for (auto& subBatch : subBatches)
|
||||||
|
for (const SHRenderable* renderable : subBatch.Renderables)
|
||||||
|
{
|
||||||
|
// Transform
|
||||||
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(renderable->GetEID());
|
||||||
|
if (!transform)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!");
|
||||||
|
transformData.emplace_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transformData.emplace_back(transform->GetTRS());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transfer to GPU
|
||||||
|
if (transformDataBuffer[frameIndex])
|
||||||
|
transformDataBuffer[frameIndex]->WriteToMemory(transformData.data(), static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBatch::Build(Handle<SHVkLogicalDevice> _device, uint32_t frameIndex)
|
||||||
|
{
|
||||||
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHBatch] Attempted to update build batch buffers with an invalid frame index.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// No need to build as there are no changes
|
// No need to build as there are no changes
|
||||||
if (!isDirty)
|
if (!isDirty[frameIndex])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Count number of elements
|
// Count number of elements
|
||||||
|
@ -99,108 +226,133 @@ namespace SHADE
|
||||||
numTotalElements += subBatch.Renderables.size();
|
numTotalElements += subBatch.Renderables.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate CPU buffers
|
// Generate CPU buffers if there are changes
|
||||||
// - Draw data
|
if (isCPUBuffersDirty)
|
||||||
drawData.reserve(subBatches.size());
|
|
||||||
drawData.clear();
|
|
||||||
// - Transform data
|
|
||||||
transformData.reserve(numTotalElements);
|
|
||||||
transformData.clear();
|
|
||||||
// - Material Properties Data
|
|
||||||
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
|
|
||||||
(
|
|
||||||
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
|
||||||
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
|
||||||
vk::ShaderStageFlagBits::eFragment
|
|
||||||
);
|
|
||||||
const bool EMPTY_MAT_PROPS = !SHADER_INFO;
|
|
||||||
Byte singleMatPropSize = 0;
|
|
||||||
Byte matPropTotalBytes = 0;
|
|
||||||
if (!EMPTY_MAT_PROPS)
|
|
||||||
{
|
{
|
||||||
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
// - Draw data
|
||||||
matPropTotalBytes = drawData.size() * singleMatPropSize;
|
drawData.reserve(subBatches.size());
|
||||||
if (matPropsDataSize < matPropTotalBytes)
|
drawData.clear();
|
||||||
|
// - Transform data
|
||||||
|
transformData.reserve(numTotalElements);
|
||||||
|
transformData.clear();
|
||||||
|
// - Material Properties Data
|
||||||
|
const Handle<SHShaderBlockInterface> SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface
|
||||||
|
(
|
||||||
|
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||||
|
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||||
|
vk::ShaderStageFlagBits::eFragment
|
||||||
|
);
|
||||||
|
const bool EMPTY_MAT_PROPS = !SHADER_INFO;
|
||||||
|
Byte matPropTotalBytes = 0;
|
||||||
|
if (!EMPTY_MAT_PROPS)
|
||||||
{
|
{
|
||||||
matPropsData.reset(new char[matPropTotalBytes]);
|
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
||||||
matPropsDataSize = matPropTotalBytes;
|
matPropTotalBytes = drawData.size() * singleMatPropSize;
|
||||||
}
|
if (matPropsDataSize < matPropTotalBytes)
|
||||||
}
|
|
||||||
|
|
||||||
// Build Sub Batches
|
|
||||||
uint32_t nextInstanceIndex = 0;
|
|
||||||
char* propsCurrPtr = matPropsData.get();
|
|
||||||
for (auto& subBatch : subBatches)
|
|
||||||
{
|
|
||||||
// Create command
|
|
||||||
drawData.emplace_back(vk::DrawIndexedIndirectCommand
|
|
||||||
{
|
|
||||||
.indexCount = subBatch.Mesh->IndexCount,
|
|
||||||
.instanceCount = static_cast<uint32_t>(subBatch.Renderables.size()),
|
|
||||||
.firstIndex = subBatch.Mesh->FirstIndex,
|
|
||||||
.vertexOffset = subBatch.Mesh->FirstVertex,
|
|
||||||
.firstInstance = nextInstanceIndex
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fill in buffers (CPU)
|
|
||||||
for (const SHRenderable* renderable : subBatch.Renderables)
|
|
||||||
{
|
|
||||||
// Transform
|
|
||||||
transformData.emplace_back(renderable->TransformMatrix);
|
|
||||||
// Material Properties
|
|
||||||
if (!EMPTY_MAT_PROPS)
|
|
||||||
{
|
{
|
||||||
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
matPropsData.reset(new char[matPropTotalBytes]);
|
||||||
propsCurrPtr += singleMatPropSize;
|
matPropsDataSize = matPropTotalBytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build Sub Batches
|
||||||
|
uint32_t nextInstanceIndex = 0;
|
||||||
|
char* propsCurrPtr = matPropsData.get();
|
||||||
|
for (auto& subBatch : subBatches)
|
||||||
|
{
|
||||||
|
// Create command
|
||||||
|
drawData.emplace_back(vk::DrawIndexedIndirectCommand
|
||||||
|
{
|
||||||
|
.indexCount = subBatch.Mesh->IndexCount,
|
||||||
|
.instanceCount = static_cast<uint32_t>(subBatch.Renderables.size()),
|
||||||
|
.firstIndex = subBatch.Mesh->FirstIndex,
|
||||||
|
.vertexOffset = subBatch.Mesh->FirstVertex,
|
||||||
|
.firstInstance = nextInstanceIndex
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fill in buffers (CPU)
|
||||||
|
for (const SHRenderable* renderable : subBatch.Renderables)
|
||||||
|
{
|
||||||
|
// Transform
|
||||||
|
auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(renderable->GetEID());
|
||||||
|
if (!transform)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!");
|
||||||
|
transformData.emplace_back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transformData.emplace_back(transform->GetTRS());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Material Properties
|
||||||
|
if (!EMPTY_MAT_PROPS)
|
||||||
|
{
|
||||||
|
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
|
||||||
|
propsCurrPtr += singleMatPropSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Successfully update CPU buffers
|
||||||
|
isCPUBuffersDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send all buffered data to the GPU buffers
|
// Send all buffered data to the GPU buffers
|
||||||
using BuffUsage = vk::BufferUsageFlagBits;
|
using BuffUsage = vk::BufferUsageFlagBits;
|
||||||
// - Draw Data
|
// - Draw Data
|
||||||
if (drawDataBuffer)
|
|
||||||
drawDataBuffer->Unmap();
|
|
||||||
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, drawData.data(), DRAW_DATA_BYTES,
|
_device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
|
||||||
BuffUsage::eIndirectBuffer
|
BuffUsage::eIndirectBuffer
|
||||||
);
|
);
|
||||||
drawDataBuffer->Map();
|
|
||||||
// - Transform Buffer
|
// - Transform Buffer
|
||||||
if (transformDataBuffer)
|
|
||||||
transformDataBuffer->Unmap();
|
|
||||||
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, transformData.data(), TF_DATA_BYTES,
|
_device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
|
||||||
BuffUsage::eVertexBuffer
|
BuffUsage::eVertexBuffer
|
||||||
);
|
);
|
||||||
transformDataBuffer->Map();
|
|
||||||
// - Material Properties Buffer
|
// - Material Properties Buffer
|
||||||
if (!EMPTY_MAT_PROPS)
|
if (matPropsData)
|
||||||
{
|
{
|
||||||
if (matPropsBuffer)
|
|
||||||
matPropsBuffer->Unmap();
|
|
||||||
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
SHVkUtil::EnsureBufferAndCopyHostVisibleData
|
||||||
(
|
(
|
||||||
device, matPropsBuffer, matPropsData.get(), static_cast<uint32_t>(matPropTotalBytes),
|
_device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
|
||||||
BuffUsage::eStorageBuffer
|
BuffUsage::eStorageBuffer
|
||||||
);
|
);
|
||||||
matPropsBuffer->Map();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isDirty = false;
|
isDirty[frameIndex] = false;
|
||||||
|
|
||||||
|
// Save logical device
|
||||||
|
this->device = _device;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* SHBatch - Usage Functions */
|
/* SHBatch - Usage Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer)
|
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHBatch] Attempted to draw a batch with an invalid frame index.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cmdBuffer->BindPipeline(pipeline);
|
cmdBuffer->BindPipeline(pipeline);
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer, 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||||
cmdBuffer->DrawMultiIndirect(drawDataBuffer, static_cast<uint32_t>(drawData.size()));
|
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* SHBatch - Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHBatch::setAllDirtyFlags()
|
||||||
|
{
|
||||||
|
for (bool& dirt : isDirty)
|
||||||
|
dirt = true;
|
||||||
|
isCPUBuffersDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,14 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
// STL Includes
|
// STL Includes
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <array>
|
||||||
// External Dependencies
|
// External Dependencies
|
||||||
#include "Graphics/SHVulkanIncludes.h"
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Resource/Handle.h"
|
#include "Resource/Handle.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||||
#include "Math/SHMatrix.h"
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -32,6 +34,7 @@ namespace SHADE
|
||||||
class SHMesh;
|
class SHMesh;
|
||||||
class SHRenderable;
|
class SHRenderable;
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
|
class SHMaterialInstance;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
@ -71,8 +74,10 @@ namespace SHADE
|
||||||
void Add(const SHRenderable* renderable);
|
void Add(const SHRenderable* renderable);
|
||||||
void Remove(const SHRenderable* renderable);
|
void Remove(const SHRenderable* renderable);
|
||||||
void Clear();
|
void Clear();
|
||||||
void Build(Handle<SHVkLogicalDevice> device);
|
void UpdateMaterialBuffer(uint32_t frameIndex);
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer);
|
void UpdateTransformBuffer(uint32_t frameIndex);
|
||||||
|
void Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex);
|
||||||
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
@ -83,19 +88,30 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
// Resources
|
||||||
|
Handle<SHVkLogicalDevice> device;
|
||||||
// Batch Properties
|
// Batch Properties
|
||||||
Handle<SHVkPipeline> pipeline;
|
Handle<SHVkPipeline> pipeline;
|
||||||
|
std::unordered_set<Handle<SHMaterialInstance>> referencedMatInstances;
|
||||||
|
std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS> matBufferDirty;
|
||||||
// Batch Tree
|
// Batch Tree
|
||||||
std::vector<SHSubBatch> subBatches;
|
std::vector<SHSubBatch> subBatches;
|
||||||
bool isDirty = true;
|
std::array<bool, SHGraphicsConstants::NUM_FRAME_BUFFERS> isDirty;
|
||||||
// CPU Buffers
|
// CPU Buffers
|
||||||
std::vector<vk::DrawIndexedIndirectCommand> drawData;
|
std::vector<vk::DrawIndexedIndirectCommand> drawData;
|
||||||
std::vector<SHMatrix> transformData;
|
std::vector<SHMatrix> transformData;
|
||||||
std::unique_ptr<char> matPropsData;
|
std::unique_ptr<char> matPropsData;
|
||||||
Byte matPropsDataSize = 0;
|
Byte matPropsDataSize = 0;
|
||||||
|
Byte singleMatPropSize = 0;
|
||||||
|
bool isCPUBuffersDirty = true;
|
||||||
// GPU Buffers
|
// GPU Buffers
|
||||||
Handle<SHVkBuffer> drawDataBuffer;
|
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> drawDataBuffer;
|
||||||
Handle<SHVkBuffer> transformDataBuffer;
|
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> transformDataBuffer;
|
||||||
Handle<SHVkBuffer> matPropsBuffer;
|
std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS> matPropsBuffer;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
void setAllDirtyFlags();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,12 +91,12 @@ namespace SHADE
|
||||||
(*superBatch)->Remove(renderable);
|
(*superBatch)->Remove(renderable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHBatcher::FinaliseBatches(Handle<SHVkLogicalDevice> device)
|
void SHBatcher::FinaliseBatches(Handle<SHVkLogicalDevice> device, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
// Build SuperBatches
|
// Build SuperBatches
|
||||||
for (auto& batch : superBatches)
|
for (auto& batch : superBatches)
|
||||||
{
|
{
|
||||||
batch->Build(device);
|
batch->Build(device, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +109,14 @@ namespace SHADE
|
||||||
superBatches.clear();
|
superBatches.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHBatcher::UpdateBuffers(uint32_t frameIndex)
|
||||||
|
{
|
||||||
|
for (auto& batch : superBatches)
|
||||||
|
{
|
||||||
|
batch->UpdateBuffers(frameIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHBatcher::RegisterSuperBatch(Handle<SHSuperBatch> superBatch)
|
void SHBatcher::RegisterSuperBatch(Handle<SHSuperBatch> superBatch)
|
||||||
{
|
{
|
||||||
superBatches.emplace_back(superBatch);
|
superBatches.emplace_back(superBatch);
|
||||||
|
|
|
@ -51,8 +51,9 @@ namespace SHADE
|
||||||
void PrepareBatches();
|
void PrepareBatches();
|
||||||
void AddToBatch(SHRenderable const* renderable);
|
void AddToBatch(SHRenderable const* renderable);
|
||||||
void RemoveFromBatch(SHRenderable const* renderable);
|
void RemoveFromBatch(SHRenderable const* renderable);
|
||||||
void FinaliseBatches(Handle<SHVkLogicalDevice> device);
|
void FinaliseBatches(Handle<SHVkLogicalDevice> device, uint32_t frameIndex);
|
||||||
void ClearBatches();
|
void ClearBatches();
|
||||||
|
void UpdateBuffers(uint32_t frameIndex);
|
||||||
void RegisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
void RegisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
||||||
void DeregisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
void DeregisterSuperBatch(Handle<SHSuperBatch> superBatch);
|
||||||
|
|
||||||
|
|
|
@ -78,21 +78,30 @@ namespace SHADE
|
||||||
batches.clear();
|
batches.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::Build(Handle<SHVkLogicalDevice> device) noexcept
|
void SHSuperBatch::UpdateBuffers(uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
// Build all batches
|
|
||||||
for (auto& batch : batches)
|
for (auto& batch : batches)
|
||||||
{
|
{
|
||||||
batch.Build(device);
|
batch.UpdateMaterialBuffer(frameIndex);
|
||||||
|
batch.UpdateTransformBuffer(frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer) noexcept
|
void SHSuperBatch::Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
// Build all batches
|
// Build all batches
|
||||||
for (auto& batch : batches)
|
for (auto& batch : batches)
|
||||||
{
|
{
|
||||||
batch.Draw(cmdBuffer);
|
batch.Build(device, frameIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
// Build all batches
|
||||||
|
for (auto& batch : batches)
|
||||||
|
{
|
||||||
|
batch.Draw(cmdBuffer, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,10 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void Add(const SHRenderable* renderable) noexcept;
|
void Add(const SHRenderable* renderable) noexcept;
|
||||||
void Remove(const SHRenderable* renderable) noexcept;
|
void Remove(const SHRenderable* renderable) noexcept;
|
||||||
void Clear() noexcept;
|
void Clear() noexcept;
|
||||||
void Build(Handle<SHVkLogicalDevice> device) noexcept;
|
void UpdateBuffers(uint32_t frameIndex);
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
|
void Build(Handle<SHVkLogicalDevice> device, uint32_t frameIndex) noexcept;
|
||||||
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "SHGraphicsGlobalData.h"
|
#include "SHGraphicsGlobalData.h"
|
||||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
#include "Graphics/Pipeline/SHPipelineState.h"
|
#include "Graphics/Pipeline/SHPipelineState.h"
|
||||||
|
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -27,7 +28,7 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// For global data (generic data and textures)
|
// For global data (generic data and textures)
|
||||||
Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ genericDataBinding, texturesBinding });
|
Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,{ genericDataBinding, texturesBinding });
|
||||||
|
|
||||||
SHVkDescriptorSetLayout::Binding lightBinding
|
SHVkDescriptorSetLayout::Binding lightBinding
|
||||||
{
|
{
|
||||||
|
@ -38,7 +39,7 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// For Dynamic global data (lights)
|
// For Dynamic global data (lights)
|
||||||
Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ lightBinding });
|
Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, { lightBinding });
|
||||||
|
|
||||||
SHVkDescriptorSetLayout::Binding cameraDataBinding
|
SHVkDescriptorSetLayout::Binding cameraDataBinding
|
||||||
{
|
{
|
||||||
|
@ -49,7 +50,7 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// For High frequency global data (camera)
|
// For High frequency global data (camera)
|
||||||
Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ cameraDataBinding });
|
Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding });
|
||||||
|
|
||||||
SHVkDescriptorSetLayout::Binding materialDataBinding
|
SHVkDescriptorSetLayout::Binding materialDataBinding
|
||||||
{
|
{
|
||||||
|
@ -60,12 +61,15 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// For High frequency global data (camera)
|
// For High frequency global data (camera)
|
||||||
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding });
|
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding });
|
||||||
|
|
||||||
globalDescSetLayouts.push_back(staticGlobalLayout);
|
globalDescSetLayouts.push_back(staticGlobalLayout);
|
||||||
globalDescSetLayouts.push_back(dynamicGlobalLayout);
|
globalDescSetLayouts.push_back(dynamicGlobalLayout);
|
||||||
globalDescSetLayouts.push_back(cameraDataGlobalLayout);
|
globalDescSetLayouts.push_back(cameraDataGlobalLayout);
|
||||||
globalDescSetLayouts.push_back(materialDataPerInstanceLayout);
|
globalDescSetLayouts.push_back(materialDataPerInstanceLayout);
|
||||||
|
|
||||||
|
|
||||||
|
dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{globalDescSetLayouts});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsGlobalData::InitDefaultVertexInputState(void) noexcept
|
void SHGraphicsGlobalData::InitDefaultVertexInputState(void) noexcept
|
||||||
|
@ -94,4 +98,9 @@ namespace SHADE
|
||||||
return defaultVertexInputState;
|
return defaultVertexInputState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::GetDummyPipelineLayout(void) const noexcept
|
||||||
|
{
|
||||||
|
return dummyPipelineLayout;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace SHADE
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHVkDescriptorSetLayout;
|
class SHVkDescriptorSetLayout;
|
||||||
class SHVkDescriptorSetGroup;
|
class SHVkDescriptorSetGroup;
|
||||||
|
class SHVkPipelineLayout;
|
||||||
|
|
||||||
class SH_API SHGraphicsGlobalData
|
class SH_API SHGraphicsGlobalData
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,10 @@ namespace SHADE
|
||||||
//! Default vertex input state (used by everything).
|
//! Default vertex input state (used by everything).
|
||||||
SHVertexInputState defaultVertexInputState;
|
SHVertexInputState defaultVertexInputState;
|
||||||
|
|
||||||
|
//! Since we want to bind global data but can't do so without a pipeline layout,
|
||||||
|
//! we create a dummy pipeline layout to use it for binding.
|
||||||
|
Handle<SHVkPipelineLayout> dummyPipelineLayout;
|
||||||
|
|
||||||
void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
void InitDefaultVertexInputState(void) noexcept;
|
void InitDefaultVertexInputState(void) noexcept;
|
||||||
public:
|
public:
|
||||||
|
@ -35,5 +40,6 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> const& GetDescSetLayouts (void) const noexcept;
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& GetDescSetLayouts (void) const noexcept;
|
||||||
SHVertexInputState const& GetDefaultViState (void) const noexcept;
|
SHVertexInputState const& GetDefaultViState (void) const noexcept;
|
||||||
|
Handle<SHVkPipelineLayout> GetDummyPipelineLayout (void) const noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,24 +22,24 @@ namespace SHADE
|
||||||
void SHCamera::SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up)
|
void SHCamera::SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up)
|
||||||
{
|
{
|
||||||
SHVec3 view = target - pos; view = SHVec3::Normalise(view);
|
SHVec3 view = target - pos; view = SHVec3::Normalise(view);
|
||||||
SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right);
|
SHVec3 right = SHVec3::Cross(view, up); right = SHVec3::Normalise(right);
|
||||||
const SHVec3 UP = SHVec3::Cross(right, view);
|
const SHVec3 UP = SHVec3::Cross(right, view);
|
||||||
|
|
||||||
viewMatrix = SHMatrix::Identity;
|
viewMatrix = SHMatrix::Identity;
|
||||||
viewMatrix(0, 0) = right[0];
|
viewMatrix(0, 0) = UP[0];
|
||||||
viewMatrix(1, 0) = right[1];
|
viewMatrix(1, 0) = UP[1];
|
||||||
viewMatrix(2, 0) = right[2];
|
viewMatrix(2, 0) = UP[2];
|
||||||
viewMatrix(0, 1) = UP[0];
|
viewMatrix(0, 1) = right[0];
|
||||||
viewMatrix(1, 1) = UP[1];
|
viewMatrix(1, 1) = right[1];
|
||||||
viewMatrix(2, 1) = UP[2];
|
viewMatrix(2, 1) = right[2];
|
||||||
viewMatrix(0, 2) = -view[0];
|
viewMatrix(0, 2) = view[0];
|
||||||
viewMatrix(1, 2) = -view[1];
|
viewMatrix(1, 2) = view[1];
|
||||||
viewMatrix(2, 2) = -view[2];
|
viewMatrix(2, 2) = view[2];
|
||||||
viewMatrix(3, 0) = -right.Dot(pos);
|
viewMatrix(3, 0) = -UP.Dot(pos);
|
||||||
viewMatrix(3, 1) = -UP.Dot(pos);
|
viewMatrix(3, 1) = -right.Dot(pos);
|
||||||
viewMatrix(3, 2) = view.Dot(pos);
|
viewMatrix(3, 2) = -view.Dot(pos);
|
||||||
|
|
||||||
isDirty = true;
|
isDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -29,6 +29,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
|
#include "Graphics/MiddleEnd/Batching/SHSuperBatch.h"
|
||||||
#include "SHGraphicsConstants.h"
|
#include "SHGraphicsConstants.h"
|
||||||
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
||||||
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -113,7 +114,8 @@ namespace SHADE
|
||||||
screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||||
screenCamera->SetOrthographic(static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.01f, 100.0f);
|
screenCamera->SetOrthographic(static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.01f, 100.0f);
|
||||||
worldCamera = resourceManager.Create<SHCamera>();
|
worldCamera = resourceManager.Create<SHCamera>();
|
||||||
worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
//worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||||
|
worldCamera->SetLookAt(SHVec3(0.0f, 5.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||||
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
||||||
|
|
||||||
// Create Default Viewport
|
// Create Default Viewport
|
||||||
|
@ -129,15 +131,17 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize world render graph
|
// Initialize world render graph
|
||||||
worldRenderGraph->Init(device, swapchain, renderContextCmdPools, globalData);
|
worldRenderGraph->Init(device, swapchain, globalData);
|
||||||
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
|
worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm);
|
||||||
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
||||||
auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", "Normals",*/ "Present" }, {}); // no predecessors
|
auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", */"Present" }, {}); // no predecessors
|
||||||
|
|
||||||
//First subpass to write to G-Buffer
|
//First subpass to write to G-Buffer
|
||||||
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
||||||
|
//gBufferWriteSubpass->AddColorOutput("Scene");
|
||||||
gBufferWriteSubpass->AddColorOutput("Present");
|
gBufferWriteSubpass->AddColorOutput("Present");
|
||||||
//writeSubpass->AddColorOutput("Normals");
|
//writeSubpass->AddColorOutput("Normals");
|
||||||
|
|
||||||
|
@ -148,9 +152,9 @@ namespace SHADE
|
||||||
//compositeSubpass->AddInput("Position");
|
//compositeSubpass->AddInput("Position");
|
||||||
|
|
||||||
// TODO: Use macro to add this node when SH_EDITOR is enabled
|
// TODO: Use macro to add this node when SH_EDITOR is enabled
|
||||||
//auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {});
|
auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"});
|
||||||
//auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
|
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
|
||||||
//imguiSubpass->AddColorOutput("Present");
|
imguiSubpass->AddColorOutput("Present");
|
||||||
|
|
||||||
worldRenderGraph->Generate();
|
worldRenderGraph->Generate();
|
||||||
|
|
||||||
|
@ -167,7 +171,7 @@ namespace SHADE
|
||||||
debugWorldRenderer->SetCamera(worldCamera);*/
|
debugWorldRenderer->SetCamera(worldCamera);*/
|
||||||
|
|
||||||
// Add world renderer to default viewport
|
// Add world renderer to default viewport
|
||||||
worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), descPool, globalData->GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, globalData->GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
||||||
worldRenderer->SetCamera(worldCamera);
|
worldRenderer->SetCamera(worldCamera);
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,6 +207,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
// Frame data for the current frame
|
// Frame data for the current frame
|
||||||
auto const& frameData = renderContext.GetCurrentFrameData();
|
auto const& frameData = renderContext.GetCurrentFrameData();
|
||||||
|
uint32_t frameIndex = renderContext.GetCurrentFrame();
|
||||||
|
|
||||||
// semaphore index. This is for render graphs to have semaphores to signal that the next render graph will use to wait on.
|
// semaphore index. This is for render graphs to have semaphores to signal that the next render graph will use to wait on.
|
||||||
bool semIndex = 0;
|
bool semIndex = 0;
|
||||||
|
@ -219,7 +224,6 @@ namespace SHADE
|
||||||
|
|
||||||
renderContext.ResetFence();
|
renderContext.ResetFence();
|
||||||
|
|
||||||
|
|
||||||
// For every viewport
|
// For every viewport
|
||||||
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
|
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
|
||||||
{
|
{
|
||||||
|
@ -228,16 +232,42 @@ namespace SHADE
|
||||||
// For every renderer
|
// For every renderer
|
||||||
for (int renIndex = 0; renIndex < static_cast<int>(renderers.size()); ++renIndex)
|
for (int renIndex = 0; renIndex < static_cast<int>(renderers.size()); ++renIndex)
|
||||||
{
|
{
|
||||||
// Draw first
|
/*-----------------------------------------------------------------------*/
|
||||||
renderers[renIndex]->Draw(renderContext.GetCurrentFrame(), MESH_DATA);
|
/* Renderer start */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
// get command buffer of the renderer in the current frame
|
||||||
|
auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(frameIndex);
|
||||||
|
|
||||||
// get render graph
|
// Begin recording the command buffer
|
||||||
auto rg = renderers[renIndex]->GetRenderGraph();
|
currentCmdBuffer->BeginRecording();
|
||||||
|
|
||||||
|
currentCmdBuffer->ForceSetPipelineLayout(globalData->GetDummyPipelineLayout());
|
||||||
|
|
||||||
|
// Bind all the buffers required for meshes
|
||||||
|
for (auto& [buffer, bindingPoint] : MESH_DATA)
|
||||||
|
{
|
||||||
|
if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer)
|
||||||
|
currentCmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0);
|
||||||
|
else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer)
|
||||||
|
currentCmdBuffer->BindIndexBuffer(buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind camera data
|
||||||
|
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
||||||
|
|
||||||
|
// Draw first
|
||||||
|
renderers[renIndex]->Draw(frameIndex);
|
||||||
|
|
||||||
|
// End the command buffer recording
|
||||||
|
currentCmdBuffer->EndRecording();
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Renderer end */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
// submit a command buffer from the current render graph and make it wait for the previous render graph before submitting it to GPU.
|
// submit a command buffer from the current render graph and make it wait for the previous render graph before submitting it to GPU.
|
||||||
graphicsQueue->SubmitCommandBuffer
|
graphicsQueue->SubmitCommandBuffer
|
||||||
(
|
(
|
||||||
{ rg->GetCommandBuffer(renderContext.GetCurrentFrame()) },
|
{ currentCmdBuffer },
|
||||||
{ (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.semRenderFinishHdl : graphSemaphores[!semIndex] },
|
{ (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.semRenderFinishHdl : graphSemaphores[!semIndex] },
|
||||||
{ (vpIndex == 0 && renIndex == 0) ? frameData.semImgAvailableHdl : graphSemaphores[semIndex] },
|
{ (vpIndex == 0 && renIndex == 0) ? frameData.semImgAvailableHdl : graphSemaphores[semIndex] },
|
||||||
{ vk::PipelineStageFlagBits::eColorAttachmentOutput },
|
{ vk::PipelineStageFlagBits::eColorAttachmentOutput },
|
||||||
|
@ -279,7 +309,7 @@ namespace SHADE
|
||||||
for (auto vp : viewports)
|
for (auto vp : viewports)
|
||||||
for (auto renderer : vp->GetRenderers())
|
for (auto renderer : vp->GetRenderers())
|
||||||
{
|
{
|
||||||
renderer->GetRenderGraph()->FinaliseBatch();
|
renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
|
@ -387,14 +417,19 @@ namespace SHADE
|
||||||
resourceManager.Free(material);
|
resourceManager.Free(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHMaterialInstance> SHGraphicsSystem::AddMaterialInstance(Handle<SHMaterial> material)
|
Handle<SHMaterialInstance> SHGraphicsSystem::AddOrGetBaseMaterialInstance(Handle<SHMaterial> material)
|
||||||
{
|
{
|
||||||
return resourceManager.Create<SHMaterialInstance>(material);
|
return materialInstanceCache.CreateOrGet(resourceManager, material);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHADE::Handle<SHADE::SHMaterialInstance> SHGraphicsSystem::AddMaterialInstance()
|
SHADE::Handle<SHADE::SHMaterialInstance> SHGraphicsSystem::AddOrGetBaseMaterialInstance()
|
||||||
{
|
{
|
||||||
return AddMaterialInstance(defaultMaterial);
|
return AddOrGetBaseMaterialInstance(defaultMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHADE::Handle<SHADE::SHMaterialInstance> SHGraphicsSystem::AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst)
|
||||||
|
{
|
||||||
|
return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
|
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
|
||||||
|
|
|
@ -28,6 +28,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/MiddleEnd/Shaders/SHShaderSourceLibrary.h"
|
#include "Graphics/MiddleEnd/Shaders/SHShaderSourceLibrary.h"
|
||||||
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
|
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
|
||||||
#include "SHMeshLibrary.h"
|
#include "SHMeshLibrary.h"
|
||||||
|
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -119,9 +120,10 @@ namespace SHADE
|
||||||
/* Material Creation Functions */
|
/* Material Creation Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHMaterial> AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass);
|
Handle<SHMaterial> AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass);
|
||||||
void RemoveMaterial(Handle<SHMaterial> material);;
|
void RemoveMaterial(Handle<SHMaterial> material);
|
||||||
Handle<SHMaterialInstance> AddMaterialInstance();
|
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance();
|
||||||
Handle<SHMaterialInstance> AddMaterialInstance(Handle<SHMaterial> material);
|
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material);
|
||||||
|
Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst);
|
||||||
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);
|
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -200,6 +202,7 @@ namespace SHADE
|
||||||
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
|
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
|
||||||
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
|
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
|
||||||
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
|
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
|
||||||
|
Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;}
|
||||||
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
|
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
|
||||||
|
|
||||||
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
||||||
|
@ -228,8 +231,9 @@ namespace SHADE
|
||||||
Handle<SHGraphicsGlobalData> globalData;
|
Handle<SHGraphicsGlobalData> globalData;
|
||||||
|
|
||||||
// Middle End Resources
|
// Middle End Resources
|
||||||
ResourceManager resourceManager;
|
ResourceManager resourceManager;
|
||||||
SHMeshLibrary meshLibrary;
|
SHMeshLibrary meshLibrary;
|
||||||
|
SHMaterialInstanceCache materialInstanceCache;
|
||||||
// Viewports
|
// Viewports
|
||||||
Handle<SHViewport> defaultViewport; // Whole screen
|
Handle<SHViewport> defaultViewport; // Whole screen
|
||||||
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace SHADE
|
||||||
dataStore.reset();
|
dataStore.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHMaterialInstance::ExportProperties(void* dest) const
|
void SHMaterialInstance::ExportProperties(void* dest)
|
||||||
{
|
{
|
||||||
assert(dataStore != nullptr);
|
assert(dataStore != nullptr);
|
||||||
|
|
||||||
|
@ -62,6 +62,9 @@ namespace SHADE
|
||||||
const auto DATA_OFFSET = variable->offset;
|
const auto DATA_OFFSET = variable->offset;
|
||||||
memcpy(static_cast<char*>(dest) + DATA_OFFSET, dataStore.get() + data.StoredDataOffset, data.DataSize);
|
memcpy(static_cast<char*>(dest) + DATA_OFFSET, dataStore.get() + data.StoredDataOffset, data.DataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data was exported so unflag
|
||||||
|
dataWasChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -62,12 +62,13 @@ namespace SHADE
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const T& GetProperty(const std::string& key) const;
|
const T& GetProperty(const std::string& key) const;
|
||||||
void ResetProperties() noexcept;
|
void ResetProperties() noexcept;
|
||||||
void ExportProperties(void* dest) const;
|
void ExportProperties(void* dest);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHMaterial> GetBaseMaterial() const { return baseMaterial; }
|
Handle<SHMaterial> GetBaseMaterial() const noexcept { return baseMaterial; }
|
||||||
|
bool HasChanged() const noexcept { return dataWasChanged; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -77,6 +78,7 @@ namespace SHADE
|
||||||
std::vector<OverrideData> overrideData;
|
std::vector<OverrideData> overrideData;
|
||||||
std::unique_ptr<char> dataStore;
|
std::unique_ptr<char> dataStore;
|
||||||
size_t dataStoreSize = 0;
|
size_t dataStoreSize = 0;
|
||||||
|
bool dataWasChanged = false;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
|
@ -53,6 +53,9 @@ namespace SHADE
|
||||||
|
|
||||||
// Save the override data information
|
// Save the override data information
|
||||||
overrideData.emplace_back(std::move(od));
|
overrideData.emplace_back(std::move(od));
|
||||||
|
|
||||||
|
// Flag
|
||||||
|
dataWasChanged = true;
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& SHMaterialInstance::GetProperty(const std::string& key)
|
T& SHMaterialInstance::GetProperty(const std::string& key)
|
||||||
|
|
|
@ -27,7 +27,6 @@ namespace SHADE
|
||||||
sharedMaterial = {};
|
sharedMaterial = {};
|
||||||
material = {};
|
material = {};
|
||||||
oldMaterial = {};
|
oldMaterial = {};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderable::OnDestroy()
|
void SHRenderable::OnDestroy()
|
||||||
|
@ -82,7 +81,7 @@ namespace SHADE
|
||||||
if (!material)
|
if (!material)
|
||||||
{
|
{
|
||||||
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
material = gfxSystem->AddMaterialInstance(sharedMaterial->GetBaseMaterial());
|
material = gfxSystem->AddOrGetBaseMaterialInstance(sharedMaterial->GetBaseMaterial());
|
||||||
}
|
}
|
||||||
|
|
||||||
return material;
|
return material;
|
||||||
|
@ -93,5 +92,4 @@ namespace SHADE
|
||||||
materialChanged = false;
|
materialChanged = false;
|
||||||
oldMaterial = {};
|
oldMaterial = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,6 @@ namespace SHADE
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
Handle<SHMesh> Mesh;
|
Handle<SHMesh> Mesh;
|
||||||
SHMatrix TransformMatrix; // TODO: Replace with Transform component
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -20,20 +20,33 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "SHMaterial.h"
|
#include "SHMaterial.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Constructor/Destructors */
|
/* Constructor/Destructors */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
SHRenderer::SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph)
|
SHRenderer::SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph)
|
||||||
: viewport { viewport }
|
: viewport { viewport }
|
||||||
, renderGraph { renderGraph }
|
, renderGraph { renderGraph }
|
||||||
{
|
{
|
||||||
cameraDescriptorSet = logicalDevice->CreateDescriptorSetGroup(descriptorPool, { cameraDescLayout }, { 1 });
|
commandBuffers.resize(static_cast<std::size_t>(numFrames));
|
||||||
cpuCameraData.resize(numFrames);
|
|
||||||
|
for (uint32_t i = 0; i < commandBuffers.size(); ++i)
|
||||||
|
commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
|
||||||
|
cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 });
|
||||||
|
|
||||||
cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData));
|
cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData));
|
||||||
|
|
||||||
|
cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
||||||
|
|
||||||
|
std::array cameraBufferArray{cameraBuffer};
|
||||||
|
|
||||||
|
cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span<Handle<SHVkBuffer>>{ cameraBufferArray.data(), cameraBufferArray.size()}, 0, sizeof (SHShaderCameraData));
|
||||||
|
|
||||||
|
cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -47,21 +60,33 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Drawing Functions */
|
/* Drawing Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void SHRenderer::Draw(uint32_t frameIndex, std::initializer_list<std::pair<Handle<SHVkBuffer>, uint32_t>> graphScopeBuffers) noexcept
|
void SHRenderer::Draw(uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
renderGraph->Execute(frameIndex, graphScopeBuffers);
|
renderGraph->Execute(frameIndex, commandBuffers[frameIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderer::BindDescriptorSet(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
|
cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
|
||||||
|
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
|
||||||
|
|
||||||
|
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
|
||||||
|
|
||||||
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderer::UpdateCameraDataToBuffer(void) noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept
|
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept
|
||||||
{
|
{
|
||||||
return renderGraph;
|
return renderGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHVkCommandBuffer> SHRenderer::GetCommandBuffer(uint32_t frameIndex) const noexcept
|
||||||
|
{
|
||||||
|
return commandBuffers[frameIndex];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace SHADE
|
||||||
class SHVkDescriptorSetGroup;
|
class SHVkDescriptorSetGroup;
|
||||||
class SHGraphicsGlobalData;
|
class SHGraphicsGlobalData;
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
|
class SHVkBuffer;
|
||||||
|
|
||||||
struct SHShaderCameraData
|
struct SHShaderCameraData
|
||||||
{
|
{
|
||||||
|
@ -63,7 +64,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Constructor/Destructors */
|
/* Constructor/Destructors */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph);
|
SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Camera Registration */
|
/* Camera Registration */
|
||||||
|
@ -73,13 +74,15 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Drawing Functions */
|
/* Drawing Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void Draw(uint32_t frameIndex, std::initializer_list<std::pair<Handle<SHVkBuffer>, uint32_t>> graphScopeBuffers) noexcept;
|
void Draw(uint32_t frameIndex) noexcept;
|
||||||
void BindDescriptorSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void UpdateDataAndBind (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
|
void UpdateCameraDataToBuffer (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Setters and Getters */
|
/* Setters and Getters */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
|
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
|
||||||
|
Handle<SHVkCommandBuffer> GetCommandBuffer(uint32_t frameIndex) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -92,7 +95,16 @@ namespace SHADE
|
||||||
Handle<SHCamera> camera;
|
Handle<SHCamera> camera;
|
||||||
Handle<SHRenderGraph> renderGraph;
|
Handle<SHRenderGraph> renderGraph;
|
||||||
Handle<SHVkDescriptorSetGroup> cameraDescriptorSet;
|
Handle<SHVkDescriptorSetGroup> cameraDescriptorSet;
|
||||||
std::vector<SHShaderCameraData> cpuCameraData;
|
Handle<SHVkBuffer> cameraBuffer;
|
||||||
|
|
||||||
|
// we really only need 1 copy even though we need %swapchainImages copies for
|
||||||
|
// GPU.
|
||||||
|
SHShaderCameraData cpuCameraData;
|
||||||
|
|
||||||
|
//! Command buffers for the render graph
|
||||||
|
std::vector<Handle<SHVkCommandBuffer>> commandBuffers;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,10 +49,10 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Renderer Registration Functions */
|
/* Renderer Registration Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
Handle<SHRenderer> SHViewport::AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph)
|
Handle<SHRenderer> SHViewport::AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph)
|
||||||
{
|
{
|
||||||
// Create the renderer
|
// Create the renderer
|
||||||
auto renderer = resourceManager.Create<SHRenderer>(device, numFrames, descriptorPool, cameraDescLayout, GetHandle(), renderGraph);
|
auto renderer = resourceManager.Create<SHRenderer>(device, numFrames, cmdPools, descriptorPool, cameraDescLayout, GetHandle(), renderGraph);
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
renderers.emplace_back(renderer);
|
renderers.emplace_back(renderer);
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace SHADE
|
||||||
class SHRenderGraph;
|
class SHRenderGraph;
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
class SHVkDescriptorSetLayout;
|
class SHVkDescriptorSetLayout;
|
||||||
|
class SHVkCommandPool;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
@ -58,7 +59,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Renderers Registration Functions */
|
/* Renderers Registration Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHRenderer> AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
|
Handle<SHRenderer> AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
|
||||||
void RemoveRenderer(Handle<SHRenderer> renderer);
|
void RemoveRenderer(Handle<SHRenderer> renderer);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHMaterialInstanceCache.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 25, 2022
|
||||||
|
\brief Contains the definition of SHMaterialInstanceCache's 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.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHMaterialInstanceCache.h"
|
||||||
|
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
|
#include "Resource/ResourceLibrary.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHADE::Handle<SHADE::SHMaterialInstance> SHMaterialInstanceCache::CreateOrGet(ResourceManager& manager, Handle<SHMaterial> material)
|
||||||
|
{
|
||||||
|
// Check if there is already an existing instance
|
||||||
|
auto matInst = cache.find(material);
|
||||||
|
if (matInst == cache.end())
|
||||||
|
{
|
||||||
|
// Create and return
|
||||||
|
return cache.emplace(material, manager.Create<SHMaterialInstance>(material)).first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return matInst->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInstanceCache::Remove(Handle<SHMaterial> material)
|
||||||
|
{
|
||||||
|
cache.erase(material);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHMaterialInstanceCache::Clear()
|
||||||
|
{
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHMaterialInstanceCache.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 25, 2022
|
||||||
|
\brief Contains the definition of SHMaterialInstanceCache.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// STL Includes
|
||||||
|
#include <unordered_map>
|
||||||
|
// Project Includes
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
class SHMaterial;
|
||||||
|
class SHMaterialInstance;
|
||||||
|
class ResourceManager;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Creates and caches base SHMaterialInstances. Note that base SHMaterialInstances
|
||||||
|
refer to SHMaterialInstances with no overrides.
|
||||||
|
*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
class SHMaterialInstanceCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
|
||||||
|
|
||||||
|
\param material
|
||||||
|
Material to get the SHMaterialInstance for.
|
||||||
|
|
||||||
|
\return
|
||||||
|
Handle to the base SHMaterialInstance that is mapped to SHMaterial.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
Handle<SHMaterialInstance> CreateOrGet(ResourceManager& manager, Handle<SHMaterial> material);
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Removes a SHMaterialInstance from the cache with a matching material.
|
||||||
|
|
||||||
|
\param material
|
||||||
|
Handle to a SHMaterial that is used to check for removal.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
void Remove(Handle<SHMaterial> material);
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Removes all SHMaterialInstances in the cache.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
using MaterialMap = std::unordered_map<Handle<SHMaterial>, Handle<SHMaterialInstance>>;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
MaterialMap cache;
|
||||||
|
};
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ namespace SHADE
|
||||||
auto pipelineLayout = logicalDevice->CreatePipelineLayout(params);
|
auto pipelineLayout = logicalDevice->CreatePipelineLayout(params);
|
||||||
|
|
||||||
// Create the pipeline and configure the default vertex input state
|
// Create the pipeline and configure the default vertex input state
|
||||||
auto newPipeline = logicalDevice->CreatePipeline(pipelineLayout, nullptr, renderpass, subpass, SH_PIPELINE_TYPE::GRAPHICS);
|
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
|
||||||
newPipeline->GetPipelineState().SetVertexInputState(globalData->GetDefaultViState());
|
newPipeline->GetPipelineState().SetVertexInputState(globalData->GetDefaultViState());
|
||||||
|
|
||||||
// Actually construct the pipeline
|
// Actually construct the pipeline
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHTextureLibrary.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 20, 2022
|
||||||
|
\brief Contains definitions for all of the functions of the classes that deal
|
||||||
|
with storage and management of buffers for textures.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHTextureLibrary.h"
|
||||||
|
|
||||||
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
#include "Graphics/Commands/SHVkCommandBuffer.h"
|
||||||
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
Handle<SHTexture> SHTextureLibrary::Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, uint32_t mipLevels)
|
||||||
|
{
|
||||||
|
isDirty = true;
|
||||||
|
|
||||||
|
auto handle = resourceManager.Create<SHTexture>();
|
||||||
|
addJobs.emplace_back(AddJob { pixelCount, pixelData, format, mipLevels });
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHTextureLibrary::Remove(Handle<SHTexture> texture)
|
||||||
|
{
|
||||||
|
if (!texture)
|
||||||
|
throw std::invalid_argument("Attempted to remove a Texture that did not belong to the Texture Library!");
|
||||||
|
|
||||||
|
removeJobs.emplace_back(texture);
|
||||||
|
isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHTextureLibrary::BuildImages(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> descLayout)
|
||||||
|
{
|
||||||
|
/* Remove Textures */
|
||||||
|
std::vector<vk::ImageMemoryBarrier> pipelineBarriers(addJobs.size());
|
||||||
|
|
||||||
|
/* Add Textures */
|
||||||
|
// Transition
|
||||||
|
for (int i = 0; auto& job : addJobs)
|
||||||
|
{
|
||||||
|
job.Image = resourceManager.Create<SHVkImage>();
|
||||||
|
job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, pipelineBarriers[i]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||||
|
vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||||
|
preparePipelineBarriers(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, srcStage, dstStage, pipelineBarriers);
|
||||||
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers);
|
||||||
|
|
||||||
|
// Copy
|
||||||
|
for (auto& job : addJobs)
|
||||||
|
{
|
||||||
|
job.Image->TransferToDeviceResource(cmdBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition
|
||||||
|
for (int i = 0; auto & job : addJobs)
|
||||||
|
{
|
||||||
|
// Transition
|
||||||
|
job.Image->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, pipelineBarriers[i]);
|
||||||
|
}
|
||||||
|
preparePipelineBarriers(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, srcStage, dstStage, pipelineBarriers);
|
||||||
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, pipelineBarriers);
|
||||||
|
|
||||||
|
// Execute Commands
|
||||||
|
graphicsQueue->SubmitCommandBuffer({ cmdBuffer });
|
||||||
|
device->WaitIdle();
|
||||||
|
|
||||||
|
// Create Image View
|
||||||
|
for (auto& job : addJobs)
|
||||||
|
{
|
||||||
|
const SHImageViewDetails DETAILS
|
||||||
|
{
|
||||||
|
.viewType = vk::ImageViewType::e2D,
|
||||||
|
.format = job.TextureFormat,
|
||||||
|
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.mipLevelCount = job.MipLevels,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 0
|
||||||
|
};
|
||||||
|
job.Handle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build Descriptor
|
||||||
|
Handle<SHVkDescriptorSetGroup> descSetGroup = descPool->Allocate({ descLayout }, { 1 });
|
||||||
|
|
||||||
|
|
||||||
|
isDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHTextureLibrary::preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector<vk::ImageMemoryBarrier>& barriers)
|
||||||
|
{
|
||||||
|
if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal)
|
||||||
|
{
|
||||||
|
srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||||
|
dstStage = vk::PipelineStageFlagBits::eTransfer;
|
||||||
|
|
||||||
|
for (auto& barrier : barriers)
|
||||||
|
{
|
||||||
|
barrier.srcAccessMask = vk::AccessFlagBits::eNone;
|
||||||
|
barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal)
|
||||||
|
{
|
||||||
|
srcStage = vk::PipelineStageFlagBits::eTransfer;
|
||||||
|
|
||||||
|
// TODO, what if we want to access in compute shader
|
||||||
|
dstStage = vk::PipelineStageFlagBits::eFragmentShader;
|
||||||
|
|
||||||
|
for (auto& barrier : barriers)
|
||||||
|
{
|
||||||
|
barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||||
|
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Image layouts are invalid. ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHTextureLibrary.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 20, 2022
|
||||||
|
\brief Contains definitions for all of the classes that deal with storage and
|
||||||
|
management of textures.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// STL Includes
|
||||||
|
#include <vector>
|
||||||
|
// Project Includes
|
||||||
|
#include "Resource/Handle.h"
|
||||||
|
#include "Resource/ResourceLibrary.h"
|
||||||
|
#include "Math/SHMath.h"
|
||||||
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Forward Declarations */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
class SHVkBuffer;
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
class SHVkCommandBuffer;
|
||||||
|
class SHVkImage;
|
||||||
|
class SHVkImageView;
|
||||||
|
class SHVkQueue;
|
||||||
|
class SHVkDescriptorPool;
|
||||||
|
class SHVkDescriptorSetLayout;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
class SHTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
using PixelChannel = float;
|
||||||
|
using TextureFormat = vk::Format; // TODO: Change
|
||||||
|
using Index = uint32_t;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
Handle<SHVkImageView> ImageView;
|
||||||
|
Index TextureArrayIndex = std::numeric_limits<Index>::max();
|
||||||
|
};
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Manages storage for all textures in the Graphics System as a single set of
|
||||||
|
textures.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
class SHTextureLibrary
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Adds a texture to the Texture Library. But this does not mean that the
|
||||||
|
textures have been added yet. A call to "BuildImages()" is required to
|
||||||
|
transfer all textures into the GPU.
|
||||||
|
|
||||||
|
\param pixelCount
|
||||||
|
Number of pixels in this Mesh.
|
||||||
|
\param positions
|
||||||
|
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
|
||||||
|
positions.
|
||||||
|
\param format
|
||||||
|
Format of the texture loaded in.
|
||||||
|
|
||||||
|
\return
|
||||||
|
Handle to the created Texture. This is not valid to be used until a call to
|
||||||
|
BuildImages().
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
Handle<SHTexture> Add(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, SHTexture::TextureFormat format, uint32_t mipLevels);
|
||||||
|
/*******************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Removes a mesh from the Texture Library. But this does not mean that the
|
||||||
|
textures have been removed yet. A call to "BuildImages()" is required to
|
||||||
|
finalise all changes.
|
||||||
|
|
||||||
|
\param mesh
|
||||||
|
Handle to the mesh to remove.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*******************************************************************************/
|
||||||
|
void Remove(Handle<SHTexture> mesh);
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Finalises all changes to the Texture Library into the GPU buffers.
|
||||||
|
|
||||||
|
\param device
|
||||||
|
Device used to create and update the buffers.
|
||||||
|
\param cmdBuffer
|
||||||
|
Command buffer used to set up transfers of data in the GPU memory. This
|
||||||
|
call must be preceded by calls to cmdBuffer's BeginRecording() and ended
|
||||||
|
with EndRecording(). Do recall to also submit the cmdBuffer to a transfer
|
||||||
|
queue.
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void BuildImages(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkQueue> graphicsQueue, Handle<SHVkDescriptorPool> descPool, Handle<SHVkDescriptorSetLayout> descLayout);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
Handle<SHVkBuffer> GetTextureBuffer() const noexcept { return texStorageBuffer; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Type Definition */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
struct AddJob
|
||||||
|
{
|
||||||
|
uint32_t PixelCount = 0;
|
||||||
|
const SHTexture::PixelChannel* PixelData = nullptr;
|
||||||
|
SHTexture::TextureFormat TextureFormat = {};
|
||||||
|
uint32_t MipLevels = 0;
|
||||||
|
Handle<SHVkImage> Image;
|
||||||
|
Handle<SHTexture> Handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
// Manipulation Queues
|
||||||
|
std::vector<AddJob> addJobs;
|
||||||
|
std::vector<Handle<SHTexture>> removeJobs;
|
||||||
|
// Tracking
|
||||||
|
ResourceManager resourceManager;
|
||||||
|
std::vector<Handle<SHTexture>> texOrder;
|
||||||
|
// CPU Storage
|
||||||
|
std::vector<SHTexture::PixelChannel> texStorage;
|
||||||
|
// GPU Storage
|
||||||
|
Handle<SHVkBuffer> texStorageBuffer{};
|
||||||
|
// Flags
|
||||||
|
bool isDirty = true;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
void preparePipelineBarriers(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::PipelineStageFlagBits& srcStage, vk::PipelineStageFlagBits& dstStage, std::vector<vk::ImageMemoryBarrier>& barriers);
|
||||||
|
};
|
||||||
|
}
|
|
@ -25,6 +25,15 @@ namespace SHADE
|
||||||
//! want to use it for allocating descriptor sets.
|
//! want to use it for allocating descriptor sets.
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts = {};
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SHPipelineLayoutParamsDummy
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* MEMBER VARIABLES */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts = {};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace SHADE
|
||||||
vk::CullModeFlags cull_mode{ vk::CullModeFlagBits::eBack };
|
vk::CullModeFlags cull_mode{ vk::CullModeFlagBits::eBack };
|
||||||
|
|
||||||
//! CW or CCW
|
//! CW or CCW
|
||||||
vk::FrontFace frontFacingOrientation{ vk::FrontFace::eClockwise };
|
vk::FrontFace frontFacingOrientation{ vk::FrontFace::eCounterClockwise };
|
||||||
|
|
||||||
bool depthBias{ VK_FALSE };
|
bool depthBias{ VK_FALSE };
|
||||||
};
|
};
|
||||||
|
|
|
@ -179,7 +179,7 @@ namespace SHADE
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\brief
|
\brief
|
||||||
Non-default ctor.
|
Non-default ctor for creating graphics pipeline.
|
||||||
|
|
||||||
\param inLogicalDeviceHdl
|
\param inLogicalDeviceHdl
|
||||||
Needed for creation and destruction.
|
Needed for creation and destruction.
|
||||||
|
@ -200,14 +200,12 @@ namespace SHADE
|
||||||
The subpass that this pipeline will be used in. If state is not
|
The subpass that this pipeline will be used in. If state is not
|
||||||
nullptr, this parameter is ignored.
|
nullptr, this parameter is ignored.
|
||||||
|
|
||||||
\param type
|
|
||||||
The type of the pipeline.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkPipeline::SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkPipelineLayout> const& inPipelineLayout, SHVkPipelineState const* const state, Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHSubpass> subpass, SH_PIPELINE_TYPE type) noexcept
|
SHVkPipeline::SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkPipelineLayout> const& inPipelineLayout, SHVkPipelineState const* const state, Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHSubpass> subpass) noexcept
|
||||||
: pipelineState{ }
|
: pipelineState{ }
|
||||||
, pipelineType {type}
|
, pipelineType {SH_PIPELINE_TYPE::GRAPHICS}
|
||||||
, vkPipeline {VK_NULL_HANDLE}
|
, vkPipeline {VK_NULL_HANDLE}
|
||||||
, logicalDeviceHdl{ inLogicalDeviceHdl }
|
, logicalDeviceHdl{ inLogicalDeviceHdl }
|
||||||
, pipelineLayout { inPipelineLayout }
|
, pipelineLayout { inPipelineLayout }
|
||||||
|
@ -250,6 +248,33 @@ namespace SHADE
|
||||||
vkPipeline = VK_NULL_HANDLE;
|
vkPipeline = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Just to differentiate between compute and graphics pipeline, we will
|
||||||
|
have a constructor that takes in less parameters; sufficient for the
|
||||||
|
compute pipeline to be created.
|
||||||
|
|
||||||
|
\param inLogicalDeviceHdl
|
||||||
|
\param inPipelineLayout
|
||||||
|
|
||||||
|
\return
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
SHVkPipeline::SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkPipelineLayout> const& inPipelineLayout) noexcept
|
||||||
|
: pipelineState{ }
|
||||||
|
, pipelineType{ SH_PIPELINE_TYPE::COMPUTE }
|
||||||
|
, vkPipeline{ VK_NULL_HANDLE }
|
||||||
|
, logicalDeviceHdl{ inLogicalDeviceHdl }
|
||||||
|
, pipelineLayout{ inPipelineLayout }
|
||||||
|
, created{ false }
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,10 @@ namespace SHADE
|
||||||
Handle<SHVkPipelineLayout> const& inPipelineLayout,
|
Handle<SHVkPipelineLayout> const& inPipelineLayout,
|
||||||
SHVkPipelineState const* const state,
|
SHVkPipelineState const* const state,
|
||||||
Handle<SHVkRenderpass> const& renderpassHdl,
|
Handle<SHVkRenderpass> const& renderpassHdl,
|
||||||
Handle<SHSubpass> subpass,
|
Handle<SHSubpass> subpass) noexcept;
|
||||||
SH_PIPELINE_TYPE type) noexcept;
|
|
||||||
|
SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
|
||||||
|
Handle<SHVkPipelineLayout> const& inPipelineLayout) noexcept;
|
||||||
|
|
||||||
SHVkPipeline (SHVkPipeline&& rhs) noexcept;
|
SHVkPipeline (SHVkPipeline&& rhs) noexcept;
|
||||||
~SHVkPipeline (void) noexcept;
|
~SHVkPipeline (void) noexcept;
|
||||||
|
|
|
@ -198,7 +198,7 @@ namespace SHADE
|
||||||
// 1 descriptor set layout for every descriptor set detected.
|
// 1 descriptor set layout for every descriptor set detected.
|
||||||
for (auto const& set : setsWithBindings)
|
for (auto const& set : setsWithBindings)
|
||||||
{
|
{
|
||||||
auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.second);
|
auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.first, set.second);
|
||||||
descriptorSetLayoutsAllocate.push_back(newDescriptorSetLayout);
|
descriptorSetLayoutsAllocate.push_back(newDescriptorSetLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,12 +254,6 @@ namespace SHADE
|
||||||
// Clear pc ranges
|
// Clear pc ranges
|
||||||
vkPcRanges.clear();
|
vkPcRanges.clear();
|
||||||
|
|
||||||
// Kill all descriptor set layouts
|
|
||||||
for (auto& layout : descriptorSetLayoutsGlobal)
|
|
||||||
SHVkInstance::GetResourceManager().Free(layout);
|
|
||||||
|
|
||||||
descriptorSetLayoutsGlobal.clear();
|
|
||||||
|
|
||||||
for (auto& layout : descriptorSetLayoutsAllocate)
|
for (auto& layout : descriptorSetLayoutsAllocate)
|
||||||
SHVkInstance::GetResourceManager().Free(layout);
|
SHVkInstance::GetResourceManager().Free(layout);
|
||||||
|
|
||||||
|
@ -285,9 +279,9 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkPipelineLayout::SHVkPipelineLayout(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, SHPipelineLayoutParams& pipelineLayoutParams) noexcept
|
SHVkPipelineLayout::SHVkPipelineLayout(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, SHPipelineLayoutParams const& pipelineLayoutParams) noexcept
|
||||||
: vkPipelineLayout {VK_NULL_HANDLE}
|
: vkPipelineLayout {VK_NULL_HANDLE}
|
||||||
, shaderModules{std::move (pipelineLayoutParams.shaderModules)}
|
, shaderModules{pipelineLayoutParams.shaderModules}
|
||||||
, logicalDeviceHdl {inLogicalDeviceHdl}
|
, logicalDeviceHdl {inLogicalDeviceHdl}
|
||||||
, pushConstantInterface{}
|
, pushConstantInterface{}
|
||||||
, vkPcRanges{}
|
, vkPcRanges{}
|
||||||
|
@ -308,6 +302,46 @@ namespace SHADE
|
||||||
RecreateIfNeeded ();
|
RecreateIfNeeded ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHVkPipelineLayout::SHVkPipelineLayout(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, SHPipelineLayoutParamsDummy const& pipelineLayoutParams) noexcept
|
||||||
|
: vkPipelineLayout{ VK_NULL_HANDLE }
|
||||||
|
, shaderModules{ }
|
||||||
|
, logicalDeviceHdl{ inLogicalDeviceHdl }
|
||||||
|
, pushConstantInterface{}
|
||||||
|
, vkPcRanges{}
|
||||||
|
, descriptorSetLayoutsGlobal{}
|
||||||
|
, descriptorSetLayoutsAllocate{}
|
||||||
|
, vkDescriptorSetLayoutsAllocate{}
|
||||||
|
, vkDescriptorSetLayoutsPipeline{}
|
||||||
|
|
||||||
|
{
|
||||||
|
vkDescriptorSetLayoutsPipeline.resize(pipelineLayoutParams.globalDescSetLayouts.size());
|
||||||
|
for (uint32_t i = 0; auto& layout : vkDescriptorSetLayoutsPipeline)
|
||||||
|
{
|
||||||
|
layout = pipelineLayoutParams.globalDescSetLayouts[i]->GetVkHandle();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::PipelineLayoutCreateInfo plCreateInfo{};
|
||||||
|
|
||||||
|
// Set push constant data to pipeline layout
|
||||||
|
plCreateInfo.pushConstantRangeCount = 0;
|
||||||
|
plCreateInfo.pPushConstantRanges = nullptr;
|
||||||
|
|
||||||
|
// To initialize the descriptor set layouts for the pipeline layout.
|
||||||
|
plCreateInfo.setLayoutCount = static_cast<uint32_t>(vkDescriptorSetLayoutsPipeline.size());
|
||||||
|
plCreateInfo.pSetLayouts = vkDescriptorSetLayoutsPipeline.data();
|
||||||
|
|
||||||
|
if (auto const RESULT = logicalDeviceHdl->GetVkLogicalDevice().createPipelineLayout(&plCreateInfo, nullptr, &vkPipelineLayout); RESULT != vk::Result::eSuccess)
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkError(RESULT, "Failed to create Pipeline Layout. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created Pipeline Layout. ");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue