Merge remote-tracking branch 'origin/main' into SP3-2-Physics
This commit is contained in:
commit
cfd387e51c
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -144,7 +144,7 @@ if %_e%==14 (goto :done) else (goto :tinyddsloader)
|
|||
:tinyddsloader
|
||||
echo --------------------tinyddsloader-------------------------
|
||||
rmdir "Dependencies/tinyddsloader" /S /Q
|
||||
git clone https://github.com/benikabocha/tinyddsloader.git "Dependencies/tinyddsloader"
|
||||
git clone https://github.com/SHADE-DP/tinyddsloader.git "Dependencies/tinyddsloader"
|
||||
|
||||
:done
|
||||
echo DONE!
|
||||
|
|
|
@ -30,11 +30,12 @@ project "SHADE_Application"
|
|||
|
||||
externalincludedirs
|
||||
{
|
||||
"%{IncludeDir.spdlog}/include",
|
||||
"%{IncludeDir.VULKAN}/include",
|
||||
"%{IncludeDir.VMA}/include",
|
||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||
"%{IncludeDir.tinyddsloader}"
|
||||
"%{IncludeDir.spdlog}/include",
|
||||
"%{IncludeDir.VULKAN}/include",
|
||||
"%{IncludeDir.VMA}/include",
|
||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||
"%{IncludeDir.RTTR}/include",
|
||||
"%{IncludeDir.tinyddsloader}"
|
||||
}
|
||||
|
||||
externalwarnings "Off"
|
||||
|
@ -72,8 +73,12 @@ project "SHADE_Application"
|
|||
|
||||
filter "configurations:Debug"
|
||||
symbols "On"
|
||||
defines {"_DEBUG"}
|
||||
defines {"_DEBUG", "SHEDITOR"}
|
||||
|
||||
filter "configurations:Release"
|
||||
optimize "On"
|
||||
defines{"_RELEASE", "SHEDITOR"}
|
||||
|
||||
filter "configurations:Publish"
|
||||
optimize "On"
|
||||
defines{"_RELEASE"}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//#define SHEDITOR
|
||||
#ifdef SHEDITOR
|
||||
#include "Editor/SHEditor.h"
|
||||
#include "Editor/SHEditor.hpp"
|
||||
//#include "Scenes/SBEditorScene.h"
|
||||
#endif // SHEDITOR
|
||||
|
||||
|
@ -46,14 +46,13 @@ namespace Sandbox
|
|||
// Set working directory
|
||||
SHADE::SHFileUtilities::SetWorkDirToExecDir();
|
||||
|
||||
SDL_Init(SDL_INIT_EVERYTHING);
|
||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||
|
||||
// Create Systems
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>();
|
||||
// TODO(Diren): Create Physics System here
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>();
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
||||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||
SHADE::SHSystemManager::CreateSystem<SHADE::SHInputManagerSystem>();
|
||||
|
||||
|
@ -79,19 +78,18 @@ namespace Sandbox
|
|||
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHInputManagerSystem, SHADE::SHInputManagerSystem::InputManagerRoutine>();
|
||||
|
||||
//TODO: REMOVE AFTER PRESENTATION
|
||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.fbx");
|
||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
|
||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
|
||||
//TODO: REMOVE AFTER PRESENTATION
|
||||
|
||||
// Set up graphics system and windows
|
||||
graphicsSystem->SetWindow(&window);
|
||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||
//auto [w, h] = window.GetWindowSize();
|
||||
//SDL_SetWindowSize(sdlWindow, w, h);
|
||||
|
||||
|
||||
SHADE::SHSystemManager::Init();
|
||||
#ifdef SHEDITOR
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
|
||||
SHADE::SHEditor::Initialise(sdlWindow);
|
||||
#else
|
||||
#endif
|
||||
|
@ -112,13 +110,9 @@ namespace Sandbox
|
|||
graphicsSystem->BeginRender();
|
||||
|
||||
#ifdef SHEDITOR
|
||||
SHADE::SHEditor::PreRender();
|
||||
//SHADE::SHEditor::Render();
|
||||
SHADE::SHEditor::Update(0.16f);
|
||||
#endif
|
||||
|
||||
#ifdef SHEDITOR
|
||||
SHADE::SHEditor::Render();
|
||||
#endif
|
||||
graphicsSystem->Run(1.0f);
|
||||
graphicsSystem->EndRender();
|
||||
|
||||
|
@ -131,11 +125,12 @@ namespace Sandbox
|
|||
{
|
||||
#ifdef SHEDITOR
|
||||
SHADE::SHEditor::Exit();
|
||||
#endif
|
||||
SHSceneManager::Exit();
|
||||
SHADE::SHSystemManager::Exit();
|
||||
SDL_DestroyWindow(sdlWindow);
|
||||
SDL_Quit();
|
||||
#endif
|
||||
|
||||
SHSceneManager::Exit();
|
||||
SHADE::SHSystemManager::Exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,9 @@ namespace Sandbox
|
|||
}
|
||||
graphicsSystem->BuildMeshBuffers();
|
||||
|
||||
//Test Textures
|
||||
auto textures{ SHADE::SHAssetManager::GetAllTextures() };
|
||||
|
||||
// Create Materials
|
||||
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
|
||||
|
||||
|
|
|
@ -117,12 +117,24 @@ project "SHADE_Engine"
|
|||
|
||||
filter "configurations:Debug"
|
||||
symbols "On"
|
||||
defines {"_DEBUG"}
|
||||
defines {"_DEBUG", "SHEDITOR"}
|
||||
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
||||
--links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
||||
|
||||
filter "configurations:Release"
|
||||
optimize "On"
|
||||
defines{"_RELEASE", "SHEDITOR"}
|
||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
||||
|
||||
filter "configurations:Publish"
|
||||
optimize "On"
|
||||
defines{"_RELEASE"}
|
||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||
excludes
|
||||
{
|
||||
"%{prj.location}/src/Editor/**.cpp",
|
||||
"%{prj.location}/src/Editor/**.h",
|
||||
"%{prj.location}/src/Editor/**.hpp",
|
||||
}
|
||||
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
|
@ -1,11 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "tinyddsloader.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHDDSAsset
|
||||
{
|
||||
tinyddsloader::DDSFile image;
|
||||
};
|
||||
}
|
|
@ -21,9 +21,9 @@ namespace SHADE
|
|||
std::string meshName;
|
||||
|
||||
std::vector<SHVec3> vertexPosition;
|
||||
std::vector<SHVec2> texCoords;
|
||||
std::vector<SHVec3> vertexTangent;
|
||||
std::vector<SHVec3> vertexNormal;
|
||||
std::vector<SHVec2> texCoords;
|
||||
std::vector<uint32_t> indices;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
#include "tinyddsloader.h"
|
||||
|
||||
#include "Graphics/MiddleEnd/Textures/SHTextureLibrary.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHTextureAsset
|
||||
{
|
||||
uint32_t numBytes;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
SHTexture::TextureFormat format;
|
||||
std::vector<uint32_t> mipOffsets;
|
||||
SHTexture::PixelChannel const * pixelData;
|
||||
|
||||
SHTextureAsset()
|
||||
: numBytes{ 0 },
|
||||
width{ 0 },
|
||||
height{ 0 },
|
||||
format{ SHTexture::TextureFormat::eUndefined },
|
||||
pixelData{ nullptr }
|
||||
{}
|
||||
|
||||
SHTextureAsset(SHTextureAsset const& rhs)
|
||||
: numBytes{ rhs.numBytes },
|
||||
width{ rhs.width },
|
||||
height{ rhs.height },
|
||||
format{ rhs.format },
|
||||
mipOffsets{ rhs.mipOffsets },
|
||||
pixelData(rhs.pixelData)
|
||||
{}
|
||||
|
||||
//SHTextureAsset(SHTextureAsset&& rhs)
|
||||
// : numBytes{ rhs.numBytes },
|
||||
// width{ rhs.width },
|
||||
// height{ rhs.height },
|
||||
// format{ rhs.format },
|
||||
// mipOffsets{ rhs.mipOffsets },
|
||||
// pixelData(std::move(rhs.pixelData))
|
||||
//{}
|
||||
};
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHDDSLoader.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
std::string SHDDSLoader::TinyDDSResultToString(tinyddsloader::Result value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case tinyddsloader::Result::ErrorFileOpen:
|
||||
return "File open err";
|
||||
case tinyddsloader::Result::ErrorRead:
|
||||
return "File read err";
|
||||
case tinyddsloader::Result::ErrorMagicWord:
|
||||
return "File header magicword err";
|
||||
case tinyddsloader::Result::ErrorSize:
|
||||
return "File size err";
|
||||
case tinyddsloader::Result::ErrorVerify:
|
||||
return "Pixel format err";
|
||||
case tinyddsloader::Result::ErrorNotSupported:
|
||||
return "Unsupported format";
|
||||
case tinyddsloader::Result::ErrorInvalidData:
|
||||
return "Invalid data";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void SHDDSLoader::LoadImageAsset(AssetPath path, SHDDSAsset& asset)
|
||||
{
|
||||
tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
|
||||
loadResult = asset.image.Load(path.string().c_str());
|
||||
if (loadResult != tinyddsloader::Result::Success)
|
||||
{
|
||||
SHLOG_ERROR("Unable to load DDS file: {} at {}", TinyDDSResultToString(loadResult), path.string());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#pragma once
|
||||
#define TINYDDSLOADER_IMPLEMENTATION
|
||||
|
||||
#include "../SHAssetMacros.h"
|
||||
#include "../Asset Types/SHDDSAsset.h"
|
||||
#include "tinyddsloader.h"
|
||||
#include <vector>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHDDSLoader
|
||||
{
|
||||
private:
|
||||
static std::string TinyDDSResultToString(tinyddsloader::Result value);
|
||||
public:
|
||||
static void LoadImageAsset(AssetPath paths, SHDDSAsset& image);
|
||||
};
|
||||
}
|
|
@ -100,9 +100,7 @@ namespace SHADE
|
|||
| aiProcess_JoinIdenticalVertices
|
||||
// join identical vertices/ optimize indexing
|
||||
| aiProcess_RemoveRedundantMaterials // remove redundant materials
|
||||
| aiProcess_FindInvalidData
|
||||
// detect invalid model data, such as invalid normal vectors
|
||||
| aiProcess_PreTransformVertices // pre-transform all vertices
|
||||
| aiProcess_FindInvalidData// detect invalid model data, such as invalid normal vectors
|
||||
| aiProcess_FlipUVs // flip the V to match the Vulkans way of doing UVs
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHMeshWriter.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
void SHADE::SHMeshWriter::WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
|
||||
{
|
||||
std::ofstream file{path, std::ios::out | std::ios::binary};
|
||||
if (!file.is_open())
|
||||
{
|
||||
SHLOG_ERROR("Unable to open file for writing mesh file: {}", path.string());
|
||||
}
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(&(asset.header.vertexCount)),
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<const char*>(&(asset.header.indexCount)),
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
|
||||
auto const vertexVec3Byte {sizeof(SHVec3) * asset.header.vertexCount};
|
||||
auto const vertexVec2Byte {sizeof(SHVec2) * asset.header.vertexCount};
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.vertexPosition.data()),
|
||||
vertexVec3Byte
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.vertexTangent.data()),
|
||||
vertexVec3Byte
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.vertexNormal.data()),
|
||||
vertexVec3Byte
|
||||
);
|
||||
|
||||
file.write(
|
||||
reinterpret_cast<char const*>(asset.texCoords.data()),
|
||||
vertexVec2Byte
|
||||
);
|
||||
|
||||
file.close();
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "../Asset Types/SHMeshAsset.h"
|
||||
#include "../SHAssetMacros.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHMeshWriter
|
||||
{
|
||||
private:
|
||||
public:
|
||||
static void WriteMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHTextureLoader.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
std::string SHTextureLoader::TinyDDSResultToString(tinyddsloader::Result value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case tinyddsloader::Result::ErrorFileOpen:
|
||||
return "File open err";
|
||||
case tinyddsloader::Result::ErrorRead:
|
||||
return "File read err";
|
||||
case tinyddsloader::Result::ErrorMagicWord:
|
||||
return "File header magic word err";
|
||||
case tinyddsloader::Result::ErrorSize:
|
||||
return "File size err";
|
||||
case tinyddsloader::Result::ErrorVerify:
|
||||
return "Pixel format err";
|
||||
case tinyddsloader::Result::ErrorNotSupported:
|
||||
return "Unsupported format";
|
||||
case tinyddsloader::Result::ErrorInvalidData:
|
||||
return "Invalid data";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
vk::Format SHTextureLoader::ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm:
|
||||
case tinyddsloader::DDSFile::DXGIFormat::BC1_UNorm_SRGB:
|
||||
return isLinear ? vk::Format::eBc1RgbaUnormBlock : vk::Format::eBc1RgbaSrgbBlock;
|
||||
case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm:
|
||||
case tinyddsloader::DDSFile::DXGIFormat::BC2_UNorm_SRGB:
|
||||
return isLinear ? vk::Format::eBc2UnormBlock : vk::Format::eBc2SrgbBlock;
|
||||
case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm:
|
||||
case tinyddsloader::DDSFile::DXGIFormat::BC3_UNorm_SRGB:
|
||||
return isLinear ? vk::Format::eBc3UnormBlock : vk::Format::eBc3SrgbBlock;
|
||||
case tinyddsloader::DDSFile::DXGIFormat::BC5_UNorm:
|
||||
case tinyddsloader::DDSFile::DXGIFormat::BC5_SNorm:
|
||||
return isLinear ? vk::Format::eBc5UnormBlock : vk::Format::eBc5SnormBlock;
|
||||
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm:
|
||||
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_UNorm_SRGB:
|
||||
return isLinear ? vk::Format::eR8G8B8A8Unorm : vk::Format::eR8G8B8A8Srgb;
|
||||
case tinyddsloader::DDSFile::DXGIFormat::R8G8B8A8_SNorm:
|
||||
return vk::Format::eR8G8B8A8Snorm;
|
||||
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm:
|
||||
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8A8_UNorm_SRGB:
|
||||
return isLinear ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8A8Srgb;
|
||||
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8X8_UNorm:
|
||||
case tinyddsloader::DDSFile::DXGIFormat::B8G8R8X8_UNorm_SRGB:
|
||||
return isLinear ? vk::Format::eB8G8R8A8Unorm : vk::Format::eB8G8R8Srgb;
|
||||
default:
|
||||
throw std::runtime_error("Unsupported DDS format.");
|
||||
}
|
||||
}
|
||||
|
||||
void SHTextureLoader::LoadImageAsset(AssetPath path, SHTextureAsset& asset)
|
||||
{
|
||||
tinyddsloader::Result loadResult = tinyddsloader::Result::Success;
|
||||
tinyddsloader::DDSFile file;
|
||||
loadResult = file.Load(path.string().c_str());
|
||||
if (loadResult != tinyddsloader::Result::Success)
|
||||
{
|
||||
SHLOG_ERROR("Unable to load Texture file: {} at {}", TinyDDSResultToString(loadResult), path.string());
|
||||
}
|
||||
|
||||
size_t totalBytes{ 0 };
|
||||
|
||||
std::vector<uint32_t> mipOff(file.GetMipCount());
|
||||
|
||||
for (auto i{0}; i < file.GetMipCount(); ++i)
|
||||
{
|
||||
mipOff.push_back(totalBytes);
|
||||
totalBytes += file.GetImageData(i, 0)->m_memSlicePitch;
|
||||
}
|
||||
|
||||
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
||||
std::memcpy(pixel, file.GetDDSData(), totalBytes);
|
||||
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
|
||||
|
||||
asset.numBytes = totalBytes;
|
||||
asset.width = file.GetWidth();
|
||||
asset.height = file.GetHeight();
|
||||
asset.format = ddsLoaderToVkFormat(file.GetFormat(), true);
|
||||
asset.mipOffsets = std::move(mipOff);
|
||||
asset.pixelData = std::move(pixel);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#define TINYDDSLOADER_IMPLEMENTATION
|
||||
|
||||
#include "../SHAssetMacros.h"
|
||||
#include "../Asset Types/SHTextureAsset.h"
|
||||
#include "tinyddsloader.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHTextureLoader
|
||||
{
|
||||
private:
|
||||
static std::string TinyDDSResultToString(tinyddsloader::Result value);
|
||||
static vk::Format ddsLoaderToVkFormat(tinyddsloader::DDSFile::DXGIFormat format, bool isLinear);
|
||||
|
||||
public:
|
||||
static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
|
||||
};
|
||||
}
|
|
@ -69,8 +69,11 @@ enum class AssetType : uint8_t
|
|||
#define SCENE_EXTENSION ".SHADE"
|
||||
#define PREFAB_EXTENSION ".SHPrefab"
|
||||
#define MATERIAL_EXTENSION ".SHMat"
|
||||
#define TEXTURE_EXTENSION ".dds"
|
||||
#define MESH_EXTENSION ".fbx"
|
||||
#define TEXTURE_EXTENSION ".shtex"
|
||||
#define DDS_EXTENSION ".dds"
|
||||
#define FBX_EXTENSION ".fbx"
|
||||
#define GLTF_EXTENSION ".gltf"
|
||||
#define MESH_EXTENSION ".shmesh"
|
||||
|
||||
std::string const EXTENSIONS[] = {
|
||||
AUDIO_EXTENSION,
|
||||
|
@ -78,11 +81,14 @@ std::string const EXTENSIONS[] = {
|
|||
MATERIAL_EXTENSION,
|
||||
IMAGE_EXTENSION,
|
||||
TEXTURE_EXTENSION,
|
||||
DDS_EXTENSION,
|
||||
MESH_EXTENSION,
|
||||
SCRIPT_EXTENSION,
|
||||
SCENE_EXTENSION,
|
||||
PREFAB_EXTENSION,
|
||||
AUDIO_WAV_EXTENSION
|
||||
AUDIO_WAV_EXTENSION,
|
||||
FBX_EXTENSION,
|
||||
GLTF_EXTENSION
|
||||
};
|
||||
|
||||
// Error flags
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "Filesystem/SHFileSystem.h"
|
||||
|
||||
#include "Libraries/SHMeshLoader.h"
|
||||
#include "Libraries/SHDDSLoader.h"
|
||||
#include "Libraries/SHTextureLoader.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ namespace SHADE
|
|||
std::unordered_map<AssetID, SHAsset> SHAssetManager::assetRegistry;
|
||||
|
||||
std::unordered_map<AssetID, SHMeshAsset> SHAssetManager::meshCollection;
|
||||
std::unordered_map<AssetID, SHDDSAsset> SHAssetManager::ddsCollection;
|
||||
std::unordered_map<AssetID, SHTextureAsset> SHAssetManager::textureCollection;
|
||||
|
||||
/****************************************************************************
|
||||
* \brief Static function to generate asset ID.
|
||||
|
@ -199,7 +199,7 @@ namespace SHADE
|
|||
{
|
||||
AssetPath path{ p };
|
||||
|
||||
if (path.extension().string() == MESH_EXTENSION)
|
||||
if (path.extension().string() == GLTF_EXTENSION)
|
||||
{
|
||||
LoadGLTF(
|
||||
{
|
||||
|
@ -211,7 +211,7 @@ namespace SHADE
|
|||
}
|
||||
);
|
||||
}
|
||||
else if (path.extension().string() == TEXTURE_EXTENSION)
|
||||
else if (path.extension().string() == DDS_EXTENSION)
|
||||
{
|
||||
LoadDDS(
|
||||
{
|
||||
|
@ -236,6 +236,17 @@ namespace SHADE
|
|||
return result;
|
||||
}
|
||||
|
||||
std::vector<SHTextureAsset> SHAssetManager::GetAllTextures() noexcept
|
||||
{
|
||||
std::vector<SHTextureAsset> result;
|
||||
for (auto const& dds : textureCollection)
|
||||
{
|
||||
result.push_back(dds.second);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* \param Path for meta data file
|
||||
* \param Path for asset file
|
||||
|
@ -294,11 +305,11 @@ namespace SHADE
|
|||
|
||||
void SHAssetManager::LoadDDS(SHAsset asset) noexcept
|
||||
{
|
||||
SHDDSAsset image;
|
||||
SHTextureAsset image;
|
||||
|
||||
SHDDSLoader::LoadImageAsset(asset.path, image);
|
||||
SHTextureLoader::LoadImageAsset(asset.path, image);
|
||||
|
||||
ddsCollection.emplace(GenerateAssetID(AssetType::DDS), image);
|
||||
textureCollection.emplace(GenerateAssetID(AssetType::DDS), image);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "SHAsset.h"
|
||||
|
||||
#include "Asset Types/SHMeshAsset.h"
|
||||
#include "Asset Types/SHDDSAsset.h"
|
||||
#include "Asset Types/SHTextureAsset.h"
|
||||
#include "SH_API.h"
|
||||
|
||||
namespace SHADE
|
||||
|
@ -73,6 +73,7 @@ namespace SHADE
|
|||
//TODO: TEMPORARY FOR TESTING GLTF & DDS
|
||||
static void LoadDataTemp(std::string path) noexcept;
|
||||
static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
|
||||
static std::vector<SHTextureAsset> GetAllTextures() noexcept;
|
||||
|
||||
private:
|
||||
/****************************************************************************
|
||||
|
@ -127,6 +128,6 @@ namespace SHADE
|
|||
static std::unordered_map<AssetID, SHAsset> assetRegistry;
|
||||
|
||||
static std::unordered_map<AssetID, SHMeshAsset> meshCollection;
|
||||
static std::unordered_map<AssetID, SHDDSAsset> ddsCollection;
|
||||
static std::unordered_map<AssetID, SHTextureAsset> textureCollection;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
//#==============================================================#
|
||||
//|| STL Includes ||
|
||||
//#==============================================================#
|
||||
#include <functional>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHBaseCommand
|
||||
{
|
||||
public:
|
||||
virtual ~SHBaseCommand() = default;
|
||||
virtual void Execute() {}
|
||||
virtual void Undo() {}
|
||||
virtual void Merge(std::shared_ptr<SHBaseCommand>) {}
|
||||
};//struct SHBaseCommand
|
||||
|
||||
template <typename T>
|
||||
class SHCommand : SHBaseCommand
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(T const&)> SetterFunction;
|
||||
|
||||
SHCommand(T const& oldVal, T const& value, SetterFunction setFnc)
|
||||
: oldValue(oldVal), newValue(value), set(setFnc)
|
||||
{
|
||||
}
|
||||
|
||||
void Execute() override
|
||||
{
|
||||
set(newValue);
|
||||
}
|
||||
|
||||
void Undo() override
|
||||
{
|
||||
set(oldValue);
|
||||
}
|
||||
|
||||
void Merge(std::shared_ptr<SHBaseCommand> newCommand) override
|
||||
{
|
||||
newValue = std::reinterpret_pointer_cast<SHCommand>(newCommand)->newValue;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T oldValue;
|
||||
T newValue;
|
||||
SetterFunction set;
|
||||
};
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,57 @@
|
|||
//#==============================================================#
|
||||
//|| PCH Include ||
|
||||
//#==============================================================#
|
||||
#include "SHpch.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "SHCommandManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
SHCommandManager::CommandStack SHCommandManager::undoStack{};
|
||||
SHCommandManager::CommandStack SHCommandManager::redoStack{};
|
||||
|
||||
void SHCommandManager::PerformCommand(CommandPtr commandPtr, bool const& overrideValue)
|
||||
{
|
||||
redoStack = CommandStack();
|
||||
commandPtr->Execute();
|
||||
if (overrideValue && !undoStack.empty())
|
||||
{
|
||||
undoStack.top()->Merge(commandPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
undoStack.push(commandPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void SHCommandManager::UndoCommand()
|
||||
{
|
||||
if (undoStack.empty())
|
||||
return;
|
||||
undoStack.top()->Undo();
|
||||
redoStack.push(undoStack.top());
|
||||
undoStack.pop();
|
||||
}
|
||||
|
||||
void SHCommandManager::RedoCommand()
|
||||
{
|
||||
if (redoStack.empty())
|
||||
return;
|
||||
redoStack.top()->Execute();
|
||||
undoStack.push(redoStack.top());
|
||||
redoStack.pop();
|
||||
}
|
||||
|
||||
std::size_t SHCommandManager::GetUndoStackSize()
|
||||
{
|
||||
return undoStack.size();
|
||||
}
|
||||
|
||||
std::size_t SHCommandManager::GetRedoStackSize()
|
||||
{
|
||||
return redoStack.size();
|
||||
}
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
//#==============================================================#
|
||||
//|| STL Includes ||
|
||||
//#==============================================================#
|
||||
#include <stack>
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "SHCommand.hpp"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHCommandManager
|
||||
{
|
||||
public:
|
||||
//#==============================================================#
|
||||
//|| Type Aliases ||
|
||||
//#==============================================================#
|
||||
using CommandPtr = std::shared_ptr<SHBaseCommand>;
|
||||
using CommandStack = std::stack<CommandPtr>;
|
||||
|
||||
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false);
|
||||
static void UndoCommand();
|
||||
static void RedoCommand();
|
||||
static std::size_t GetUndoStackSize();
|
||||
static std::size_t GetRedoStackSize();
|
||||
|
||||
private:
|
||||
static CommandStack undoStack;
|
||||
static CommandStack redoStack;
|
||||
};
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,21 @@
|
|||
#include "SHpch.h"
|
||||
|
||||
#include "SHDragDrop.hpp"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
bool SHDragDrop::hasDragDrop = false;
|
||||
|
||||
bool SHDragDrop::BeginSource(ImGuiDragDropFlags const flags)
|
||||
{ return ImGui::BeginDragDropSource(flags); }
|
||||
|
||||
void SHDragDrop::EndSource()
|
||||
{ ImGui::EndDragDropSource();}
|
||||
|
||||
bool SHDragDrop::BeginTarget()
|
||||
{ return ImGui::BeginDragDropTarget(); }
|
||||
|
||||
void SHDragDrop::EndTarget()
|
||||
{ ImGui::EndDragDropTarget(); hasDragDrop = false;}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <imgui.h>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
//TODO: Convert to RTTR?
|
||||
constexpr auto DRAG_EID = "DragEID";
|
||||
constexpr auto DRAG_RESOURCE = "DragResource";
|
||||
|
||||
|
||||
struct SHDragDrop
|
||||
{
|
||||
static bool BeginSource(ImGuiDragDropFlags const flags = 0);
|
||||
/**
|
||||
* \brief Ends the DragDrop Source. ONLY CALL IF BeginSource returns true
|
||||
*/
|
||||
static void EndSource();
|
||||
|
||||
template<typename T>
|
||||
static bool SetPayload(std::string_view const type, T* object, ImGuiCond const cond = 0)
|
||||
{
|
||||
hasDragDrop = ImGui::SetDragDropPayload(type.data(), static_cast<void*>(object), sizeof(T), cond);
|
||||
return hasDragDrop;
|
||||
}
|
||||
|
||||
static bool BeginTarget();
|
||||
/**
|
||||
* \brief Ends the DragDrop Target. ONLY CALL IF BeginTarget returns true
|
||||
*/
|
||||
static void EndTarget();
|
||||
|
||||
template<typename T>
|
||||
static T* AcceptPayload(std::string_view const type, ImGuiDragDropFlags const flags = 0)
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(type.data(), flags))
|
||||
return static_cast<T*>(payload->Data);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool hasDragDrop;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
//#==============================================================#
|
||||
//|| PCH Include ||
|
||||
//#==============================================================#
|
||||
#include "SHpch.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "Editor/SHImGuiHelpers.hpp"
|
||||
#include "Editor/SHEditorWidgets.hpp"
|
||||
#include "SHHierarchyPanel.h"
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Editor/SHEditor.hpp"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||
#include "Tools/SHException.h"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <imgui.h>
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
//#==============================================================#
|
||||
//|| Public Member Functions ||
|
||||
//#==============================================================#
|
||||
SHHierarchyPanel::SHHierarchyPanel()
|
||||
:SHEditorWindow("Hierarchy Panel", ImGuiWindowFlags_MenuBar)
|
||||
{
|
||||
}
|
||||
|
||||
void SHHierarchyPanel::Init()
|
||||
{
|
||||
SHEditorWindow::Init();
|
||||
}
|
||||
|
||||
void SHHierarchyPanel::Update()
|
||||
{
|
||||
SHEditorWindow::Update();
|
||||
|
||||
isAnyNodeSelected = false;
|
||||
|
||||
if (Begin())
|
||||
{
|
||||
DrawMenuBar();
|
||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
if(const auto root = sceneGraph.GetRoot())
|
||||
{
|
||||
auto const& children = root->GetChildren();
|
||||
for (const auto child : children)
|
||||
{
|
||||
RecursivelyDrawEntityNode(child);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_WARNING("Scene Graph root is null! Unable to render hierarchy.")
|
||||
}
|
||||
|
||||
if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||
{
|
||||
SHEditor::selectedEntities.clear();
|
||||
}
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
void SHHierarchyPanel::Exit()
|
||||
{
|
||||
SHEditorWindow::Exit();
|
||||
}
|
||||
|
||||
//#==============================================================#
|
||||
//|| Private Member Functions ||
|
||||
//#==============================================================#
|
||||
void SHHierarchyPanel::DrawMenuBar() const noexcept
|
||||
{
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::SmallButton(ICON_MD_ADD))
|
||||
{
|
||||
SHEntityManager::CreateEntity();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Add Entity");
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
}
|
||||
|
||||
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* currentNode)
|
||||
{
|
||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
|
||||
//Get node data (Children, eid, selected)
|
||||
auto& children = currentNode->GetChildren();
|
||||
EntityID eid = currentNode->GetEntityID();
|
||||
const bool isSelected = (std::ranges::find(SHEditor::selectedEntities, eid) != SHEditor::selectedEntities.end());
|
||||
|
||||
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
||||
|
||||
//bool highlighted = false;
|
||||
//if(highlighted)
|
||||
//{
|
||||
// ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
|
||||
//}
|
||||
|
||||
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
||||
//Draw Node
|
||||
bool isNodeOpen = ImGui::TreeNodeEx((void*)eid, nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str());
|
||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
|
||||
//Check For Begin Drag
|
||||
if (SHDragDrop::BeginSource())
|
||||
{
|
||||
ImGui::Text("Moving EID: %zu", eid);
|
||||
SHDragDrop::SetPayload<EntityID>(DRAG_EID, &eid);
|
||||
SHDragDrop::EndSource();
|
||||
}
|
||||
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
||||
{
|
||||
if (const EntityID* eidPayload = SHDragDrop::AcceptPayload<EntityID>(DRAG_EID)) //If payload is valid
|
||||
{
|
||||
EntityID const dropEID = *eidPayload;
|
||||
if(!sceneGraph.GetChild(dropEID, eid))
|
||||
sceneGraph.SetParent(dropEID, eid); //Set dropEID parent to eid (belonging to current Node)
|
||||
SHDragDrop::EndTarget();
|
||||
}
|
||||
}
|
||||
|
||||
//Context menu
|
||||
if(ImGui::BeginPopupContextItem(std::to_string(eid).c_str()))
|
||||
{
|
||||
if(!isSelected)
|
||||
{
|
||||
SHEditor::selectedEntities.clear();
|
||||
SHEditor::selectedEntities.push_back(eid);
|
||||
}
|
||||
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||
{
|
||||
SHEntityManager::DestroyEntity(eid);
|
||||
}
|
||||
|
||||
if((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
|
||||
{
|
||||
sceneGraph.SetParent(currentNode->GetEntityID(), nullptr);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
//Handle node selection
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||
{
|
||||
if (!isSelected)
|
||||
{
|
||||
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||
SHEditor::selectedEntities.clear();
|
||||
SHEditor::selectedEntities.push_back(eid);
|
||||
}//if not selected
|
||||
else
|
||||
{
|
||||
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||
{
|
||||
auto it = std::ranges::remove(SHEditor::selectedEntities, eid).begin();
|
||||
}//if mod ctrl is not pressed
|
||||
else
|
||||
{
|
||||
SHEditor::selectedEntities.clear();
|
||||
SHEditor::selectedEntities.push_back(eid);
|
||||
}
|
||||
}//if selected
|
||||
}//if left mouse button released
|
||||
}//if item hovered
|
||||
|
||||
if (isNodeOpen)
|
||||
{
|
||||
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||
const float horizontalOffset = 0.0f;
|
||||
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||
|
||||
ImVec2 vertLineStart = ImGui::GetCursorScreenPos();
|
||||
vertLineStart.x += horizontalOffset;
|
||||
ImVec2 vertLineEnd = vertLineStart;
|
||||
|
||||
for (const auto child : children)
|
||||
{
|
||||
const float horizontalLineSize = 8.0f;
|
||||
const ImRect childRect = RecursivelyDrawEntityNode(child);
|
||||
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
|
||||
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 2);
|
||||
vertLineEnd.y = midPoint;
|
||||
}
|
||||
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 2);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
return nodeRect;
|
||||
}
|
||||
|
||||
void SHHierarchyPanel::CreateChildEntity(EntityID parentEID) const noexcept
|
||||
{
|
||||
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
|
||||
}
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <imgui.h>
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "imgui_internal.h"
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHSceneNode;
|
||||
constexpr ImVec4 highlightedColor = ImVec4(0.f, 0.7f, 0.0f, 1.0f);
|
||||
|
||||
class SHHierarchyPanel final : public SHEditorWindow
|
||||
{
|
||||
public:
|
||||
SHHierarchyPanel();
|
||||
void Init() override;
|
||||
void Update() override;
|
||||
void Exit() override;
|
||||
private:
|
||||
void DrawMenuBar() const noexcept;
|
||||
ImRect RecursivelyDrawEntityNode(SHSceneNode*);
|
||||
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||
std::string filter;
|
||||
bool isAnyNodeSelected = false;
|
||||
};//class SHHierarchyPanel
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <imgui.h>
|
||||
#include <rttr/type>
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
#include "Editor/SHEditorWidgets.hpp"
|
||||
namespace SHADE
|
||||
{
|
||||
template<typename T, std::enable_if_t<std::is_base_of<SHComponent, T>::value, bool> = true>
|
||||
static void DrawContextMenu(T* component)
|
||||
{
|
||||
if(!component)
|
||||
return;
|
||||
rttr::string_view componentName = rttr::type::get<T>().get_name();
|
||||
|
||||
if (ImGui::BeginPopupContextItem(componentName.data()))
|
||||
{
|
||||
|
||||
if (ImGui::Selectable(std::format("{} Copy {}", ICON_MD_CONTENT_COPY, componentName.data()).data()))
|
||||
{
|
||||
//SHClipboardUtil::WriteStringToClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT, SHComponentToString(component));
|
||||
}
|
||||
if (ImGui::Selectable(std::format("{} Paste {}", ICON_MD_CONTENT_PASTE, componentName.data()).data()))
|
||||
{
|
||||
//SHStringToComponent(component, SHClipboardUtil::ReadStringFromClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT));
|
||||
}
|
||||
if (ImGui::Selectable(std::format("{} Delete {}", ICON_MD_DELETE, componentName.data()).data()))
|
||||
{
|
||||
SHComponentManager::RemoveComponent<T>(component->GetEID());
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
template<typename T, std::enable_if_t<std::is_base_of_v<SHComponent, T>, bool> = true>
|
||||
static void DrawComponent(T* component)
|
||||
{
|
||||
if (!component)
|
||||
return;
|
||||
auto componentType = rttr::type::get(*component);
|
||||
CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
||||
ImGui::SameLine();
|
||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||
{
|
||||
DrawContextMenu(component);
|
||||
auto const& properties = componentType.get_properties();
|
||||
for (auto const& property : properties)
|
||||
{
|
||||
auto const& type = property.get_type();
|
||||
|
||||
if (type == rttr::type::get<SHVec4>())
|
||||
{
|
||||
DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); });
|
||||
}
|
||||
else if (type == rttr::type::get<SHVec3>())
|
||||
{
|
||||
DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); });
|
||||
}
|
||||
}
|
||||
}
|
||||
else DrawContextMenu(component);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#include "SHpch.h"
|
||||
|
||||
#include "SHEditorInspector.h"
|
||||
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
|
||||
#include "Editor/SHEditor.hpp"
|
||||
#include "Editor/SHImGuiHelpers.hpp"
|
||||
#include "Editor/SHEditorWidgets.hpp"
|
||||
#include "SHEditorComponentView.hpp"
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||
void DrawAddComponentButton(EntityID const& eid)
|
||||
{
|
||||
if(!SHComponentManager::HasComponent<ComponentType>(eid) && ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()))
|
||||
{
|
||||
SHComponentManager::AddComponent<ComponentType>(eid);
|
||||
}
|
||||
}
|
||||
|
||||
SHEditorInspector::SHEditorInspector()
|
||||
:SHEditorWindow("Inspector", ImGuiWindowFlags_MenuBar)
|
||||
{
|
||||
}
|
||||
|
||||
void SHEditorInspector::Init()
|
||||
{
|
||||
SHEditorWindow::Init();
|
||||
}
|
||||
|
||||
void SHEditorInspector::Update()
|
||||
{
|
||||
SHEditorWindow::Update();
|
||||
if (Begin())
|
||||
{
|
||||
if (!SHEditor::selectedEntities.empty())
|
||||
{
|
||||
EntityID const& eid = SHEditor::selectedEntities[0];
|
||||
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||
|
||||
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
||||
CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::InputText("##EntityName", &entity->name);
|
||||
|
||||
if (auto transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid))
|
||||
{
|
||||
DrawComponent(transformComponent);
|
||||
}
|
||||
ImGui::Separator();
|
||||
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
||||
{
|
||||
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||
DrawAddComponentButton<SHRenderable>(eid);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
void SHEditorInspector::Exit()
|
||||
{
|
||||
SHEditorWindow::Exit();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <imgui.h>
|
||||
#include <rttr/type>
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHComponent;
|
||||
|
||||
class SHEditorInspector final : public SHEditorWindow
|
||||
{
|
||||
public:
|
||||
SHEditorInspector();
|
||||
void Init() override;
|
||||
void Update() override;
|
||||
void Exit() override;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
#include "SHpch.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "SHEditorMenuBar.h"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Editor/Command/SHCommandManager.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <rttr/type>
|
||||
|
||||
#include "Editor/SHEditor.hpp"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||
|
||||
constexpr ImGuiWindowFlags dockspaceFlags = ImGuiDockNodeFlags_PassthruCentralNode;
|
||||
|
||||
//#==============================================================#
|
||||
//|| Public Member Functions ||
|
||||
//#==============================================================#
|
||||
SHEditorMenuBar::SHEditorMenuBar()
|
||||
:SHEditorWindow("SHEditorMenuBar", editorMenuBarFlags | ImGuiWindowFlags_NoBackground)
|
||||
{
|
||||
}
|
||||
|
||||
void SHEditorMenuBar::Init()
|
||||
{
|
||||
SHEditorWindow::Init();
|
||||
}
|
||||
|
||||
void SHEditorMenuBar::Update()
|
||||
{
|
||||
SHEditorWindow::Update();
|
||||
DrawMainMenuBar();
|
||||
DrawSecondaryBar();
|
||||
DrawStatusBar();
|
||||
}
|
||||
|
||||
//#==============================================================#
|
||||
//|| Private Member Functions ||
|
||||
//#==============================================================#
|
||||
void SHEditorMenuBar::DrawMainMenuBar() noexcept
|
||||
{
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { ImVec2(0.0f, 0.0f) });
|
||||
if (Begin())
|
||||
{
|
||||
ImGui::PopStyleVar(3);
|
||||
|
||||
if (ImGui::BeginMainMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
{
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if(ImGui::BeginMenu("Edit"))
|
||||
{
|
||||
ImGui::BeginDisabled(!SHCommandManager::GetUndoStackSize());
|
||||
if(ImGui::Button(std::format("{} Undo", ICON_MD_UNDO).data()))
|
||||
{
|
||||
SHCommandManager::UndoCommand();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::BeginDisabled(!SHCommandManager::GetRedoStackSize());
|
||||
if(ImGui::Button(std::format("{} Redo", ICON_MD_REDO).data()))
|
||||
{
|
||||
SHCommandManager::RedoCommand();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if(ImGui::BeginMenu("Theme"))
|
||||
{
|
||||
auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
|
||||
auto values = styles.get_values();
|
||||
for (auto style : values)
|
||||
{
|
||||
if(ImGui::Selectable(style.to_string().c_str()))
|
||||
{
|
||||
SHEditor::SetStyle(style.convert<SHEditor::Style>());
|
||||
}
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
const ImGuiID dockspace_id = ImGui::GetID("DockSpace");
|
||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspaceFlags);
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
void SHEditorMenuBar::DrawSecondaryBar() const noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHEditorMenuBar::DrawStatusBar() const noexcept
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { ImVec2(0.0f, 0.0f) });
|
||||
if (ImGui::BeginViewportSideBar("MainStatusBar", ImGui::GetMainViewport(), ImGuiDir_Down, menuBarHeight, editorMenuBarFlags))
|
||||
{
|
||||
ImGui::Text("Entity count: ");
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::PopStyleVar(3);
|
||||
|
||||
}
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHEditorMenuBar final : public SHEditorWindow
|
||||
{
|
||||
public:
|
||||
SHEditorMenuBar();
|
||||
virtual void Init() override;
|
||||
virtual void Update() override;
|
||||
private:
|
||||
void DrawMainMenuBar() noexcept;
|
||||
void DrawSecondaryBar() const noexcept;
|
||||
void DrawStatusBar() const noexcept;
|
||||
float menuBarHeight = 20.0f;
|
||||
};//class SHEditorMenuBar
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,46 @@
|
|||
//#==============================================================#
|
||||
//|| PCH Include ||
|
||||
//#==============================================================#
|
||||
#include "SHpch.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "SHEditorWindow.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <imgui.h>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
//#==============================================================#
|
||||
//|| Public Member Functions ||
|
||||
//#==============================================================#
|
||||
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
|
||||
: isOpen(true), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
|
||||
{
|
||||
}
|
||||
|
||||
void SHEditorWindow::Init()
|
||||
{
|
||||
}
|
||||
|
||||
void SHEditorWindow::Update()
|
||||
{
|
||||
}
|
||||
|
||||
void SHEditorWindow::Exit()
|
||||
{
|
||||
}
|
||||
|
||||
//#==============================================================#
|
||||
//|| Protected Member Functions ||
|
||||
//#==============================================================#
|
||||
bool SHEditorWindow::Begin()
|
||||
{
|
||||
return ImGui::Begin(windowName.data(), &isOpen, windowFlags);
|
||||
}
|
||||
}//namespace SHADE
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
//#==============================================================#
|
||||
//|| STL Includes ||
|
||||
//#==============================================================#
|
||||
#include <string>
|
||||
|
||||
//#==============================================================#
|
||||
//|| Forward Declarations ||
|
||||
//#==============================================================#
|
||||
struct ImGuiIO;
|
||||
typedef int ImGuiWindowFlags;
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHEditorWindow
|
||||
{
|
||||
public:
|
||||
SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags);
|
||||
virtual ~SHEditorWindow() = default;
|
||||
virtual void Init();
|
||||
virtual void Update();
|
||||
virtual void Exit();
|
||||
bool isOpen = false;
|
||||
std::string_view windowName;
|
||||
protected:
|
||||
virtual bool Begin();
|
||||
ImGuiWindowFlags windowFlags = 0;
|
||||
ImGuiIO& io;
|
||||
};//class SHEditorWindow
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar
|
||||
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
|
||||
#include "Inspector/SHEditorInspector.h" //Inspector
|
File diff suppressed because it is too large
Load Diff
|
@ -1,79 +1,125 @@
|
|||
//#==============================================================#
|
||||
//|| PCH Include ||
|
||||
//#==============================================================#
|
||||
#include "SHpch.h"
|
||||
#include "SHEditor.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include "IconsMaterialDesign.h"
|
||||
#include "DragDrop/SHDragDrop.hpp"
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "Tools/SHLogger.h"
|
||||
#include "Tools/SHException.h"
|
||||
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
|
||||
#include "Graphics/Instance/SHVkInstance.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||
|
||||
//IMGUI Backend includes
|
||||
#include "SHEditor.hpp"
|
||||
#include "SHEditorWidgets.hpp"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Editor Window Includes ||
|
||||
//#==============================================================#
|
||||
#include "EditorWindow/SHEditorWindowIncludes.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <imgui.h>
|
||||
#include <SDL.h>
|
||||
#include <rttr/registration>
|
||||
|
||||
//#==============================================================#
|
||||
//|| ImGui Backend Includes ||
|
||||
//#==============================================================#
|
||||
#include <backends/imgui_impl_sdl.h>
|
||||
#include <backends/imgui_impl_vulkan.h>
|
||||
|
||||
RTTR_REGISTRATION
|
||||
{
|
||||
using namespace SHADE;
|
||||
using namespace rttr;
|
||||
registration::enumeration<SHEditor::Style>("Style")
|
||||
(
|
||||
value("SHADE", SHEditor::Style::SHADE),
|
||||
value("DARK", SHEditor::Style::DARK),
|
||||
value("LIGHT", SHEditor::Style::LIGHT),
|
||||
value("CLASSIC", SHEditor::Style::CLASSIC)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
//#==============================================================#
|
||||
//|| Initialise static members ||
|
||||
//#==============================================================#
|
||||
Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
|
||||
Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
|
||||
SHEditor::EditorWindowMap SHEditor::editorWindows{};
|
||||
SHEditor::EditorWindowID SHEditor::windowCount{};
|
||||
std::vector<EntityID> SHEditor::selectedEntities;
|
||||
|
||||
void SHEditor::Initialise(SDL_Window* sdlWindow)
|
||||
//#==============================================================#
|
||||
//|| Public Member Functions ||
|
||||
//#==============================================================#
|
||||
void SHEditor::Initialise(SDL_Window* const sdlWindow)
|
||||
{
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
if(auto context = ImGui::CreateContext())
|
||||
{
|
||||
if(context == nullptr)
|
||||
{
|
||||
SHLOG_CRITICAL("Failed to create ImGui Context")
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||
|
||||
ImGui_ImplSDL2_InitForVulkan(sdlWindow);
|
||||
InitFonts();
|
||||
InitBackend(sdlWindow);
|
||||
|
||||
auto* gfxSystem = reinterpret_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
|
||||
SetStyle(Style::SHADE);
|
||||
|
||||
//Add editor windows
|
||||
CreateEditorWindow<SHEditorMenuBar>();
|
||||
CreateEditorWindow<SHHierarchyPanel>();
|
||||
CreateEditorWindow<SHEditorInspector>();
|
||||
|
||||
ImGui_ImplVulkan_InitInfo initInfo{};
|
||||
initInfo.Instance = SHVkInstance::GetVkInstance();
|
||||
initInfo.PhysicalDevice = gfxSystem->GetPhysicalDevice()->GetVkPhysicalDevice();
|
||||
initInfo.Device = gfxSystem->GetDevice()->GetVkLogicalDevice();
|
||||
initInfo.Queue = gfxSystem->GetQueue()->GetVkQueue();
|
||||
initInfo.DescriptorPool = gfxSystem->GetDescriptorPool()->GetVkHandle();
|
||||
initInfo.MinImageCount = initInfo.ImageCount = gfxSystem->GetSwapchain()->GetNumImages();
|
||||
initInfo.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
|
||||
/*auto renderPass = gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetRenderpass();
|
||||
ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass());*/
|
||||
|
||||
imguiCommandBuffer->BeginRecording();
|
||||
ImGui_ImplVulkan_CreateFontsTexture(imguiCommandBuffer->GetVkCommandBuffer());
|
||||
imguiCommandBuffer->EndRecording();
|
||||
gfxSystem->GetQueue()->SubmitCommandBuffer({imguiCommandBuffer}, {}, {}, vk::PipelineStageFlagBits::eNone, {});
|
||||
|
||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||
|
||||
/*gfxSystem->GetRenderGraph().GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||
});*/
|
||||
|
||||
//ImGuiIO& io = ImGui::GetIO();
|
||||
//int w, h;
|
||||
//SDL_GetWindowSize(sdlWindow, &w, &h);
|
||||
//io.DisplaySize = { static_cast<float>(w),static_cast<float>(h)};
|
||||
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
||||
}
|
||||
|
||||
void SHEditor::PreRender()
|
||||
void SHEditor::Update(float const dt)
|
||||
{
|
||||
(void)dt;
|
||||
NewFrame();
|
||||
|
||||
ImGui::ShowDemoWindow();
|
||||
ImGui::Begin("Your mom");
|
||||
if (ImGui::Button("OP"))
|
||||
for (const auto& window : editorWindows | std::views::values)
|
||||
{
|
||||
std::cout << "HEHEHEOHEIOHIEOH\n";
|
||||
window->Update();
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||
{
|
||||
SHCommandManager::RedoCommand();
|
||||
}
|
||||
else if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||
{
|
||||
SHCommandManager::UndoCommand();
|
||||
}
|
||||
|
||||
|
||||
Render();
|
||||
}
|
||||
|
||||
void SHEditor::Render()
|
||||
|
@ -87,6 +133,18 @@ namespace SHADE
|
|||
}
|
||||
}
|
||||
|
||||
void SHEditor::InitFonts() noexcept
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImFont* mainFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
|
||||
|
||||
static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
||||
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.PixelSnapH = true;
|
||||
ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path
|
||||
|
||||
io.Fonts->Build();
|
||||
}
|
||||
|
||||
void SHEditor::Exit()
|
||||
{
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
|
@ -94,19 +152,164 @@ namespace SHADE
|
|||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
|
||||
void SHEditor::InitBackend()
|
||||
void SHEditor::SetStyle(Style style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
default:
|
||||
case Style::SHADE:
|
||||
{
|
||||
ImGuiStyle& imStyle = ImGui::GetStyle();
|
||||
ImVec4* colors = imStyle.Colors;
|
||||
colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f);
|
||||
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
|
||||
colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f);
|
||||
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f);
|
||||
colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f);
|
||||
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||
colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg];
|
||||
colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg];
|
||||
colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg];
|
||||
colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f);
|
||||
colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg];
|
||||
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
|
||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f);
|
||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
|
||||
colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
|
||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
|
||||
colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f);
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||
colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||
colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f);
|
||||
colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f);
|
||||
colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg];
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
|
||||
colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg];
|
||||
colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
|
||||
colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f);
|
||||
colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg];
|
||||
colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg];
|
||||
colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
|
||||
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
|
||||
colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
|
||||
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
|
||||
colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f);
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.141f, 0.141f, 0.141f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight];
|
||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f);
|
||||
|
||||
imStyle.WindowPadding = ImVec2(8.00f, 8.00f);
|
||||
imStyle.FramePadding = ImVec2(5.00f, 2.00f);
|
||||
imStyle.CellPadding = ImVec2(6.00f, 8.00f);
|
||||
imStyle.ItemSpacing = ImVec2(6.00f, 6.00f);
|
||||
imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f);
|
||||
imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f);
|
||||
imStyle.IndentSpacing = 25;
|
||||
imStyle.ScrollbarSize = 15;
|
||||
imStyle.GrabMinSize = 10;
|
||||
imStyle.WindowBorderSize = 0.6f;
|
||||
imStyle.ChildBorderSize = 1;
|
||||
imStyle.PopupBorderSize = 1;
|
||||
imStyle.FrameBorderSize = 1;
|
||||
imStyle.TabBorderSize = 1;
|
||||
imStyle.WindowRounding = 7;
|
||||
imStyle.ChildRounding = 4;
|
||||
imStyle.FrameRounding = 3;
|
||||
imStyle.PopupRounding = 4;
|
||||
imStyle.ScrollbarRounding = 9;
|
||||
imStyle.GrabRounding = 3;
|
||||
imStyle.LogSliderDeadzone = 4;
|
||||
imStyle.TabRounding = 4;
|
||||
imStyle.WindowMenuButtonPosition = ImGuiDir_None;
|
||||
}
|
||||
break;
|
||||
case Style::DARK: ImGui::StyleColorsDark(); break;
|
||||
case Style::LIGHT: ImGui::StyleColorsLight(); break;
|
||||
case Style::CLASSIC: ImGui::StyleColorsClassic(); break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//#==============================================================#
|
||||
//|| Private Member Functions ||
|
||||
//#==============================================================#
|
||||
void SHEditor::InitBackend(SDL_Window* sdlWindow)
|
||||
{
|
||||
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
|
||||
{
|
||||
SHLOG_CRITICAL("Editor backend initialisation; Failed to perform SDL initialisation for Vulkan")
|
||||
}
|
||||
|
||||
const auto* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
|
||||
ImGui_ImplVulkan_InitInfo initInfo{};
|
||||
initInfo.Instance = SHVkInstance::GetVkInstance();
|
||||
initInfo.PhysicalDevice = gfxSystem->GetPhysicalDevice()->GetVkPhysicalDevice();
|
||||
initInfo.Device = gfxSystem->GetDevice()->GetVkLogicalDevice();
|
||||
initInfo.Queue = gfxSystem->GetQueue()->GetVkQueue();
|
||||
initInfo.DescriptorPool = gfxSystem->GetDescriptorPool()->GetVkHandle();
|
||||
initInfo.MinImageCount = initInfo.ImageCount = gfxSystem->GetSwapchain()->GetNumImages();
|
||||
initInfo.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||
imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||
|
||||
auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||
|
||||
SHASSERT(!renderers.empty(), "No Renderers available")
|
||||
auto renderGraph = renderers[0]->GetRenderGraph();
|
||||
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
|
||||
|
||||
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
||||
{
|
||||
SHLOG_CRITICAL("Editor backend initialisation; Failed to initialise Vulkan backend")
|
||||
}
|
||||
|
||||
imguiCommandBuffer->BeginRecording();
|
||||
if(ImGui_ImplVulkan_CreateFontsTexture(imguiCommandBuffer->GetVkCommandBuffer()) == false)
|
||||
{
|
||||
SHLOG_CRITICAL("Editor backend initialisation; Failed to create fonts texture for Vulkan backend")
|
||||
}
|
||||
imguiCommandBuffer->EndRecording();
|
||||
gfxSystem->GetQueue()->SubmitCommandBuffer({ imguiCommandBuffer }, {}, {}, vk::PipelineStageFlagBits::eNone, {});
|
||||
|
||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||
|
||||
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) {
|
||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||
});
|
||||
}
|
||||
|
||||
void SHEditor::NewFrame()
|
||||
{
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event) != 0)
|
||||
{
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
}
|
||||
ImGui_ImplVulkan_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
|
||||
void SHEditor::EndFrame()
|
||||
{
|
||||
}
|
||||
}
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "SH_API.h"
|
||||
#include <SDL.h>
|
||||
|
||||
#include "Resource/Handle.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHVkCommandBuffer;
|
||||
class SHVkCommandPool;
|
||||
|
||||
class SH_API SHEditor
|
||||
{
|
||||
public:
|
||||
static void Initialise(SDL_Window* sdlWindow);
|
||||
static void PreRender();
|
||||
static void Render();
|
||||
static void Exit();
|
||||
private:
|
||||
static void InitBackend();
|
||||
static void NewFrame();
|
||||
static void EndFrame();
|
||||
|
||||
static Handle<SHVkCommandPool> imguiCommandPool;
|
||||
static Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
#pragma once
|
||||
|
||||
//#==============================================================#
|
||||
//|| STL Includes ||
|
||||
//#==============================================================#
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include "Resource/Handle.h"
|
||||
#include "EditorWindow/SHEditorWindow.h"
|
||||
#include "Tools/SHLogger.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <SDL_video.h>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
//#==============================================================#
|
||||
//|| Forward Declarations ||
|
||||
//#==============================================================#
|
||||
class SHVkCommandBuffer;
|
||||
class SHVkCommandPool;
|
||||
|
||||
/**
|
||||
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
||||
*
|
||||
*/
|
||||
class SH_API SHEditor
|
||||
{
|
||||
public:
|
||||
//#==============================================================#
|
||||
//|| Type Aliases ||
|
||||
//#==============================================================#
|
||||
using EditorWindowID = uint8_t;
|
||||
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
||||
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
||||
|
||||
/**
|
||||
* @brief Style options
|
||||
*
|
||||
*/
|
||||
enum class Style : uint8_t
|
||||
{
|
||||
SHADE,
|
||||
DARK,
|
||||
LIGHT,
|
||||
CLASSIC
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialise the editor
|
||||
*
|
||||
* @param sdlWindow pointer to SDL_Window object created in application
|
||||
*/
|
||||
static void Initialise(SDL_Window* sdlWindow);
|
||||
|
||||
/**
|
||||
* @brief Update the editor and add to ImGui DrawList
|
||||
*
|
||||
* @param dt Delta-time of the frame
|
||||
*/
|
||||
static void Update(float dt);
|
||||
|
||||
/**
|
||||
* @brief Safely shutdown the editor
|
||||
*
|
||||
*/
|
||||
static void Exit();
|
||||
|
||||
/**
|
||||
* @brief Set the Style for the editor
|
||||
*
|
||||
* @param style Desired style
|
||||
*/
|
||||
static void SetStyle(Style style);
|
||||
|
||||
/**
|
||||
* @brief Get ID for the Editor Window Type
|
||||
*
|
||||
* @tparam T Type of Editor Window
|
||||
* @return EditorWindowID ID of Editor Window Type
|
||||
*/
|
||||
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||
static EditorWindowID GetEditorWindowID()
|
||||
{
|
||||
static EditorWindowID id;
|
||||
static bool idCreated = false;
|
||||
if (!idCreated)
|
||||
{
|
||||
id = windowCount++;
|
||||
idCreated = true;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get pointer to the Editor Window
|
||||
*
|
||||
* @tparam T Type of editor window to retrieve
|
||||
* @return T* Pointer to the editor window
|
||||
*/
|
||||
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||
static T* GetEditorWindow()
|
||||
{
|
||||
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
|
||||
}
|
||||
|
||||
// List of selected entities
|
||||
static std::vector<EntityID> selectedEntities;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Initialise Backend for ImGui (SDL and Vulkan backend)
|
||||
*
|
||||
* @param sdlWindow Pointer to SDL_Window
|
||||
*/
|
||||
static void InitBackend(SDL_Window* sdlWindow);
|
||||
/**
|
||||
* @brief Start new frame for editor
|
||||
*
|
||||
*/
|
||||
static void NewFrame();
|
||||
/**
|
||||
* @brief Perform ImGui and ImGui Backend Render
|
||||
*
|
||||
*/
|
||||
static void Render();
|
||||
|
||||
/**
|
||||
* @brief Create an Editor Window
|
||||
*
|
||||
* @tparam T Type of Editor Window to create
|
||||
*/
|
||||
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
|
||||
static void CreateEditorWindow()
|
||||
{
|
||||
static bool isCreated = false;
|
||||
if (!isCreated)
|
||||
{
|
||||
editorWindows[GetEditorWindowID<T>()] = std::make_unique<T>();
|
||||
isCreated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_WARNING("Attempt to create duplicate of Editor window type")
|
||||
}
|
||||
}
|
||||
|
||||
static void InitFonts() noexcept;
|
||||
|
||||
// Handle to command pool used for ImGui Vulkan Backend
|
||||
static Handle<SHVkCommandPool> imguiCommandPool;
|
||||
// Handle to command buffer used for ImGui Vulkan Backend
|
||||
static Handle<SHVkCommandBuffer> imguiCommandBuffer;
|
||||
|
||||
// Number of windows; used for Editor Window ID Generation
|
||||
static EditorWindowID windowCount;
|
||||
// Map of Editor Windows
|
||||
static EditorWindowMap editorWindows;
|
||||
};//class SHEditor
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,187 @@
|
|||
#pragma once
|
||||
//#==============================================================#
|
||||
//|| STL Includes ||
|
||||
//#==============================================================#
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "Math/SHMath.h"
|
||||
#include "Command/SHCommandManager.h"
|
||||
#include "SHImGuiHelpers.hpp"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <misc/cpp/imgui_stdlib.h>
|
||||
#include <rttr/type.h>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
//#==============================================================#
|
||||
//|| Custom Widgets ||
|
||||
//#==============================================================#
|
||||
static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f)
|
||||
{
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
const ImGuiID id = window->GetID("##Splitter");
|
||||
ImRect bb;
|
||||
bb.Min = window->DC.CursorPos + (verticalSplit ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
|
||||
bb.Max = bb.Min + (verticalSplit ? ImVec2(thickness, splitterAxisSize) : ImVec2(splitterAxisSize, thickness));
|
||||
return ImGui::SplitterBehavior(bb, id, verticalSplit ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, minSize1, minSize2, 0.0f);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
static bool DragN(const std::string& fieldLabel, std::vector<std::string>const& componentLabels,
|
||||
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(),
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
const ImGuiContext& g = *GImGui;
|
||||
bool valueChanged = false;
|
||||
ImGui::BeginGroup();
|
||||
ImGui::PushID(fieldLabel.c_str());
|
||||
PushMultiItemsWidthsAndLabels(componentLabels, 0.0f);
|
||||
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
|
||||
ImGui::SetColumnWidth(-1, 80.0f);
|
||||
ImGui::Text(fieldLabel.c_str());
|
||||
ImGui::NextColumn();
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
{
|
||||
ImGui::PushID(static_cast<int>(i));
|
||||
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str())); ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(80.0f);
|
||||
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
|
||||
|
||||
const ImVec2 min = ImGui::GetItemRectMin();
|
||||
const ImVec2 max = ImGui::GetItemRectMax();
|
||||
const float spacing = g.Style.FrameRounding;
|
||||
const float halfSpacing = spacing / 2;
|
||||
|
||||
window->DrawList->AddLine({ min.x + spacing, max.y - halfSpacing }, { max.x - spacing, max.y - halfSpacing },
|
||||
ImGuiColors::colors[i], 4);
|
||||
|
||||
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
ImGui::PopID();
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
ImGui::EndColumns();
|
||||
ImGui::PopID();
|
||||
ImGui::EndGroup();
|
||||
|
||||
return valueChanged;
|
||||
}
|
||||
|
||||
static bool DragVec2(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
|
||||
std::function<void(SHVec2)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
SHVec2 values = get();
|
||||
bool changed = false;
|
||||
if (DragN<float, 2>(fieldLabel, componentLabels, {&values.x, &values.y}, speed, displayFormat, valueMin, valueMax, flags))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||
else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), true);
|
||||
else if(ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DragVec3(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
|
||||
std::function<void(SHVec3)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
SHVec3 values = get();
|
||||
bool changed = false;
|
||||
if (DragN<float, 3>(fieldLabel, componentLabels, {&values.x, &values.y, &values.z}, speed, displayFormat, valueMin, valueMax, flags))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||
else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), true);
|
||||
else if(ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DragVec4(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
|
||||
std::function<void(SHVec4)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
SHVec4 values = get();
|
||||
bool changed = false;
|
||||
if (DragN<float, 4>(fieldLabel, componentLabels, {&values.x, &values.y, &values.z, &values.w}, speed, displayFormat, valueMin, valueMax, flags))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||
else if(ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), true);
|
||||
else if(ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
//#==============================================================#
|
||||
//|| Widget Extensions ||
|
||||
//#==============================================================#
|
||||
|
||||
static bool CheckBox(std::string const& label, std::function<bool(void)> get, std::function<void(bool const&)> set)
|
||||
{
|
||||
bool value = get();
|
||||
if (ImGui::Checkbox(label.c_str(), &value))
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static bool RadioButton(std::vector<std::string> const& listLabels, std::vector<T> const& listTypes, std::function<T(void)> get, std::function<void(T const&)> set)
|
||||
{
|
||||
T type = get();
|
||||
for (size_t i = 0; i < listTypes.size(); i++)
|
||||
{
|
||||
if (ImGui::RadioButton(listLabels[i].c_str(), type == listTypes[i]))
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), listTypes[i], set)), false);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}//namespace SHADE
|
|
@ -0,0 +1,69 @@
|
|||
#pragma once
|
||||
|
||||
//#==============================================================#
|
||||
//|| STL Includes ||
|
||||
//#==============================================================#
|
||||
#include <string>
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "Math/SHMath.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| SHADE-ImGui Math Conversions ||
|
||||
//#==============================================================#
|
||||
#ifndef SH_IM_MATH
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \
|
||||
operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);}
|
||||
#define IM_VEC3_CLASS_EXTRA \
|
||||
ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \
|
||||
operator SHADE::SHVec3() const {return SHADE::SHVec3(x,y,z);}
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const SHADE::SHVec4& vec) {x = vec.x; y = vec.y; z = vec.z; w = vec.w;} \
|
||||
operator SHADE::SHVec4() const {return SHADE::SHVec4(x,y,z,w);}
|
||||
#endif
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
//#==============================================================#
|
||||
#include <imgui_internal.h>
|
||||
#include <imgui.h>
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
namespace ImGuiColors
|
||||
{
|
||||
constexpr ImVec4 red = {1.0f, 0.0f, 0.0f, 1.f};
|
||||
constexpr ImVec4 green = {0.0f, 1.0f, 0.0f, 1.f};
|
||||
constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f};
|
||||
constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f};
|
||||
|
||||
constexpr ImU32 colors[] = {
|
||||
0xBB0000FF, // red
|
||||
0xBB00FF00, // green
|
||||
0xBBFF0000, // blue
|
||||
0xBBFFFFFF, // white
|
||||
};
|
||||
}
|
||||
|
||||
static void PushMultiItemsWidthsAndLabels(const std::vector<std::string>& labels, float wFull)
|
||||
{
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
const ImGuiStyle& style = GImGui->Style;
|
||||
if (wFull <= 0.0f)
|
||||
wFull = ImGui::GetContentRegionAvail().x;
|
||||
const auto size = labels.size();
|
||||
const float w_item_one =
|
||||
ImMax(1.0f, (wFull - (static_cast<float>(size) - 1.0f) * (style.ItemInnerSpacing.x * 2.0f)) / static_cast<float>(
|
||||
size)) -
|
||||
style.ItemInnerSpacing.x;
|
||||
for (int i = 0; i < size; i++)
|
||||
window->DC.ItemWidthStack.push_back(w_item_one - ImGui::CalcTextSize(labels[i].c_str()).x);
|
||||
window->DC.ItemWidth = window->DC.ItemWidthStack.back();
|
||||
}
|
||||
} //namespace SHADE
|
|
@ -135,11 +135,13 @@ namespace SHADE
|
|||
//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);
|
||||
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
||||
auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", "Normals",*/ "Present" }, {}); // no predecessors
|
||||
auto node = worldRenderGraph->AddNode("G-Buffer", { /*"Composite", "Position", */"Present" }, {}); // no predecessors
|
||||
|
||||
//First subpass to write to G-Buffer
|
||||
auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
|
||||
//gBufferWriteSubpass->AddColorOutput("Scene");
|
||||
gBufferWriteSubpass->AddColorOutput("Present");
|
||||
//writeSubpass->AddColorOutput("Normals");
|
||||
|
||||
|
|
|
@ -202,6 +202,7 @@ namespace SHADE
|
|||
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
|
||||
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
|
||||
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
|
||||
Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;}
|
||||
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
|
||||
|
||||
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
||||
|
|
|
@ -284,6 +284,7 @@ namespace SHADE
|
|||
SHRenderGraph(SHRenderGraph&& rhs) noexcept;
|
||||
SHRenderGraph& operator=(SHRenderGraph&& rhs) noexcept;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "SHPch.h"
|
||||
#include "SHWindowMap.h"
|
||||
#include "SHWindow.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Input/SHInputManagerSystem.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
|
@ -339,6 +341,14 @@ namespace SHADE
|
|||
OnPosChange(reinterpret_cast<LPWINDOWPOS>(lparam));
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
if (auto im = SHSystemManager::GetSystem<SHInputManagerSystem>())
|
||||
{
|
||||
im->PollWheelVerticalDelta(wparam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return ::DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#pragma once
|
||||
//#include <Xinput.h>
|
||||
//#include "../../SHADE_Managed/src/SHpch.h"
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/System/SHSystem.h"
|
||||
#include "ECS_Base/System/SHFixedSystemRoutine.h"
|
||||
|
||||
|
|
|
@ -144,4 +144,15 @@ namespace SHADE
|
|||
updateQueue.push({ UpdateCommandType::WORLD_SCALE, newWorldScale });
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
||||
} // namespace SHADE
|
||||
|
||||
RTTR_REGISTRATION
|
||||
{
|
||||
using namespace SHADE;
|
||||
using namespace rttr;
|
||||
|
||||
registration::class_<SHTransformComponent>("Transform Component")
|
||||
.property("Translate", &SHTransformComponent::GetLocalPosition, &SHTransformComponent::SetLocalPosition)
|
||||
.property("Rotate", &SHTransformComponent::GetLocalRotation, select_overload<void(SHVec3 const&)>(&SHTransformComponent::SetLocalRotation))
|
||||
.property("Scale", &SHTransformComponent::GetLocalScale, &SHTransformComponent::SetLocalScale);
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <queue>
|
||||
|
||||
#include <rttr/registration>
|
||||
// Project Headers
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
|
@ -116,6 +117,8 @@ namespace SHADE
|
|||
SHTransform world;
|
||||
|
||||
UpdateQueue updateQueue;
|
||||
|
||||
RTTR_ENABLE()
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -66,27 +66,23 @@ namespace SHADE
|
|||
|
||||
for (const auto* child : node->GetChildren())
|
||||
{
|
||||
|
||||
|
||||
|
||||
const bool HAS_TRANSFORM = SHComponentManager::HasComponent<SHTransformComponent>(child->GetEntityID());
|
||||
if (!HAS_TRANSFORM)
|
||||
continue;
|
||||
|
||||
auto* childTransform = SHComponentManager::GetComponent<SHTransformComponent>(child->GetEntityID());
|
||||
|
||||
// Only update if node in hierarchy and component are both active
|
||||
const bool IS_NODE_ACTIVE = child->IsActive();
|
||||
if (IS_NODE_ACTIVE && childTransform->isActive)
|
||||
auto* childTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(child->GetEntityID());
|
||||
if (childTransform)
|
||||
{
|
||||
if (childTransform->dirty || HAS_PARENT_CHANGED)
|
||||
UpdateTransform(*childTransform, NODE_TRANSFORM);
|
||||
// Only update if node in hierarchy and component are both active
|
||||
const bool IS_NODE_ACTIVE = child->IsActive();
|
||||
if (IS_NODE_ACTIVE && childTransform->isActive)
|
||||
{
|
||||
if (childTransform->dirty || HAS_PARENT_CHANGED)
|
||||
UpdateTransform(*childTransform, NODE_TRANSFORM);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateEntity(child);
|
||||
|
||||
// Clear dirty flag after all children are updated
|
||||
childTransform->dirty = false;
|
||||
if (childTransform)
|
||||
childTransform->dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,8 +140,8 @@ namespace SHADE
|
|||
tf.world.ComputeTRS();
|
||||
|
||||
// Transpose TRS to column major
|
||||
tf.local.trs.Transpose();
|
||||
tf.world.trs.Transpose();
|
||||
//tf.local.trs.Transpose();
|
||||
//tf.world.trs.Transpose();
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -7,7 +7,8 @@ workspace "SHADE"
|
|||
configurations
|
||||
{
|
||||
"Debug",
|
||||
"Release"
|
||||
"Release",
|
||||
"Publish"
|
||||
}
|
||||
|
||||
flags
|
||||
|
|
Loading…
Reference in New Issue