Add Editor Features - Transform Gizmo #105
|
@ -0,0 +1,3 @@
|
|||
Name: Cube.003
|
||||
ID: 110152941
|
||||
Type:
|
|
@ -0,0 +1,3 @@
|
|||
Name: Cube.012
|
||||
ID: 107348815
|
||||
Type:
|
|
@ -9,8 +9,8 @@ Size=1920,1036
|
|||
Collapsed=0
|
||||
|
||||
[Window][Hierarchy Panel]
|
||||
Pos=0,89
|
||||
Size=286,971
|
||||
Pos=0,120
|
||||
Size=225,940
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
|
@ -20,23 +20,29 @@ Size=400,400
|
|||
Collapsed=0
|
||||
|
||||
[Window][Inspector]
|
||||
Pos=1494,24
|
||||
Size=426,1036
|
||||
Pos=1686,24
|
||||
Size=234,1036
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Profiler]
|
||||
Pos=0,24
|
||||
Size=286,63
|
||||
Size=225,94
|
||||
Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=227,24
|
||||
Size=1457,1036
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,55 Size=1920,1036 Split=X
|
||||
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1492,1036 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=286,1036 Split=Y Selected=0xE096E5AE
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=140,63 Selected=0x1E6EB881
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=140,971 Selected=0xE096E5AE
|
||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1204,1036 CentralNode=1
|
||||
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=426,1036 Selected=0xE7039252
|
||||
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1684,1036 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=225,1036 Split=Y Selected=0x1E6EB881
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE
|
||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1293,1036 CentralNode=1 Selected=0x13926F0B
|
||||
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=234,1036 Selected=0xE7039252
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Name: RaccoonPreTexturedVer1_Base9
|
||||
ID: 91918845
|
||||
Type:
|
|
@ -104,10 +104,10 @@ namespace Sandbox
|
|||
|
||||
//TODO: REMOVE AFTER PRESENTATION
|
||||
//SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
||||
SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
|
||||
//SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
|
||||
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
|
||||
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
|
||||
SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
|
||||
//SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
|
||||
//TODO: REMOVE AFTER PRESENTATION
|
||||
|
||||
|
||||
|
@ -125,6 +125,8 @@ namespace Sandbox
|
|||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
||||
|
||||
SHFrameRateController::UpdateFRC();
|
||||
|
||||
SHAssetManager::Load();
|
||||
}
|
||||
|
||||
void SBApplication::Update(void)
|
||||
|
@ -139,17 +141,10 @@ namespace Sandbox
|
|||
SHSceneManager::UpdateSceneManager();
|
||||
#ifdef SHEDITOR
|
||||
if(editor->editorState == SHEditor::State::PLAY)
|
||||
#endif
|
||||
SHSceneManager::SceneUpdate(0.016f);
|
||||
#ifdef SHEDITOR
|
||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
||||
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||
{
|
||||
editor->PollPicking();
|
||||
}
|
||||
#else
|
||||
SHSystemManager::RunRoutines(false, 0.016f);
|
||||
#endif
|
||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
||||
editor->PollPicking();
|
||||
}
|
||||
// Finish all graphics jobs first
|
||||
graphicsSystem->AwaitGraphicsExecution();
|
||||
|
@ -165,6 +160,7 @@ namespace Sandbox
|
|||
|
||||
SHSceneManager::Exit();
|
||||
SHSystemManager::Exit();
|
||||
SHAssetManager::Unload();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace SHADE
|
|||
{
|
||||
bool compiled;
|
||||
|
||||
std::string name;
|
||||
uint32_t numBytes;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <fstream>
|
||||
|
||||
void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
|
||||
std::string SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
|
||||
{
|
||||
std::string newPath{ path.string() };
|
||||
newPath = newPath.substr(0, newPath.find_last_of('/') + 1);
|
||||
|
@ -67,4 +67,6 @@ void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPat
|
|||
);
|
||||
|
||||
file.close();
|
||||
|
||||
return newPath;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,6 @@ namespace SHADE
|
|||
{
|
||||
private:
|
||||
public:
|
||||
static void CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
|
||||
static std::string CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
|
||||
};
|
||||
}
|
|
@ -142,8 +142,7 @@ namespace SHADE
|
|||
SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
|
||||
}
|
||||
|
||||
std::string name{ path.filename().string() };
|
||||
name = name.substr(0, name.find_last_of('.'));
|
||||
const std::string name{ path.stem().string() };
|
||||
|
||||
file.seekg(0);
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ namespace SHADE
|
|||
|
||||
static void LoadExternal(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
|
||||
|
||||
static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept;
|
||||
public:
|
||||
static void LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
|
||||
static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept;
|
||||
};
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path)
|
||||
std::string SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path)
|
||||
{
|
||||
std::string newPath{ path.string() };
|
||||
newPath = newPath.substr(0, newPath.find_last_of('.'));
|
||||
|
@ -69,5 +69,7 @@ namespace SHADE
|
|||
);
|
||||
|
||||
file.close();
|
||||
|
||||
return newPath;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,6 @@ namespace SHADE
|
|||
{
|
||||
struct SHTextureCompiler
|
||||
{
|
||||
static void CompileTextureBinary(SHTextureAsset const& asset, AssetPath path);
|
||||
static std::string CompileTextureBinary(SHTextureAsset const& asset, AssetPath path);
|
||||
};
|
||||
}
|
|
@ -93,6 +93,7 @@ namespace SHADE
|
|||
std::memcpy(pixel, file.GetImageData()->m_mem, totalBytes);
|
||||
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
|
||||
|
||||
asset.name = path.stem().string();
|
||||
asset.compiled = false;
|
||||
asset.numBytes = static_cast<uint32_t>(totalBytes);
|
||||
asset.width = file.GetWidth();
|
||||
|
|
|
@ -26,8 +26,8 @@ namespace SHADE
|
|||
|
||||
|
||||
static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept;
|
||||
static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
|
||||
public:
|
||||
static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
|
||||
static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef FMOD::Sound* SHSound;
|
|||
#define ASSET_META_VER "1.0"
|
||||
|
||||
// Asset type enum
|
||||
enum class AssetType : uint8_t
|
||||
enum class AssetType : AssetTypeMeta
|
||||
{
|
||||
INVALID = 0,
|
||||
AUDIO = 1,
|
||||
|
@ -57,7 +57,12 @@ enum class AssetType : uint8_t
|
|||
};
|
||||
|
||||
//Directory
|
||||
#define ASSET_ROOT "./Assets/"
|
||||
#ifdef _PUBLISH
|
||||
#define ASSET_ROOT "Assets"
|
||||
#else
|
||||
#define ASSET_ROOT "../../Assets"
|
||||
#endif
|
||||
|
||||
|
||||
// ASSET EXTENSIONS
|
||||
#define META_EXTENSION ".shmeta"
|
||||
|
|
|
@ -255,6 +255,26 @@ namespace SHADE
|
|||
return result;
|
||||
}
|
||||
|
||||
SHMeshAsset const* SHAssetManager::GetMesh(AssetID id) noexcept
|
||||
{
|
||||
if (meshCollection.find(id) == meshCollection.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &meshCollection[id];
|
||||
}
|
||||
|
||||
SHTextureAsset const* SHAssetManager::GetTexture(AssetID id) noexcept
|
||||
{
|
||||
if (textureCollection.find(id) == textureCollection.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &textureCollection[id];
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* \param Path for meta data file
|
||||
* \param Path for asset file
|
||||
|
@ -307,12 +327,22 @@ namespace SHADE
|
|||
|
||||
for (auto const& mesh : meshes)
|
||||
{
|
||||
meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh);
|
||||
auto id{ GenerateAssetID(AssetType::MESH) };
|
||||
meshCollection.emplace(id, mesh);
|
||||
|
||||
AssetPath path;
|
||||
if (!mesh.compiled)
|
||||
{
|
||||
SHMeshCompiler::CompileMeshBinary(mesh, asset.path);
|
||||
path = SHMeshCompiler::CompileMeshBinary(mesh, asset.path);
|
||||
}
|
||||
|
||||
assetCollection.emplace_back(
|
||||
mesh.header.meshName,
|
||||
id,
|
||||
AssetType::MESH,
|
||||
path,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,11 +352,20 @@ namespace SHADE
|
|||
|
||||
SHTextureLoader::LoadImageAsset(asset.path, image);
|
||||
|
||||
textureCollection.emplace(GenerateAssetID(AssetType::DDS), image);
|
||||
|
||||
if (!image.compiled)
|
||||
{
|
||||
SHTextureCompiler::CompileTextureBinary(image, asset.path);
|
||||
auto id{ GenerateAssetID(AssetType::TEXTURE) };
|
||||
textureCollection.emplace(id, image);
|
||||
|
||||
auto path{ SHTextureCompiler::CompileTextureBinary(image, asset.path) };
|
||||
|
||||
assetCollection.emplace_back(
|
||||
image.name,
|
||||
id,
|
||||
AssetType::TEXTURE,
|
||||
path,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,8 +383,24 @@ namespace SHADE
|
|||
****************************************************************************/
|
||||
void SHAssetManager::LoadAllData() noexcept
|
||||
{
|
||||
//TODO Remove when on demand loading is done
|
||||
for (auto const& asset : assetCollection)
|
||||
{
|
||||
switch (asset.type)
|
||||
{
|
||||
case AssetType::MESH:
|
||||
meshCollection.emplace(asset.id, SHMeshAsset());
|
||||
SHMeshLoader::LoadSHMesh(meshCollection[asset.id], asset.path);
|
||||
break;
|
||||
|
||||
case AssetType::TEXTURE:
|
||||
textureCollection.emplace(asset.id, SHTextureAsset());
|
||||
SHTextureLoader::LoadSHTexture(asset.path, textureCollection[asset.id]);
|
||||
break;
|
||||
|
||||
default:
|
||||
void;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,40 +417,51 @@ namespace SHADE
|
|||
std::vector<AssetPath> metaFiles;
|
||||
std::vector<AssetPath> 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 (auto const dir : std::filesystem::recursive_directory_iterator(ASSET_ROOT))
|
||||
{
|
||||
for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() };
|
||||
it != AssetFiles.cend();
|
||||
++it)
|
||||
if (dir.path().extension().string() == META_EXTENSION)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
auto meta{ SHAssetMetaHandler::RetrieveMetaData(dir.path()) };
|
||||
|
||||
assetCollection.push_back(meta);
|
||||
assetRegistry.emplace(meta.id, meta);
|
||||
}
|
||||
}
|
||||
|
||||
//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";
|
||||
}
|
||||
}
|
||||
//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
|
||||
|
|
|
@ -75,6 +75,8 @@ namespace SHADE
|
|||
static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
|
||||
static std::vector<SHTextureAsset> GetAllTextures() noexcept;
|
||||
|
||||
static SHMeshAsset const* GetMesh(AssetID id) noexcept;
|
||||
static SHTextureAsset const* GetTexture(AssetID id) noexcept;
|
||||
private:
|
||||
/****************************************************************************
|
||||
* \brief Load resource data into memory
|
||||
|
|
|
@ -72,6 +72,13 @@ namespace SHADE
|
|||
std::string line;
|
||||
SHAsset meta;
|
||||
|
||||
// Get resource name
|
||||
GetFieldValue(metaFile, line);
|
||||
std::stringstream nameStream{ line };
|
||||
AssetName name;
|
||||
nameStream >> name;
|
||||
meta.name = name;
|
||||
|
||||
// Get resource id
|
||||
GetFieldValue(metaFile, line);
|
||||
std::stringstream idStream{ line };
|
||||
|
@ -88,6 +95,8 @@ namespace SHADE
|
|||
|
||||
metaFile.close();
|
||||
|
||||
meta.path = path.parent_path().string() + "/" + path.stem().string();
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
|
@ -103,7 +112,7 @@ namespace SHADE
|
|||
std::string path{ meta.path.string() };
|
||||
path.append(META_EXTENSION);
|
||||
|
||||
std::ofstream metaFile{ path, std::ios_base::out };
|
||||
std::ofstream metaFile{ path, std::ios_base::out | std::ios_base::trunc };
|
||||
|
||||
if (!metaFile.is_open())
|
||||
{
|
||||
|
@ -113,17 +122,17 @@ namespace SHADE
|
|||
|
||||
metaFile << "Name: " << meta.name << "\n";
|
||||
metaFile << "ID: " << meta.id << "\n";
|
||||
metaFile << "Type: " << static_cast<int>(meta.type) << std::endl;
|
||||
metaFile << "Type: " << static_cast<AssetTypeMeta>(meta.type) << std::endl;
|
||||
|
||||
//TODO Add in information that is specific to types like mesh
|
||||
switch(meta.type)
|
||||
{
|
||||
case AssetType::MESH:
|
||||
break;
|
||||
////TODO Add in information that is specific to types like mesh
|
||||
//switch(meta.type)
|
||||
//{
|
||||
//case AssetType::MESH:
|
||||
// break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
//default:
|
||||
// break;
|
||||
//}
|
||||
|
||||
metaFile.close();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
//#==============================================================#
|
||||
#include <imgui.h>
|
||||
|
||||
#include "Serialization/SHSerialization.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -181,6 +183,10 @@ namespace SHADE
|
|||
editor->selectedEntities.clear();
|
||||
editor->selectedEntities.push_back(eid);
|
||||
}
|
||||
if(ImGui::Selectable("Copy"))
|
||||
{
|
||||
SHLOG_INFO(SHSerialization::SerializeEntitiesToString(editor->selectedEntities))
|
||||
}
|
||||
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||
{
|
||||
SHEntityManager::DestroyEntity(eid);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include <imgui_internal.h>
|
||||
#include <rttr/type>
|
||||
|
||||
#include "Serialization/SHSerialization.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||
|
@ -73,7 +75,14 @@ namespace SHADE
|
|||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
{
|
||||
|
||||
if(ImGui::Selectable("Save"))
|
||||
{
|
||||
SHSerialization::SerializeSceneToFile("../../Assets/Scenes/Test.SHADE");
|
||||
}
|
||||
if(ImGui::Selectable("Load"))
|
||||
{
|
||||
SHSerialization::DeserializeSceneFromFile("../../Assets/Scenes/Test.SHADE");
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if(ImGui::BeginMenu("Edit"))
|
||||
|
|
|
@ -54,6 +54,7 @@ namespace SHADE
|
|||
windowPos = {wndPos.x, wndPos.y};
|
||||
OnPosChange();
|
||||
}
|
||||
isWindowHovered = ImGui::IsWindowHovered();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace SHADE
|
|||
virtual void Update();
|
||||
virtual void Exit();
|
||||
bool isOpen;
|
||||
bool isWindowHovered;
|
||||
std::string_view windowName;
|
||||
protected:
|
||||
virtual bool Begin();
|
||||
|
@ -34,5 +35,6 @@ namespace SHADE
|
|||
ImGuiIO& io;
|
||||
SHVec2 windowSize;
|
||||
SHVec2 windowPos;
|
||||
SHVec2 viewportMousePos;
|
||||
};//class SHEditorWindow
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -2,7 +2,11 @@
|
|||
#include "SHEditorViewport.h"
|
||||
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/SHEditor.hpp"
|
||||
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -24,8 +28,27 @@ namespace SHADE
|
|||
{
|
||||
DrawMenuBar();
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
//auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
|
||||
//ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize());
|
||||
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
|
||||
auto mousePos = ImGui::GetMousePos();
|
||||
auto cursorPos = ImGui::GetCursorScreenPos();
|
||||
viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y};
|
||||
gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos);
|
||||
//if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||
//{
|
||||
// auto eid = gfxSystem->GetMousePickSystem ()->GetPickedEntity();
|
||||
// if(eid != MAX_EID)
|
||||
// {
|
||||
// auto editor = SHSystemManager::GetSystem<SHEditor>();
|
||||
// editor->selectedEntities.clear();
|
||||
// editor->selectedEntities.push_back(eid);
|
||||
// if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>())
|
||||
// {
|
||||
// hierarchyPanel->SetScrollTo(eid);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize());
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
@ -39,6 +62,11 @@ namespace SHADE
|
|||
{
|
||||
SHEditorWindow::OnResize();
|
||||
//Get graphics system to resize swapchain image
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
|
||||
//auto pos = ImGui::GetCursorPos();
|
||||
//windowCursorPos = {}
|
||||
gfxSystem->PrepareResize(static_cast<uint32_t>(windowSize.x), static_cast<uint32_t>(windowSize.y));
|
||||
}
|
||||
|
||||
void SHEditorViewport::OnPosChange()
|
||||
|
|
|
@ -304,10 +304,11 @@ namespace SHADE
|
|||
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();
|
||||
//auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||
auto const& renderers = gfxSystem->GetEditorViewport()->GetRenderers();
|
||||
|
||||
SHASSERT(!renderers.empty(), "No Renderers available")
|
||||
auto renderGraph = renderers[0]->GetRenderGraph();
|
||||
auto renderGraph = renderers[SHGraphicsConstants::RenderGraphIndices::EDITOR]->GetRenderGraph();
|
||||
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
|
||||
|
||||
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
||||
|
@ -336,7 +337,8 @@ namespace SHADE
|
|||
{
|
||||
if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
|
||||
{
|
||||
if (!ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
|
||||
if (viewportWindow->isWindowHovered && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||
{
|
||||
EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity();
|
||||
if(pickedEID == MAX_EID)
|
||||
|
|
|
@ -67,6 +67,11 @@ namespace SHADE
|
|||
ImGui::Separator();
|
||||
}
|
||||
|
||||
bool SHEditorUI::IsItemHovered()
|
||||
{
|
||||
return ImGui::IsItemHovered();
|
||||
}
|
||||
|
||||
bool SHEditorUI::BeginMenu(const std::string& label)
|
||||
{
|
||||
return ImGui::BeginMenu(label.data());
|
||||
|
@ -82,6 +87,16 @@ namespace SHADE
|
|||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
void SHEditorUI::BeginTooltip()
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
}
|
||||
|
||||
void SHEditorUI::EndTooltip()
|
||||
{
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Pop Ups */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -135,24 +150,30 @@ namespace SHADE
|
|||
return ImGui::Selectable(std::format("{} {}", icon, label).data());
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value)
|
||||
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::Checkbox("#", &value);
|
||||
}
|
||||
bool SHEditorUI::InputInt(const std::string& label, int& value)
|
||||
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputInt("#", &value,
|
||||
1, 10,
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value)
|
||||
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered)
|
||||
{
|
||||
int signedVal = static_cast<int>(value);
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
const bool CHANGED = InputInt("#", signedVal);
|
||||
if (CHANGED)
|
||||
|
@ -162,35 +183,43 @@ namespace SHADE
|
|||
}
|
||||
return CHANGED;
|
||||
}
|
||||
bool SHEditorUI::InputFloat(const std::string& label, float& value)
|
||||
bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputFloat("#", &value,
|
||||
0.1f, 1.0f, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
bool SHEditorUI::InputDouble(const std::string& label, double& value)
|
||||
bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputDouble("#", &value,
|
||||
0.1, 1.0, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
bool SHEditorUI::InputAngle(const std::string& label, double& value)
|
||||
bool SHEditorUI::InputAngle(const std::string& label, double& value, bool* isHovered)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputDouble("#", &value,
|
||||
1.0, 45.0, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value)
|
||||
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered)
|
||||
{
|
||||
float val = static_cast<float>(value);
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
const bool CHANGED = ImGui::SliderFloat("#", &val,
|
||||
static_cast<float>(min), static_cast<float>(max), "%.3f",
|
||||
|
@ -204,22 +233,24 @@ namespace SHADE
|
|||
return CHANGED;
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value)
|
||||
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered)
|
||||
{
|
||||
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y" };
|
||||
return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y });
|
||||
return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y }, 0.1f, "%.3f", float{}, float{}, 0, isHovered);
|
||||
}
|
||||
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, float speed)
|
||||
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered, float speed)
|
||||
{
|
||||
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"};
|
||||
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f");
|
||||
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f", float{}, float{}, 0, isHovered);
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputTextField(const std::string& label, std::string& value)
|
||||
bool SHEditorUI::InputTextField(const std::string& label, std::string& value, bool* isHovered)
|
||||
{
|
||||
std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' };
|
||||
strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str());
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
||||
if (CHANGED)
|
||||
|
@ -229,13 +260,15 @@ namespace SHADE
|
|||
return CHANGED;
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames)
|
||||
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered)
|
||||
{
|
||||
// Clamp input value
|
||||
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
|
||||
bool b = false;
|
||||
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
||||
{
|
||||
|
|
|
@ -90,12 +90,19 @@ namespace SHADE
|
|||
static void SameLine();
|
||||
static void Separator();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Queries */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static bool IsItemHovered();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Menu */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static bool BeginMenu(const std::string& label);
|
||||
static bool BeginMenu(const std::string& label, const char* icon);
|
||||
static void EndMenu();
|
||||
static void BeginTooltip();
|
||||
static void EndTooltip();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Pop Ups */
|
||||
|
@ -165,8 +172,9 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputCheckbox(const std::string& label, bool& value);
|
||||
static bool InputCheckbox(const std::string& label, bool& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a integer field widget for integer input.
|
||||
/// <br/>
|
||||
|
@ -174,8 +182,9 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputInt(const std::string& label, int& value);
|
||||
static bool InputInt(const std::string& label, int& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a integer field widget for unsigned integer input.
|
||||
/// <br/>
|
||||
|
@ -186,8 +195,9 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputUnsignedInt(const std::string& label, unsigned int& value);
|
||||
static bool InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a decimal field widget for single precision float input.
|
||||
/// <br/>
|
||||
|
@ -195,8 +205,9 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputFloat(const std::string& label, float& value);
|
||||
static bool InputFloat(const std::string& label, float& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a decimal field widget for double precision float input.
|
||||
/// <br/>
|
||||
|
@ -204,8 +215,9 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputDouble(const std::string& label, double& value);
|
||||
static bool InputDouble(const std::string& label, double& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a decimal field widget for double input with increments of higher
|
||||
/// steps meant for angle variables.
|
||||
|
@ -214,8 +226,9 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputAngle(const std::string& label, double& value);
|
||||
static bool InputAngle(const std::string& label, double& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a double slider field widget for double input.
|
||||
/// <br/>
|
||||
|
@ -225,8 +238,9 @@ namespace SHADE
|
|||
/// <param name="min">Minimum value of the slider.</param>
|
||||
/// <param name="max">Maximum value of the slider.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputSlider(const std::string& label, double min, double max, double& value);
|
||||
static bool InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a 2x double field widget for Vector2 input.
|
||||
/// <br/>
|
||||
|
@ -234,8 +248,9 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputVec2(const std::string& label, SHVec2& value);
|
||||
static bool InputVec2(const std::string& label, SHVec2& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a 3x double field widget for Vector3 input.
|
||||
/// <br/>
|
||||
|
@ -243,8 +258,9 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputVec3(const std::string& label, SHVec3& value, float speed = 0.1f);
|
||||
static bool InputVec3(const std::string& label, SHVec3& value, bool* isHovered = nullptr, float speed = 0.1f);
|
||||
/// <summary>
|
||||
/// Creates a text field widget for string input.
|
||||
/// <br/>
|
||||
|
@ -252,8 +268,9 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputTextField(const std::string& label, std::string& value);
|
||||
static bool InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a combo box for enumeration input.
|
||||
/// </summary>
|
||||
|
@ -264,17 +281,19 @@ namespace SHADE
|
|||
/// <param name="toStrFn">
|
||||
/// Conversion function from the type of enum to C-style string.
|
||||
/// </param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>Whether the value was modified.</returns>
|
||||
template<typename Enum>
|
||||
static bool InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char*(Enum)> toStrFn);
|
||||
static bool InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char*(Enum)> toStrFn, bool* isHovered = nullptr);
|
||||
/// <summary>
|
||||
/// Creates a combo box for enumeration input using a specified list of names.
|
||||
/// </summary>
|
||||
/// <param name="label">The name of the input.</param>
|
||||
/// <param name="v">The reference to the value to modify.</param>
|
||||
/// <param name="enumNames">Vector of names for each enumeration value.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <returns>Whether the value was modified.</returns>
|
||||
static bool InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames);
|
||||
static bool InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered = nullptr);
|
||||
|
||||
|
||||
private:
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace SHADE
|
|||
/* ImGui Wrapper Functions - Widgets */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
template<typename Enum>
|
||||
inline bool SHEditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char* (Enum)> toStrFn)
|
||||
inline bool SHEditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char* (Enum)> toStrFn, bool* isHovered)
|
||||
{
|
||||
std::vector<Enum> values;
|
||||
for (int i = 0; i <= maxVal; ++i)
|
||||
|
@ -28,6 +28,11 @@ namespace SHADE
|
|||
values.emplace_back(static_cast<Enum>(i));
|
||||
}
|
||||
bool b = false;
|
||||
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::BeginCombo(label.c_str(), toStrFn(v), ImGuiComboFlags_None))
|
||||
{
|
||||
for (int i = 0; i <= maxVal; ++i)
|
||||
|
|
|
@ -160,7 +160,7 @@ namespace SHADE
|
|||
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)
|
||||
ImGuiSliderFlags flags = 0, bool* isHovered = nullptr)
|
||||
{
|
||||
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
|
@ -174,6 +174,8 @@ namespace SHADE
|
|||
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
|
||||
ImGui::SetColumnWidth(-1, 80.0f);
|
||||
ImGui::Text(fieldLabel.c_str());
|
||||
if (isHovered)
|
||||
*isHovered = ImGui::IsItemHovered();
|
||||
ImGui::NextColumn();
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
{
|
||||
|
|
|
@ -99,7 +99,7 @@ namespace SHADE
|
|||
|
||||
void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message) noexcept
|
||||
{
|
||||
SHLOGV_INFO(message);
|
||||
//SHLOGV_INFO(message);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -172,7 +172,7 @@ namespace SHADE
|
|||
// write sampler and image view
|
||||
auto& [view, sampler, layout] = imageViewsAndSamplers[i];
|
||||
writeInfo.descImageInfos[i].imageView = view->GetImageView();
|
||||
writeInfo.descImageInfos[i].sampler = sampler->GetVkSampler();
|
||||
writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
||||
writeInfo.descImageInfos[i].imageLayout = layout;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
#include "SHPch.h"
|
||||
#include "SHVkDescriptorSetLayout.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/Images/SHVkSampler.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructor/Destructor */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex set, const std::vector<Binding>& bindings)
|
||||
SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex set, const std::vector<Binding>& bindings, bool genImmutableSamplers/* = false*/)
|
||||
: device { device }
|
||||
, layoutDesc { bindings }
|
||||
, setIndex {set}
|
||||
, immutableSampler{}
|
||||
{
|
||||
// Check if auto-binding point calculation configuration is valid
|
||||
bool autoCalc = false;
|
||||
|
@ -26,6 +28,25 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
vk::Sampler tempVkSampler = nullptr;
|
||||
if (genImmutableSamplers)
|
||||
{
|
||||
// Create sampler
|
||||
immutableSampler = device->CreateSampler(
|
||||
{
|
||||
.minFilter = vk::Filter::eLinear,
|
||||
.magFilter = vk::Filter::eLinear,
|
||||
.addressMode = vk::SamplerAddressMode::eRepeat,
|
||||
.mipmapMode = vk::SamplerMipmapMode::eLinear,
|
||||
.minLod = -1000,
|
||||
.maxLod = 1000
|
||||
}
|
||||
);
|
||||
|
||||
tempVkSampler = immutableSampler->GetVkSampler();
|
||||
}
|
||||
|
||||
|
||||
// Fill up VK bindings with auto calculated bind points if needed
|
||||
std::vector<vk::DescriptorSetLayoutBinding> layoutBindings;
|
||||
layoutBindings.reserve(bindings.size());
|
||||
|
@ -39,7 +60,7 @@ namespace SHADE
|
|||
.descriptorType = binding.Type,
|
||||
.descriptorCount = binding.DescriptorCount,
|
||||
.stageFlags = binding.Stage,
|
||||
.pImmutableSamplers = nullptr // We will create our own samplers
|
||||
.pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr,
|
||||
};
|
||||
layoutBindings.emplace_back(VK_BINDING);
|
||||
|
||||
|
@ -75,7 +96,8 @@ namespace SHADE
|
|||
: device {rhs.device}
|
||||
, setLayout {rhs.setLayout}
|
||||
, layoutDesc{std::move (rhs.layoutDesc)}
|
||||
, setIndex {rhs.setIndex}
|
||||
, setIndex{ rhs.setIndex }
|
||||
, immutableSampler{ rhs.immutableSampler }
|
||||
{
|
||||
rhs.setLayout = VK_NULL_HANDLE;
|
||||
}
|
||||
|
@ -106,6 +128,7 @@ namespace SHADE
|
|||
setLayout = rhs.setLayout;
|
||||
layoutDesc = std::move(rhs.layoutDesc);
|
||||
setIndex = rhs.setIndex;
|
||||
immutableSampler = rhs.immutableSampler;
|
||||
|
||||
rhs.setLayout = VK_NULL_HANDLE;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace SHADE
|
|||
/* Forward Declarations */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
class SHVkLogicalDevice;
|
||||
class SHVkSampler;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
|
@ -74,7 +75,7 @@ namespace SHADE
|
|||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="bindings"></param>
|
||||
SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex setIndex, const std::vector<Binding>& bindings);
|
||||
SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex setIndex, const std::vector<Binding>& bindings, bool genImmutableSamplers = false);
|
||||
SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete;
|
||||
SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept;
|
||||
/// <summary>
|
||||
|
@ -107,5 +108,6 @@ namespace SHADE
|
|||
vk::DescriptorSetLayout setLayout;
|
||||
std::vector<Binding> layoutDesc; // Stores description of the layout
|
||||
SetIndex setIndex; // Index of the set
|
||||
Handle<SHVkSampler> immutableSampler;
|
||||
};
|
||||
}
|
|
@ -550,10 +550,9 @@ namespace SHADE
|
|||
|
||||
}
|
||||
|
||||
Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept
|
||||
Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers/* = false*/) noexcept
|
||||
{
|
||||
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex, bindings);
|
||||
|
||||
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex, bindings, genImmutableSamplers);
|
||||
}
|
||||
|
||||
Handle<SHVkDescriptorPool> SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept
|
||||
|
|
|
@ -186,7 +186,7 @@ namespace SHADE
|
|||
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept;
|
||||
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::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<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept;
|
||||
Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers = false) noexcept;
|
||||
Handle<SHVkDescriptorPool> CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept;
|
||||
Handle<SHVkDescriptorSetGroup> CreateDescriptorSetGroup(Handle<SHVkDescriptorPool> pool,
|
||||
std::vector<Handle<SHVkDescriptorSetLayout>> const& layouts,
|
||||
|
|
|
@ -24,14 +24,15 @@ namespace SHADE
|
|||
{
|
||||
const vk::SamplerCreateInfo SAMPLER_CREATE_INFO
|
||||
{
|
||||
.magFilter = params.magFilter,
|
||||
.minFilter = params.minFilter,
|
||||
.mipmapMode = params.mipmapMode,
|
||||
.addressModeU = params.addressMode,
|
||||
.addressModeV = params.addressMode,
|
||||
.addressModeW = params.addressMode,
|
||||
.minLod = params.minLod,
|
||||
.maxLod = params.maxLod
|
||||
.magFilter = params.magFilter,
|
||||
.minFilter = params.minFilter,
|
||||
.mipmapMode = params.mipmapMode,
|
||||
.addressModeU = params.addressMode,
|
||||
.addressModeV = params.addressMode,
|
||||
.addressModeW = params.addressMode,
|
||||
.maxAnisotropy = 1.0f,
|
||||
.minLod = params.minLod,
|
||||
.maxLod = params.maxLod,
|
||||
};
|
||||
|
||||
// Create the sampler
|
||||
|
@ -39,7 +40,8 @@ namespace SHADE
|
|||
}
|
||||
|
||||
SHVkSampler::SHVkSampler(SHVkSampler&& rhs) noexcept
|
||||
: vkSampler { rhs.vkSampler }
|
||||
: vkSampler{ rhs.vkSampler }
|
||||
, device{ rhs.device }
|
||||
{
|
||||
rhs.vkSampler = nullptr;
|
||||
}
|
||||
|
@ -56,6 +58,7 @@ namespace SHADE
|
|||
SHADE::SHVkSampler& SHVkSampler::operator=(SHVkSampler&& rhs) noexcept
|
||||
{
|
||||
vkSampler = rhs.vkSampler;
|
||||
device = rhs.device;
|
||||
rhs.vkSampler = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,12 @@ namespace SHADE
|
|||
struct SHGraphicsConstants
|
||||
{
|
||||
public:
|
||||
struct RenderGraphIndices
|
||||
{
|
||||
static constexpr uint32_t WORLD = 0;
|
||||
static constexpr uint32_t EDITOR = 0;
|
||||
};
|
||||
|
||||
struct DescriptorSetIndex
|
||||
{
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -36,11 +36,9 @@ of DigiPen Institute of Technology is prohibited.
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
#pragma region INIT_EXIT
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructor/Destructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHGraphicsSystem::Init(void)
|
||||
void SHGraphicsSystem::InitBoilerplate(void) noexcept
|
||||
{
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* BACKEND BOILERPLATE */
|
||||
|
@ -51,7 +49,7 @@ namespace SHADE
|
|||
// Get Physical Device and Construct Logical Device
|
||||
physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST);
|
||||
device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice);
|
||||
|
||||
|
||||
// Construct surface
|
||||
surface = device->CreateSurface(window->GetHWND());
|
||||
|
||||
|
@ -71,7 +69,15 @@ namespace SHADE
|
|||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
renderContext.SetIsResized(true);
|
||||
#ifdef SHEDITOR
|
||||
|
||||
//PrepareResize(1, 1, SHVec2(0, 0));
|
||||
|
||||
#else
|
||||
|
||||
PrepareResize(resizeWidth, resizeHeight, SHVec2(0, 0));
|
||||
|
||||
#endif
|
||||
});
|
||||
|
||||
window->RegisterWindowCloseCallback([&](void)
|
||||
|
@ -106,11 +112,12 @@ namespace SHADE
|
|||
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
||||
{
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* MIDDLE END SETUP
|
||||
/* MIDDLE END SETUP
|
||||
- Viewports
|
||||
- Renderer
|
||||
- Render graph in renderers
|
||||
|
@ -118,8 +125,8 @@ namespace SHADE
|
|||
- Default vertex input state
|
||||
- Global data
|
||||
/*-----------------------------------------------------------------------*/
|
||||
auto windowDims = window->GetWindowSize();
|
||||
|
||||
SHGraphicsGlobalData::Init(device);
|
||||
|
||||
// Set Up Cameras
|
||||
screenCamera = resourceManager.Create<SHCamera>();
|
||||
|
@ -131,12 +138,12 @@ namespace SHADE
|
|||
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
||||
|
||||
// Create Default Viewport
|
||||
defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
|
||||
|
||||
worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
|
||||
|
||||
// Get render graph from default viewport world renderer
|
||||
worldRenderGraph = resourceManager.Create<SHRenderGraph>();
|
||||
|
||||
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{swapchain->GetNumImages()};
|
||||
|
||||
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
|
||||
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
||||
{
|
||||
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
|
||||
|
@ -144,44 +151,27 @@ namespace SHADE
|
|||
|
||||
// Initialize world render graph
|
||||
worldRenderGraph->Init(device, swapchain);
|
||||
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||
worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second);
|
||||
worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||
|
||||
//worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||
//worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||
//worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||
//worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm);
|
||||
auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Present"}, {}); // no predecessors
|
||||
auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors
|
||||
|
||||
//First subpass to write to G-Buffer
|
||||
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
||||
gBufferWriteSubpass->AddColorOutput("Present");
|
||||
gBufferWriteSubpass->AddColorOutput("Scene");
|
||||
gBufferWriteSubpass->AddColorOutput("Entity ID");
|
||||
gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL);
|
||||
gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
||||
|
||||
// We do this to just transition our scene layout to shader read
|
||||
auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition");
|
||||
sceneLayoutTransitionSubpass->AddInput("Scene");
|
||||
|
||||
// TODO: Use macro to add this node when SH_EDITOR is enabled
|
||||
auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"});
|
||||
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
|
||||
imguiSubpass->AddColorOutput("Present");
|
||||
|
||||
// Generate world render graph
|
||||
worldRenderGraph->Generate();
|
||||
|
||||
// Create Semaphore
|
||||
for (auto& semaHandle : graphSemaphores)
|
||||
{
|
||||
semaHandle = device->CreateSemaphore();
|
||||
}
|
||||
|
||||
// Create Debug Renderers
|
||||
/*debugScreenRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph);
|
||||
debugScreenRenderer->SetCamera(screenCamera);
|
||||
debugWorldRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph);
|
||||
debugWorldRenderer->SetCamera(worldCamera);*/
|
||||
|
||||
// Add world renderer to default viewport
|
||||
worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
||||
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
||||
worldRenderer->SetCamera(worldCamera);
|
||||
|
||||
|
||||
|
@ -198,17 +188,97 @@ namespace SHADE
|
|||
cubeFS->Reflect();
|
||||
|
||||
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
||||
{
|
||||
SHGraphicsGlobalData::Init(device);
|
||||
|
||||
InitSceneRenderGraph();
|
||||
|
||||
#ifdef SHEDITOR
|
||||
InitEditorRenderGraph();
|
||||
#endif
|
||||
|
||||
// Create Semaphore
|
||||
for (auto& semaHandle : graphSemaphores)
|
||||
{
|
||||
semaHandle = device->CreateSemaphore();
|
||||
}
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::InitSubsystems(void) noexcept
|
||||
{
|
||||
|
||||
mousePickSystem = resourceManager.Create<SHMousePickSystem>();
|
||||
|
||||
std::vector<Handle<SHVkCommandPool>> cmdPools;
|
||||
cmdPools.reserve(swapchain->GetNumImages());
|
||||
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
|
||||
cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]);
|
||||
cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]);
|
||||
|
||||
mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID"));
|
||||
|
||||
// Register the post offscreen render to the system
|
||||
postOffscreenRender = resourceManager.Create<SHPostOffscreenRenderSystem>();
|
||||
postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool);
|
||||
}
|
||||
|
||||
#ifdef SHEDITOR
|
||||
void SHGraphicsSystem::InitEditorRenderGraph(void) noexcept
|
||||
{
|
||||
auto windowDims = window->GetWindowSize();
|
||||
|
||||
// Create Default Viewport
|
||||
editorViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 1.0f));
|
||||
|
||||
// Get render graph from viewport editor renderer
|
||||
editorRenderGraph = resourceManager.Create<SHRenderGraph>();
|
||||
|
||||
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
|
||||
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
||||
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
|
||||
|
||||
editorRenderGraph->Init(device, swapchain);
|
||||
editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
|
||||
|
||||
|
||||
auto imguiNode = editorRenderGraph->AddNode("ImGui Node", { "Present"}, {});
|
||||
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
|
||||
imguiSubpass->AddColorOutput("Present");
|
||||
|
||||
// Generate world render graph
|
||||
editorRenderGraph->Generate();
|
||||
|
||||
// Add world renderer to default viewport
|
||||
editorRenderer = editorViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], editorRenderGraph);
|
||||
editorRenderer->SetCamera(worldCamera);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructor/Destructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void SHGraphicsSystem::Init(void)
|
||||
{
|
||||
InitBoilerplate();
|
||||
InitMiddleEnd();
|
||||
InitSubsystems();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::Exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
#pragma endregion INIT_EXIT
|
||||
|
||||
#pragma region LIFECYCLE
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Lifecycle Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
@ -227,12 +297,6 @@ namespace SHADE
|
|||
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||
return;
|
||||
|
||||
if (renderContext.GetResized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Frame data for the current frame
|
||||
auto const& frameData = renderContext.GetCurrentFrameData();
|
||||
uint32_t frameIndex = renderContext.GetCurrentFrame();
|
||||
|
@ -328,14 +392,7 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::Exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Lifecycle Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
|
@ -400,12 +457,6 @@ namespace SHADE
|
|||
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||
return;
|
||||
|
||||
if (renderContext.GetResized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
|
||||
auto& currFrameData = renderContext.GetCurrentFrameData();
|
||||
|
||||
|
@ -417,9 +468,7 @@ namespace SHADE
|
|||
// If swapchain is incompatible/outdated
|
||||
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
|
||||
{
|
||||
|
||||
HandleResize();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -427,6 +476,10 @@ namespace SHADE
|
|||
renderContext.AdvanceFrame();
|
||||
}
|
||||
|
||||
#pragma endregion LIFECYCLE
|
||||
|
||||
#pragma region ADD_REMOVE_BUILD
|
||||
|
||||
Handle<SHViewport> SHGraphicsSystem::AddViewport(const vk::Viewport& viewport)
|
||||
{
|
||||
// Create the viewport
|
||||
|
@ -537,36 +590,9 @@ namespace SHADE
|
|||
);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::HandleResize(void) noexcept
|
||||
{
|
||||
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||
return;
|
||||
|
||||
auto windowDims = window->GetWindowSize();
|
||||
|
||||
// Resize the swapchain
|
||||
swapchain->Resize(surface, windowDims.first, windowDims.second);
|
||||
|
||||
renderContext.HandleResize();
|
||||
|
||||
worldRenderGraph->HandleResize(windowDims.first, windowDims.second);
|
||||
|
||||
defaultViewport->SetWidth(static_cast<float>(windowDims.first));
|
||||
defaultViewport->SetHeight(static_cast<float>(windowDims.second));
|
||||
|
||||
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::AwaitGraphicsExecution()
|
||||
{
|
||||
device->WaitIdle();
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
|
||||
{
|
||||
window = wind;
|
||||
}
|
||||
#pragma endregion ADD_REMOVE
|
||||
|
||||
#pragma region ROUTINES
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* System Routine Functions - BeginRoutine */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -638,5 +664,62 @@ namespace SHADE
|
|||
renderable.ResetChangedFlag();
|
||||
}
|
||||
}
|
||||
#pragma endregion ROUTINES
|
||||
|
||||
#pragma region MISC
|
||||
|
||||
void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept
|
||||
{
|
||||
resizeWidth = newWidth;
|
||||
resizeHeight = newHeight;
|
||||
|
||||
renderContext.SetIsResized(true);
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::HandleResize(void) noexcept
|
||||
{
|
||||
device->WaitIdle();
|
||||
|
||||
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||
return;
|
||||
|
||||
graphSemaphores[0].Free();
|
||||
graphSemaphores[1].Free();
|
||||
|
||||
auto windowDims = window->GetWindowSize();
|
||||
|
||||
// Resize the swapchain
|
||||
swapchain->Resize(surface, windowDims.first, windowDims.second);
|
||||
|
||||
renderContext.HandleResize();
|
||||
|
||||
worldRenderGraph->HandleResize(resizeWidth, resizeHeight);
|
||||
editorRenderGraph->HandleResize(windowDims.first, windowDims.second);
|
||||
|
||||
mousePickSystem->HandleResize();
|
||||
postOffscreenRender->HandleResize();
|
||||
|
||||
worldViewport->SetWidth(static_cast<float>(resizeWidth));
|
||||
worldViewport->SetHeight(static_cast<float>(resizeHeight));
|
||||
|
||||
worldCamera->SetPerspective(90.0f, static_cast<float>(resizeWidth), static_cast<float>(resizeHeight), 0.0f, 100.0f);
|
||||
|
||||
for (auto& semaHandle : graphSemaphores)
|
||||
semaHandle = device->CreateSemaphore();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::AwaitGraphicsExecution()
|
||||
{
|
||||
device->WaitIdle();
|
||||
}
|
||||
|
||||
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
|
||||
{
|
||||
window = wind;
|
||||
}
|
||||
|
||||
|
||||
#pragma endregion MISC
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
|
||||
#include "../Textures/SHTextureLibrary.h"
|
||||
#include "../Textures/SHVkSamplerCache.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -66,6 +67,16 @@ namespace SHADE
|
|||
/***********************************************************************************/
|
||||
class SH_API SHGraphicsSystem : public SHSystem
|
||||
{
|
||||
private:
|
||||
void InitBoilerplate (void) noexcept;
|
||||
void InitSceneRenderGraph (void) noexcept;
|
||||
void InitMiddleEnd (void) noexcept;
|
||||
void InitSubsystems (void) noexcept;
|
||||
|
||||
#ifdef SHEDITOR
|
||||
void InitEditorRenderGraph (void) noexcept;
|
||||
#endif
|
||||
|
||||
public:
|
||||
class SH_API BeginRoutine final : public SHSystemRoutine
|
||||
{
|
||||
|
@ -251,6 +262,7 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
void BuildTextures();
|
||||
|
||||
void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||
void HandleResize(void) noexcept;
|
||||
void AwaitGraphicsExecution();
|
||||
|
||||
|
@ -262,20 +274,25 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
/* Getters (Temporary) */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Handle<SHVkLogicalDevice> GetDevice() const { return device; }
|
||||
Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; }
|
||||
Handle<SHVkSurface> GetSurface() const { return surface; }
|
||||
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
|
||||
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
|
||||
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
|
||||
Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;}
|
||||
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
|
||||
Handle<SHVkLogicalDevice> GetDevice() const { return device; }
|
||||
Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; }
|
||||
Handle<SHVkSurface> GetSurface() const { return surface; }
|
||||
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
|
||||
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
|
||||
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
|
||||
Handle<SHViewport> GetDefaultViewport() const {return worldViewport;}
|
||||
#ifdef SHEDITOR
|
||||
Handle<SHViewport> GetEditorViewport () const {return editorViewport;};
|
||||
#endif
|
||||
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
|
||||
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
|
||||
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
|
||||
|
||||
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -296,13 +313,19 @@ namespace SHADE
|
|||
SHWindow* window = nullptr;
|
||||
|
||||
// Middle End Resources
|
||||
ResourceManager resourceManager;
|
||||
ResourceManager resourceManager;
|
||||
SHMeshLibrary meshLibrary;
|
||||
SHTextureLibrary texLibrary;
|
||||
SHSamplerCache samplerCache;
|
||||
SHMaterialInstanceCache materialInstanceCache;
|
||||
// Viewports
|
||||
Handle<SHViewport> defaultViewport; // Whole screen
|
||||
#ifdef SHEDITOR
|
||||
Handle<SHViewport> editorViewport;
|
||||
Handle<SHRenderer> editorRenderer;
|
||||
Handle<SHRenderGraph> editorRenderGraph;
|
||||
#endif
|
||||
|
||||
Handle<SHViewport> worldViewport; // Whole screen
|
||||
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
||||
|
||||
// Debug Renderers
|
||||
|
@ -327,5 +350,9 @@ namespace SHADE
|
|||
|
||||
// Sub systems
|
||||
Handle<SHMousePickSystem> mousePickSystem;
|
||||
Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
|
||||
|
||||
uint32_t resizeWidth;
|
||||
uint32_t resizeHeight;
|
||||
};
|
||||
}
|
|
@ -6,11 +6,16 @@
|
|||
#include "Graphics/Synchronization/SHVkFence.h"
|
||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||
#include "Graphics/SHVkUtil.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHMousePickSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept
|
||||
void SHMousePickSystem::Init(Handle<SHVkLogicalDevice> device, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept
|
||||
{
|
||||
logicalDevice = device;
|
||||
|
||||
pickedEID = MAX_EID;
|
||||
|
||||
// Create command buffers
|
||||
for (auto& pool : cmdPools)
|
||||
{
|
||||
|
@ -20,13 +25,7 @@ namespace SHADE
|
|||
// assign the attachment
|
||||
entityIDAttachment = eidAttachment;
|
||||
|
||||
// Create the fence
|
||||
afterCopyFence = logicalDevice->CreateFence();
|
||||
|
||||
uint32_t bufferSize = entityIDAttachment->GetWidth() * eidAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
|
||||
|
||||
// Create the buffer
|
||||
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
||||
HandleResize();
|
||||
}
|
||||
|
||||
void SHMousePickSystem::Run(Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept
|
||||
|
@ -54,13 +53,36 @@ namespace SHADE
|
|||
// wait for the copy to be done
|
||||
afterCopyFence->Wait(true, std::numeric_limits<uint64_t>::max());
|
||||
|
||||
int mouseX = 0, mouseY = 0;
|
||||
SHInputManager::GetMouseWindowPosition(&mouseX, &mouseY);
|
||||
pickedEID = imageDataDstBuffer->GetDataFromMappedPointer<uint32_t>(static_cast<uint32_t>(viewportMousePos.y) * entityIDAttachment->GetWidth() + static_cast<uint32_t>(viewportMousePos.x));
|
||||
|
||||
pickedEID = imageDataDstBuffer->GetDataFromMappedPointer<uint32_t>(mouseY * entityIDAttachment->GetWidth() + mouseX);
|
||||
}
|
||||
}
|
||||
|
||||
void SHMousePickSystem::HandleResize(void) noexcept
|
||||
{
|
||||
if (afterCopyFence)
|
||||
{
|
||||
afterCopyFence->Reset();
|
||||
afterCopyFence.Free();
|
||||
}
|
||||
|
||||
if (imageDataDstBuffer)
|
||||
imageDataDstBuffer.Free();
|
||||
|
||||
// Create the fence
|
||||
afterCopyFence = logicalDevice->CreateFence();
|
||||
|
||||
uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
|
||||
|
||||
// Create the buffer
|
||||
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
||||
}
|
||||
|
||||
void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept
|
||||
{
|
||||
viewportMousePos = vpMousePos;
|
||||
}
|
||||
|
||||
EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept
|
||||
{
|
||||
return pickedEID;
|
||||
|
|
|
@ -13,10 +13,13 @@ namespace SHADE
|
|||
class SHVkFence;
|
||||
class SHVkQueue;
|
||||
class SHVkBuffer;
|
||||
class SHViewport;
|
||||
|
||||
class SHMousePickSystem
|
||||
{
|
||||
private:
|
||||
Handle<SHVkLogicalDevice> logicalDevice;
|
||||
|
||||
//! Handle to the render graph resource that will contain the entity IDs
|
||||
Handle<SHRenderGraphResource> entityIDAttachment;
|
||||
|
||||
|
@ -30,17 +33,24 @@ namespace SHADE
|
|||
Handle<SHVkBuffer> imageDataDstBuffer;
|
||||
|
||||
//! eid picked from screen
|
||||
EntityID pickedEID = MAX_EID;
|
||||
EntityID pickedEID;
|
||||
|
||||
//! mouse position relative to the viewport window displaying the world
|
||||
SHVec2 viewportMousePos;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept;
|
||||
void Init(Handle<SHVkLogicalDevice> device, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept;
|
||||
void Run (Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept;
|
||||
void HandleResize (void) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void SetViewportMousePos (SHVec2 vpMousePos) noexcept;
|
||||
|
||||
EntityID GetPickedEntity (void) const noexcept;
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHPostOffscreenRenderSystem.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/Images/SHVkSampler.h"
|
||||
#include "Graphics/RenderGraph/SHRenderGraphResource.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
This function basically creates the entities required for offscreen
|
||||
rendering. It takes in a render graph resource. Side note: it creates
|
||||
a descriptor set layout that is similar to the one created in imgui. This
|
||||
is so that the descriptor set passed to imGui won't be invalid.
|
||||
|
||||
\param logicalDevice
|
||||
For vulkan object creation
|
||||
|
||||
\param renderGraphResource
|
||||
The resource in which has been
|
||||
|
||||
\param descriptorPool
|
||||
|
||||
\return
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHPostOffscreenRenderSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHRenderGraphResource> renderGraphResource, Handle<SHVkDescriptorPool> descriptorPool) noexcept
|
||||
{
|
||||
offscreenRender = renderGraphResource;
|
||||
|
||||
// Create sampler
|
||||
offscreenRenderSampler = logicalDevice->CreateSampler(
|
||||
{
|
||||
.minFilter = vk::Filter::eLinear,
|
||||
.magFilter = vk::Filter::eLinear,
|
||||
.addressMode = vk::SamplerAddressMode::eRepeat,
|
||||
.mipmapMode = vk::SamplerMipmapMode::eLinear,
|
||||
.minLod = -1000,
|
||||
.maxLod = 1000
|
||||
}
|
||||
);
|
||||
|
||||
// Create descriptor set layout binding
|
||||
SHVkDescriptorSetLayout::Binding imageBinding
|
||||
{
|
||||
.Type = vk::DescriptorType::eCombinedImageSampler,
|
||||
.Stage = vk::ShaderStageFlagBits::eFragment,
|
||||
.BindPoint = 0,
|
||||
.DescriptorCount = 1,
|
||||
};
|
||||
|
||||
// Create descriptor set layout
|
||||
offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, false);
|
||||
|
||||
// Create descriptor set
|
||||
offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 });
|
||||
|
||||
HandleResize();
|
||||
}
|
||||
|
||||
void SHPostOffscreenRenderSystem::HandleResize(void) noexcept
|
||||
{
|
||||
std::vector combinedImageSampler
|
||||
{
|
||||
std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal),
|
||||
};
|
||||
|
||||
// Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change
|
||||
offscreenRenderDescSet->ModifyWriteDescImage(0, 0, combinedImageSampler);
|
||||
offscreenRenderDescSet->UpdateDescriptorSetImages(0, 0);
|
||||
}
|
||||
|
||||
Handle<SHVkDescriptorSetGroup> SHPostOffscreenRenderSystem::GetDescriptorSetGroup(void) const noexcept
|
||||
{
|
||||
return offscreenRenderDescSet;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "Resource/Handle.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHVkLogicalDevice;
|
||||
class SHVkDescriptorSetLayout;
|
||||
class SHVkDescriptorSetGroup;
|
||||
class SHVkDescriptorPool;
|
||||
class SHVkSampler;
|
||||
class SHRenderGraphResource;
|
||||
|
||||
class SHPostOffscreenRenderSystem
|
||||
{
|
||||
private:
|
||||
Handle<SHRenderGraphResource> offscreenRender;
|
||||
|
||||
Handle<SHVkDescriptorSetLayout> offscreenRenderDescSetLayout;
|
||||
Handle<SHVkDescriptorSetGroup> offscreenRenderDescSet;
|
||||
Handle<SHVkSampler> offscreenRenderSampler;
|
||||
|
||||
public:
|
||||
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHRenderGraphResource> renderGraphResource, Handle<SHVkDescriptorPool> descriptorPool) noexcept;
|
||||
//void Run ()
|
||||
|
||||
void HandleResize (void) noexcept;
|
||||
|
||||
Handle<SHVkDescriptorSetGroup> GetDescriptorSetGroup (void) const noexcept;
|
||||
};
|
||||
}
|
|
@ -75,12 +75,15 @@ namespace SHADE
|
|||
|
||||
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||
{
|
||||
cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
|
||||
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
|
||||
if (camera)
|
||||
{
|
||||
cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
|
||||
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
|
||||
|
||||
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
|
||||
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
|
||||
|
||||
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
||||
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
||||
}
|
||||
}
|
||||
|
||||
void SHRenderer::UpdateCameraDataToBuffer(void) noexcept
|
||||
|
|
|
@ -85,4 +85,14 @@ namespace SHADE
|
|||
|
||||
}
|
||||
|
||||
void SHViewport::SetX(float x) noexcept
|
||||
{
|
||||
viewport.x = x;
|
||||
}
|
||||
|
||||
void SHViewport::SetY(float y) noexcept
|
||||
{
|
||||
viewport.y = y;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
void SetWidth(float w) noexcept;
|
||||
void SetHeight (float h) noexcept;
|
||||
void SetX (float x) noexcept;
|
||||
void SetY (float y) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Getters */
|
||||
|
|
|
@ -52,7 +52,6 @@ namespace SHADE
|
|||
{
|
||||
frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Initialize all the info.
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHAttachmentDescInitParams.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "Resource/Handle.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHRenderGraphResource;
|
||||
|
||||
struct SHAttachmentDescInitParams
|
||||
{
|
||||
Handle<SHRenderGraphResource> resourceHdl;
|
||||
bool dontClearOnLoad{false};
|
||||
};
|
||||
}
|
|
@ -3,12 +3,13 @@
|
|||
namespace SHADE
|
||||
{
|
||||
// Used for attachment description creation for renderpass node
|
||||
enum class SH_ATT_DESC_TYPE
|
||||
enum class SH_ATT_DESC_TYPE_FLAGS
|
||||
{
|
||||
COLOR,
|
||||
COLOR_PRESENT,
|
||||
DEPTH,
|
||||
STENCIL,
|
||||
DEPTH_STENCIL,
|
||||
COLOR = 0x01,
|
||||
COLOR_PRESENT = 0x02,
|
||||
DEPTH = 0x04,
|
||||
STENCIL = 0x08,
|
||||
DEPTH_STENCIL = 0x10,
|
||||
INPUT = 0x20
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,10 +8,17 @@
|
|||
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||
#include "Tools/SHLogger.h"
|
||||
#include "SHAttachmentDescInitParams.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
|
||||
SHRenderGraph::ResourceInstruction::ResourceInstruction(char const* resourceName, bool dontClearOnLoad /*= false*/) noexcept
|
||||
: resourceName{ resourceName }
|
||||
, dontClearOnLoad{ dontClearOnLoad }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
@ -40,7 +47,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
|
||||
void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
|
||||
{
|
||||
// If we set to
|
||||
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
||||
|
@ -50,7 +57,7 @@ namespace SHADE
|
|||
format = swapchainHdl->GetSurfaceFormatKHR().format;
|
||||
}
|
||||
|
||||
graphResources.try_emplace(resourceName, resourceManager.Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, usageFlags, createFlags));
|
||||
graphResources.try_emplace(resourceName, resourceManager->Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags));
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -82,7 +89,7 @@ namespace SHADE
|
|||
{
|
||||
for (auto& color : subpass->colorReferences)
|
||||
{
|
||||
if (i == nodes.size() - 1 && node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)))
|
||||
resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
||||
else
|
||||
resourceAttLayouts[color.attachment] = color.layout;
|
||||
|
@ -95,11 +102,11 @@ namespace SHADE
|
|||
resourceAttLayouts[input.attachment] = input.layout;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < node->attachmentDescriptions.size(); ++i)
|
||||
for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
|
||||
{
|
||||
auto& att = node->attachmentDescriptions[i];
|
||||
auto& att = node->attachmentDescriptions[j];
|
||||
att.initialLayout = vk::ImageLayout::eUndefined;
|
||||
att.finalLayout = resourceAttLayouts[i];
|
||||
att.finalLayout = resourceAttLayouts[j];
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
@ -210,10 +217,18 @@ namespace SHADE
|
|||
for (auto& inputAtt : subpass->inputReferences)
|
||||
{
|
||||
auto resource = node->attResources[inputAtt.attachment];
|
||||
if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR || resource->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||
colorRead |= (1 << i);
|
||||
else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL)
|
||||
depthRead |= (1 << i);
|
||||
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::INPUT))
|
||||
{
|
||||
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR) ||
|
||||
resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
|
||||
colorRead |= (1 << i);
|
||||
else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL))
|
||||
depthRead |= (1 << i);
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. ");
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
|
@ -350,10 +365,9 @@ namespace SHADE
|
|||
, swapchainHdl{ }
|
||||
, nodes{}
|
||||
, graphResources{}
|
||||
, resourceManager{}
|
||||
|
||||
, resourceManager{nullptr}
|
||||
{
|
||||
|
||||
resourceManager = std::make_shared<ResourceManager>();
|
||||
}
|
||||
|
||||
SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept
|
||||
|
@ -400,7 +414,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
Handle<SHRenderGraphNode> SHRenderGraph::AddNode(std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept
|
||||
SHADE::Handle<SHADE::SHRenderGraphNode> SHRenderGraph::AddNode(std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept
|
||||
{
|
||||
if (nodeIndexing.contains(nodeName))
|
||||
{
|
||||
|
@ -408,12 +422,19 @@ namespace SHADE
|
|||
return {};
|
||||
}
|
||||
|
||||
std::vector<Handle<SHRenderGraphResource>> resources;
|
||||
for (auto const& name : resourceNames)
|
||||
std::vector<SHAttachmentDescInitParams> descInitParams;
|
||||
for (auto const& instruction : resourceInstruction)
|
||||
{
|
||||
// If the resource that the new node is requesting for exists, allow the graph to reference it
|
||||
if (graphResources.contains(name))
|
||||
resources.push_back(graphResources.at(name));
|
||||
if (graphResources.contains(instruction.resourceName))
|
||||
{
|
||||
descInitParams.push_back(
|
||||
{
|
||||
.resourceHdl = graphResources.at(instruction.resourceName),
|
||||
.dontClearOnLoad = false,
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node.");
|
||||
|
@ -435,7 +456,7 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources));
|
||||
nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources));
|
||||
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
||||
return nodes.at(nodeIndexing[nodeName]);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -33,7 +34,17 @@ namespace SHADE
|
|||
|
||||
class SH_API SHRenderGraph
|
||||
{
|
||||
public:
|
||||
struct ResourceInstruction
|
||||
{
|
||||
std::string resourceName;
|
||||
bool dontClearOnLoad;
|
||||
|
||||
ResourceInstruction (char const* resourceName, bool dontClearOnLoad = false) noexcept;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
@ -60,7 +71,7 @@ namespace SHADE
|
|||
std::unordered_map<std::string, Handle<SHRenderGraphResource>> graphResources;
|
||||
|
||||
//! Resource library for graph handles
|
||||
ResourceManager resourceManager;
|
||||
std::shared_ptr<ResourceManager> resourceManager;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
@ -74,13 +85,14 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
|
||||
void AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
|
||||
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
|
||||
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
|
||||
void AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
|
||||
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
|
||||
|
||||
void Generate (void) noexcept;
|
||||
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace SHADE
|
|||
|
||||
for (uint32_t j = 0; j < attResources.size(); ++j)
|
||||
{
|
||||
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0;
|
||||
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
|
||||
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
|
||||
|
||||
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
|
||||
|
@ -69,7 +69,7 @@ namespace SHADE
|
|||
|
||||
for (uint32_t j = 0; j < attResources.size(); ++j)
|
||||
{
|
||||
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0;
|
||||
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
|
||||
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
|
||||
|
||||
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
|
||||
|
@ -104,14 +104,14 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
||||
SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr<ResourceManager> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
||||
: logicalDeviceHdl{ logicalDevice }
|
||||
, renderpass{}
|
||||
, framebuffers{}
|
||||
, prereqNodes{ std::move(predecessors) }
|
||||
, attachmentDescriptions{}
|
||||
, resourceAttachmentMapping{}
|
||||
, attResources{ std::move(attRes) }
|
||||
, attResources{ }
|
||||
, subpasses{}
|
||||
, executed{ false }
|
||||
, configured{ false }
|
||||
|
@ -121,6 +121,12 @@ namespace SHADE
|
|||
// pipeline library initialization
|
||||
pipelineLibrary.Init(logicalDeviceHdl);
|
||||
|
||||
// Store all the handles to resources
|
||||
attResources.reserve (attDescInitParams.size());
|
||||
for (auto& param : attDescInitParams)
|
||||
attResources.push_back(param.resourceHdl);
|
||||
|
||||
// We have as many descriptions as we have resources
|
||||
attachmentDescriptions.resize(attResources.size());
|
||||
|
||||
bool containsSwapchainImage = false;
|
||||
|
@ -140,7 +146,7 @@ namespace SHADE
|
|||
|
||||
newDesc.format = attResources[i]->resourceFormat;
|
||||
|
||||
if (attResources[i]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||
if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
|
||||
containsSwapchainImage = true;
|
||||
|
||||
resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i);
|
||||
|
@ -156,7 +162,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept
|
||||
: resourceManager{ rhs.resourceManager }
|
||||
: resourceManager{ std::move (rhs.resourceManager) }
|
||||
, logicalDeviceHdl{ rhs.logicalDeviceHdl }
|
||||
, renderpass{ rhs.renderpass }
|
||||
, framebuffers{ std::move(rhs.framebuffers) }
|
||||
|
@ -171,6 +177,8 @@ namespace SHADE
|
|||
, ptrToResources{ rhs.ptrToResources }
|
||||
, pipelineLibrary{ std::move(rhs.pipelineLibrary) }
|
||||
, batcher{ std::move(rhs.batcher) }
|
||||
, spDescs{ std::move(rhs.spDescs) }
|
||||
, spDeps{ std::move(rhs.spDeps) }
|
||||
|
||||
{
|
||||
rhs.renderpass = {};
|
||||
|
@ -181,7 +189,7 @@ namespace SHADE
|
|||
if (&rhs == this)
|
||||
return *this;
|
||||
|
||||
resourceManager = rhs.resourceManager;
|
||||
resourceManager = std::move(rhs.resourceManager);
|
||||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
||||
renderpass = rhs.renderpass;
|
||||
framebuffers = std::move(rhs.framebuffers);
|
||||
|
@ -194,6 +202,9 @@ namespace SHADE
|
|||
ptrToResources = std::move(rhs.ptrToResources);
|
||||
pipelineLibrary = std::move(rhs.pipelineLibrary);
|
||||
batcher = std::move(rhs.batcher);
|
||||
spDescs = std::move(rhs.spDescs);
|
||||
spDeps = std::move(rhs.spDeps);
|
||||
|
||||
|
||||
rhs.renderpass = {};
|
||||
|
||||
|
@ -224,10 +235,10 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Add subpass to container and create mapping for it
|
||||
subpasses.emplace_back(resourceManager.Create<SHSubpass>(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
|
||||
subpasses.emplace_back(resourceManager->Create<SHSubpass>(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
|
||||
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
||||
Handle<SHSubpass> subpass = subpasses.back();
|
||||
subpass->Init(resourceManager);
|
||||
subpass->Init(*resourceManager);
|
||||
|
||||
// Register the SuperBatch
|
||||
batcher.RegisterSuperBatch(subpass->GetSuperBatch());
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "SH_API.h"
|
||||
#include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h"
|
||||
#include "Graphics/MiddleEnd/Batching/SHBatcher.h"
|
||||
#include "SHAttachmentDescInitParams.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -25,7 +26,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER VARIABLES */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
ResourceManager& resourceManager;
|
||||
std::shared_ptr<ResourceManager> resourceManager;
|
||||
|
||||
//! For Vulkan object creation
|
||||
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
||||
|
@ -87,7 +88,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* CTORS AND DTORS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
|
||||
SHRenderGraphNode(std::shared_ptr<ResourceManager> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
|
||||
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
|
||||
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
|
||||
|
||||
|
|
|
@ -45,10 +45,10 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
|
||||
SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
|
||||
: logicalDevice {logicalDevice}
|
||||
, swapchain{ swapchain }
|
||||
, resourceType{ type }
|
||||
, resourceTypeFlags{ }
|
||||
, resourceFormat{ format }
|
||||
, images{}
|
||||
, imageViews{}
|
||||
|
@ -58,52 +58,10 @@ namespace SHADE
|
|||
, resourceName{ name }
|
||||
{
|
||||
// If the resource type is an arbitrary image and not swapchain image
|
||||
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)
|
||||
{
|
||||
imageAspectFlags = vk::ImageAspectFlags{};
|
||||
usage = usageFlags;
|
||||
resourceTypeFlags |= static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT);
|
||||
|
||||
// Check the resource type and set image usage flags and image aspect flags accordingly
|
||||
switch (resourceType)
|
||||
{
|
||||
case SH_ATT_DESC_TYPE::COLOR:
|
||||
usage |= vk::ImageUsageFlagBits::eColorAttachment;
|
||||
imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE::DEPTH:
|
||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||
imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE::STENCIL:
|
||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
|
||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
|
||||
break;
|
||||
}
|
||||
|
||||
// The resource is not a swapchain image, just use the first slot of the vector
|
||||
images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
|
||||
|
||||
// prepare image view details
|
||||
SHImageViewDetails viewDetails
|
||||
{
|
||||
.viewType = vk::ImageViewType::e2D,
|
||||
.format = images[0]->GetImageFormat(),
|
||||
.imageAspectFlags = imageAspectFlags,
|
||||
.baseMipLevel = 0,
|
||||
.mipLevelCount = mipLevels,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
|
||||
// just 1 image view created
|
||||
imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
|
||||
}
|
||||
else // if swapchain image resource
|
||||
{
|
||||
// Prepare image view details
|
||||
SHImageViewDetails viewDetails
|
||||
{
|
||||
|
@ -126,6 +84,65 @@ namespace SHADE
|
|||
imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails);
|
||||
}
|
||||
}
|
||||
else // if swapchain image resource
|
||||
{
|
||||
imageAspectFlags = vk::ImageAspectFlags{};
|
||||
usage = usageFlags;
|
||||
|
||||
for (auto& type : typeFlags)
|
||||
{
|
||||
// store the flags
|
||||
resourceTypeFlags |= static_cast<uint32_t>(type);
|
||||
|
||||
// Check the resource type and set image usage flags and image aspect flags accordingly
|
||||
switch (type)
|
||||
{
|
||||
case SH_ATT_DESC_TYPE_FLAGS::COLOR:
|
||||
usage |= vk::ImageUsageFlagBits::eColorAttachment;
|
||||
imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
|
||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||
imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
|
||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
|
||||
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
|
||||
imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE_FLAGS::INPUT:
|
||||
usage |= vk::ImageUsageFlagBits::eInputAttachment;
|
||||
usage |= vk::ImageUsageFlagBits::eSampled;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT:
|
||||
{
|
||||
SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The resource is not a swapchain image, just use the first slot of the vector
|
||||
images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
|
||||
|
||||
// prepare image view details
|
||||
SHImageViewDetails viewDetails
|
||||
{
|
||||
.viewType = vk::ImageViewType::e2D,
|
||||
.format = images[0]->GetImageFormat(),
|
||||
.imageAspectFlags = imageAspectFlags,
|
||||
.baseMipLevel = 0,
|
||||
.mipLevelCount = mipLevels,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
|
||||
// just 1 image view created
|
||||
imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -141,7 +158,7 @@ namespace SHADE
|
|||
/***************************************************************************/
|
||||
SHRenderGraphResource::SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept
|
||||
: resourceName{ std::move(rhs.resourceName) }
|
||||
, resourceType{ std::move(rhs.resourceType) }
|
||||
, resourceTypeFlags{ std::move(rhs.resourceTypeFlags) }
|
||||
, images{ std::move(rhs.images) }
|
||||
, imageViews{ std::move(rhs.imageViews) }
|
||||
, resourceFormat{ std::move(rhs.resourceFormat) }
|
||||
|
@ -149,6 +166,7 @@ namespace SHADE
|
|||
, height{ rhs.height }
|
||||
, mipLevels{ rhs.mipLevels }
|
||||
, imageAspectFlags{ rhs.imageAspectFlags }
|
||||
, swapchain {rhs.swapchain}
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -172,7 +190,7 @@ namespace SHADE
|
|||
return *this;
|
||||
|
||||
resourceName = std::move(rhs.resourceName);
|
||||
resourceType = std::move(rhs.resourceType);
|
||||
resourceTypeFlags = std::move(rhs.resourceTypeFlags);
|
||||
images = std::move(rhs.images);
|
||||
imageViews = std::move(rhs.imageViews);
|
||||
resourceFormat = std::move(rhs.resourceFormat);
|
||||
|
@ -180,6 +198,7 @@ namespace SHADE
|
|||
height = rhs.height;
|
||||
mipLevels = rhs.mipLevels;
|
||||
imageAspectFlags = rhs.imageAspectFlags;
|
||||
swapchain = rhs.swapchain;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -202,7 +221,7 @@ namespace SHADE
|
|||
width = newWidth;
|
||||
height = newHeight;
|
||||
|
||||
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||
if ((resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) == 0)
|
||||
{
|
||||
// prepare image view details
|
||||
SHImageViewDetails viewDetails
|
||||
|
@ -299,4 +318,9 @@ namespace SHADE
|
|||
return height;
|
||||
}
|
||||
|
||||
Handle<SHVkImageView> SHRenderGraphResource::GetImageView(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept
|
||||
{
|
||||
return imageViews [index];
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,8 @@ namespace SHADE
|
|||
class SHVkCommandBuffer;
|
||||
class SHVkBuffer;
|
||||
|
||||
static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0;
|
||||
|
||||
class SH_API SHRenderGraphResource
|
||||
{
|
||||
private:
|
||||
|
@ -32,7 +34,7 @@ namespace SHADE
|
|||
std::string resourceName;
|
||||
|
||||
//! Used for initializing image layouts
|
||||
SH_ATT_DESC_TYPE resourceType;
|
||||
SHRenderGraphResourceFlags resourceTypeFlags;
|
||||
|
||||
//! The resource itself (this is a vector because if the resource happens
|
||||
//! to be a swapchain image, then we need however many frames in flight).
|
||||
|
@ -67,7 +69,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* CTORS AND DTORS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
|
||||
SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
|
||||
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
||||
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
||||
~SHRenderGraphResource(void) noexcept;
|
||||
|
@ -82,9 +84,10 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
vk::Format GetResourceFormat (void) const noexcept;
|
||||
uint32_t GetWidth (void) const noexcept;
|
||||
uint32_t GetHeight (void) const noexcept;
|
||||
vk::Format GetResourceFormat (void) const noexcept;
|
||||
uint32_t GetWidth (void) const noexcept;
|
||||
uint32_t GetHeight (void) const noexcept;
|
||||
Handle<SHVkImageView> GetImageView (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
|
||||
|
||||
friend class SHRenderGraphNode;
|
||||
friend class SHRenderGraph;
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
SHSubpass::SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
||||
SHSubpass::SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
||||
: resourceAttachmentMapping{ mapping }
|
||||
, ptrToResources{ resources }
|
||||
, parentNode{ parent }
|
||||
|
@ -55,6 +55,8 @@ namespace SHADE
|
|||
, inputReferences{ std::move(rhs.inputReferences) }
|
||||
, resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
|
||||
, ptrToResources{ rhs.ptrToResources }
|
||||
, descriptorSetLayout{ rhs.descriptorSetLayout }
|
||||
, exteriorDrawCalls{ std::move (rhs.exteriorDrawCalls) }
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -83,6 +85,8 @@ namespace SHADE
|
|||
inputReferences = std::move(rhs.inputReferences);
|
||||
resourceAttachmentMapping = rhs.resourceAttachmentMapping;
|
||||
ptrToResources = rhs.ptrToResources;
|
||||
descriptorSetLayout = rhs.descriptorSetLayout;
|
||||
exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -120,18 +124,18 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept
|
||||
void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType) noexcept
|
||||
{
|
||||
vk::ImageLayout imageLayout;
|
||||
switch (attachmentDescriptionType)
|
||||
{
|
||||
case SH_ATT_DESC_TYPE::DEPTH:
|
||||
case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
|
||||
imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE::STENCIL:
|
||||
case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
|
||||
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
|
||||
break;
|
||||
case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
|
||||
case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
|
||||
imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
/* CTORS AND DTORS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
|
||||
SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
|
||||
SHSubpass(SHSubpass&& rhs) noexcept;
|
||||
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
|
||||
|
||||
|
@ -71,7 +71,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------*/
|
||||
// Preparation functions
|
||||
void AddColorOutput(std::string resourceToReference) noexcept;
|
||||
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept;
|
||||
void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept;
|
||||
void AddInput(std::string resourceToReference) noexcept;
|
||||
|
||||
// Runtime functions
|
||||
|
|
|
@ -253,7 +253,8 @@ namespace SHADE
|
|||
|
||||
SHVkRenderpass::~SHVkRenderpass(void) noexcept
|
||||
{
|
||||
logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr);
|
||||
if (vkRenderpass)
|
||||
logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace SHADE
|
|||
using BindingAndSetHash = uint64_t;
|
||||
using SetIndex = uint32_t;
|
||||
using SHSubPassIndex = uint32_t;
|
||||
using SHRenderGraphResourceFlags = uint32_t;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -59,9 +59,9 @@ namespace SHADE
|
|||
SparseSet();
|
||||
~SparseSet() = default;
|
||||
|
||||
// Disallow moving or copying
|
||||
SparseSet(const SparseSet&) = delete;
|
||||
SparseSet(SparseSet&&) = delete;
|
||||
//// Disallow moving or copying
|
||||
//SparseSet(const SparseSet&) = delete;
|
||||
//SparseSet(SparseSet&&) = delete;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* Script Serialisation Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity) const
|
||||
std::string SHScriptEngine::SerialiseScripts(EntityID entity) const
|
||||
{
|
||||
// Create buffer needed to store serialised script data
|
||||
constexpr int BUFFER_SIZE = 10240;
|
||||
|
@ -124,7 +124,7 @@ namespace SHADE
|
|||
|
||||
// Attempt to serialise the script
|
||||
std::string result;
|
||||
if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE))
|
||||
if (csScriptsSerialise(entity, buffer.get(), BUFFER_SIZE))
|
||||
{
|
||||
result = std::string(buffer.get());
|
||||
}
|
||||
|
@ -140,9 +140,9 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Script Serialisation Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml) const
|
||||
void SHScriptEngine::DeserialiseScript(EntityID entity, const std::string& yaml) const
|
||||
{
|
||||
csScriptDeserialise(entity.GetEID(), yaml.c_str());
|
||||
csScriptDeserialise(entity, yaml.c_str());
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -148,7 +148,7 @@ namespace SHADE
|
|||
/// <returns>
|
||||
/// String that represents the set of scripts attached to the specified Entity.
|
||||
/// </returns>
|
||||
std::string SerialiseScripts(const SHEntity& entity) const;
|
||||
std::string SerialiseScripts(EntityID entity) const;
|
||||
/// <summary>
|
||||
/// Loads the specified JSON string and creates a Script for the specified Entity
|
||||
/// based on the specified JSON string.
|
||||
|
@ -157,7 +157,7 @@ namespace SHADE
|
|||
/// <param name="yaml">
|
||||
/// The YAML string that represents the Script to load into the Entity.
|
||||
/// </param>
|
||||
void DeserialiseScript(const SHEntity& entity, const std::string& yaml) const;
|
||||
void DeserialiseScript(EntityID entity, const std::string& yaml) const;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Script Editor Functions */
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHSerializationHelper.hpp"
|
||||
#include "SHSerialization.h"
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Tools/SHException.h"
|
||||
#include "Assets/SHAssetManager.h"
|
||||
#include <fstream>
|
||||
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHSerialization::SerializeSceneToFile(std::filesystem::path const& path)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
SerializeSceneToEmitter(out);
|
||||
std::ofstream file(path.c_str());
|
||||
if (file.good())
|
||||
{
|
||||
file << out.c_str();
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
std::string SHSerialization::SerializeSceneToString()
|
||||
{
|
||||
YAML::Emitter out;
|
||||
SerializeSceneToEmitter(out);
|
||||
return std::basic_string<char>(out.c_str());
|
||||
}
|
||||
|
||||
void SHSerialization::SerializeSceneToEmitter(YAML::Emitter& out)
|
||||
{
|
||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
auto root = sceneGraph.GetRoot();
|
||||
|
||||
SHASSERT(root != nullptr, "Root is null. Failed to serialize scene to node.");
|
||||
|
||||
auto const& children = root->GetChildren();
|
||||
out << YAML::BeginSeq;
|
||||
|
||||
auto pred = [&out](SHSceneNode* node) {out << SerializeEntityToNode(node); };
|
||||
sceneGraph.Traverse(pred);
|
||||
//out << SerializeEntityToNode(child);
|
||||
|
||||
out << YAML::EndSeq;
|
||||
}
|
||||
|
||||
static void DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
|
||||
{
|
||||
if (!node[EIDNode])
|
||||
return;
|
||||
EntityID eid = node[EIDNode].as<EntityID>();
|
||||
std::string name = "Default";
|
||||
if (node[EntityNameNode])
|
||||
name = node[EntityNameNode].as<std::string>();
|
||||
//Compile component IDs
|
||||
const auto componentIDList = SHSerialization::GetComponentIDList(node[ComponentsNode]);
|
||||
eid = SHEntityManager::CreateEntity(componentIDList, eid, name, parentEID);
|
||||
createdEntities.push_back(eid);
|
||||
if (node[NumberOfChildrenNode])
|
||||
{
|
||||
if(const int numOfChildren = node[NumberOfChildrenNode].as<int>(); numOfChildren > 0)
|
||||
{
|
||||
++it;
|
||||
for (int i = 0; i < numOfChildren; ++i)
|
||||
{
|
||||
DeserializeEntity(it, (*it), createdEntities, eid);
|
||||
if((i + 1) < numOfChildren)
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHSerialization::DeserializeSceneFromFile(std::filesystem::path const& path)
|
||||
{
|
||||
//TODO:Shift to using XQ's FileIO
|
||||
std::ifstream iFile;
|
||||
iFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
std::string fileContent = "";
|
||||
|
||||
try
|
||||
{
|
||||
// Open file
|
||||
// Read file's buffer contents into streams
|
||||
iFile.open(path);
|
||||
std::stringstream fileStream;
|
||||
fileStream << iFile.rdbuf();
|
||||
|
||||
fileContent = fileStream.str();
|
||||
|
||||
// Close file handler
|
||||
iFile.close();
|
||||
}
|
||||
catch (std::ifstream::failure e)
|
||||
{
|
||||
SHLOG_ERROR("Could not read file");
|
||||
}
|
||||
YAML::Node entities = YAML::Load(fileContent);
|
||||
std::vector<EntityID> createdEntities{};
|
||||
|
||||
//Create Entities
|
||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||
{
|
||||
DeserializeEntity(it, (*it), createdEntities);
|
||||
}
|
||||
|
||||
//Initialize Entity
|
||||
auto entityVecIt = createdEntities.begin();
|
||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||
{
|
||||
InitializeEntity(*it, *entityVecIt++);
|
||||
}
|
||||
}
|
||||
|
||||
void SHSerialization::EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out)
|
||||
{
|
||||
out << SerializeEntityToNode(entityNode);
|
||||
auto const& children = entityNode->GetChildren();
|
||||
for(auto const& child : children)
|
||||
{
|
||||
EmitEntity(child, out);
|
||||
}
|
||||
}
|
||||
|
||||
std::string SHSerialization::SerializeEntitiesToString(std::vector<EntityID> const& entities)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
YAML::Node node;
|
||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
for (auto const& eid : entities)
|
||||
{
|
||||
auto entityNode = sceneGraph.GetNode(eid);
|
||||
EmitEntity(entityNode, out);
|
||||
}
|
||||
return std::basic_string<char>(out.c_str());
|
||||
}
|
||||
|
||||
void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
|
||||
{
|
||||
}
|
||||
|
||||
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
|
||||
{
|
||||
YAML::Node node;
|
||||
auto eid = sceneNode->GetEntityID();
|
||||
auto entity = SHEntityManager::GetEntityByID(eid);
|
||||
if (!sceneNode || !entity)
|
||||
{
|
||||
node = YAML::Null;
|
||||
return node;
|
||||
}
|
||||
node.SetStyle(YAML::EmitterStyle::Block);
|
||||
node[EIDNode] = eid;
|
||||
node[EntityNameNode] = entity->name;
|
||||
node[IsActiveNode] = sceneNode->IsActive();
|
||||
auto const& children = sceneNode->GetChildren();
|
||||
node[NumberOfChildrenNode] = children.size();
|
||||
|
||||
YAML::Node components;
|
||||
|
||||
if (const auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||
{
|
||||
components[rttr::type::get<SHTransformComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(transform);
|
||||
}
|
||||
if (const auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(eid))
|
||||
{
|
||||
components[rttr::type::get<SHRenderable>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(renderable);
|
||||
}
|
||||
if (const auto rigidbody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid))
|
||||
{
|
||||
components[rttr::type::get<SHRigidBodyComponent>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(rigidbody);
|
||||
}
|
||||
node[ComponentsNode] = components;
|
||||
return node;
|
||||
}
|
||||
|
||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
std::optional<ComponentTypeID> GetComponentID(YAML::Node const& componentNode)
|
||||
{
|
||||
if (componentNode[rttr::type::get<ComponentType>().get_name().data()])
|
||||
return { SHFamilyID<SHComponent>::GetID<ComponentType>() };
|
||||
else
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<ComponentTypeID> SHSerialization::GetComponentIDList(YAML::Node const& componentsNode)
|
||||
{
|
||||
std::vector<ComponentTypeID> componentIDList;
|
||||
|
||||
auto id = GetComponentID<SHTransformComponent>(componentsNode);
|
||||
if (id.has_value())
|
||||
componentIDList.push_back(id.value());
|
||||
|
||||
id = GetComponentID<SHRenderable>(componentsNode);
|
||||
if (id.has_value())
|
||||
componentIDList.push_back(id.value());
|
||||
|
||||
id = GetComponentID<SHRigidBodyComponent>(componentsNode);
|
||||
if (id.has_value())
|
||||
componentIDList.push_back(id.value());
|
||||
|
||||
return componentIDList;
|
||||
}
|
||||
|
||||
void SHSerialization::InitializeEntity(YAML::Node const& entityNode, EntityID const& eid)
|
||||
{
|
||||
auto const componentsNode = entityNode[ComponentsNode];
|
||||
if (!componentsNode)
|
||||
return;
|
||||
SHSerializationHelper::InitializeComponentFromNode<SHTransformComponent>(componentsNode, eid);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
|
||||
#include "SH_API.h"
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
#include <ECS_Base/Components/SHComponent.h>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Emitter;
|
||||
class Node;
|
||||
}
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHSceneNode;
|
||||
|
||||
constexpr const char* ComponentsNode = "Components";
|
||||
constexpr const char* EntityNameNode = "Name";
|
||||
constexpr const char* EIDNode = "EID";
|
||||
constexpr const char* IsActiveNode = "IsActive";
|
||||
constexpr const char* NumberOfChildrenNode = "NumberOfChildren";
|
||||
|
||||
struct SH_API SHSerialization
|
||||
{
|
||||
//TODO: change paths to resource ID
|
||||
static void SerializeSceneToFile(std::filesystem::path const& path);
|
||||
static std::string SerializeSceneToString();
|
||||
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
||||
static void DeserializeSceneFromFile(std::filesystem::path const& path);
|
||||
|
||||
|
||||
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
|
||||
static std::string SerializeEntitiesToString(std::vector<EntityID> const& entities);
|
||||
static void SerializeEntityToFile(std::filesystem::path const& path);
|
||||
static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode);
|
||||
|
||||
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
||||
private:
|
||||
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
#pragma once
|
||||
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#include <rttr/registration>
|
||||
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHSerializationHelper
|
||||
{
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static std::string SerializeComponentToString(ComponentType* component)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path)
|
||||
{
|
||||
}
|
||||
|
||||
static YAML::Node RTTRToNode(const rttr::variant& var)
|
||||
{
|
||||
YAML::Node node;
|
||||
auto varType = var.get_type();
|
||||
if (varType == rttr::type::get<SHVec4>())
|
||||
{
|
||||
node.SetStyle(YAML::EmitterStyle::Flow);
|
||||
node["X"] = var.convert<SHVec4>().x;
|
||||
node["Y"] = var.convert<SHVec4>().y;
|
||||
node["Z"] = var.convert<SHVec4>().z;
|
||||
node["W"] = var.convert<SHVec4>().w;
|
||||
}
|
||||
else if (varType == rttr::type::get<SHVec3>())
|
||||
{
|
||||
node.SetStyle(YAML::EmitterStyle::Flow);
|
||||
node["X"] = var.convert<SHVec3>().x;
|
||||
node["Y"] = var.convert<SHVec3>().y;
|
||||
node["Z"] = var.convert<SHVec3>().z;
|
||||
}
|
||||
else if (varType == rttr::type::get<SHVec2>())
|
||||
{
|
||||
node.SetStyle(YAML::EmitterStyle::Flow);
|
||||
node["X"] = var.convert<SHVec3>().x;
|
||||
node["Y"] = var.convert<SHVec3>().y;
|
||||
}
|
||||
else if (varType.is_arithmetic())
|
||||
{
|
||||
bool ok = false;
|
||||
if (varType == rttr::type::get<bool>())
|
||||
node = var.to_bool();
|
||||
else if (varType == rttr::type::get<int8_t>())
|
||||
node = var.to_int8(&ok);
|
||||
else if (varType == rttr::type::get<int16_t>())
|
||||
node = var.to_int16(&ok);
|
||||
else if (varType == rttr::type::get<int32_t>())
|
||||
node = var.to_int32(&ok);
|
||||
else if (varType == rttr::type::get<int64_t>())
|
||||
node = var.to_int64(&ok);
|
||||
else if (varType == rttr::type::get<uint8_t>())
|
||||
node = var.to_uint8(&ok);
|
||||
else if (varType == rttr::type::get<uint16_t>())
|
||||
node = var.to_uint16(&ok);
|
||||
else if (varType == rttr::type::get<uint32_t>())
|
||||
node = var.to_uint32(&ok);
|
||||
else if (varType == rttr::type::get<uint64_t>())
|
||||
node = var.to_uint64(&ok);
|
||||
else if (varType == rttr::type::get<float>())
|
||||
node = var.to_float(&ok);
|
||||
else if (varType == rttr::type::get<double>())
|
||||
node = var.to_double(&ok);
|
||||
//else if (varType == rttr::type::get<char>()) //same as uint8_t
|
||||
// node = var.to_uint8();
|
||||
}
|
||||
else if (varType.is_enumeration())
|
||||
{
|
||||
bool ok = false;
|
||||
auto result = var.to_string(&ok);
|
||||
if (ok)
|
||||
{
|
||||
node = var.to_string();
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
auto value = var.to_uint64(&ok);
|
||||
if (ok)
|
||||
node = value;
|
||||
else
|
||||
node = YAML::Null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto properties = var.get_type().get_properties();
|
||||
for (auto property : properties)
|
||||
{
|
||||
node[property.get_name().data()] = RTTRToNode(property.get_value(var));
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static YAML::Node SerializeComponentToNode(ComponentType* component)
|
||||
{
|
||||
YAML::Node node{};
|
||||
if (!component)
|
||||
return node;
|
||||
|
||||
auto componentType = rttr::type::get<ComponentType>();
|
||||
node = RTTRToNode(*component);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static void InitializeProperty(ComponentType* component, rttr::property const& prop, YAML::Node const& propertyNode)
|
||||
{
|
||||
auto propType = prop.get_type();
|
||||
if (propType == rttr::type::get<SHVec4>())
|
||||
{
|
||||
SHVec4 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>(), propertyNode["W"].as<float>() };
|
||||
prop.set_value(component, vec);
|
||||
}
|
||||
else if (propType == rttr::type::get<SHVec3>())
|
||||
{
|
||||
SHVec3 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>() };
|
||||
prop.set_value(component, vec);
|
||||
}
|
||||
else if (propType == rttr::type::get<SHVec2>())
|
||||
{
|
||||
SHVec2 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>() };
|
||||
prop.set_value(component, vec);
|
||||
}
|
||||
else if (propType.is_arithmetic())
|
||||
{
|
||||
bool ok = false;
|
||||
if (propType == rttr::type::get<bool>())
|
||||
prop.set_value(component, propertyNode.as<bool>());
|
||||
else if (propType == rttr::type::get<int8_t>())
|
||||
prop.set_value(component, propertyNode.as<int8_t>());
|
||||
else if (propType == rttr::type::get<int16_t>())
|
||||
prop.set_value(component, propertyNode.as<int16_t>());
|
||||
else if (propType == rttr::type::get<int32_t>())
|
||||
prop.set_value(component, propertyNode.as<int32_t>());
|
||||
else if (propType == rttr::type::get<int64_t>())
|
||||
prop.set_value(component, propertyNode.as<int64_t>());
|
||||
else if (propType == rttr::type::get<uint8_t>())
|
||||
prop.set_value(component, propertyNode.as<uint8_t>());
|
||||
else if (propType == rttr::type::get<uint16_t>())
|
||||
prop.set_value(component, propertyNode.as<uint16_t>());
|
||||
else if (propType == rttr::type::get<uint32_t>())
|
||||
prop.set_value(component, propertyNode.as<uint32_t>());
|
||||
else if (propType == rttr::type::get<uint64_t>())
|
||||
prop.set_value(component, propertyNode.as<uint64_t>());
|
||||
else if (propType == rttr::type::get<float>())
|
||||
prop.set_value(component, propertyNode.as<float>());
|
||||
else if (propType == rttr::type::get<double>())
|
||||
prop.set_value(component, propertyNode.as<double>());
|
||||
}
|
||||
else if (propType.is_enumeration())
|
||||
{
|
||||
auto enumAlign = prop.get_enumeration();
|
||||
prop.set_value(component, enumAlign.name_to_value(propertyNode.as<std::string>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto properties = propType.get_properties();
|
||||
for (auto property : properties)
|
||||
{
|
||||
InitializeProperty(component, property, propertyNode[property.get_name().data()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
static void InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid)
|
||||
{
|
||||
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||
if (componentsNode.IsNull() && !component)
|
||||
return;
|
||||
auto rttrType = rttr::type::get<ComponentType>();
|
||||
auto componentNode = componentsNode[rttrType.get_name().data()];
|
||||
if (componentsNode.IsNull())
|
||||
return;
|
||||
auto properties = rttrType.get_properties();
|
||||
for (auto const& prop : properties)
|
||||
{
|
||||
if (componentNode[prop.get_name().data()])
|
||||
{
|
||||
InitializeProperty<ComponentType>(component, prop, componentNode[prop.get_name().data()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
|
@ -29,6 +29,7 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Editor/Command/SHCommandManager.h"
|
||||
#include "Editor/Command/SHCommand.hpp"
|
||||
#include "TooltipAttribute.hxx"
|
||||
|
||||
// Using Directives
|
||||
using namespace System;
|
||||
|
@ -48,17 +49,17 @@ using namespace System::Collections::Generic;
|
|||
/// <param name="MANAGED_TYPE">The managed type of the object to edit.</param>
|
||||
/// <param name="NATIVE_TYPE">The native type of the object to edit.</param>
|
||||
/// <param name="FUNC">The SHEditorUI:: function to use for editing.</param>
|
||||
#define RENDER_FIELD(MANAGED_TYPE, NATIVE_TYPE, FUNC) \
|
||||
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||
{ \
|
||||
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
||||
NATIVE_TYPE oldVal = val; \
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
||||
{ \
|
||||
field->SetValue(object, val); \
|
||||
registerUndoAction(object, field, val, oldVal); \
|
||||
} \
|
||||
} \
|
||||
#define RENDER_FIELD(MANAGED_TYPE, NATIVE_TYPE, FUNC) \
|
||||
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||
{ \
|
||||
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
||||
NATIVE_TYPE oldVal = val; \
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered))\
|
||||
{ \
|
||||
field->SetValue(object, val); \
|
||||
registerUndoAction(object, field, val, oldVal); \
|
||||
} \
|
||||
} \
|
||||
/// <summary>
|
||||
/// Macro expansion that is used in renderFieldInInspector() to check the type of a field
|
||||
/// named "field" against the specified type and if it matches, retrieves the value of
|
||||
|
@ -76,7 +77,7 @@ using namespace System::Collections::Generic;
|
|||
{ \
|
||||
NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \
|
||||
NATIVE_TYPE oldVal = val; \
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered)) \
|
||||
{ \
|
||||
field->SetValue(object, Convert::ToCLI(val)); \
|
||||
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \
|
||||
|
@ -196,6 +197,8 @@ namespace SHADE
|
|||
}
|
||||
void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object)
|
||||
{
|
||||
bool isHovered = false;
|
||||
|
||||
if RENDER_FIELD (Int16, int, InputInt)
|
||||
else if RENDER_FIELD (Int32, int, InputInt)
|
||||
else if RENDER_FIELD (Int64, int, InputInt)
|
||||
|
@ -244,6 +247,15 @@ namespace SHADE
|
|||
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the field has a specific attribute
|
||||
TooltipAttribute^ toolTip = hasAttribute<TooltipAttribute^>(field);
|
||||
if (toolTip && isHovered)
|
||||
{
|
||||
SHEditorUI::BeginTooltip();
|
||||
SHEditorUI::Text(Convert::ToNative(toolTip->Description));
|
||||
SHEditorUI::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::renderScriptContextMenu(Entity entity, Script^ script)
|
||||
|
@ -274,4 +286,24 @@ namespace SHADE
|
|||
SHCommandManager::RegisterCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCLICommand>()));
|
||||
}
|
||||
|
||||
generic<typename Attribute>
|
||||
Attribute Editor::hasAttribute(System::Reflection::FieldInfo^ field)
|
||||
{
|
||||
array<System::Object^>^ attributes = field->GetCustomAttributes(true);
|
||||
for each (System::Object^ attrib in attributes)
|
||||
{
|
||||
try
|
||||
{
|
||||
Attribute attribute = safe_cast<Attribute>(attrib);
|
||||
if (attribute != nullptr)
|
||||
return attribute;
|
||||
}
|
||||
catch (System::InvalidCastException^)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Failed to find
|
||||
return Attribute{};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace SHADE
|
|||
/// <summary>
|
||||
/// Static class for Editor-related functions
|
||||
/// </summary>
|
||||
public ref class Editor abstract sealed
|
||||
private ref class Editor abstract sealed
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -48,7 +48,13 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------*/
|
||||
/* UndoRedoStack Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Undoes the last script inspector change if there is any.
|
||||
/// </summary>
|
||||
static void Undo();
|
||||
/// <summary>
|
||||
/// Redoes the last script inspector change if there is any.
|
||||
/// </summary>
|
||||
static void Redo();
|
||||
|
||||
private:
|
||||
|
@ -86,5 +92,7 @@ namespace SHADE
|
|||
/// <param name="script">The Script to render the inspector for.</param>
|
||||
static void renderScriptContextMenu(Entity entity, Script^ script);
|
||||
static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData);
|
||||
generic<typename Attribute> where Attribute : System::Attribute
|
||||
static Attribute hasAttribute(System::Reflection::FieldInfo^ field);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
/************************************************************************************//*!
|
||||
\file SerializeFieldAttribute.cxx
|
||||
\file TooltipAttribute.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 5, 2021
|
||||
\brief Contains the definition of the functions of the managed SerializeField
|
||||
Attribute class.
|
||||
\date Oct 18, 2022
|
||||
\brief Contains the definition of the functions of the managed Tooltip Attribute
|
||||
class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2021 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Headers
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "SerializeFieldAttribute.hxx"
|
||||
#include "TooltipAttribute.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
System::String^ TooltipAttribute::Description::get()
|
||||
{
|
||||
return desc;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SerializeField::SerializeField()
|
||||
TooltipAttribute::TooltipAttribute(System::String^ description)
|
||||
: desc { description }
|
||||
{}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/************************************************************************************//*!
|
||||
\file TooltipAttribute.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 18, 2022
|
||||
\brief Contains the definition of the managed Tooltip Attribute class with
|
||||
the declaration of functions for working with it.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple attribute to mark that a field in a Script should be serialised.
|
||||
/// </summary>
|
||||
[System::AttributeUsage(System::AttributeTargets::Field)]
|
||||
public ref class TooltipAttribute : public System::Attribute
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Description that is to be shown in the Tooltip.
|
||||
/// </summary>
|
||||
property System::String^ Description
|
||||
{
|
||||
System::String^ get();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Constructor for a Tooltip attribute that fills in the description.
|
||||
/// </summary>
|
||||
/// <param name="description">Text to be shown when a field is hovered.</param>
|
||||
TooltipAttribute(System::String^ description);
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
System::String^ desc;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/************************************************************************************//*!
|
||||
\file Input.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 16, 2022
|
||||
\brief Contains the definition of the managed Input static class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#include "SHpch.h"
|
||||
#include "Input.hxx"
|
||||
#include "Utility/Convert.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
Vector3 Input::MousePosition::get()
|
||||
{
|
||||
int x, y;
|
||||
SHInputManager::GetMouseWindowPosition(&x, &y);
|
||||
return Vector3(static_cast<float>(x), static_cast<float>(y), 0.0f);
|
||||
}
|
||||
int Input::MouseScrollDelta::get()
|
||||
{
|
||||
return SHInputManager::GetMouseWheelVerticalDelta();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
bool Input::GetKey(KeyCode key)
|
||||
{
|
||||
return SHInputManager::GetKey(static_cast<SHInputManager::SH_KEYCODE>(key));
|
||||
}
|
||||
|
||||
bool Input::GetKeyDown(KeyCode key)
|
||||
{
|
||||
return SHInputManager::GetKeyDown(static_cast<SHInputManager::SH_KEYCODE>(key));
|
||||
}
|
||||
|
||||
bool Input::GetKeyUp(KeyCode key)
|
||||
{
|
||||
return SHInputManager::GetKeyUp(static_cast<SHInputManager::SH_KEYCODE>(key));
|
||||
}
|
||||
|
||||
bool Input::GetMouseButton(MouseCode mouseButton)
|
||||
{
|
||||
return SHInputManager::GetKey(static_cast<SHInputManager::SH_KEYCODE>(mouseButton));
|
||||
}
|
||||
|
||||
bool Input::GetMouseButtonDown(MouseCode mouseButton)
|
||||
{
|
||||
return SHInputManager::GetKeyDown(static_cast<SHInputManager::SH_KEYCODE>(mouseButton));
|
||||
}
|
||||
|
||||
bool Input::GetMouseButtonUp(MouseCode mouseButton)
|
||||
{
|
||||
return SHInputManager::GetKeyUp(static_cast<SHInputManager::SH_KEYCODE>(mouseButton));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Cursor Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void Input::SetMousePosition(Vector2 pos)
|
||||
{
|
||||
SHInputManager::SetMouseWindowPosition
|
||||
(
|
||||
static_cast<int>(pos.x),
|
||||
static_cast<int>(pos.y)
|
||||
);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Time Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
double Input::GetKeyHeldTime(KeyCode key)
|
||||
{
|
||||
return SHInputManager::GetKeyHeldTime(static_cast<SHInputManager::SH_KEYCODE>(key));
|
||||
}
|
||||
|
||||
double Input::GetKeyReleasedTime(KeyCode key)
|
||||
{
|
||||
return SHInputManager::GetKeyReleasedTime(static_cast<SHInputManager::SH_KEYCODE>(key));
|
||||
}
|
||||
|
||||
double Input::GetMouseHeldTime(MouseCode key)
|
||||
{
|
||||
return SHInputManager::GetKeyHeldTime(static_cast<SHInputManager::SH_KEYCODE>(key));
|
||||
}
|
||||
|
||||
double Input::GetMouseReleasedTime(MouseCode key)
|
||||
{
|
||||
return SHInputManager::GetKeyReleasedTime(static_cast<SHInputManager::SH_KEYCODE>(key));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,325 @@
|
|||
/************************************************************************************//*!
|
||||
\file Input.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Oct 16, 2022
|
||||
\brief Contains the definition of the managed Input static class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include "Input/SHInputManager.h"
|
||||
#include "Math/Vector2.hxx"
|
||||
#include "Math/Vector3.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class responsible for providing access to Input-related functionality.
|
||||
/// </summary>
|
||||
public ref class Input abstract sealed
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Represents the available supported keycodes that can be passed into the
|
||||
/// key-based Input functions.
|
||||
/// </summary>
|
||||
enum class KeyCode : int
|
||||
{
|
||||
Space = static_cast<int>(SHInputManager::SH_KEYCODE::SPACE),
|
||||
//Apostrophe = static_cast<int>(SHInputManager::SH_KEYCODE::APOSTROPHE),
|
||||
Comma = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_COMMA),
|
||||
Minus = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_MINUS),
|
||||
Period = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_PERIOD),
|
||||
//Slash = static_cast<int>(SHInputManager::SH_KEYCODE::SLASH),
|
||||
Key0 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_0),
|
||||
Key1 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_1),
|
||||
Key2 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_2),
|
||||
Key3 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_3),
|
||||
Key4 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_4),
|
||||
Key5 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_5),
|
||||
Key6 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_6),
|
||||
Key7 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_7),
|
||||
Key8 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_8),
|
||||
Key9 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_9),
|
||||
|
||||
//Semicolon = static_cast<int>(SHInputManager::SH_KEYCODE::SEMICOLON),
|
||||
//Equal = static_cast<int>(SHInputManager::SH_KEYCODE::EQUAL),
|
||||
|
||||
A = static_cast<int>(SHInputManager::SH_KEYCODE::A),
|
||||
B = static_cast<int>(SHInputManager::SH_KEYCODE::B),
|
||||
C = static_cast<int>(SHInputManager::SH_KEYCODE::C),
|
||||
D = static_cast<int>(SHInputManager::SH_KEYCODE::D),
|
||||
E = static_cast<int>(SHInputManager::SH_KEYCODE::E),
|
||||
F = static_cast<int>(SHInputManager::SH_KEYCODE::F),
|
||||
G = static_cast<int>(SHInputManager::SH_KEYCODE::G),
|
||||
H = static_cast<int>(SHInputManager::SH_KEYCODE::H),
|
||||
I = static_cast<int>(SHInputManager::SH_KEYCODE::I),
|
||||
J = static_cast<int>(SHInputManager::SH_KEYCODE::J),
|
||||
K = static_cast<int>(SHInputManager::SH_KEYCODE::K),
|
||||
L = static_cast<int>(SHInputManager::SH_KEYCODE::L),
|
||||
M = static_cast<int>(SHInputManager::SH_KEYCODE::M),
|
||||
N = static_cast<int>(SHInputManager::SH_KEYCODE::N),
|
||||
O = static_cast<int>(SHInputManager::SH_KEYCODE::O),
|
||||
P = static_cast<int>(SHInputManager::SH_KEYCODE::P),
|
||||
Q = static_cast<int>(SHInputManager::SH_KEYCODE::Q),
|
||||
R = static_cast<int>(SHInputManager::SH_KEYCODE::R),
|
||||
S = static_cast<int>(SHInputManager::SH_KEYCODE::S),
|
||||
T = static_cast<int>(SHInputManager::SH_KEYCODE::T),
|
||||
U = static_cast<int>(SHInputManager::SH_KEYCODE::U),
|
||||
V = static_cast<int>(SHInputManager::SH_KEYCODE::V),
|
||||
W = static_cast<int>(SHInputManager::SH_KEYCODE::W),
|
||||
X = static_cast<int>(SHInputManager::SH_KEYCODE::X),
|
||||
Y = static_cast<int>(SHInputManager::SH_KEYCODE::Y),
|
||||
Z = static_cast<int>(SHInputManager::SH_KEYCODE::Z),
|
||||
|
||||
//LeftBracket = static_cast<int>(SHInputManager::SH_KEYCODE::LEFTBRACKET),
|
||||
//BackSlash = static_cast<int>(SHInputManager::SH_KEYCODE::BACKSLASH),
|
||||
//RightBracket = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHTBRACKET),
|
||||
//GraveAccent = static_cast<int>(SHInputManager::SH_KEYCODE::GRAVEACCENT),
|
||||
|
||||
//WORLD1 = static_cast<int>(SHInputManager::SH_KEYCODE::WORLD1),
|
||||
//WORLD2 = static_cast<int>(SHInputManager::SH_KEYCODE::WORLD2),
|
||||
|
||||
/* Function keys */
|
||||
Escape = static_cast<int>(SHInputManager::SH_KEYCODE::ESCAPE),
|
||||
Enter = static_cast<int>(SHInputManager::SH_KEYCODE::ENTER),
|
||||
Tab = static_cast<int>(SHInputManager::SH_KEYCODE::TAB),
|
||||
Backspace = static_cast<int>(SHInputManager::SH_KEYCODE::BACKSPACE),
|
||||
Insert = static_cast<int>(SHInputManager::SH_KEYCODE::INSERT),
|
||||
Delete = static_cast<int>(SHInputManager::SH_KEYCODE::DEL),
|
||||
Right = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_ARROW),
|
||||
Left = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_ARROW),
|
||||
Down = static_cast<int>(SHInputManager::SH_KEYCODE::DOWN_ARROW),
|
||||
Up = static_cast<int>(SHInputManager::SH_KEYCODE::UP_ARROW),
|
||||
PageUp = static_cast<int>(SHInputManager::SH_KEYCODE::PAGE_UP),
|
||||
PageDown = static_cast<int>(SHInputManager::SH_KEYCODE::PAGE_DOWN),
|
||||
Home = static_cast<int>(SHInputManager::SH_KEYCODE::HOME),
|
||||
End = static_cast<int>(SHInputManager::SH_KEYCODE::END),
|
||||
CapsLock = static_cast<int>(SHInputManager::SH_KEYCODE::CAPS_LOCK),
|
||||
ScrollLock = static_cast<int>(SHInputManager::SH_KEYCODE::SCROLL_LOCK),
|
||||
NumLock = static_cast<int>(SHInputManager::SH_KEYCODE::NUM_LOCK),
|
||||
PrintScreen = static_cast<int>(SHInputManager::SH_KEYCODE::PRINT_SCREEN),
|
||||
Pause = static_cast<int>(SHInputManager::SH_KEYCODE::PAUSE),
|
||||
F1 = static_cast<int>(SHInputManager::SH_KEYCODE::F1),
|
||||
F2 = static_cast<int>(SHInputManager::SH_KEYCODE::F2),
|
||||
F3 = static_cast<int>(SHInputManager::SH_KEYCODE::F3),
|
||||
F4 = static_cast<int>(SHInputManager::SH_KEYCODE::F4),
|
||||
F5 = static_cast<int>(SHInputManager::SH_KEYCODE::F5),
|
||||
F6 = static_cast<int>(SHInputManager::SH_KEYCODE::F6),
|
||||
F7 = static_cast<int>(SHInputManager::SH_KEYCODE::F7),
|
||||
F8 = static_cast<int>(SHInputManager::SH_KEYCODE::F8),
|
||||
F9 = static_cast<int>(SHInputManager::SH_KEYCODE::F9),
|
||||
F10 = static_cast<int>(SHInputManager::SH_KEYCODE::F10),
|
||||
F11 = static_cast<int>(SHInputManager::SH_KEYCODE::F11),
|
||||
F12 = static_cast<int>(SHInputManager::SH_KEYCODE::F12),
|
||||
F13 = static_cast<int>(SHInputManager::SH_KEYCODE::F13),
|
||||
F14 = static_cast<int>(SHInputManager::SH_KEYCODE::F14),
|
||||
F15 = static_cast<int>(SHInputManager::SH_KEYCODE::F15),
|
||||
F16 = static_cast<int>(SHInputManager::SH_KEYCODE::F16),
|
||||
F17 = static_cast<int>(SHInputManager::SH_KEYCODE::F17),
|
||||
F18 = static_cast<int>(SHInputManager::SH_KEYCODE::F18),
|
||||
F19 = static_cast<int>(SHInputManager::SH_KEYCODE::F19),
|
||||
F20 = static_cast<int>(SHInputManager::SH_KEYCODE::F20),
|
||||
F21 = static_cast<int>(SHInputManager::SH_KEYCODE::F21),
|
||||
F22 = static_cast<int>(SHInputManager::SH_KEYCODE::F22),
|
||||
F23 = static_cast<int>(SHInputManager::SH_KEYCODE::F23),
|
||||
F24 = static_cast<int>(SHInputManager::SH_KEYCODE::F24),
|
||||
|
||||
/* Keypad */
|
||||
KeyPad0 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_0),
|
||||
KeyPad1 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_1),
|
||||
KeyPad2 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_2),
|
||||
KeyPad3 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_3),
|
||||
KeyPad4 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_4),
|
||||
KeyPad5 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_5),
|
||||
KeyPad6 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_6),
|
||||
KeyPad7 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_7),
|
||||
KeyPad8 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_8),
|
||||
KeyPad9 = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_9),
|
||||
//KeyPadDecimal = static_cast<int>(SHInputManager::SH_KEYCODE::KPDECIMAL),
|
||||
//KeyPadDivide = static_cast<int>(SHInputManager::SH_KEYCODE::KPDIVIDE),
|
||||
//KeyPadMultiply = static_cast<int>(SHInputManager::SH_KEYCODE::KPMULTIPLY),
|
||||
//KeyPadSubtract = static_cast<int>(SHInputManager::SH_KEYCODE::KPSUBTRACT),
|
||||
//KeyPadAdd = static_cast<int>(SHInputManager::SH_KEYCODE::KPADD),
|
||||
//KeyPadEnter = static_cast<int>(SHInputManager::SH_KEYCODE::KPENTER),
|
||||
//KeyPadEqual = static_cast<int>(SHInputManager::SH_KEYCODE::KEYPAD),
|
||||
|
||||
Shift = static_cast<int>(SHInputManager::SH_KEYCODE::SHIFT),
|
||||
LeftControl = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_CTRL),
|
||||
LeftAlt = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_ALT),
|
||||
LeftSuper = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_WINDOWS),
|
||||
RightShift = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_SHIFT),
|
||||
RightControl = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_CTRL),
|
||||
RightAlt = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_ALT),
|
||||
RightSuper = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_WINDOWS),
|
||||
|
||||
/* Gamepad */
|
||||
JoystickA = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_A),
|
||||
JoystickB = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_B),
|
||||
JoystickX = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_X),
|
||||
JoystickY = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_Y),
|
||||
JoystickLeftBumper = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTSHOULDER),
|
||||
JoystickRightBumper = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTSHOULDER),
|
||||
JoystickLeftTrigger = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTTRIGGER),
|
||||
JoystickRightTrigger = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTTRIGGER),
|
||||
JoystickDPadUp = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_UP),
|
||||
JoystickDPadDown = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_DOWN),
|
||||
JoystickDPadLeft = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_LEFT),
|
||||
JoystickDPadRight = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_RIGHT),
|
||||
JoystickMenu = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_MENU),
|
||||
JoystickView = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_VIEW),
|
||||
JoystickLeftStick = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_LEFT_THUMBSTICK_BUTTON),
|
||||
JoystickRightStick = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHT_THUMBSTICK_BUTTON),
|
||||
|
||||
/* Unity Gamepad Mappings */
|
||||
JoystickButton0 = JoystickA,
|
||||
JoystickButton1 = JoystickB,
|
||||
JoystickButton2 = JoystickX,
|
||||
JoystickButton3 = JoystickY,
|
||||
JoystickButton4 = JoystickLeftBumper,
|
||||
JoystickButton5 = JoystickRightBumper,
|
||||
JoystickButton6 = JoystickView,
|
||||
JoystickButton7 = JoystickMenu,
|
||||
JoystickButton8 = JoystickLeftStick,
|
||||
JoystickButton9 = JoystickRightStick
|
||||
|
||||
};
|
||||
/// <summary>
|
||||
/// Represents the available supported mouse keycodes that can be passed into the
|
||||
/// mouse-button-based Input functions.
|
||||
/// </summary>
|
||||
enum class MouseCode : int
|
||||
{
|
||||
LeftButton = static_cast<int>(SHInputManager::SH_KEYCODE::LMB),
|
||||
RightButton = static_cast<int>(SHInputManager::SH_KEYCODE::RMB),
|
||||
MiddleButton = static_cast<int>(SHInputManager::SH_KEYCODE::MMB),
|
||||
Button3 = static_cast<int>(SHInputManager::SH_KEYCODE::XMB1),
|
||||
Button4 = static_cast<int>(SHInputManager::SH_KEYCODE::XMB2)
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Properites */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Mouse position in screen coordinates relative to the top left of the window.
|
||||
/// This value is a Vector3 for compatibility with functions that have Vector3
|
||||
/// arguments. The z component of the Vector3 is always 0
|
||||
/// </summary>
|
||||
static property Vector3 MousePosition
|
||||
{
|
||||
Vector3 get();
|
||||
}
|
||||
/// <summary>
|
||||
/// Amnount of vertical mouse scroll in this frame.
|
||||
/// </summary>
|
||||
static property int MouseScrollDelta
|
||||
{
|
||||
int get();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Checks if a specified key is being held down.
|
||||
/// This will also be true if GetKeyDown() is true.
|
||||
/// </summary>
|
||||
/// <param name="key">KeyCode of the key to check.</param>
|
||||
/// <returns>True while the user holds down the key specified.</returns>
|
||||
static bool GetKey(KeyCode key);
|
||||
/// <summary>
|
||||
/// Checks if a specified key is pressed and was not pressed before.
|
||||
/// </summary>
|
||||
/// <param name="key">KeyCode of the key to check.</param>
|
||||
/// <returns>
|
||||
/// True during the frame the user starts pressing down the key specified.
|
||||
/// </returns>
|
||||
static bool GetKeyDown(KeyCode key);
|
||||
/// <summary>
|
||||
/// Checks if a specified key is no longer pressed pressed and was pressed
|
||||
/// before.
|
||||
/// </summary>
|
||||
/// <param name="key">KeyCode of the key to check.</param>
|
||||
/// <returns>
|
||||
/// True during the frame the user releases the key identified by name.
|
||||
/// </returns>
|
||||
static bool GetKeyUp(KeyCode key);
|
||||
/// <summary>
|
||||
/// Checks if a specified mouse button is being held down.
|
||||
/// This will also be true if GetMouseButtonDown() is true.
|
||||
/// </summary>
|
||||
/// <param name="mouseButton">MouseCode of the mouse button to check.</param>
|
||||
/// <returns>True while the user holds down the mouse button specified.</returns>
|
||||
static bool GetMouseButton(MouseCode mouseButton);
|
||||
/// <summary>
|
||||
/// Checks if a specified mouse button is pressed and was not pressed before.
|
||||
/// </summary>
|
||||
/// <param name="mouseButton">MouseCode of the mouse button to check.</param>
|
||||
/// <returns>
|
||||
/// True during the frame the user pressed the given mouse button.
|
||||
/// </returns>
|
||||
static bool GetMouseButtonDown(MouseCode mouseButton);
|
||||
/// <summary>
|
||||
/// Checks if a specified mouse button is no longer pressed and was pressed
|
||||
/// before.
|
||||
/// </summary>
|
||||
/// <param name="mouseButton">MouseCode of the mouse button to check.</param>
|
||||
/// <returns>
|
||||
/// True during the frame the user releases the given mouse button.
|
||||
/// </returns>
|
||||
static bool GetMouseButtonUp(MouseCode mouseButton);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Cursor Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Sets the position of the mouse cursor relative to the top left corner of the
|
||||
/// window.
|
||||
/// </summary>
|
||||
/// <param name="pos">
|
||||
/// Position of the mouse in window pixel coordinates to set.
|
||||
/// </param>
|
||||
static void SetMousePosition(Vector2 pos);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Timing Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Retrieves the duration that the specified key has been held or was last held
|
||||
/// for.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to check.</param>
|
||||
/// <returns>Time in seconds that the key was held.</returns>
|
||||
static double GetKeyHeldTime(KeyCode key);
|
||||
/// <summary>
|
||||
/// Retrieves the duration that the specified key has not been held or was last
|
||||
/// not been held for.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to check.</param>
|
||||
/// <returns>Time in seconds that the key was held.</returns>
|
||||
static double GetKeyReleasedTime(KeyCode key);
|
||||
/// <summary>
|
||||
/// Retrieves the duration that the specified key has been held or was last held
|
||||
/// for.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to check.</param>
|
||||
/// <returns>Time in seconds that the key was held.</returns>
|
||||
static double GetMouseHeldTime(MouseCode mouseButton);
|
||||
/// <summary>
|
||||
/// Retrieves the duration that the specified key has not been held or was last
|
||||
/// not been held for.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to check.</param>
|
||||
/// <returns>Time in seconds that the key was held.</returns>
|
||||
static double GetMouseReleasedTime(MouseCode mouseButton);
|
||||
};
|
||||
}
|
|
@ -21,15 +21,6 @@ namespace SHADE
|
|||
/// </summary>
|
||||
[System::AttributeUsage(System::AttributeTargets::Field)]
|
||||
public ref class SerializeField : public System::Attribute
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Default Constructor
|
||||
/// </summary>
|
||||
SerializeField();
|
||||
};
|
||||
{};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,12 @@ using System;
|
|||
|
||||
public class RaccoonShowcase : Script
|
||||
{
|
||||
public double RotateSpeed = 1.0;
|
||||
public Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0);
|
||||
[SerializeField]
|
||||
[Tooltip("Speed of the rotation in radians per second.")]
|
||||
private double RotateSpeed = 1.0;
|
||||
[SerializeField]
|
||||
[Tooltip("Speed of the scaling in radians per second around each axis.")]
|
||||
private Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0);
|
||||
private Transform Transform;
|
||||
private double rotation = 0.0;
|
||||
private Vector3 scale = Vector3.Zero;
|
||||
|
|
|
@ -3,7 +3,9 @@ using System;
|
|||
|
||||
public class RaccoonSpin : Script
|
||||
{
|
||||
public double RotateSpeed = 1.0;
|
||||
[SerializeField]
|
||||
[Tooltip("Speed of the rotation in radians per second.")]
|
||||
private double RotateSpeed = 1.0;
|
||||
private double rotation = 0.0;
|
||||
private Transform Transform;
|
||||
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
|
||||
|
|
Loading…
Reference in New Issue