Merge branch 'main' into SP3-2-Physics
This commit is contained in:
commit
877507284e
|
@ -145,6 +145,9 @@ namespace Sandbox
|
||||||
|
|
||||||
SHADE::SHSystemManager::RunRoutines(false, 0.016f);
|
SHADE::SHSystemManager::RunRoutines(false, 0.016f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finish all graphics jobs first
|
||||||
|
graphicsSystem->AwaitGraphicsExecution();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ namespace Sandbox
|
||||||
renderable.SetMaterial(customMat);
|
renderable.SetMaterial(customMat);
|
||||||
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||||
renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 1);
|
renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
||||||
|
|
||||||
transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f });
|
transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f });
|
||||||
transform.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
transform.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
||||||
|
@ -159,7 +159,7 @@ namespace Sandbox
|
||||||
renderableShowcase.SetMaterial(customMat);
|
renderableShowcase.SetMaterial(customMat);
|
||||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 1);
|
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
|
||||||
|
|
||||||
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
|
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
|
||||||
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
||||||
|
|
|
@ -163,8 +163,8 @@ project "SHADE_Engine"
|
||||||
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||||
excludes
|
excludes
|
||||||
{
|
{
|
||||||
"%{prj.location}/src/Editor/**.cpp",
|
-- "%{prj.location}/src/Editor/**.cpp",
|
||||||
"%{prj.location}/src/Editor/**.h",
|
-- "%{prj.location}/src/Editor/**.h",
|
||||||
"%{prj.location}/src/Editor/**.hpp",
|
-- "%{prj.location}/src/Editor/**.hpp",
|
||||||
}
|
}
|
||||||
links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
|
@ -17,7 +17,8 @@ namespace SHADE
|
||||||
SHTexture::PixelChannel const * pixelData;
|
SHTexture::PixelChannel const * pixelData;
|
||||||
|
|
||||||
SHTextureAsset()
|
SHTextureAsset()
|
||||||
: numBytes{ 0 },
|
: compiled{ false },
|
||||||
|
numBytes{ 0 },
|
||||||
width{ 0 },
|
width{ 0 },
|
||||||
height{ 0 },
|
height{ 0 },
|
||||||
format{ SHTexture::TextureFormat::eUndefined },
|
format{ SHTexture::TextureFormat::eUndefined },
|
||||||
|
@ -25,7 +26,8 @@ namespace SHADE
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SHTextureAsset(SHTextureAsset const& rhs)
|
SHTextureAsset(SHTextureAsset const& rhs)
|
||||||
: numBytes{ rhs.numBytes },
|
: compiled{ false },
|
||||||
|
numBytes{ rhs.numBytes },
|
||||||
width{ rhs.width },
|
width{ rhs.width },
|
||||||
height{ rhs.height },
|
height{ rhs.height },
|
||||||
format{ rhs.format },
|
format{ rhs.format },
|
||||||
|
|
|
@ -91,8 +91,8 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.header.vertexCount = result.vertexPosition.size();
|
result.header.vertexCount = static_cast<uint32_t>(result.vertexPosition.size());
|
||||||
result.header.indexCount = result.indices.size();
|
result.header.indexCount = static_cast<uint32_t>(result.indices.size());
|
||||||
result.header.meshName = mesh.mName.C_Str();
|
result.header.meshName = mesh.mName.C_Str();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -83,10 +83,10 @@ namespace SHADE
|
||||||
|
|
||||||
std::vector<uint32_t> mipOff(file.GetMipCount());
|
std::vector<uint32_t> mipOff(file.GetMipCount());
|
||||||
|
|
||||||
for (auto i{0}; i < file.GetMipCount(); ++i)
|
for (size_t i{0}; i < file.GetMipCount(); ++i)
|
||||||
{
|
{
|
||||||
mipOff[i] = totalBytes;
|
mipOff[i] = static_cast<uint32_t>(totalBytes);
|
||||||
totalBytes += file.GetImageData(i, 0)->m_memSlicePitch;
|
totalBytes += file.GetImageData(static_cast<uint32_t>(i), 0)->m_memSlicePitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
SHTexture::PixelChannel* pixel = new SHTexture::PixelChannel[totalBytes];
|
||||||
|
@ -94,7 +94,7 @@ namespace SHADE
|
||||||
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
|
//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
|
||||||
|
|
||||||
asset.compiled = false;
|
asset.compiled = false;
|
||||||
asset.numBytes = totalBytes;
|
asset.numBytes = static_cast<uint32_t>(totalBytes);
|
||||||
asset.width = file.GetWidth();
|
asset.width = file.GetWidth();
|
||||||
asset.height = file.GetHeight();
|
asset.height = file.GetHeight();
|
||||||
asset.format = ddsLoaderToVkFormat(file.GetFormat(), true);
|
asset.format = ddsLoaderToVkFormat(file.GetFormat(), true);
|
||||||
|
|
|
@ -72,12 +72,13 @@ namespace SHADE
|
||||||
|
|
||||||
AssetType type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string().c_str());
|
AssetType type = SHAssetMetaHandler::GetTypeFromExtension(path.extension().string().c_str());
|
||||||
std::string folder;
|
std::string folder;
|
||||||
switch (type)
|
//TODO Implement asset type generation
|
||||||
{
|
//switch (type)
|
||||||
default:
|
//{
|
||||||
//TODO:ASSERT UNSUPPORTED FILE TYPE
|
//default:
|
||||||
return std::filesystem::path();
|
// //TODO:ASSERT UNSUPPORTED FILE TYPE
|
||||||
}
|
// return std::filesystem::path();
|
||||||
|
//}
|
||||||
|
|
||||||
return std::filesystem::path(ASSET_ROOT + folder + path.filename().string());
|
return std::filesystem::path(ASSET_ROOT + folder + path.filename().string());
|
||||||
}
|
}
|
||||||
|
@ -108,12 +109,13 @@ namespace SHADE
|
||||||
meta.type = type;
|
meta.type = type;
|
||||||
|
|
||||||
std::string folder;
|
std::string folder;
|
||||||
switch (type)
|
//TODO implement folder choosing
|
||||||
{
|
//switch (type)
|
||||||
default:
|
//{
|
||||||
folder = "";
|
//default:
|
||||||
break;
|
// folder = "";
|
||||||
}
|
// break;
|
||||||
|
//}
|
||||||
AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
|
AssetPath path{ ASSET_ROOT + folder + name + SHAssetMetaHandler::GetExtensionFromType(type) };
|
||||||
|
|
||||||
SHAssetMetaHandler::WriteMetaData(meta);
|
SHAssetMetaHandler::WriteMetaData(meta);
|
||||||
|
|
|
@ -122,7 +122,7 @@ namespace SHADE
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
void;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
metaFile.close();
|
metaFile.close();
|
||||||
|
|
|
@ -5,9 +5,13 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHBaseCommand
|
class SH_API SHBaseCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~SHBaseCommand() = default;
|
virtual ~SHBaseCommand() = default;
|
||||||
|
@ -48,4 +52,20 @@ namespace SHADE
|
||||||
T newValue;
|
T newValue;
|
||||||
SetterFunction set;
|
SetterFunction set;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SH_API SHCLICommand : SHBaseCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHCLICommand() = default;
|
||||||
|
void Execute() override
|
||||||
|
{
|
||||||
|
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->RedoScriptInspectorChanges();
|
||||||
|
}
|
||||||
|
void Undo() override
|
||||||
|
{
|
||||||
|
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->UndoScriptInspectorChanges();
|
||||||
|
}
|
||||||
|
};
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -27,6 +27,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::RegisterCommand(CommandPtr commandPtr)
|
||||||
|
{
|
||||||
|
undoStack.push(commandPtr);
|
||||||
|
}
|
||||||
|
|
||||||
void SHCommandManager::UndoCommand()
|
void SHCommandManager::UndoCommand()
|
||||||
{
|
{
|
||||||
if (undoStack.empty())
|
if (undoStack.empty())
|
||||||
|
|
|
@ -9,10 +9,11 @@
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "SHCommand.hpp"
|
#include "SHCommand.hpp"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHCommandManager
|
class SH_API SHCommandManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -22,6 +23,7 @@ namespace SHADE
|
||||||
using CommandStack = std::stack<CommandPtr>;
|
using CommandStack = std::stack<CommandPtr>;
|
||||||
|
|
||||||
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false);
|
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false);
|
||||||
|
static void RegisterCommand(CommandPtr commandPtr);
|
||||||
static void UndoCommand();
|
static void UndoCommand();
|
||||||
static void RedoCommand();
|
static void RedoCommand();
|
||||||
static std::size_t GetUndoStackSize();
|
static std::size_t GetUndoStackSize();
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "AudioSystem/SHAudioSystem.h"
|
#include "AudioSystem/SHAudioSystem.h"
|
||||||
|
#include "Physics/Components/SHRigidBodyComponent.h"
|
||||||
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -70,23 +72,28 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawComponent(renderableComponent);
|
DrawComponent(renderableComponent);
|
||||||
}
|
}
|
||||||
if(auto testComponent = SHComponentManager::GetComponent_s<SHComponent_ENUM>(eid))
|
if(auto colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(eid))
|
||||||
{
|
{
|
||||||
DrawComponent(testComponent);
|
DrawComponent(colliderComponent);
|
||||||
}
|
}
|
||||||
|
if(auto rigidbodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(rigidbodyComponent);
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
// Render Scripts
|
||||||
|
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->RenderScriptsInInspector(eid);
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
|
||||||
{
|
{
|
||||||
DrawAddComponentButton<SHTransformComponent>(eid);
|
DrawAddComponentButton<SHTransformComponent>(eid);
|
||||||
DrawAddComponentButton<SHRenderable>(eid);
|
DrawAddComponentButton<SHRenderable>(eid);
|
||||||
DrawAddComponentButton<SHComponent_ENUM>(eid);
|
DrawAddComponentButton<SHColliderComponent>(eid);
|
||||||
|
DrawAddComponentButton<SHRigidBodyComponent>(eid);
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render Scripts
|
|
||||||
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
|
||||||
scriptEngine->RenderScriptsInInspector(eid);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "SHFileSystem.h"
|
#include "SHFileSystem.h"
|
||||||
#include "fileapi.h"
|
#include "fileapi.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <cassert>
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -27,8 +26,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
||||||
|
|
||||||
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
|
if (count >= FOLDER_MAX_COUNT)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Max subfolder reached: {}\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
auto const location = static_cast<FolderLocation>(count);
|
auto const location = static_cast<FolderLocation>(count);
|
||||||
|
|
||||||
|
@ -37,7 +39,10 @@ namespace SHADE
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(folders.contains(here), "Folder creation location does not exist/invalid\n");
|
if (!folders.contains(here))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Folder creation location does not exist/invalid: {}\n", here);
|
||||||
|
}
|
||||||
|
|
||||||
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
|
||||||
|
|
||||||
|
@ -45,7 +50,11 @@ namespace SHADE
|
||||||
location <<= FOLDER_BIT_ALLOCATE;
|
location <<= FOLDER_BIT_ALLOCATE;
|
||||||
location |= count;
|
location |= count;
|
||||||
|
|
||||||
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
|
if (count >= FOLDER_MAX_COUNT)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Max subfolder reached: {}\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
CreateFolder(folders[0]->path, here, location, name);
|
CreateFolder(folders[0]->path, here, location, name);
|
||||||
|
|
||||||
return location;
|
return location;
|
||||||
|
@ -53,7 +62,10 @@ namespace SHADE
|
||||||
|
|
||||||
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
|
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
|
||||||
{
|
{
|
||||||
assert(folders.contains(location->id), "Delete target does not exist/invalid.\n");
|
if (!folders.contains(location->id))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Delete target does not exist/invalid: {}\n", location->name);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto const& subFolder : folders[location->id]->subFolders)
|
for (auto const& subFolder : folders[location->id]->subFolders)
|
||||||
{
|
{
|
||||||
|
@ -116,10 +128,11 @@ namespace SHADE
|
||||||
|
|
||||||
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
|
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
|
||||||
{
|
{
|
||||||
assert(
|
|
||||||
CreateDirectoryA(path.c_str(), nullptr),
|
if (!CreateDirectoryA(path.c_str(), nullptr))
|
||||||
"Failed to create folder\n"
|
{
|
||||||
);
|
SHLOG_ERROR("Failed to create folder: {}\n", path);
|
||||||
|
}
|
||||||
|
|
||||||
folders[location] = std::make_unique<SHFolder>(location, name);
|
folders[location] = std::make_unique<SHFolder>(location, name);
|
||||||
folders[location]->path = path;
|
folders[location]->path = path;
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkCommandBuffer::~SHVkCommandBuffer(void) noexcept
|
SHVkCommandBuffer::~SHVkCommandBuffer(void) noexcept
|
||||||
{
|
{
|
||||||
if (vkCommandBuffer)
|
if (vkCommandBuffer && parentPool)
|
||||||
parentPool->GetLogicalDevice()->GetVkLogicalDevice().freeCommandBuffers(parentPool->GetVkCommandPool(), commandBufferCount, &vkCommandBuffer);
|
parentPool->GetLogicalDevice()->GetVkLogicalDevice().freeCommandBuffers(parentPool->GetVkCommandPool(), commandBufferCount, &vkCommandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,6 @@ namespace SHADE
|
||||||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
||||||
transient = rhs.transient;
|
transient = rhs.transient;
|
||||||
|
|
||||||
static_cast<ISelfHandle<SHVkCommandPool>&>(*this) = static_cast<ISelfHandle<SHVkCommandPool>&>(rhs);
|
|
||||||
|
|
||||||
rhs.vkCommandPool = VK_NULL_HANDLE;
|
rhs.vkCommandPool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -208,7 +208,7 @@ namespace SHADE
|
||||||
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||||
|
|
||||||
// to index a set
|
// to index a set
|
||||||
uint32_t setIndex = setIndexing[bsHash];
|
uint32_t setIndex = setIndexing[set];
|
||||||
|
|
||||||
// to index a write for a binding
|
// to index a write for a binding
|
||||||
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||||
|
@ -233,7 +233,7 @@ namespace SHADE
|
||||||
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||||
|
|
||||||
// to index a set
|
// to index a set
|
||||||
uint32_t setIndex = setIndexing[bsHash];
|
uint32_t setIndex = setIndexing[set];
|
||||||
|
|
||||||
// to index a write for a binding
|
// to index a write for a binding
|
||||||
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace SHADE
|
||||||
//uint32_t minBuffer
|
//uint32_t minBuffer
|
||||||
if (alignmentSize > 0)
|
if (alignmentSize > 0)
|
||||||
{
|
{
|
||||||
alignedSize = (alignedSize + alignmentSize - 1) & ~(alignmentSize - 1);
|
alignedSize = (alignedSize + static_cast<uint32_t>(alignmentSize) - 1) & ~(alignmentSize - 1);
|
||||||
}
|
}
|
||||||
return alignedSize;
|
return alignedSize;
|
||||||
}
|
}
|
||||||
|
@ -195,6 +195,8 @@ namespace SHADE
|
||||||
|
|
||||||
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
|
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
|
||||||
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
|
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
|
||||||
|
descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true;
|
||||||
|
descIndexingFeature.runtimeDescriptorArray = true;
|
||||||
|
|
||||||
// Prepare to create the device
|
// Prepare to create the device
|
||||||
vk::DeviceCreateInfo deviceCreateInfo
|
vk::DeviceCreateInfo deviceCreateInfo
|
||||||
|
@ -249,6 +251,22 @@ namespace SHADE
|
||||||
vkLogicalDevice.destroy(nullptr);
|
vkLogicalDevice.destroy(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHVkLogicalDevice& SHVkLogicalDevice::operator=(SHVkLogicalDevice&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
vkLogicalDevice = std::move (rhs.vkLogicalDevice);
|
||||||
|
queueFamilyIndices = std::move (rhs.queueFamilyIndices);
|
||||||
|
vmaAllocator = rhs.vmaAllocator;
|
||||||
|
nonDedicatedBestIndex = 0;
|
||||||
|
parentPhysicalDeviceHdl = rhs.parentPhysicalDeviceHdl;
|
||||||
|
|
||||||
|
rhs.vkLogicalDevice = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace SHADE
|
||||||
~SHVkLogicalDevice (void) noexcept;
|
~SHVkLogicalDevice (void) noexcept;
|
||||||
|
|
||||||
SHVkLogicalDevice& operator= (SHVkLogicalDevice const& rhs) noexcept = default;
|
SHVkLogicalDevice& operator= (SHVkLogicalDevice const& rhs) noexcept = default;
|
||||||
SHVkLogicalDevice& operator= (SHVkLogicalDevice&& rhs) noexcept = default;
|
SHVkLogicalDevice& operator= (SHVkLogicalDevice&& rhs) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER VARIABLES */
|
/* PUBLIC MEMBER VARIABLES */
|
||||||
|
|
|
@ -98,6 +98,51 @@ namespace SHADE
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkFramebuffer::HandleResize(Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept
|
||||||
|
{
|
||||||
|
width = inWidth;
|
||||||
|
height = inHeight;
|
||||||
|
|
||||||
|
for (auto& attachment : attachments)
|
||||||
|
{
|
||||||
|
// Not sure if its an error to pass in diff dimension images.
|
||||||
|
if (attachment->GetParentImage()->GetWidth() != (*attachments.begin())->GetParentImage()->GetWidth() || attachment->GetParentImage()->GetHeight() != (*attachments.begin())->GetParentImage()->GetHeight())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Dimensions of images not same as each other. Cannot create framebuffer.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<vk::ImageView> vkAttachments(attachments.size());
|
||||||
|
|
||||||
|
uint32_t i = 0;
|
||||||
|
for(auto const& attachment : attachments)
|
||||||
|
{
|
||||||
|
vkAttachments[i] = attachment->GetImageView();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::FramebufferCreateInfo createInfo
|
||||||
|
{
|
||||||
|
.renderPass = renderpassHdl->GetVkRenderpass(),
|
||||||
|
.attachmentCount = static_cast<uint32_t>(vkAttachments.size()),
|
||||||
|
.pAttachments = vkAttachments.data(),
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.layers = 1 // TODO: Find out why this is 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createFramebuffer(&createInfo, nullptr, &vkFramebuffer); result != vk::Result::eSuccess)
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkError(result, "Failed to create framebuffer. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created framebuffer. ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ namespace SHADE
|
||||||
SHVkFramebuffer(SHVkFramebuffer&& rhs) noexcept;
|
SHVkFramebuffer(SHVkFramebuffer&& rhs) noexcept;
|
||||||
SHVkFramebuffer& operator=(SHVkFramebuffer&& rhs) noexcept;
|
SHVkFramebuffer& operator=(SHVkFramebuffer&& rhs) noexcept;
|
||||||
|
|
||||||
|
void HandleResize (Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -79,6 +79,41 @@ namespace SHADE
|
||||||
vmaUnmapMemory(*vmaAllocator, stagingAlloc);
|
vmaUnmapMemory(*vmaAllocator, stagingAlloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkImage::CreateFramebufferImage(void) noexcept
|
||||||
|
{
|
||||||
|
vk::ImageCreateInfo imageCreateInfo{};
|
||||||
|
imageCreateInfo.imageType = vk::ImageType::e2D;
|
||||||
|
imageCreateInfo.extent.width = width;
|
||||||
|
imageCreateInfo.extent.height = height;
|
||||||
|
imageCreateInfo.extent.depth = depth;
|
||||||
|
imageCreateInfo.mipLevels = mipLevelCount;
|
||||||
|
imageCreateInfo.arrayLayers = layerCount;
|
||||||
|
imageCreateInfo.format = imageFormat;
|
||||||
|
imageCreateInfo.tiling = vk::ImageTiling::eOptimal;
|
||||||
|
imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
|
||||||
|
imageCreateInfo.usage = usageFlags;
|
||||||
|
imageCreateInfo.sharingMode = vk::SharingMode::eExclusive;
|
||||||
|
imageCreateInfo.samples = vk::SampleCountFlagBits::e1;
|
||||||
|
imageCreateInfo.flags = createFlags;
|
||||||
|
|
||||||
|
|
||||||
|
// Prepare allocation parameters for call to create images later
|
||||||
|
VmaAllocationCreateInfo allocCreateInfo{};
|
||||||
|
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||||
|
allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set
|
||||||
|
|
||||||
|
VmaAllocationInfo allocInfo{};
|
||||||
|
|
||||||
|
VkImage tempImage;
|
||||||
|
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||||
|
vkImage = tempImage;
|
||||||
|
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
||||||
|
else
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
|
||||||
|
}
|
||||||
|
|
||||||
SHVkImage::SHVkImage(
|
SHVkImage::SHVkImage(
|
||||||
VmaAllocator const* allocator,
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
|
@ -196,37 +231,7 @@ namespace SHADE
|
||||||
, createFlags {create}
|
, createFlags {create}
|
||||||
, vmaAllocator {allocator}
|
, vmaAllocator {allocator}
|
||||||
{
|
{
|
||||||
vk::ImageCreateInfo imageCreateInfo{};
|
CreateFramebufferImage();
|
||||||
imageCreateInfo.imageType = vk::ImageType::e2D;
|
|
||||||
imageCreateInfo.extent.width = width;
|
|
||||||
imageCreateInfo.extent.height = height;
|
|
||||||
imageCreateInfo.extent.depth = depth;
|
|
||||||
imageCreateInfo.mipLevels = mipLevelCount;
|
|
||||||
imageCreateInfo.arrayLayers = layerCount;
|
|
||||||
imageCreateInfo.format = imageFormat;
|
|
||||||
imageCreateInfo.tiling = vk::ImageTiling::eOptimal;
|
|
||||||
imageCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
|
|
||||||
imageCreateInfo.usage = usageFlags;
|
|
||||||
imageCreateInfo.sharingMode = vk::SharingMode::eExclusive;
|
|
||||||
imageCreateInfo.samples = vk::SampleCountFlagBits::e1;
|
|
||||||
imageCreateInfo.flags = createFlags;
|
|
||||||
|
|
||||||
|
|
||||||
// Prepare allocation parameters for call to create images later
|
|
||||||
VmaAllocationCreateInfo allocCreateInfo{};
|
|
||||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
|
||||||
allocCreateInfo.flags = {}; // TODO: Make sure the vk::MemoryPropertyFlags returned from vmaGetAllocationMemoryProperties has the device local bit set
|
|
||||||
|
|
||||||
VmaAllocationInfo allocInfo{};
|
|
||||||
|
|
||||||
VkImage tempImage;
|
|
||||||
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
|
||||||
vkImage = tempImage;
|
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
|
||||||
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
|
||||||
else
|
|
||||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
|
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
|
||||||
|
@ -288,6 +293,16 @@ namespace SHADE
|
||||||
barrier.subresourceRange.layerCount = layerCount;
|
barrier.subresourceRange.layerCount = layerCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkImage::HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept
|
||||||
|
{
|
||||||
|
vmaDestroyImage(*vmaAllocator, vkImage, alloc);
|
||||||
|
|
||||||
|
width = newWidth;
|
||||||
|
height = newHeight;
|
||||||
|
|
||||||
|
CreateFramebufferImage();
|
||||||
|
}
|
||||||
|
|
||||||
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
||||||
{
|
{
|
||||||
vkImage = inVkImage;
|
vkImage = inVkImage;
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace SHADE
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept;
|
void PrepStagingBuffer(const void* data, uint32_t srcSize) noexcept;
|
||||||
|
void CreateFramebufferImage (void) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -137,7 +137,8 @@ namespace SHADE
|
||||||
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
||||||
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
|
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
|
||||||
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
||||||
|
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -6,6 +6,67 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void SHVkImageView::Create(void) noexcept
|
||||||
|
{
|
||||||
|
auto parentImageCreateFlags = parentImage->GetImageeCreateFlags();
|
||||||
|
|
||||||
|
// 2D array image type means parent image must be 2D array compatible
|
||||||
|
if (imageViewDetails.viewType == vk::ImageViewType::e2DArray)
|
||||||
|
{
|
||||||
|
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Failed to create image view. Parent image not 2D array compatible. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if its possible for the image view to have different format than parent image
|
||||||
|
if (imageViewDetails.format != parentImage->GetImageFormat())
|
||||||
|
{
|
||||||
|
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Failed to create image view. Format for image view not same as image but image not initialized with mutable format bit. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vk::ImageViewCreateInfo viewCreateInfo
|
||||||
|
{
|
||||||
|
.pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information
|
||||||
|
.image = parentImage->GetVkImage(),
|
||||||
|
.viewType = imageViewDetails.viewType,
|
||||||
|
.format = imageViewDetails.format,
|
||||||
|
.components
|
||||||
|
{
|
||||||
|
.r = vk::ComponentSwizzle::eR,
|
||||||
|
.g = vk::ComponentSwizzle::eG,
|
||||||
|
.b = vk::ComponentSwizzle::eB,
|
||||||
|
.a = vk::ComponentSwizzle::eA,
|
||||||
|
},
|
||||||
|
.subresourceRange
|
||||||
|
{
|
||||||
|
.aspectMask = imageViewDetails.imageAspectFlags,
|
||||||
|
.baseMipLevel = imageViewDetails.baseMipLevel,
|
||||||
|
.levelCount = imageViewDetails.mipLevelCount,
|
||||||
|
.baseArrayLayer = imageViewDetails.baseArrayLayer,
|
||||||
|
.layerCount = imageViewDetails.layerCount,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess)
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -18,70 +79,12 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkImageView::SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
|
SHVkImageView::SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
|
||||||
: parentImage{ }
|
: parentImage{ parent }
|
||||||
, vkImageView{}
|
, vkImageView{}
|
||||||
, imageViewDetails{}
|
, imageViewDetails{createParams}
|
||||||
, logicalDeviceHdl {inLogicalDeviceHdl}
|
, logicalDeviceHdl {inLogicalDeviceHdl}
|
||||||
{
|
{
|
||||||
auto parentImageCreateFlags = parent->GetImageeCreateFlags();
|
Create();
|
||||||
|
|
||||||
// 2D array image type means parent image must be 2D array compatible
|
|
||||||
if (createParams.viewType == vk::ImageViewType::e2DArray)
|
|
||||||
{
|
|
||||||
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::e2DArrayCompatible))
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Failed to create image view. Parent image not 2D array compatible. ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if its possible for the image view to have different format than parent image
|
|
||||||
if (createParams.format != parent->GetImageFormat())
|
|
||||||
{
|
|
||||||
if (!(parentImageCreateFlags & vk::ImageCreateFlagBits::eMutableFormat))
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Failed to create image view. Format for image view not same as image but image not initialized with mutable format bit. ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vk::ImageViewCreateInfo viewCreateInfo
|
|
||||||
{
|
|
||||||
.pNext = nullptr, // Can be used to override with a VkImageViewUsageCreateInfo to override usage. See Vulkan spec page 877 for more information
|
|
||||||
.image = parent->GetVkImage(),
|
|
||||||
.viewType = createParams.viewType,
|
|
||||||
.format = createParams.format,
|
|
||||||
.components
|
|
||||||
{
|
|
||||||
.r = vk::ComponentSwizzle::eR,
|
|
||||||
.g = vk::ComponentSwizzle::eG,
|
|
||||||
.b = vk::ComponentSwizzle::eB,
|
|
||||||
.a = vk::ComponentSwizzle::eA,
|
|
||||||
},
|
|
||||||
.subresourceRange
|
|
||||||
{
|
|
||||||
.aspectMask = createParams.imageAspectFlags,
|
|
||||||
.baseMipLevel = createParams.baseMipLevel,
|
|
||||||
.levelCount = createParams.mipLevelCount,
|
|
||||||
.baseArrayLayer = createParams.baseArrayLayer,
|
|
||||||
.layerCount = createParams.layerCount,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (auto result = inLogicalDeviceHdl->GetVkLogicalDevice().createImageView(&viewCreateInfo, nullptr, &vkImageView); result != vk::Result::eSuccess)
|
|
||||||
{
|
|
||||||
SHVulkanDebugUtil::ReportVkError(result, "Failed to create image view! ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image view. ");
|
|
||||||
}
|
|
||||||
|
|
||||||
// After success, THEN assign variables
|
|
||||||
parentImage = parent;
|
|
||||||
imageViewDetails = createParams;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVkImageView::SHVkImageView(SHVkImageView&& rhs) noexcept
|
SHVkImageView::SHVkImageView(SHVkImageView&& rhs) noexcept
|
||||||
|
@ -94,6 +97,17 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHVkImageView::ViewNewImage(Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept
|
||||||
|
{
|
||||||
|
imageViewDetails = createParams;
|
||||||
|
parentImage = parent;
|
||||||
|
|
||||||
|
if (vkImageView)
|
||||||
|
logicalDeviceHdl->GetVkLogicalDevice().destroyImageView(vkImageView, nullptr);
|
||||||
|
|
||||||
|
Create();
|
||||||
|
}
|
||||||
|
|
||||||
Handle<SHVkImage> const& SHVkImageView::GetParentImage(void) const noexcept
|
Handle<SHVkImage> const& SHVkImageView::GetParentImage(void) const noexcept
|
||||||
{
|
{
|
||||||
return parentImage;
|
return parentImage;
|
||||||
|
|
|
@ -25,12 +25,17 @@ namespace SHADE
|
||||||
//! Logical Device needed for creation and destruction
|
//! Logical Device needed for creation and destruction
|
||||||
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
||||||
|
|
||||||
|
//! Create new image view
|
||||||
|
void Create (void) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
|
SHVkImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
|
||||||
~SHVkImageView(void) noexcept;
|
~SHVkImageView(void) noexcept;
|
||||||
SHVkImageView(SHVkImageView&& rhs) noexcept;
|
SHVkImageView(SHVkImageView&& rhs) noexcept;
|
||||||
SHVkImageView& operator=(SHVkImageView&& rhs) noexcept;
|
SHVkImageView& operator=(SHVkImageView&& rhs) noexcept;
|
||||||
|
|
||||||
|
void ViewNewImage (Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -249,7 +249,7 @@ namespace SHADE
|
||||||
if (!EMPTY_MAT_PROPS)
|
if (!EMPTY_MAT_PROPS)
|
||||||
{
|
{
|
||||||
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
singleMatPropSize = SHADER_INFO->GetBytesRequired();
|
||||||
singleMatPropAlignedSize = device->PadSSBOSize(singleMatPropSize);
|
singleMatPropAlignedSize = device->PadSSBOSize(static_cast<uint32_t>(singleMatPropSize));
|
||||||
matPropTotalBytes = numTotalElements * singleMatPropAlignedSize;
|
matPropTotalBytes = numTotalElements * singleMatPropAlignedSize;
|
||||||
if (matPropsDataSize < matPropTotalBytes)
|
if (matPropsDataSize < matPropTotalBytes)
|
||||||
{
|
{
|
||||||
|
@ -386,7 +386,7 @@ namespace SHADE
|
||||||
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
|
||||||
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
|
||||||
bufferList,
|
bufferList,
|
||||||
0, matPropsDataSize
|
0, static_cast<uint32_t>(matPropsDataSize)
|
||||||
);
|
);
|
||||||
matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer
|
||||||
(
|
(
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace SHADE
|
||||||
SHMatrix inverseViewMatrix;
|
SHMatrix inverseViewMatrix;
|
||||||
SHMatrix inverseProjMatrix;
|
SHMatrix inverseProjMatrix;
|
||||||
SHMatrix inverseVpMatrix;
|
SHMatrix inverseVpMatrix;
|
||||||
bool isDirty;
|
bool isDirty = true;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
|
@ -67,9 +67,17 @@ namespace SHADE
|
||||||
// Register callback to notify render context upon a window resize
|
// Register callback to notify render context upon a window resize
|
||||||
window->RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height)
|
window->RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height)
|
||||||
{
|
{
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
renderContext.SetIsResized(true);
|
renderContext.SetIsResized(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window->RegisterWindowCloseCallback([&](void)
|
||||||
|
{
|
||||||
|
renderContext.SetWindowIsDead(true);
|
||||||
|
}
|
||||||
|
);
|
||||||
// Create graphics queue
|
// Create graphics queue
|
||||||
graphicsQueue = device->GetQueue(SH_Q_FAM::GRAPHICS, 0);
|
graphicsQueue = device->GetQueue(SH_Q_FAM::GRAPHICS, 0);
|
||||||
transferQueue = device->GetQueue(SH_Q_FAM::TRANSFER, 0);
|
transferQueue = device->GetQueue(SH_Q_FAM::TRANSFER, 0);
|
||||||
|
@ -116,8 +124,8 @@ namespace SHADE
|
||||||
screenCamera = resourceManager.Create<SHCamera>();
|
screenCamera = resourceManager.Create<SHCamera>();
|
||||||
screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||||
screenCamera->SetOrthographic(static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.01f, 100.0f);
|
screenCamera->SetOrthographic(static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.01f, 100.0f);
|
||||||
|
|
||||||
worldCamera = resourceManager.Create<SHCamera>();
|
worldCamera = resourceManager.Create<SHCamera>();
|
||||||
//worldCamera->SetLookAt(SHVec3(1.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
|
||||||
worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, 0.0f), SHVec3(0.0f, 0.0f, -2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, 0.0f), SHVec3(0.0f, 0.0f, -2.0f), SHVec3(0.0f, 1.0f, 0.0f));
|
||||||
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
|
||||||
|
|
||||||
|
@ -125,7 +133,7 @@ namespace SHADE
|
||||||
defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
|
defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
|
||||||
|
|
||||||
// Get render graph from default viewport world renderer
|
// Get render graph from default viewport world renderer
|
||||||
auto worldRenderGraph = resourceManager.Create<SHRenderGraph>();
|
worldRenderGraph = resourceManager.Create<SHRenderGraph>();
|
||||||
|
|
||||||
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{swapchain->GetNumImages()};
|
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{swapchain->GetNumImages()};
|
||||||
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
||||||
|
@ -210,6 +218,15 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHGraphicsSystem::Run(double) noexcept
|
void SHGraphicsSystem::Run(double) noexcept
|
||||||
{
|
{
|
||||||
|
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (renderContext.GetResized())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Frame data for the current frame
|
// Frame data for the current frame
|
||||||
auto const& frameData = renderContext.GetCurrentFrameData();
|
auto const& frameData = renderContext.GetCurrentFrameData();
|
||||||
uint32_t frameIndex = renderContext.GetCurrentFrame();
|
uint32_t frameIndex = renderContext.GetCurrentFrame();
|
||||||
|
@ -249,6 +266,10 @@ namespace SHADE
|
||||||
// Begin recording the command buffer
|
// Begin recording the command buffer
|
||||||
currentCmdBuffer->BeginRecording();
|
currentCmdBuffer->BeginRecording();
|
||||||
|
|
||||||
|
uint32_t w = static_cast<uint32_t>(viewports[vpIndex]->GetWidth());
|
||||||
|
uint32_t h = static_cast<uint32_t>(viewports[vpIndex]->GetHeight());
|
||||||
|
currentCmdBuffer->SetViewportScissor (static_cast<float>(w), static_cast<float>(h), w, h);
|
||||||
|
|
||||||
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout());
|
currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout());
|
||||||
|
|
||||||
// Bind all the buffers required for meshes
|
// Bind all the buffers required for meshes
|
||||||
|
@ -304,13 +325,6 @@ namespace SHADE
|
||||||
|
|
||||||
void SHGraphicsSystem::Exit(void)
|
void SHGraphicsSystem::Exit(void)
|
||||||
{
|
{
|
||||||
renderContext.Destroy();
|
|
||||||
graphicsQueue.Free();
|
|
||||||
swapchain.Free();
|
|
||||||
surface.Free();
|
|
||||||
device.Free();
|
|
||||||
|
|
||||||
SHVkInstance::Destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -328,6 +342,9 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHGraphicsSystem::BeginRender()
|
void SHGraphicsSystem::BeginRender()
|
||||||
{
|
{
|
||||||
|
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||||
|
return;
|
||||||
|
|
||||||
// Finalise all batches
|
// Finalise all batches
|
||||||
for (auto vp : viewports)
|
for (auto vp : viewports)
|
||||||
for (auto renderer : vp->GetRenderers())
|
for (auto renderer : vp->GetRenderers())
|
||||||
|
@ -341,10 +358,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
device->WaitIdle();
|
device->WaitIdle();
|
||||||
|
|
||||||
// Resize the swapchain
|
HandleResize();
|
||||||
swapchain->Resize(surface, windowDims.first, windowDims.second);
|
|
||||||
|
|
||||||
renderContext.HandleResize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
|
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
|
||||||
|
@ -377,6 +391,16 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHGraphicsSystem::EndRender()
|
void SHGraphicsSystem::EndRender()
|
||||||
{
|
{
|
||||||
|
if (window->IsMinimized() || renderContext.GetWindowIsDead())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (renderContext.GetResized())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
|
const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
|
||||||
auto& currFrameData = renderContext.GetCurrentFrameData();
|
auto& currFrameData = renderContext.GetCurrentFrameData();
|
||||||
|
|
||||||
|
@ -387,10 +411,8 @@ namespace SHADE
|
||||||
// If swapchain is incompatible/outdated
|
// If swapchain is incompatible/outdated
|
||||||
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
|
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
|
||||||
{
|
{
|
||||||
auto windowDims = window->GetWindowSize();
|
|
||||||
swapchain->Resize(surface, windowDims.first, windowDims.second);
|
|
||||||
|
|
||||||
renderContext.HandleResize();
|
HandleResize();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -509,25 +531,79 @@ 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
|
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
|
||||||
{
|
{
|
||||||
window = wind;
|
window = wind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* System Routine Functions - BeginRoutine */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHGraphicsSystem::BeginRoutine::BeginRoutine()
|
||||||
|
: SHSystemRoutine("Graphics System Frame Set Up", false)
|
||||||
|
{}
|
||||||
|
|
||||||
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
|
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender();
|
reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* System Routine Functions - RenderRoutine */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHGraphicsSystem::RenderRoutine::RenderRoutine()
|
||||||
|
: SHSystemRoutine("Graphics System Render", false)
|
||||||
|
{}
|
||||||
|
|
||||||
void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept
|
void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept
|
||||||
{
|
{
|
||||||
reinterpret_cast<SHGraphicsSystem*>(system)->Run(dt);
|
reinterpret_cast<SHGraphicsSystem*>(system)->Run(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* System Routine Functions - EndRoutine */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHGraphicsSystem::EndRoutine::EndRoutine()
|
||||||
|
: SHSystemRoutine("Graphics System Frame Clean Up", false)
|
||||||
|
{}
|
||||||
|
|
||||||
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* System Routine Functions - BatcherDispatcherRoutine */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHGraphicsSystem::BatcherDispatcherRoutine::BatcherDispatcherRoutine()
|
||||||
|
: SHSystemRoutine("Graphics System Batcher Dispatcher", false)
|
||||||
|
{}
|
||||||
|
|
||||||
void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept
|
void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept
|
||||||
{
|
{
|
||||||
auto& renderables = SHComponentManager::GetDense<SHRenderable>();
|
auto& renderables = SHComponentManager::GetDense<SHRenderable>();
|
||||||
|
|
|
@ -69,21 +69,25 @@ namespace SHADE
|
||||||
class SH_API BeginRoutine final : public SHSystemRoutine
|
class SH_API BeginRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
BeginRoutine();
|
||||||
virtual void Execute(double dt) noexcept override final;
|
virtual void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
class SH_API RenderRoutine final : public SHSystemRoutine
|
class SH_API RenderRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
RenderRoutine();
|
||||||
virtual void Execute(double dt) noexcept override final;
|
virtual void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
class SH_API EndRoutine final : public SHSystemRoutine
|
class SH_API EndRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
EndRoutine();
|
||||||
virtual void Execute(double dt) noexcept override final;
|
virtual void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine
|
class SH_API BatcherDispatcherRoutine final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
BatcherDispatcherRoutine();
|
||||||
virtual void Execute(double dt) noexcept override final;
|
virtual void Execute(double dt) noexcept override final;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -246,6 +250,9 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void BuildTextures();
|
void BuildTextures();
|
||||||
|
|
||||||
|
void HandleResize(void) noexcept;
|
||||||
|
void AwaitGraphicsExecution();
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Setters */
|
/* Setters */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -279,7 +286,6 @@ namespace SHADE
|
||||||
Handle<SHVkQueue> transferQueue;
|
Handle<SHVkQueue> transferQueue;
|
||||||
Handle<SHVkDescriptorPool> descPool;
|
Handle<SHVkDescriptorPool> descPool;
|
||||||
Handle<SHVkCommandPool> graphicsCmdPool;
|
Handle<SHVkCommandPool> graphicsCmdPool;
|
||||||
Handle<SHVkCommandPool> transferCmdPool;
|
|
||||||
Handle<SHVkCommandBuffer> transferCmdBuffer;
|
Handle<SHVkCommandBuffer> transferCmdBuffer;
|
||||||
Handle<SHVkCommandBuffer> graphicsTexCmdBuffer;
|
Handle<SHVkCommandBuffer> graphicsTexCmdBuffer;
|
||||||
SHRenderContext renderContext;
|
SHRenderContext renderContext;
|
||||||
|
@ -314,5 +320,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Temp Materials
|
// Temp Materials
|
||||||
Handle<SHMaterial> defaultMaterial;
|
Handle<SHMaterial> defaultMaterial;
|
||||||
|
|
||||||
|
Handle<SHRenderGraph> worldRenderGraph;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -63,7 +63,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHVkPipeline> pipeline;
|
Handle<SHVkPipeline> pipeline;
|
||||||
std::unique_ptr<char> propMemory;
|
std::unique_ptr<char> propMemory;
|
||||||
Byte propMemorySize;
|
Byte propMemorySize = 0;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
|
@ -49,6 +49,14 @@ namespace SHADE
|
||||||
cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA);
|
cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHRenderer::~SHRenderer(void)
|
||||||
|
{
|
||||||
|
//for (auto& cmdBuffer : commandBuffers)
|
||||||
|
//{
|
||||||
|
// cmdBuffer.Free();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Camera Registration */
|
/* Camera Registration */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -65,6 +65,7 @@ namespace SHADE
|
||||||
/* Constructor/Destructors */
|
/* Constructor/Destructors */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph);
|
SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph);
|
||||||
|
~SHRenderer(void);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Camera Registration */
|
/* Camera Registration */
|
||||||
|
|
|
@ -73,4 +73,16 @@ namespace SHADE
|
||||||
iter->Free();
|
iter->Free();
|
||||||
renderers.erase(iter);
|
renderers.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHViewport::SetWidth(float w) noexcept
|
||||||
|
{
|
||||||
|
viewport.width = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHViewport::SetHeight(float h) noexcept
|
||||||
|
{
|
||||||
|
viewport.height = h;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,12 @@ namespace SHADE
|
||||||
Handle<SHRenderer> AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
|
Handle<SHRenderer> AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, std::vector<Handle<SHVkCommandPool>>& cmdPools, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
|
||||||
void RemoveRenderer(Handle<SHRenderer> renderer);
|
void RemoveRenderer(Handle<SHRenderer> renderer);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Setters */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
void SetWidth(float w) noexcept;
|
||||||
|
void SetHeight (float h) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getters */
|
/* Getters */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -196,12 +196,12 @@ namespace SHADE
|
||||||
static SHMeshData meshData = Cube();
|
static SHMeshData meshData = Cube();
|
||||||
return meshLibrary.AddMesh
|
return meshLibrary.AddMesh
|
||||||
(
|
(
|
||||||
meshData.VertexPositions.size(),
|
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
||||||
meshData.VertexPositions.data(),
|
meshData.VertexPositions.data(),
|
||||||
meshData.VertexTexCoords.data(),
|
meshData.VertexTexCoords.data(),
|
||||||
meshData.VertexTangents.data(),
|
meshData.VertexTangents.data(),
|
||||||
meshData.VertexNormals.data(),
|
meshData.VertexNormals.data(),
|
||||||
meshData.Indices.size(),
|
static_cast<uint32_t>(meshData.Indices.size()),
|
||||||
meshData.Indices.data()
|
meshData.Indices.data()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -211,12 +211,12 @@ namespace SHADE
|
||||||
static SHMeshData meshData = Cube();
|
static SHMeshData meshData = Cube();
|
||||||
return gfxSystem.AddMesh
|
return gfxSystem.AddMesh
|
||||||
(
|
(
|
||||||
meshData.VertexPositions.size(),
|
static_cast<uint32_t>(meshData.VertexPositions.size()),
|
||||||
meshData.VertexPositions.data(),
|
meshData.VertexPositions.data(),
|
||||||
meshData.VertexTexCoords.data(),
|
meshData.VertexTexCoords.data(),
|
||||||
meshData.VertexTangents.data(),
|
meshData.VertexTangents.data(),
|
||||||
meshData.VertexNormals.data(),
|
meshData.VertexNormals.data(),
|
||||||
meshData.Indices.size(),
|
static_cast<uint32_t>(meshData.Indices.size()),
|
||||||
meshData.Indices.data()
|
meshData.Indices.data()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,11 @@ namespace SHADE
|
||||||
isResized = resized;
|
isResized = resized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderContext::SetWindowIsDead(bool dead) noexcept
|
||||||
|
{
|
||||||
|
windowIsDead = dead;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -197,6 +202,11 @@ namespace SHADE
|
||||||
return currentFrame;
|
return currentFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHRenderContext::GetResized(void) noexcept
|
||||||
|
{
|
||||||
|
return isResized;
|
||||||
|
}
|
||||||
|
|
||||||
bool SHRenderContext::GetResizeAndReset(void) noexcept
|
bool SHRenderContext::GetResizeAndReset(void) noexcept
|
||||||
{
|
{
|
||||||
bool b = isResized;
|
bool b = isResized;
|
||||||
|
@ -204,4 +214,9 @@ namespace SHADE
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHRenderContext::GetWindowIsDead(void) const noexcept
|
||||||
|
{
|
||||||
|
return windowIsDead;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -36,6 +36,7 @@ namespace SHADE
|
||||||
uint32_t currentFrame;
|
uint32_t currentFrame;
|
||||||
|
|
||||||
bool isResized{ false };
|
bool isResized{ false };
|
||||||
|
bool windowIsDead {false};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHRenderContext(void) noexcept;
|
SHRenderContext(void) noexcept;
|
||||||
|
@ -51,12 +52,15 @@ namespace SHADE
|
||||||
bool WaitForFence (void) noexcept;
|
bool WaitForFence (void) noexcept;
|
||||||
void ResetFence (void) noexcept;
|
void ResetFence (void) noexcept;
|
||||||
|
|
||||||
void SetIsResized (bool resized) noexcept;
|
void SetIsResized (bool resized) noexcept;
|
||||||
|
void SetWindowIsDead (bool dead) noexcept;
|
||||||
|
|
||||||
SHPerFrameData& GetCurrentFrameData(void) noexcept;
|
SHPerFrameData& GetCurrentFrameData(void) noexcept;
|
||||||
SHPerFrameData& GetFrameData (uint32_t index) noexcept;
|
SHPerFrameData& GetFrameData (uint32_t index) noexcept;
|
||||||
uint32_t GetCurrentFrame (void) const noexcept;
|
uint32_t GetCurrentFrame (void) const noexcept;
|
||||||
|
bool GetResized (void) noexcept;
|
||||||
bool GetResizeAndReset (void) noexcept;
|
bool GetResizeAndReset (void) noexcept;
|
||||||
|
bool GetWindowIsDead (void) const noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
texOrder.emplace_back(job.TextureHandle);
|
texOrder.emplace_back(job.TextureHandle);
|
||||||
combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal));
|
combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal));
|
||||||
job.TextureHandle->TextureArrayIndex = texOrder.size() - 1;
|
job.TextureHandle->TextureArrayIndex = static_cast<uint32_t>(texOrder.size()) - 1U;
|
||||||
}
|
}
|
||||||
addJobs.clear();
|
addJobs.clear();
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace SHADE
|
||||||
class SHVkDescriptorSetLayout;
|
class SHVkDescriptorSetLayout;
|
||||||
class SHVkDescriptorSetGroup;
|
class SHVkDescriptorSetGroup;
|
||||||
class SHVkSampler;
|
class SHVkSampler;
|
||||||
class SHTextureAsset;
|
struct SHTextureAsset;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace SHADE
|
||||||
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
||||||
{
|
{
|
||||||
w = swapchainHdl->GetSwapchainImage(0)->GetWidth();
|
w = swapchainHdl->GetSwapchainImage(0)->GetWidth();
|
||||||
w = swapchainHdl->GetSwapchainImage(0)->GetHeight();
|
h = swapchainHdl->GetSwapchainImage(0)->GetHeight();
|
||||||
format = swapchainHdl->GetSurfaceFormatKHR().format;
|
format = swapchainHdl->GetSurfaceFormatKHR().format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,9 +465,6 @@ namespace SHADE
|
||||||
// better way to manage these
|
// better way to manage these
|
||||||
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
|
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
|
||||||
{
|
{
|
||||||
// TODO: DON'T HARDCODE THIS
|
|
||||||
cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080);
|
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
node->Execute(cmdBuffer, descPool, frameIndex);
|
node->Execute(cmdBuffer, descPool, frameIndex);
|
||||||
}
|
}
|
||||||
|
@ -480,6 +477,18 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraph::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept
|
||||||
|
{
|
||||||
|
// resize resources
|
||||||
|
for (auto& [name, resource]: graphResources)
|
||||||
|
resource->HandleResize(newWidth, newHeight);
|
||||||
|
|
||||||
|
for (auto& node : nodes)
|
||||||
|
{
|
||||||
|
node->HandleResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Handle<SHRenderGraphNode> SHRenderGraph::GetNode(std::string const& nodeName) const noexcept
|
Handle<SHRenderGraphNode> SHRenderGraph::GetNode(std::string const& nodeName) const noexcept
|
||||||
{
|
{
|
||||||
if (nodeIndexing.contains(nodeName))
|
if (nodeIndexing.contains(nodeName))
|
||||||
|
|
|
@ -80,6 +80,7 @@ namespace SHADE
|
||||||
void Generate (void) noexcept;
|
void Generate (void) noexcept;
|
||||||
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
|
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
#include "Graphics/Images/SHVkImageView.h"
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
|
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
|
||||||
#include "SHRenderGraphResource.h"
|
#include "SHRenderGraphResource.h"
|
||||||
#include "SHSubpass.h"
|
#include "SHSubpass.h"
|
||||||
|
|
||||||
|
@ -56,6 +57,33 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNode::HandleResize(void) noexcept
|
||||||
|
{
|
||||||
|
renderpass->HandleResize();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < framebuffers.size(); ++i)
|
||||||
|
{
|
||||||
|
std::vector<Handle<SHVkImageView>> imageViews(attResources.size());
|
||||||
|
uint32_t fbWidth = std::numeric_limits<uint32_t>::max();
|
||||||
|
uint32_t fbHeight = std::numeric_limits<uint32_t>::max();
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < attResources.size(); ++j)
|
||||||
|
{
|
||||||
|
uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::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
|
||||||
|
if (fbWidth > attResources[j]->width)
|
||||||
|
fbWidth = attResources[j]->width;
|
||||||
|
if (fbHeight > attResources[j]->height)
|
||||||
|
fbHeight = attResources[j]->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void CreateRenderpass(void) noexcept;
|
void CreateRenderpass(void) noexcept;
|
||||||
void CreateFramebuffer(void) noexcept;
|
void CreateFramebuffer(void) noexcept;
|
||||||
|
void HandleResize (void) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
#include "SHRenderGraphResource.h"
|
#include "SHRenderGraphResource.h"
|
||||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -42,7 +44,9 @@ 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::ImageCreateFlagBits createFlags) noexcept
|
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::ImageCreateFlagBits createFlags) noexcept
|
||||||
: resourceType{ type }
|
: logicalDevice {logicalDevice}
|
||||||
|
, swapchain{ swapchain }
|
||||||
|
, resourceType{ type }
|
||||||
, resourceFormat{ format }
|
, resourceFormat{ format }
|
||||||
, images{}
|
, images{}
|
||||||
, imageViews{}
|
, imageViews{}
|
||||||
|
@ -52,10 +56,10 @@ namespace SHADE
|
||||||
, resourceName{ name }
|
, resourceName{ name }
|
||||||
{
|
{
|
||||||
// If the resource type is an arbitrary image and not swapchain image
|
// If the resource type is an arbitrary image and not swapchain image
|
||||||
if (type != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||||
{
|
{
|
||||||
vk::ImageAspectFlags imageAspectFlags;
|
imageAspectFlags = vk::ImageAspectFlags{};
|
||||||
vk::ImageUsageFlags usage = {};
|
usage = {};
|
||||||
|
|
||||||
// Check the resource type and set image usage flags and image aspect flags accordingly
|
// Check the resource type and set image usage flags and image aspect flags accordingly
|
||||||
switch (resourceType)
|
switch (resourceType)
|
||||||
|
@ -142,6 +146,7 @@ namespace SHADE
|
||||||
, width{ rhs.width }
|
, width{ rhs.width }
|
||||||
, height{ rhs.height }
|
, height{ rhs.height }
|
||||||
, mipLevels{ rhs.mipLevels }
|
, mipLevels{ rhs.mipLevels }
|
||||||
|
, imageAspectFlags{ rhs.imageAspectFlags }
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -172,6 +177,7 @@ namespace SHADE
|
||||||
width = rhs.width;
|
width = rhs.width;
|
||||||
height = rhs.height;
|
height = rhs.height;
|
||||||
mipLevels = rhs.mipLevels;
|
mipLevels = rhs.mipLevels;
|
||||||
|
imageAspectFlags = rhs.imageAspectFlags;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -189,4 +195,51 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphResource::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept
|
||||||
|
{
|
||||||
|
width = newWidth;
|
||||||
|
height = newHeight;
|
||||||
|
|
||||||
|
if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
|
||||||
|
{
|
||||||
|
// prepare image view details
|
||||||
|
SHImageViewDetails viewDetails
|
||||||
|
{
|
||||||
|
.viewType = vk::ImageViewType::e2D,
|
||||||
|
.format = images[0]->GetImageFormat(),
|
||||||
|
.imageAspectFlags = imageAspectFlags,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.mipLevelCount = mipLevels,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < images.size(); ++i)
|
||||||
|
{
|
||||||
|
images[i]->HandleResizeFramebufferImage(width, height);
|
||||||
|
imageViews[i]->ViewNewImage(images[i], viewDetails);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Prepare image view details
|
||||||
|
SHImageViewDetails viewDetails
|
||||||
|
{
|
||||||
|
.viewType = vk::ImageViewType::e2D,
|
||||||
|
.format = swapchain->GetSurfaceFormatKHR().format,
|
||||||
|
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.mipLevelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
|
||||||
|
{
|
||||||
|
images[i] = swapchain->GetSwapchainImage(i);
|
||||||
|
imageViews[i]->ViewNewImage(images[i], viewDetails);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -20,6 +20,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
// for creation/recreation
|
||||||
|
Handle<SHVkLogicalDevice> logicalDevice;
|
||||||
|
|
||||||
|
// for creation/recreation
|
||||||
|
Handle<SHVkSwapchain> swapchain;
|
||||||
|
|
||||||
//! Name of the resource
|
//! Name of the resource
|
||||||
std::string resourceName;
|
std::string resourceName;
|
||||||
|
|
||||||
|
@ -47,6 +53,14 @@ namespace SHADE
|
||||||
|
|
||||||
//! Number of mipmap levels
|
//! Number of mipmap levels
|
||||||
uint8_t mipLevels;
|
uint8_t mipLevels;
|
||||||
|
|
||||||
|
//! image aspect flags
|
||||||
|
vk::ImageAspectFlags imageAspectFlags;
|
||||||
|
|
||||||
|
//! usage flags
|
||||||
|
vk::ImageUsageFlags usage = {};
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
|
@ -56,6 +70,8 @@ namespace SHADE
|
||||||
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
||||||
~SHRenderGraphResource(void) noexcept;
|
~SHRenderGraphResource(void) noexcept;
|
||||||
|
|
||||||
|
void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
|
||||||
|
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,10 @@ namespace SHADE
|
||||||
SHVkRenderpass::SHVkRenderpass(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept
|
SHVkRenderpass::SHVkRenderpass(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept
|
||||||
: logicalDeviceHdl {inLogicalDeviceHdl}
|
: logicalDeviceHdl {inLogicalDeviceHdl}
|
||||||
, numAttDescs {static_cast<uint32_t>(vkDescriptions.size())}
|
, numAttDescs {static_cast<uint32_t>(vkDescriptions.size())}
|
||||||
|
, vkSubpassDescriptions{}
|
||||||
|
, vkSubpassDeps{}
|
||||||
, clearColors{}
|
, clearColors{}
|
||||||
|
, vkAttachmentDescriptions{}
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -42,7 +45,6 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
||||||
std::vector<vk::SubpassDependency> subpassDeps;
|
|
||||||
|
|
||||||
// For validating the depth ref
|
// For validating the depth ref
|
||||||
auto isValidDepthRef = [&](vk::AttachmentReference const& depthRef) -> bool
|
auto isValidDepthRef = [&](vk::AttachmentReference const& depthRef) -> bool
|
||||||
|
@ -50,13 +52,16 @@ namespace SHADE
|
||||||
return !(depthRef.attachment == static_cast<uint32_t> (-1) && depthRef.layout == vk::ImageLayout::eUndefined);
|
return !(depthRef.attachment == static_cast<uint32_t> (-1) && depthRef.layout == vk::ImageLayout::eUndefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||||
|
vkAttachmentDescriptions[i] = vkDescriptions[i];
|
||||||
|
|
||||||
uint32_t subpassIndex = 0;
|
uint32_t subpassIndex = 0;
|
||||||
if (!subpasses.empty())
|
if (!subpasses.empty())
|
||||||
{
|
{
|
||||||
for (auto& subpass : subpasses)
|
for (auto& subpass : subpasses)
|
||||||
{
|
{
|
||||||
subpassDescriptions.emplace_back();
|
vkSubpassDescriptions.emplace_back();
|
||||||
auto& spDesc = subpassDescriptions.back();
|
auto& spDesc = vkSubpassDescriptions.back();
|
||||||
|
|
||||||
spDesc.pColorAttachments = subpass.colorRefs.data();
|
spDesc.pColorAttachments = subpass.colorRefs.data();
|
||||||
spDesc.colorAttachmentCount = static_cast<uint32_t>(subpass.colorRefs.size());
|
spDesc.colorAttachmentCount = static_cast<uint32_t>(subpass.colorRefs.size());
|
||||||
|
@ -88,18 +93,18 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
// Push a new dependency
|
// Push a new dependency
|
||||||
subpassDeps.push_back(dependency);
|
vkSubpassDeps.push_back(dependency);
|
||||||
|
|
||||||
++subpassIndex;
|
++subpassIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renderpass create info for render pass creation
|
// Renderpass create info for render pass creation
|
||||||
renderPassCreateInfo.attachmentCount = static_cast<uint32_t>(vkDescriptions.size());
|
renderPassCreateInfo.attachmentCount = static_cast<uint32_t>(vkAttachmentDescriptions.size());
|
||||||
renderPassCreateInfo.pAttachments = vkDescriptions.data();
|
renderPassCreateInfo.pAttachments = vkAttachmentDescriptions.data();
|
||||||
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(subpassDescriptions.size());
|
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(vkSubpassDescriptions.size());
|
||||||
renderPassCreateInfo.pSubpasses = subpassDescriptions.data();
|
renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data();
|
||||||
renderPassCreateInfo.dependencyCount = static_cast<uint32_t>(subpassDeps.size());
|
renderPassCreateInfo.dependencyCount = static_cast<uint32_t>(vkSubpassDeps.size());
|
||||||
renderPassCreateInfo.pDependencies = subpassDeps.data();
|
renderPassCreateInfo.pDependencies = vkSubpassDeps.data();
|
||||||
|
|
||||||
}
|
}
|
||||||
// No subpasses passed in, create a default one.
|
// No subpasses passed in, create a default one.
|
||||||
|
@ -172,6 +177,8 @@ namespace SHADE
|
||||||
: logicalDeviceHdl{ inLogicalDeviceHdl }
|
: logicalDeviceHdl{ inLogicalDeviceHdl }
|
||||||
, numAttDescs{ static_cast<uint32_t>(vkDescriptions.size()) }
|
, numAttDescs{ static_cast<uint32_t>(vkDescriptions.size()) }
|
||||||
, clearColors{}
|
, clearColors{}
|
||||||
|
, vkSubpassDescriptions{ }
|
||||||
|
, vkSubpassDeps{ }
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -181,18 +188,24 @@ namespace SHADE
|
||||||
clearColors[i].color = { {{0.0f, 0.0f, 0.0f, 1.0f}} };
|
clearColors[i].color = { {{0.0f, 0.0f, 0.0f, 1.0f}} };
|
||||||
}
|
}
|
||||||
|
|
||||||
subpassDescriptions.resize (spDescs.size());
|
vkAttachmentDescriptions.resize(vkDescriptions.size());
|
||||||
for (uint32_t i = 0; i < subpassDescriptions.size(); ++i)
|
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||||
{
|
vkAttachmentDescriptions[i] = vkDescriptions[i];
|
||||||
subpassDescriptions[i] = spDescs[i];
|
|
||||||
}
|
vkSubpassDescriptions.resize (spDescs.size());
|
||||||
|
for (uint32_t i = 0; i < vkSubpassDescriptions.size(); ++i)
|
||||||
|
vkSubpassDescriptions[i] = spDescs[i];
|
||||||
|
|
||||||
|
vkSubpassDeps.resize(spDeps.size());
|
||||||
|
for (uint32_t i = 0; i < vkSubpassDeps.size(); ++i)
|
||||||
|
vkSubpassDeps[i] = spDeps[i];
|
||||||
|
|
||||||
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
||||||
|
|
||||||
renderPassCreateInfo.attachmentCount = static_cast<uint32_t>(vkDescriptions.size());
|
renderPassCreateInfo.attachmentCount = static_cast<uint32_t>(vkDescriptions.size());
|
||||||
renderPassCreateInfo.pAttachments = vkDescriptions.data();
|
renderPassCreateInfo.pAttachments = vkDescriptions.data();
|
||||||
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(subpassDescriptions.size());
|
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(vkSubpassDescriptions.size());
|
||||||
renderPassCreateInfo.pSubpasses = subpassDescriptions.data();
|
renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data();
|
||||||
renderPassCreateInfo.dependencyCount = static_cast<uint32_t>(spDeps.size());
|
renderPassCreateInfo.dependencyCount = static_cast<uint32_t>(spDeps.size());
|
||||||
renderPassCreateInfo.pDependencies = spDeps.data();
|
renderPassCreateInfo.pDependencies = spDeps.data();
|
||||||
|
|
||||||
|
@ -210,8 +223,11 @@ namespace SHADE
|
||||||
SHVkRenderpass::SHVkRenderpass(SHVkRenderpass&& rhs) noexcept
|
SHVkRenderpass::SHVkRenderpass(SHVkRenderpass&& rhs) noexcept
|
||||||
: vkRenderpass {rhs.vkRenderpass}
|
: vkRenderpass {rhs.vkRenderpass}
|
||||||
, logicalDeviceHdl {rhs.logicalDeviceHdl}
|
, logicalDeviceHdl {rhs.logicalDeviceHdl}
|
||||||
, subpassDescriptions {std::move (rhs.subpassDescriptions)}
|
, vkSubpassDescriptions{ std::move(rhs.vkSubpassDescriptions) }
|
||||||
, clearColors {std::move (rhs.clearColors)}
|
, vkSubpassDeps{ std::move(rhs.vkSubpassDeps) }
|
||||||
|
, clearColors{ std::move(rhs.clearColors) }
|
||||||
|
, vkAttachmentDescriptions{ std::move(rhs.vkAttachmentDescriptions) }
|
||||||
|
, numAttDescs{rhs.numAttDescs}
|
||||||
{
|
{
|
||||||
rhs.vkRenderpass = VK_NULL_HANDLE;
|
rhs.vkRenderpass = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
@ -224,8 +240,11 @@ namespace SHADE
|
||||||
|
|
||||||
vkRenderpass = rhs.vkRenderpass;
|
vkRenderpass = rhs.vkRenderpass;
|
||||||
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
logicalDeviceHdl = rhs.logicalDeviceHdl;
|
||||||
subpassDescriptions = std::move(rhs.subpassDescriptions);
|
vkSubpassDescriptions = std::move(rhs.vkSubpassDescriptions);
|
||||||
|
vkSubpassDeps = std::move(rhs.vkSubpassDeps);
|
||||||
clearColors = std::move(rhs.clearColors);
|
clearColors = std::move(rhs.clearColors);
|
||||||
|
vkAttachmentDescriptions = std::move(rhs.vkAttachmentDescriptions);
|
||||||
|
numAttDescs = std::move(rhs.numAttDescs);
|
||||||
|
|
||||||
rhs.vkRenderpass = VK_NULL_HANDLE;
|
rhs.vkRenderpass = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
@ -238,6 +257,31 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHVkRenderpass::HandleResize(void) noexcept
|
||||||
|
{
|
||||||
|
logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr);
|
||||||
|
|
||||||
|
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
||||||
|
|
||||||
|
renderPassCreateInfo.attachmentCount = static_cast<uint32_t>(vkAttachmentDescriptions.size());
|
||||||
|
renderPassCreateInfo.pAttachments = vkAttachmentDescriptions.data();
|
||||||
|
renderPassCreateInfo.subpassCount = static_cast<uint32_t>(vkSubpassDescriptions.size());
|
||||||
|
renderPassCreateInfo.pSubpasses = vkSubpassDescriptions.data();
|
||||||
|
renderPassCreateInfo.dependencyCount = static_cast<uint32_t>(vkSubpassDeps.size());
|
||||||
|
renderPassCreateInfo.pDependencies = vkSubpassDeps.data();
|
||||||
|
|
||||||
|
|
||||||
|
if (auto result = logicalDeviceHdl->GetVkLogicalDevice().createRenderPass(&renderPassCreateInfo, nullptr, &vkRenderpass); result != vk::Result::eSuccess)
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkError(result, "Failed to create Renderpass. ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created Renderpass. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
vk::RenderPass SHVkRenderpass::GetVkRenderpass(void) const noexcept
|
vk::RenderPass SHVkRenderpass::GetVkRenderpass(void) const noexcept
|
||||||
{
|
{
|
||||||
return vkRenderpass;
|
return vkRenderpass;
|
||||||
|
|
|
@ -29,7 +29,13 @@ namespace SHADE
|
||||||
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
Handle<SHVkLogicalDevice> logicalDeviceHdl;
|
||||||
|
|
||||||
//! Container of subpass information used to construct subpasses
|
//! Container of subpass information used to construct subpasses
|
||||||
std::vector<vk::SubpassDescription> subpassDescriptions;
|
std::vector<vk::SubpassDescription> vkSubpassDescriptions;
|
||||||
|
|
||||||
|
//! Container of subpass dependencies used to create renderpass
|
||||||
|
std::vector<vk::SubpassDependency> vkSubpassDeps;
|
||||||
|
|
||||||
|
//! Attachment descriptions
|
||||||
|
std::vector<vk::AttachmentDescription> vkAttachmentDescriptions;
|
||||||
|
|
||||||
//! Clear colors for the color and depth
|
//! Clear colors for the color and depth
|
||||||
std::array<vk::ClearValue, NUM_CLEAR_COLORS> clearColors;
|
std::array<vk::ClearValue, NUM_CLEAR_COLORS> clearColors;
|
||||||
|
@ -49,6 +55,8 @@ namespace SHADE
|
||||||
SHVkRenderpass(SHVkRenderpass&& rhs) noexcept;
|
SHVkRenderpass(SHVkRenderpass&& rhs) noexcept;
|
||||||
SHVkRenderpass& operator=(SHVkRenderpass&& rhs) noexcept;
|
SHVkRenderpass& operator=(SHVkRenderpass&& rhs) noexcept;
|
||||||
|
|
||||||
|
void HandleResize (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -272,6 +272,17 @@ namespace SHADE
|
||||||
windowResizeCallbacks.erase(callbackid);
|
windowResizeCallbacks.erase(callbackid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHWindow::CALLBACKID SHWindow::RegisterWindowCloseCallback(WindowCloseCallbackFn windowCloseCallback)
|
||||||
|
{
|
||||||
|
windowCloseCallbacks.try_emplace(windowResizeCallbackCount, windowCloseCallback);
|
||||||
|
return windowCloseCallbackCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHWindow::UnregisterWindowCloseCallback(CALLBACKID const& callbackid)
|
||||||
|
{
|
||||||
|
windowCloseCallbacks.erase(callbackid);
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT SHWindow::WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
LRESULT SHWindow::WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||||
{
|
{
|
||||||
auto window = windowMap.GetWindow(hwnd);
|
auto window = windowMap.GetWindow(hwnd);
|
||||||
|
@ -307,6 +318,8 @@ namespace SHADE
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
OnCreate(hwnd, reinterpret_cast<LPCREATESTRUCT>(wparam));
|
OnCreate(hwnd, reinterpret_cast<LPCREATESTRUCT>(wparam));
|
||||||
break;
|
break;
|
||||||
|
case WM_CLOSE:
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
OnDestroy();
|
OnDestroy();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -362,8 +375,17 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHADE::SHWindow::OnClose()
|
||||||
|
{
|
||||||
|
for (const auto& callbackFn : windowCloseCallbacks | std::views::values)
|
||||||
|
{
|
||||||
|
callbackFn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHWindow::OnDestroy()
|
void SHWindow::OnDestroy()
|
||||||
{
|
{
|
||||||
|
OnClose();
|
||||||
this->Destroy();
|
this->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,6 +397,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
wndData.width = static_cast<unsigned>(size.cx);
|
wndData.width = static_cast<unsigned>(size.cx);
|
||||||
wndData.height = static_cast<unsigned>(size.cy);
|
wndData.height = static_cast<unsigned>(size.cy);
|
||||||
|
|
||||||
|
if (type == SIZE_MINIMIZED)
|
||||||
|
{
|
||||||
|
wndData.isMinimised = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wndData.isMinimised = false;
|
||||||
|
|
||||||
for (auto const& entry : windowResizeCallbacks)
|
for (auto const& entry : windowResizeCallbacks)
|
||||||
{
|
{
|
||||||
entry.second(static_cast<uint32_t>(wndData.width), static_cast<uint32_t>(wndData.height));
|
entry.second(static_cast<uint32_t>(wndData.width), static_cast<uint32_t>(wndData.height));
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WindowData
|
struct WindowData
|
||||||
{
|
{
|
||||||
unsigned x = 0;
|
unsigned x = 0;
|
||||||
|
|
||||||
unsigned y = 0;
|
unsigned y = 0;
|
||||||
|
@ -42,7 +42,7 @@ namespace SHADE
|
||||||
bool closable = true;
|
bool closable = true;
|
||||||
|
|
||||||
bool minimizable = true;
|
bool minimizable = true;
|
||||||
|
|
||||||
bool maximizable = true;
|
bool maximizable = true;
|
||||||
|
|
||||||
//bool canFullscreen = true;
|
//bool canFullscreen = true;
|
||||||
|
@ -56,11 +56,13 @@ namespace SHADE
|
||||||
bool shadowEnabled = true;
|
bool shadowEnabled = true;
|
||||||
|
|
||||||
bool isVisible = true;
|
bool isVisible = true;
|
||||||
|
|
||||||
bool isFullscreen = false;
|
bool isFullscreen = false;
|
||||||
|
|
||||||
bool modal = false;
|
bool modal = false;
|
||||||
|
|
||||||
|
bool isMinimised = false;
|
||||||
|
|
||||||
std::wstring title = L"SHADE ENGINE";
|
std::wstring title = L"SHADE ENGINE";
|
||||||
|
|
||||||
std::wstring name = L"SHADEEngineApp";
|
std::wstring name = L"SHADEEngineApp";
|
||||||
|
@ -73,6 +75,7 @@ namespace SHADE
|
||||||
public:
|
public:
|
||||||
using SHVec2 = std::pair<uint32_t, uint32_t>;
|
using SHVec2 = std::pair<uint32_t, uint32_t>;
|
||||||
typedef std::function<void(uint32_t width, uint32_t height)> WindowResizeCallbackFn;
|
typedef std::function<void(uint32_t width, uint32_t height)> WindowResizeCallbackFn;
|
||||||
|
typedef std::function<void(void)> WindowCloseCallbackFn;
|
||||||
typedef uint16_t CALLBACKID;
|
typedef uint16_t CALLBACKID;
|
||||||
SHWindow();
|
SHWindow();
|
||||||
|
|
||||||
|
@ -103,7 +106,7 @@ namespace SHADE
|
||||||
void SetMousePosition(unsigned x, unsigned y);
|
void SetMousePosition(unsigned x, unsigned y);
|
||||||
|
|
||||||
//unsigned GetBGColor();
|
//unsigned GetBGColor();
|
||||||
|
|
||||||
void SetBGColor(unsigned color);
|
void SetBGColor(unsigned color);
|
||||||
|
|
||||||
void Minimize();
|
void Minimize();
|
||||||
|
@ -123,6 +126,9 @@ namespace SHADE
|
||||||
|
|
||||||
CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn);
|
CALLBACKID RegisterWindowSizeCallback(WindowResizeCallbackFn);
|
||||||
void UnregisterWindowSizeCallback(CALLBACKID const& callbackid);
|
void UnregisterWindowSizeCallback(CALLBACKID const& callbackid);
|
||||||
|
CALLBACKID RegisterWindowCloseCallback(WindowCloseCallbackFn);
|
||||||
|
void UnregisterWindowCloseCallback(CALLBACKID const& callbackid);
|
||||||
|
bool IsMinimized() const { return wndData.isMinimised; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static LRESULT CALLBACK WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
static LRESULT CALLBACK WndProcStatic(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||||
|
@ -154,10 +160,13 @@ namespace SHADE
|
||||||
HFONT font;
|
HFONT font;
|
||||||
|
|
||||||
std::unordered_map<CALLBACKID, WindowResizeCallbackFn> windowResizeCallbacks;
|
std::unordered_map<CALLBACKID, WindowResizeCallbackFn> windowResizeCallbacks;
|
||||||
|
std::unordered_map<CALLBACKID, WindowCloseCallbackFn> windowCloseCallbacks;
|
||||||
CALLBACKID windowResizeCallbackCount{};
|
CALLBACKID windowResizeCallbackCount{};
|
||||||
|
CALLBACKID windowCloseCallbackCount{};
|
||||||
//TODO: Shift to events abstraction
|
//TODO: Shift to events abstraction
|
||||||
|
|
||||||
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
|
void OnCreate(HWND hwnd, LPCREATESTRUCT create_struct);
|
||||||
|
void OnClose();
|
||||||
void OnDestroy();
|
void OnDestroy();
|
||||||
//void OnFileDrop(HDROP drop);
|
//void OnFileDrop(HDROP drop);
|
||||||
void OnSize(UINT msg, UINT type, SIZE size);
|
void OnSize(UINT msg, UINT type, SIZE size);
|
||||||
|
|
|
@ -390,6 +390,13 @@ RTTR_REGISTRATION
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
using namespace rttr;
|
using namespace rttr;
|
||||||
|
|
||||||
|
registration::enumeration<SHRigidBodyComponent::Type>("RigidBody Type")
|
||||||
|
(
|
||||||
|
value("Static", SHRigidBodyComponent::Type::STATIC),
|
||||||
|
value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC),
|
||||||
|
value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC)
|
||||||
|
);
|
||||||
|
|
||||||
registration::class_<SHRigidBodyComponent>("RigidBody Component")
|
registration::class_<SHRigidBodyComponent>("RigidBody Component")
|
||||||
.property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType )
|
.property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType )
|
||||||
.property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass )
|
.property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass )
|
||||||
|
|
|
@ -8,9 +8,9 @@ namespace SHADE
|
||||||
ResourceManager::~ResourceManager()
|
ResourceManager::~ResourceManager()
|
||||||
{
|
{
|
||||||
// Delete all resources libraries
|
// Delete all resources libraries
|
||||||
for (const auto& deleter : deleters)
|
for (auto iter = deleters.rbegin(); iter != deleters.rend(); ++iter)
|
||||||
{
|
{
|
||||||
deleter();
|
(*iter)();
|
||||||
}
|
}
|
||||||
deleters.clear();
|
deleters.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ namespace SHADE
|
||||||
/// <param name="handle">Handle to the resource object.</param>
|
/// <param name="handle">Handle to the resource object.</param>
|
||||||
/// <returns>Read-only reference to the resource object.</returns>
|
/// <returns>Read-only reference to the resource object.</returns>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const T& Get(Handle<T> handle) const;
|
const T& Get(Handle<T> handle) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -90,10 +90,15 @@ namespace SHADE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Go through the map and release all the nodes
|
// Go through the map and release all the nodes
|
||||||
for (auto* node : entityNodeMap | std::views::values)
|
for (auto*& node : entityNodeMap | std::views::values)
|
||||||
ReleaseNode(node);
|
{
|
||||||
|
delete node;
|
||||||
|
node = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
delete root;
|
entityNodeMap.clear();
|
||||||
|
|
||||||
|
//delete root;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
SHLOG_INFO("Scene Graph Destroyed Successfully!")
|
SHLOG_INFO("Scene Graph Destroyed Successfully!")
|
||||||
|
|
|
@ -153,6 +153,16 @@ namespace SHADE
|
||||||
csEditorRenderScripts(entity);
|
csEditorRenderScripts(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHScriptEngine::UndoScriptInspectorChanges() const
|
||||||
|
{
|
||||||
|
csEditorUndo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHScriptEngine::RedoScriptInspectorChanges() const
|
||||||
|
{
|
||||||
|
csEditorRedo();
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Static Utility Functions */
|
/* Static Utility Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -400,6 +410,18 @@ namespace SHADE
|
||||||
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
||||||
"RenderScriptsInInspector"
|
"RenderScriptsInInspector"
|
||||||
);
|
);
|
||||||
|
csEditorUndo = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
||||||
|
"Undo"
|
||||||
|
);
|
||||||
|
csEditorRedo = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
||||||
|
"Redo"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHScriptEngine::registerEvents()
|
void SHScriptEngine::registerEvents()
|
||||||
|
|
|
@ -171,6 +171,14 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||||
void RenderScriptsInInspector(EntityID entity) const;
|
void RenderScriptsInInspector(EntityID entity) const;
|
||||||
|
/// <summary>
|
||||||
|
/// Performs an undo for script inspector changes if it exists.
|
||||||
|
/// </summary>
|
||||||
|
void UndoScriptInspectorChanges() const;
|
||||||
|
/// <summary>
|
||||||
|
/// Performs a redo for script inspector changes if it exists.
|
||||||
|
/// </summary>
|
||||||
|
void RedoScriptInspectorChanges() const;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Static Utility Functions */
|
/* Static Utility Functions */
|
||||||
|
@ -243,9 +251,8 @@ namespace SHADE
|
||||||
CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml = nullptr;
|
CsScriptSerialiseYamlFuncPtr csScriptDeserialiseYaml = nullptr;
|
||||||
// - Editor
|
// - Editor
|
||||||
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
|
CsScriptEditorFuncPtr csEditorRenderScripts = nullptr;
|
||||||
// Delegates
|
CsFuncPtr csEditorUndo = nullptr;
|
||||||
/*ECS::EntityEvent::Delegate onEntityCreate;
|
CsFuncPtr csEditorRedo = nullptr;
|
||||||
ECS::EntityEvent::Delegate onEntityDestroy;*/
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Event Handler Functions */
|
/* Event Handler Functions */
|
||||||
|
|
|
@ -30,7 +30,8 @@ project "SHADE_Managed"
|
||||||
"%{IncludeDir.imguizmo}",
|
"%{IncludeDir.imguizmo}",
|
||||||
"%{IncludeDir.imnodes}",
|
"%{IncludeDir.imnodes}",
|
||||||
"%{IncludeDir.yamlcpp}",
|
"%{IncludeDir.yamlcpp}",
|
||||||
"%{IncludeDir.RTTR}/include",
|
"%{IncludeDir.RTTR}/include",
|
||||||
|
"%{IncludeDir.dotnet}\\include",
|
||||||
"%{wks.location}/SHADE_Engine/src"
|
"%{wks.location}/SHADE_Engine/src"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,3 +86,8 @@ project "SHADE_Managed"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE"}
|
defines{"_RELEASE"}
|
||||||
links{"librttr_core.lib"}
|
links{"librttr_core.lib"}
|
||||||
|
|
||||||
|
filter "configurations:Publish"
|
||||||
|
optimize "On"
|
||||||
|
defines{"_RELEASE"}
|
||||||
|
links{"librttr_core.lib"}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
\par email: kahwei.tng\@digipen.edu
|
\par email: kahwei.tng\@digipen.edu
|
||||||
\date Sep 27, 2022
|
\date Sep 27, 2022
|
||||||
\brief Contains the definition of the functions for the ScriptStore managed
|
\brief Contains the definition of the functions for the Editor managed
|
||||||
static class.
|
static class.
|
||||||
|
|
||||||
Note: This file is written in C++17/CLI.
|
Note: This file is written in C++17/CLI.
|
||||||
|
@ -16,6 +16,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
// Primary Header
|
// Primary Header
|
||||||
#include "Editor/Editor.hxx"
|
#include "Editor/Editor.hxx"
|
||||||
|
// STL Includes
|
||||||
|
#include <memory>
|
||||||
// External Dependencies
|
// External Dependencies
|
||||||
#include "Editor/SHEditorUI.h"
|
#include "Editor/SHEditorUI.h"
|
||||||
// Project Headers
|
// Project Headers
|
||||||
|
@ -25,6 +27,8 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Utility/Debug.hxx"
|
#include "Utility/Debug.hxx"
|
||||||
#include "Serialisation/ReflectionUtilities.hxx"
|
#include "Serialisation/ReflectionUtilities.hxx"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
|
#include "Editor/Command/SHCommand.hpp"
|
||||||
|
|
||||||
// Using Directives
|
// Using Directives
|
||||||
using namespace System;
|
using namespace System;
|
||||||
|
@ -48,9 +52,11 @@ using namespace System::Collections::Generic;
|
||||||
(field->FieldType == MANAGED_TYPE::typeid) \
|
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||||
{ \
|
{ \
|
||||||
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
||||||
|
NATIVE_TYPE oldVal = val; \
|
||||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
||||||
{ \
|
{ \
|
||||||
field->SetValue(object, val); \
|
field->SetValue(object, val); \
|
||||||
|
registerUndoAction(object, field, val, oldVal); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -69,9 +75,11 @@ using namespace System::Collections::Generic;
|
||||||
(field->FieldType == MANAGED_TYPE::typeid) \
|
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||||
{ \
|
{ \
|
||||||
NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \
|
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)) \
|
||||||
{ \
|
{ \
|
||||||
field->SetValue(object, Convert::ToCLI(val)); \
|
field->SetValue(object, Convert::ToCLI(val)); \
|
||||||
|
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal)); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
@ -105,26 +113,43 @@ namespace SHADE
|
||||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.RenderScriptsInInspector")
|
SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.RenderScriptsInInspector")
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::RenderScriptAddButton(Entity entity)
|
void Editor::RenderScriptAddButton(Entity entity)
|
||||||
{
|
{
|
||||||
// Get list of Scripts
|
// Get list of Scripts
|
||||||
auto scriptTypes = ScriptStore::GetAvailableScriptList();
|
auto scriptTypes = ScriptStore::GetAvailableScriptList();
|
||||||
|
|
||||||
// Define pop up
|
// Define pop up
|
||||||
if (SHEditorUI::BeginMenu("Add Script", ICON_MD_LIBRARY_ADD))
|
if (SHEditorUI::BeginMenu("Add Script", ICON_MD_LIBRARY_ADD))
|
||||||
{
|
{
|
||||||
for each (Type ^ type in scriptTypes)
|
for each (Type ^ type in scriptTypes)
|
||||||
{
|
{
|
||||||
if (SHEditorUI::Selectable(Convert::ToNative(type->Name)))
|
if (SHEditorUI::Selectable(Convert::ToNative(type->Name)))
|
||||||
{
|
{
|
||||||
// Add the script
|
// Add the script
|
||||||
ScriptStore::AddScriptViaName(entity, type->Name);
|
ScriptStore::AddScriptViaName(entity, type->Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SHEditorUI::EndMenu();
|
SHEditorUI::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* UndoRedoStack Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void Editor::Undo()
|
||||||
|
{
|
||||||
|
SAFE_NATIVE_CALL_BEGIN
|
||||||
|
actionStack.Undo();
|
||||||
|
SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.Undo")
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::Redo()
|
||||||
|
{
|
||||||
|
SAFE_NATIVE_CALL_BEGIN
|
||||||
|
actionStack.Redo();
|
||||||
|
SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.Redo")
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
@ -192,9 +217,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
int val = safe_cast<int>(field->GetValue(object));
|
int val = safe_cast<int>(field->GetValue(object));
|
||||||
|
int oldVal = val;
|
||||||
if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames))
|
if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames))
|
||||||
{
|
{
|
||||||
field->SetValue(object, val);
|
field->SetValue(object, val);
|
||||||
|
registerUndoAction(object, field, val, oldVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if RENDER_FIELD_CASTED(Vector2, SHVec2, InputVec2)
|
else if RENDER_FIELD_CASTED(Vector2, SHVec2, InputVec2)
|
||||||
|
@ -210,9 +237,11 @@ namespace SHADE
|
||||||
|
|
||||||
// Actual Field
|
// Actual Field
|
||||||
std::string val = Convert::ToNative(stringVal);
|
std::string val = Convert::ToNative(stringVal);
|
||||||
|
std::string oldVal = val;
|
||||||
if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val))
|
if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val))
|
||||||
{
|
{
|
||||||
field->SetValue(object, Convert::ToCLI(val));
|
field->SetValue(object, Convert::ToCLI(val));
|
||||||
|
registerUndoAction(object, field, Convert::ToCLI(val), Convert::ToCLI(oldVal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,4 +260,18 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData)
|
||||||
|
{
|
||||||
|
// Create command and add it into the undo stack
|
||||||
|
UndoRedoStack::Command cmd;
|
||||||
|
cmd.Field = field;
|
||||||
|
cmd.Object = object;
|
||||||
|
cmd.NewData = newData;
|
||||||
|
cmd.OldData = oldData;
|
||||||
|
actionStack.Add(cmd);
|
||||||
|
|
||||||
|
// Inform the C++ Undo-Redo stack
|
||||||
|
SHCommandManager::RegisterCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCLICommand>()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Engine/Entity.hxx"
|
#include "Engine/Entity.hxx"
|
||||||
#include "Scripts/Script.hxx"
|
#include "Scripts/Script.hxx"
|
||||||
|
#include "UndoRedoStack.hxx"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -36,15 +37,26 @@ namespace SHADE
|
||||||
/// rendering code.
|
/// rendering code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||||
static void RenderScriptsInInspector(Entity entity);
|
static void RenderScriptsInInspector(Entity entity);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Renders a dropdown button that allows for the addition of PlushieScripts
|
/// Renders a dropdown button that allows for the addition of PlushieScripts
|
||||||
/// onto the specified Entity.
|
/// onto the specified Entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entity">The Entity to add PlushieScripts to.</param>
|
/// <param name="entity">The Entity to add PlushieScripts to.</param>
|
||||||
static void RenderScriptAddButton(Entity entity);
|
static void RenderScriptAddButton(Entity entity);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* UndoRedoStack Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static void Undo();
|
||||||
|
static void Redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static UndoRedoStack actionStack;
|
||||||
|
|
||||||
private:
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -73,5 +85,6 @@ namespace SHADE
|
||||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||||
/// <param name="script">The Script to render the inspector for.</param>
|
/// <param name="script">The Script to render the inspector for.</param>
|
||||||
static void renderScriptContextMenu(Entity entity, Script^ script);
|
static void renderScriptContextMenu(Entity entity, Script^ script);
|
||||||
|
static void registerUndoAction(System::Object^ object, System::Reflection::FieldInfo^ field, System::Object^ newData, System::Object^ oldData);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file UndoRedoStack.cxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 29, 2022
|
||||||
|
\brief Contains the definition of the functions for the UndoRedoStack managed
|
||||||
|
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.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
// Precompiled Headers
|
||||||
|
#include "SHpch.h"
|
||||||
|
// Primary Header
|
||||||
|
#include "UndoRedoStack.hxx"
|
||||||
|
// External Dependencies
|
||||||
|
#include "Editor/SHEditorUI.h"
|
||||||
|
// Project Headers
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
bool UndoRedoStack::UndoActionPresent::get()
|
||||||
|
{
|
||||||
|
return commandStack->Count > 0 && latestActionIndex >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UndoRedoStack::RedoActionPresent::get()
|
||||||
|
{
|
||||||
|
return latestActionIndex >= 0 && latestActionIndex < commandStack->Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UndoRedoStack::Add(Command command)
|
||||||
|
{
|
||||||
|
// Erase any other actions ahead of the current action
|
||||||
|
if (latestActionIndex >= 0 && latestActionIndex < commandStack->Count - 1)
|
||||||
|
{
|
||||||
|
commandStack->RemoveRange(latestActionIndex, commandStack->Count - latestActionIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the command
|
||||||
|
commandStack->Add(command);
|
||||||
|
|
||||||
|
// Set the latest command
|
||||||
|
latestActionIndex = commandStack->Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UndoRedoStack::Undo()
|
||||||
|
{
|
||||||
|
if (!UndoActionPresent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Command cmd = commandStack[latestActionIndex];
|
||||||
|
cmd.Field->SetValue(cmd.Object, cmd.OldData);
|
||||||
|
--latestActionIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UndoRedoStack::Redo()
|
||||||
|
{
|
||||||
|
if (!RedoActionPresent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Command cmd = commandStack[latestActionIndex];
|
||||||
|
cmd.Field->SetValue(cmd.Object, cmd.NewData);
|
||||||
|
++latestActionIndex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file UndoRedoStack.hxx
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 29, 2022
|
||||||
|
\brief Contains the definition of the managed UndoRedoStack 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
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class that is able to store a stack of actions that can be done and redone.
|
||||||
|
/// </summary>
|
||||||
|
private ref class UndoRedoStack sealed
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Command for the stack that represents a data modification.
|
||||||
|
/// </summary>
|
||||||
|
value struct Command
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
System::Object^ Object;
|
||||||
|
System::Reflection::FieldInfo^ Field;
|
||||||
|
System::Object^ NewData;
|
||||||
|
System::Object^ OldData;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Properties */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// True if there is an undoable action in the stack.
|
||||||
|
/// </summary>
|
||||||
|
property bool UndoActionPresent { bool get(); }
|
||||||
|
/// <summary>
|
||||||
|
/// True if there is a redoable action in the stack.
|
||||||
|
/// </summary>
|
||||||
|
property bool RedoActionPresent { bool get(); }
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a command onto the stack.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command"></param>
|
||||||
|
void Add(Command command);
|
||||||
|
/// <summary>
|
||||||
|
/// Undos the last added command if it exists.
|
||||||
|
/// </summary>
|
||||||
|
void Undo();
|
||||||
|
/// <summary>
|
||||||
|
/// Redoes the last undo-ed command if it exists.
|
||||||
|
/// </summary>
|
||||||
|
void Redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
int latestActionIndex = -1;
|
||||||
|
System::Collections::Generic::List<Command>^ commandStack = gcnew System::Collections::Generic::List<Command>();
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue