This commit is contained in:
Brandon Mak 2022-09-17 22:28:03 +08:00
parent a85df55fc9
commit 3766a10edd
32 changed files with 2131 additions and 328 deletions

View File

@ -2,7 +2,7 @@
#include "SBApplication.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#define SHEDITOR
//#define SHEDITOR
#ifdef SHEDITOR
#include "Editor/SHEditor.h"
//#include "Scenes/SBEditorScene.h"
@ -76,6 +76,8 @@ namespace Sandbox
#endif
graphicsSystem->Run(1.0f);
graphicsSystem->EndRender();
SHADE::SHSystemManager::RunRoutines(false, 0.016f);
}
}

View File

@ -255,7 +255,7 @@ namespace SHADE
*/
/***************************************************************************/
void SHVkCommandBuffer::SetviewportScissor(float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX /*= 0.0f*/, float vpY /*= 0.0f*/, int32_t sX /*= 0.0f*/, int32_t sY /*= 0.0f*/, float vpMinDepth /*= 0.0f*/, float vpMaxDepth /*= 1.0f*/) noexcept
void SHVkCommandBuffer::SetViewportScissor(float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX /*= 0.0f*/, float vpY /*= 0.0f*/, int32_t sX /*= 0.0f*/, int32_t sY /*= 0.0f*/, float vpMinDepth /*= 0.0f*/, float vpMaxDepth /*= 1.0f*/) noexcept
{
vk::Viewport dynamicViewport
{

View File

@ -104,7 +104,7 @@ namespace SHADE
void NextSubpass (void) noexcept;
// Dynamic State
void SetviewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
void SetViewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
// Binding Commands
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;

View File

@ -234,7 +234,7 @@ namespace SHADE
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
}
void SHVkImage::TransferToDeviceResource(Handle<SHVkCommandBuffer> const& cmdBufferHdl) noexcept
void SHVkImage::TransferToDeviceResource(void) noexcept
{
// prepare copy regions
std::vector<vk::BufferImageCopy> copyRegions{mipOffsets.size()};
@ -252,6 +252,7 @@ namespace SHADE
copyRegions[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 };
}
//PrepareImageTransition();
}
/***************************************************************************/

View File

@ -135,7 +135,7 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
void TransferToDeviceResource (Handle<SHVkCommandBuffer> const& cmdBufferHdl) noexcept;
void TransferToDeviceResource (void) noexcept;
void PrepareImageTransition (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
/*-----------------------------------------------------------------------*/

View File

@ -0,0 +1,151 @@
/************************************************************************************//*!
\file SHCamera.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 21, 2022
\brief
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHCamera.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* View Set Functions */
/*---------------------------------------------------------------------------------*/
void SHCamera::SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up)
{
const SHVec3 VIEW = (target - pos).Normalized();
const SHVec3 RIGHT = SHVec3::Cross(VIEW, up).Normalized();
const SHVec3 UP = SHVec3::Cross(RIGHT, VIEW);
viewMatrix = SHMatrix::Identity;
viewMatrix(0, 0) = RIGHT[0];
viewMatrix(1, 0) = RIGHT[1];
viewMatrix(2, 0) = RIGHT[2];
viewMatrix(0, 1) = UP[0];
viewMatrix(1, 1) = UP[1];
viewMatrix(2, 1) = UP[2];
viewMatrix(0, 2) = -VIEW[0];
viewMatrix(1, 2) = -VIEW[1];
viewMatrix(2, 2) = -VIEW[2];
viewMatrix(3, 0) = -RIGHT.Dot(pos);
viewMatrix(3, 1) = -UP.Dot(pos);
viewMatrix(3, 2) = VIEW.Dot(pos);
isDirty = true;
}
/*---------------------------------------------------------------------------------*/
/* Projection Set Functions */
/*---------------------------------------------------------------------------------*/
void SHCamera::SetPerspective(float fov, float width, float height, float zNear, float zFar)
{
const float ASPECT_RATIO = width / height;
const float TAN_HALF_FOV = tan(fov * 0.5f);
projMatrix = SHMatrix::Identity;
projMatrix(0, 0) = 1.0f / (ASPECT_RATIO * TAN_HALF_FOV);
projMatrix(1, 1) = 1.0f / TAN_HALF_FOV;
projMatrix(2, 2) = zFar / (zFar - zNear);
projMatrix(2, 3) = 1.0f;
projMatrix(3, 2) = -(zFar * zNear) / (zFar - zNear);
isDirty = true;
}
void SHCamera::SetOrthographic(float width, float height, float zNear, float zFar)
{
const float R = width * 0.5f;
const float L = -R;
const float T = height * 0.5f;
const float B = -T;
projMatrix = SHMatrix::Identity;
projMatrix(0, 0) = 2.0f / (R - L);
projMatrix(1, 1) = 2.0f / (B - T);
projMatrix(2, 2) = 1.0f / (zFar - zNear);
projMatrix(3, 0) = -(R + L) / (R - L);
projMatrix(3, 1) = -(B + T) / (B - T);
projMatrix(3, 2) = -zNear / (zFar - zNear);
isDirty = true;
}
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
SHMathMat4f SHCamera::GetViewMatrix() const
{
return viewMatrix;
}
SHMathMat4f SHCamera::GetProjectionMatrix() const
{
return projMatrix;
}
SHMathMat4f SHCamera::GetViewProjectionMatrix()
{
updateMatrices();
return vpMatrix;
}
SHMathMat4f SHCamera::GetInverseViewMatrix() const
{
return inverseVpMatrix;
}
SHMathMat4f SHCamera::GetInverseProjectionMatrix() const
{
return inverseProjMatrix;
}
SHMathMat4f SHCamera::GetInverseViewProjectionMatrix()
{
updateMatrices();
return inverseViewMatrix;
}
/*---------------------------------------------------------------------------------*/
/* Mapping Functions */
/*---------------------------------------------------------------------------------*/
SHVec3 SHCamera::ScreenToWorld(const SHVec3& vec) const
{
return multiplyHomogenous(inverseVpMatrix, vec);
}
SHVec3 SHCamera::WorldToScreen(const SHVec3& vec) const
{
return multiplyHomogenous(vpMatrix, vec);
}
SHVec3 SHCamera::CameraToWorld(const SHVec3& vec) const
{
return multiplyHomogenous(inverseViewMatrix, vec);
}
SHVec3 SHCamera::WorldToCamera(const SHVec3& vec) const
{
return multiplyHomogenous(viewMatrix, vec);
}
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
void SHCamera::updateMatrices()
{
if (isDirty)
{
vpMatrix = viewMatrix * projMatrix;
inverseVpMatrix = vpMatrix;
inverseVpMatrix.Inverse();
}
}
SHVec3 SHCamera::multiplyHomogenous(const SHMathMat4f& mat, const SHVec3& vec)
{
const SHVec4 HOMO_VEC = { vec[0], vec[1], vec[2], 1.0f };
const SHVec4 RESULT = mat * HOMO_VEC;
return SHVec3 { RESULT[0], RESULT[1], RESULT[2] };
}
}

View File

@ -0,0 +1,80 @@
/************************************************************************************//*!
\file SHCamera.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 21, 2022
\brief
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
// Project Includes
#include "Math/SHMath.h"
namespace SHADE
{
/***********************************************************************************/
/*!
\brief
Object that manages the view and projection transformations for rendering
a 3D scene.
*/
/***********************************************************************************/
class SHCamera
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------*/
/* View Set Functions */
/*-----------------------------------------------------------------------------*/
void SetLookAt(const SHVec3& pos, const SHVec3& target, const SHVec3& up);
/*-----------------------------------------------------------------------------*/
/* Projection Set Functions */
/*-----------------------------------------------------------------------------*/
void SetPerspective(float fov, float width, float height, float zNear, float zFar);
void SetOrthographic(float width, float height, float zNear, float zFar);
/*-----------------------------------------------------------------------------*/
/* Getter Functions */
/*-----------------------------------------------------------------------------*/
SHMatrix GetViewMatrix() const;
SHMatrix GetProjectionMatrix() const;
SHMatrix GetViewProjectionMatrix();
SHMatrix GetInverseViewMatrix() const;
SHMatrix GetInverseProjectionMatrix() const;
SHMatrix GetInverseViewProjectionMatrix();
/*-----------------------------------------------------------------------------*/
/* Mapping Functions */
/*-----------------------------------------------------------------------------*/
SHVec3 ScreenToWorld(const SHVec3& vec) const;
SHVec3 WorldToScreen(const SHVec3& vec) const;
SHVec3 CameraToWorld(const SHVec3& vec) const;
SHVec3 WorldToCamera(const SHVec3& vec) const;
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
SHMatrix viewMatrix;
SHMatrix projMatrix;
SHMatrix vpMatrix;
SHMatrix inverseViewMatrix;
SHMatrix inverseProjMatrix;
SHMatrix inverseVpMatrix;
bool isDirty;
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
void updateMatrices();
static SHVec3 multiplyHomogenous(const SHMatrix& mat, const SHMatrix& vec);
};
}

View File

@ -0,0 +1,82 @@
/************************************************************************************//*!
\file SHGraphicsSystem.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 8, 2022
\brief Contains definition of constants that relate to the SHGraphicsSystem.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <cstdint>
namespace SHADE
{
/***********************************************************************************/
/*!
\brief
Contains definition of constants related to the Graphics System.
*/
/***********************************************************************************/
struct SHGraphicsConstants
{
public:
struct DescriptorSetIndex
{
/***************************************************************************/
/*!
\brief
DescriptorSet Index for static global values like generic data, and
texture samplers
*/
/***************************************************************************/
static constexpr uint32_t STATIC_GLOBALS = 0;
/***************************************************************************/
/*!
\brief
DescriptorSet Index for dynamic global values like lights.
*/
/***************************************************************************/
static constexpr uint32_t DYNAMIC_GLOBALS = 1;
/***************************************************************************/
/*!
\brief
DescriptorSet Index for high frequency changing global values like
camera matrices.
*/
/***************************************************************************/
static constexpr uint32_t HIGH_FREQUENCY_GLOBALS = 2;
/***************************************************************************/
/*!
\brief
DescriptorSet Index for per-instance/material changing values.
*/
/***************************************************************************/
static constexpr uint32_t PER_INSTANCE = 3;
};
struct DescriptorSetBindings
{
/***************************************************************************/
/*!
\brief
DescriptorSet binding for per instance material values.
*/
/***************************************************************************/
static constexpr uint32_t BATCHED_PER_INST_DATA = 0;
};
/*******************************************************************************/
/*!
\brief
Number of frame buffers used by the Graphics System.
*/
/*******************************************************************************/
static constexpr int NUM_FRAME_BUFFERS = 3;
};
}

View File

@ -10,7 +10,7 @@ Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHPch.h"
#include "SHpch.h"
#include "SHGraphicsSystem.h"
#include "Graphics/Instance/SHVkInstance.h"
@ -19,6 +19,11 @@ of DigiPen Institute of Technology is prohibited.
//#include "SHRenderer.h"
#include "Graphics/Windowing/SHWindow.h"
#include "Graphics/MiddleEnd/PerFrame/SHPerFrameData.h"
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
namespace SHADE
{
@ -28,6 +33,9 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
void SHGraphicsSystem::Init(void)
{
/*-----------------------------------------------------------------------*/
/* BACKEND BOILERPLATE */
/*-----------------------------------------------------------------------*/
// Set Up Instance
SHVkInstance::Init(true, true, true);
@ -49,6 +57,7 @@ namespace SHADE
.vsyncOn = false, // TODO: Set to true when shipping game
});
// Register callback to notify render context upon a window resize
window->RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height)
{
renderContext.SetIsResized(true);
@ -72,80 +81,133 @@ namespace SHADE
}
);
// Create Frame and Command Buffers
for (int i = 0; i < NUM_FRAME_BUFFERS; ++i)
{
//frameBuffers[i] = device->CreateFramebuffer(renderPass, { renderContext.GetFrameData(i).swapchainImageViewHdl }, windowDims[0], windowDims[1]);
SHPerFrameData& frameData = renderContext.GetFrameData(i);
if (frameData.cmdPoolHdls.empty())
throw std::runtime_error("No command pools available!");
Handle<SHVkCommandPool> commandPool = frameData.cmdPoolHdls[0];
//commandBuffers[i] = commandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // works
}
// Create a descriptor pool
descPool = device->CreateDescriptorPools();
// Create generic command buffer
transferCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::TRANSFER, SH_CMD_POOL_RESET::POOL_BASED, true);
transferCmdBuffer = transferCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
/*-----------------------------------------------------------------------*/
/* RENDERGRAPH TESTING */
/* MIDDLE END SETUP
- Viewports
- Renderer
- Render graph in renderers
- Render graph command buffer semaphores
- Default vertex input state
/*-----------------------------------------------------------------------*/
// Set Up Cameras
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->SetOrthographic(windowDims.first, windowDims.second, 0.01f, 100.0f);
worldCamera = resourceManager.Create<SHCamera>();
worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f));
worldCamera->SetPerspective(90.0f, windowDims.first, windowDims.second, 0.0f, 100.0f);
renderGraph.Init(device, swapchain);
renderGraph.AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
renderGraph.AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
renderGraph.AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
renderGraph.AddResource("Downscale", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
renderGraph.AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
auto node = renderGraph.AddNode("G-Buffer", { "Composite", "Position", "Normals", "Present" }, {}); // no predecessors
// Create Default Viewport
defaultViewport = AddViewport(vk::Viewport(0, 0, window->GetWindowSize().first, window->GetWindowSize().second, 0.0f, 1.0f));
// First subpass to write to G-Buffer
// Create Debug Renderers
debugScreenRenderer = defaultViewport->AddRenderer(resourceManager);
debugScreenRenderer->SetCamera(screenCamera);
debugWorldRenderer = defaultViewport->AddRenderer(resourceManager);
debugWorldRenderer->SetCamera(worldCamera);
// Add world renderer to default viewport
worldRenderer = defaultViewport->AddRenderer(resourceManager);
worldRenderer->SetCamera(worldCamera);
// Get render graph from default viewport world renderer
auto worldRenderGraph = worldRenderer->GetRenderGraph();
// Initialize world render graph
worldRenderGraph->Init(device, swapchain);
worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
auto node = worldRenderGraph->AddNode("G-Buffer", { "Composite", "Position", "Normals", "Present" }, {}); // no predecessors
//First subpass to write to G-Buffer
auto writeSubpass = node->AddSubpass("G-Buffer Write");
writeSubpass->AddColorOutput("Position");
//writeSubpass->AddColorOutput("Present");
writeSubpass->AddColorOutput("Normals");
// Second subpass to read from G-Buffer
//auto compositeSubpass = node->AddSubpass("G-Buffer Composite");
// compositeSubpass->AddColorOutput("Composite");
// compositeSubpass->AddInput("Normals");
// compositeSubpass->AddInput("Position");
//Second subpass to read from G-Buffer
auto compositeSubpass = node->AddSubpass("G-Buffer Composite");
compositeSubpass->AddColorOutput("Present"); // TODO: This should be "Composite" and then composite will write to swapchain image "Present"
compositeSubpass->AddInput("Normals");
compositeSubpass->AddInput("Position");
auto imguiNode = renderGraph.AddNode("ImGui Node", { "Present" }, {}); // no predecessors
auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {});
auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
imguiSubpass->AddColorOutput("Present");
//auto compositeNode = renderGraph.AddNode("Bloom", { "Composite", "Downscale", "Present" }, { "G-Buffer" });
//auto bloomSubpass = compositeNode->AddSubpass("Downsample");
//bloomSubpass->AddInput("Composite");
//bloomSubpass->AddColorOutput("Downscale");
//bloomSubpass->AddColorOutput("Present");
worldRenderGraph->Generate();
renderGraph.Generate();
/*-----------------------------------------------------------------------*/
/* RENDERGRAPH END TESTING */
/*-----------------------------------------------------------------------*/
// Create Semaphore
for (auto& semaHandle : graphSemaphores)
{
semaHandle = device->CreateSemaphore();
}
void SHGraphicsSystem::Run(float dt) noexcept
ConfigureDefaultVertexInputState();
//pipelineLibrary.Init(device, &defaultVertexInputState, );
}
/***************************************************************************/
/*!
\brief
Main render loop. Loops through viewports -> renderers -> invoke render
graphs sequentially using semaphores.
\param dt
\return
*/
/***************************************************************************/
void SHGraphicsSystem::Run(double dt) noexcept
{
// Frame data for the current frame
auto const& frameData = renderContext.GetCurrentFrameData();
renderGraph.Execute(renderContext.GetCurrentFrame());
// semaphore index. This is for render graphs to have semaphores to signal that the next render graph will use to wait on.
bool semIndex = 0;
graphicsQueue->SubmitCommandBuffer({ renderGraph.GetCommandBuffer(renderContext.GetCurrentFrame()) },
{ frameData.semRenderFinishHdl },
{ frameData.semImgAvailableHdl },
vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests);
// For every viewport
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
{
auto const& renderers = viewports[vpIndex]->GetRenderers();
// For every renderer
for (int renIndex = 0; renIndex < static_cast<int>(renderers.size()); ++renIndex)
{
// Draw first
renderers[renIndex]->Draw(renderContext.GetCurrentFrame());
// get render graph
auto rg = renderers[renIndex]->GetRenderGraph();
// submit a command buffer from the current render graph and make it wait for the previous render graph before submitting it to GPU.
graphicsQueue->SubmitCommandBuffer
(
{ rg->GetCommandBuffer(renderContext.GetCurrentFrame()) },
{ (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.semRenderFinishHdl : graphSemaphores[!semIndex]},
{ (vpIndex == 0 && renIndex == 0) ? frameData.semImgAvailableHdl : graphSemaphores[semIndex]},
{}
);
semIndex = !semIndex;
}
}
}
void SHGraphicsSystem::Exit(void)
{
//renderPass.Free();
renderContext.Destroy();
graphicsQueue.Free();
swapchain.Free();
@ -221,7 +283,7 @@ namespace SHADE
presentInfo.pImageIndices = &CURR_FRAME_IDX;
// #BackEndTest: queues an image for presentation
if (auto result = graphicsQueue->Present(swapchain, {currFrameData.semRenderFinishHdl}, CURR_FRAME_IDX); result != vk::Result::eSuccess)
if (auto result = graphicsQueue->Present(swapchain, { currFrameData.semRenderFinishHdl }, CURR_FRAME_IDX); result != vk::Result::eSuccess)
{
// If swapchain is incompatible/outdated
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
@ -237,19 +299,61 @@ namespace SHADE
// #BackEndTest: Cycle frame count
renderContext.AdvanceFrame();
}
//Handle<SHRenderer> SHGraphicsSystem::AddRenderer()
//{
// return Handle<SHRenderer>();
//}
//void SHGraphicsSystem::RemoveRenderer(Handle<SHRenderer> renderer)
//{
//}
Handle<SHScreenSegment> SHGraphicsSystem::AddSegment(const VkViewport& viewport, Handle<SHVkImage> imageToUse)
Handle<SHViewport> SHGraphicsSystem::AddViewport(const vk::Viewport& viewport)
{
return Handle<SHScreenSegment>();
// Create the viewport
auto vp = SHVkInstance::GetResourceManager().Create<SHViewport>(device, viewport);
viewports.emplace_back(vp);
return vp;
}
void SHGraphicsSystem::RemoveSegment(Handle<SHScreenSegment> segment)
void SHGraphicsSystem::RemoveViewport(Handle<SHViewport> viewport)
{
// Check if the viewport exists
auto iter = std::find(viewports.begin(), viewports.end(), viewport);
if (iter == viewports.end())
throw std::invalid_argument("Attempted to remove viewport that does not belong to this Graphics System.");
// Remove
viewport.Free();
viewports.erase(iter);
}
Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader)
{
// Retrieve pipeline from pipeline storage or create if unavailable
auto shaderPair = std::make_pair(vertShader, fragShader);
Handle<SHVkPipeline> pipeline = pipelineLibrary.GetDrawPipline(shaderPair);
if (!pipeline)
{
pipeline = pipelineLibrary.CreateDrawPipeline
(
shaderPair,
);
}
// Create material
auto mat = resourceManager.Create<SHMaterial>();
mat->SetPipeline(pipeline);
return mat;
}
void SHGraphicsSystem::RemoveMaterial(Handle<SHMaterial> material)
{
resourceManager.Free(material);
}
Handle<SHMaterialInstance> SHGraphicsSystem::AddMaterialInstance(Handle<SHMaterial> material)
{
return resourceManager.Create<SHMaterialInstance>(material);
}
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
{
resourceManager.Free(materialInstance);
}
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
@ -257,13 +361,28 @@ namespace SHADE
window = wind;
}
SHRenderGraph const& SHGraphicsSystem::GetRenderGraph(void) const noexcept
void SHGraphicsSystem::ConfigureDefaultVertexInputState(void) noexcept
{
return renderGraph;
defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // positions at binding 0
defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_2D)}); // UVs at binding 1
defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // Normals at binding 2
defaultVertexInputState.AddBinding(false, false, {SHVertexAttribute(SHAttribFormat::FLOAT_3D)}); // Tangents at binding 3
defaultVertexInputState.AddBinding(true, true, {SHVertexAttribute(SHAttribFormat::MAT_4D)}); // Transform at binding 4 - 7 (4 slots)
}
void SHGraphicsSystem::SHGraphicsSystemRoutine::Execute(double dt) noexcept
void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
{
reinterpret_cast<SHGraphicsSystem*>(system)->BeginRender();
}
void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept
{
reinterpret_cast<SHGraphicsSystem*>(system)->Run(dt);
}
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
{
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
}
}

View File

@ -24,6 +24,7 @@ of DigiPen Institute of Technology is prohibited.
#include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h"
namespace SHADE
{
@ -37,28 +38,18 @@ namespace SHADE
class SHVkSurface;
class SHVkSwapchain;
class SHScreenSegment;
//class SHRenderer;
class SHWindow;
class SHVkImage;
class SHVkFramebuffer;
class SHVkCommandBuffer;
class SHRenderer;
class SHViewport;
class SHCamera;
class SHVkShaderModule;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Represents an axis aligned box on the screen to render to along with the
specified Image to render to that spot.
*/
/***********************************************************************************/
struct SHScreenSegment
{
VkViewport Viewport;
Handle<SHVkImage> ImageToUse;
};
/***********************************************************************************/
/*!
\brief
@ -69,10 +60,20 @@ namespace SHADE
class SH_API SHGraphicsSystem : public SHSystem
{
public:
class SH_API SHGraphicsSystemRoutine : public SHSystemRoutine
class SH_API BeginRoutine final : public SHSystemRoutine
{
public:
virtual void Execute(double dt) noexcept override;
virtual void Execute(double dt) noexcept override final;
};
class SH_API RenderRoutine final : public SHSystemRoutine
{
public:
virtual void Execute(double dt) noexcept override final;
};
class SH_API EndRoutine final : public SHSystemRoutine
{
public:
virtual void Execute(double dt) noexcept override final;
};
public:
@ -84,15 +85,15 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/
SHGraphicsSystem (void) = default;
SHGraphicsSystem(void) = default;
~SHGraphicsSystem(void) noexcept = default;
/*-----------------------------------------------------------------------------*/
/* SHSystem overrides */
/*-----------------------------------------------------------------------------*/
virtual void Init(void) override;
void Run (float dt) noexcept;
virtual void Exit(void) override;
virtual void Init(void) override final;
void Run(double dt) noexcept;
virtual void Exit(void) override final;
/*-----------------------------------------------------------------------------*/
/* Lifecycle Functions */
@ -100,22 +101,25 @@ namespace SHADE
void BeginRender();
void EndRender();
/*-----------------------------------------------------------------------------*/
/* Renderers Registration Functions */
/*-----------------------------------------------------------------------------*/
//Handle<SHRenderer> AddRenderer();
//void RemoveRenderer(Handle<SHRenderer> renderer);
/*-----------------------------------------------------------------------------*/
/* Viewport Registration Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHScreenSegment> AddSegment(const VkViewport& viewport, Handle<SHVkImage> imageToUse);
void RemoveSegment(Handle<SHScreenSegment> segment);
Handle<SHViewport> AddViewport(const vk::Viewport& viewport);
void RemoveViewport(Handle<SHViewport> viewport);
/*-----------------------------------------------------------------------------*/
/* Material Creation Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHMaterial> AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader);
void RemoveMaterial(Handle<SHMaterial> material);;
Handle<SHMaterialInstance> AddMaterialInstance(Handle<SHMaterial> material);
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);
/*-----------------------------------------------------------------------------*/
/* Setters */
/*-----------------------------------------------------------------------------*/
void SetWindow (SHWindow* wind) noexcept;
void SetWindow(SHWindow* wind) noexcept;
/*-----------------------------------------------------------------------------*/
/* Getters (Temporary) */
@ -123,10 +127,10 @@ namespace SHADE
Handle<SHVkLogicalDevice> GetDevice() const { return device; }
Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; }
Handle<SHVkSurface> GetSurface() const { return surface; }
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const {return physicalDevice;}
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
SHRenderGraph const& GetRenderGraph (void) const noexcept;
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
@ -135,27 +139,46 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
// Owned Resources
// Owned Vulkan Resources
Handle<SHVkPhysicalDevice> physicalDevice;
Handle<SHVkLogicalDevice> device;
Handle<SHVkSurface> surface;
Handle<SHVkSwapchain> swapchain;
Handle<SHVkQueue> graphicsQueue;
Handle<SHVkDescriptorPool> descPool;
//Handle<SHVkRenderpass> renderPass; // Potentially bring out?
std::vector<SHScreenSegment> screenSegments;
Handle<SHVkCommandPool> transferCmdPool;
Handle<SHVkCommandBuffer> transferCmdBuffer;
SHRenderContext renderContext;
//std::array<Handle<SHVkFramebuffer>, NUM_FRAME_BUFFERS> frameBuffers;
//std::array<Handle<SHVkCommandBuffer>, NUM_FRAME_BUFFERS> commandBuffers;
std::array<Handle<SHVkSemaphore>, 2> graphSemaphores;
// Not Owned Resources
SHWindow* window;
// Renderers
//Handle<SHRenderer> debugWorldRenderer;
//Handle<SHRenderer> debugScreenRenderer;
//std::vector<SHRenderer> renderers;
SHRenderGraph renderGraph;
friend SHGraphicsSystemRoutine;
SHPipelineLibrary pipelineLibrary;
std::vector<SHVkDescriptorSetLayout> globalDescSetLayouts;
// Middle End Resources
ResourceManager resourceManager;
// Viewports
Handle<SHViewport> defaultViewport; // Whole screen
std::vector<Handle<SHViewport>> viewports; // Additional viewports
// Debug Renderers
Handle<SHRenderer> debugWorldRenderer;
Handle<SHRenderer> debugScreenRenderer;
// Temp Cameras
Handle<SHCamera> worldCamera;
Handle<SHCamera> screenCamera;
// Temp renderers
Handle<SHRenderer> worldRenderer;
SHVertexInputState defaultVertexInputState;
/*-----------------------------------------------------------------------------*/
/* Private member functions */
/*-----------------------------------------------------------------------------*/
void ConfigureDefaultVertexInputState (void) noexcept;
};
}

View File

@ -0,0 +1,67 @@
#include "SHpch.h"
#include "SHMaterial.h"
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "SHGraphicsConstants.h"
#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Pipeline Functions */
/*---------------------------------------------------------------------------------*/
void SHMaterial::SetPipeline(Handle<SHVkPipeline> _pipeline)
{
pipeline = _pipeline;
// Set up properties based on the pipeline
if (!pipeline)
{
// Clear memory and all that
propMemory.reset();
return;
}
// Allocate memory for properties
propMemorySize = getShaderBlockInterface()->GetBytesRequired();
propMemory.reset(new char[propMemorySize]);
ResetProperties();
}
Handle<SHVkPipeline> SHMaterial::GetPipeline() const
{
return pipeline;
}
/*---------------------------------------------------------------------------------*/
/* Property Functions */
/*---------------------------------------------------------------------------------*/
void SHMaterial::ResetProperties()
{
// Reset all the properties to default values
memset(propMemory.get(), 0, propMemorySize);
}
void SHMaterial::ExportProperties(void* dest) const noexcept
{
memcpy(dest, propMemory.get(), propMemorySize);
}
size_t SHMaterial::GetPropertiesMemorySize() const noexcept
{
return getShaderBlockInterface()->GetBytesRequired();
}
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterial::getShaderBlockInterface() const noexcept
{
return pipeline->GetPipelineLayout()->GetShaderBlockInterface
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
vk::ShaderStageFlagBits::eFragment
);
}
}

View File

@ -0,0 +1,75 @@
/************************************************************************************//*!
\file SHMaterial.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 30, 2022
\brief Contains the class definition of SHMaterial.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <unordered_map>
// Project Includes
#include "Resource/Handle.h"
#include "SHCommonTypes.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Forward Declarations */
/*---------------------------------------------------------------------------------*/
class SHVkPipeline;
class SHShaderBlockInterface;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Describes a Pipeline along with it's associated properties for this instance.
*/
/***********************************************************************************/
class SHMaterial
{
public:
/*-----------------------------------------------------------------------------*/
/* Pipeline Functions */
/*-----------------------------------------------------------------------------*/
void SetPipeline(Handle<SHVkPipeline> _pipeline);
Handle<SHVkPipeline> GetPipeline() const;
/*-----------------------------------------------------------------------------*/
/* Property Functions */
/*-----------------------------------------------------------------------------*/
template<typename T>
void SetProperty(const std::string& key, const T& value);
template<typename T>
T& GetProperty(const std::string& key);
template<typename T>
const T& GetProperty(const std::string& key) const;
void ResetProperties();
void ExportProperties(void* dest) const noexcept;
Byte GetPropertiesMemorySize() const noexcept;
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
Handle<SHVkPipeline> pipeline;
std::unique_ptr<char> propMemory;
Byte propMemorySize;
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> getShaderBlockInterface() const noexcept;
};
}
#include "SHMaterial.hpp"

View File

@ -0,0 +1,59 @@
/************************************************************************************//*!
\file SHMaterial.hpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 8, 2022
\brief Contains the template function definitions of SHMaterial.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
#include "SHMaterial.h"
#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Property Functions */
/*---------------------------------------------------------------------------------*/
template<typename T>
void SHMaterial::SetProperty(const std::string& key, const T& value)
{
const auto SHADER_INFO = getShaderBlockInterface();
const auto PROP_INFO = SHADER_INFO->GetVariable(key);
if (PROP_INFO == nullptr)
{
throw std::invalid_argument("Attempted to set an invalid property!");
}
// Get offset and modify the memory directly
T* dataPtr = propMemory.get() + PROP_INFO->offset;
*dataPtr = value;
}
template<typename T>
T& SHMaterial::GetProperty(const std::string& key)
{
const auto SHADER_INFO = getShaderBlockInterface();
const auto PROP_INFO = SHADER_INFO->GetVariable(key);
if (PROP_INFO == nullptr)
{
throw std::invalid_argument("Attempted to set an invalid property!");
}
// Get offset and return the memory directly
T* dataPtr = propMemory.get() + PROP_INFO->offset;
return *dataPtr;
}
template<typename T>
const T& SHMaterial::GetProperty(const std::string& key) const
{
return const_cast<const T&>(const_cast<SHMaterial*>(this)->GetProperty(key));
}
}

View File

@ -0,0 +1,62 @@
/************************************************************************************//*!
\file SHMaterialInstance.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 17, 2022
\brief Contains the definition of functions of SHMaterialInstance.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHMaterialInstance.h"
#include "Tools/SHLogger.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructor */
/*-----------------------------------------------------------------------------------*/
SHMaterialInstance::SHMaterialInstance(Handle<SHMaterial> material)
: baseMaterial { material }
{}
/*-----------------------------------------------------------------------------------*/
/* Property Functions */
/*-----------------------------------------------------------------------------------*/
void SHMaterialInstance::ResetProperties() noexcept
{
// Reset all the properties to default values
memset(dataStore.get(), 0, dataStoreSize);
overrideData.clear();
dataStore.reset();
}
void SHMaterialInstance::ExportProperties(void* dest) const
{
assert(dataStore != nullptr);
if (!baseMaterial)
throw std::runtime_error("[SHMaterialInstance] Attempted to set export a Material Instance with no base Material!");
// Copy default data from Material
baseMaterial->ExportProperties(dest);
// Follow up with copying our data over
const auto SHADER_INFO = getShaderBlockInterface();
for (const auto& data : overrideData)
{
// Get memory offset to the data
SHShaderBlockInterface::Variable variable = SHADER_INFO->GetVariable(data.Index);
if (variable == nullptr)
{
SHLOG_WARNING("[SHMaterialInstance] Invalid override data indices provided. Skipping.");
continue;
}
const auto DATA_OFFSET = variable->offset;
memcpy_s(dest + DATA_OFFSET, dataStore.get() + data.StoredDataOffset, data.DataSize);
}
}
}

View File

@ -0,0 +1,82 @@
/************************************************************************************//*!
\file SHMaterialInstance.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 17, 2022
\brief Contains the class definition of SHMaterialInstance.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <memory>
// Project Includes
#include "Resource/Handle.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Forward Declarations */
/*---------------------------------------------------------------------------------*/
class SHMaterial;
class SHGraphicsSystem;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Describes an instance of a SHMaterial that can be used to describe how to render
a SHRenderable.
*/
/***********************************************************************************/
class SHMaterialInstance
{
public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
struct OverrideData
{
size_t Index;
size_t DataSize;
size_t StoredDataOffset;
};
/*-----------------------------------------------------------------------------*/
/* Constructor */
/*-----------------------------------------------------------------------------*/
SHMaterialInstance(Handle<SHMaterial> material = {});
/*-----------------------------------------------------------------------------*/
/* Property Functions */
/*-----------------------------------------------------------------------------*/
template<typename T>
void SetProperty(const std::string& key, const T& value);
template<typename T>
T& GetProperty(const std::string& key);
template<typename T>
const T& GetProperty(const std::string& key) const;
void ResetProperties() noexcept;
void ExportProperties(void* dest) const;
/*-----------------------------------------------------------------------------*/
/* Getter Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHMaterial> GetBaseMaterial() const { return baseMaterial; }
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
Handle<SHMaterial> baseMaterial;
std::vector<OverrideData> overrideData;
std::unique_ptr<char> dataStore;
size_t dataStoreSize = 0;
};
}
#include "SHMaterialInstance.hpp"

View File

@ -0,0 +1,85 @@
/************************************************************************************//*!
\file SHMaterialInstance.hpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 17, 2022
\brief Contains the definition of functions templates of SHMaterialInstance.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
#include "SHMaterialInstance.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Property Functions */
/*---------------------------------------------------------------------------------*/
template<typename T>
void SHMaterialInstance::SetProperty(const std::string& key, const T& value)
{
const auto SHADER_INFO = getShaderBlockInterface();
const auto PROP_INFO = SHADER_INFO->GetVariable(key);
if (PROP_INFO == nullptr)
{
throw std::invalid_argument("Attempted to set an invalid property!");
}
// Allocate data store if it was empty
if (dataStore == nullptr)
{
dataStoreSize = SHADER_INFO->GetBytesRequired();dataStoreSize
dataStore.reset(new char[dataStoreSize]);
}
OverrideData od;
od.Index = SHADER_INFO.GetVariableIndex(key);
od.DataSize = sizeof(T);
if (overrideData.empty())
{
od.StoredDataOffset = 0;
}
else
{
const OverrideData& lastInsertedData = overrideData.back();
od.StoredDataOffset = lastInsertedData.StoredDataOffset + lastInsertedData.DataSize;
}
// Get offset and modify the memory directly
T* dataPtr = dataStore.get() + od.StoredDataOffset;
*dataPtr = value;
// Save the override data information
overrideData.emplace_back(std::move(od));
}
template<typename T>
T& SHMaterialInstance::GetProperty(const std::string& key)
{
const auto SHADER_INFO = getShaderBlockInterface();
const auto PROP_INFO = SHADER_INFO->GetVariable(key);
if (PROP_INFO == nullptr)
{
throw std::invalid_argument("Attempted to get an invalid property!");
}
// Search Override Data for the property
uint32_t PROP_IDX = SHADER_INFO.GetVariableIndex(key);
auto prop = std::find(overrideData.begin(), overrideData.end(), [&](const OverrideData& data)
{
return PROP_IDX == data.Index;
});
if (prop == overrideData.end())
throw std::invalid_argument("Attempted to get an property that was not set previously!");
// Get offset and return the memory directly
T* dataPtr = dataStore.get() + prop->StoredDataOffset;
return *dataPtr;
}
template<typename T>
const T& SHMaterialInstance::GetProperty(const std::string& key) const
{
return const_cast<const T&>(const_cast<SHMaterialInstance*>(this)->GetProperty(key));
}
}

View File

@ -0,0 +1,201 @@
/************************************************************************************//*!
\file SHMeshLibrary.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 30, 2022
\brief Contains definitions for all of the functions of the classes that deal
with storage and management of vertex and index buffers of meshes.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHMeshLibrary.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Commands/SHVkCommandBuffer.h"
#include "../../SHVkUtil.h"
namespace SHADE
{
SHADE::Handle<SHADE::SHMesh> SHMeshLibrary::AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices)
{
isDirty = true;
auto handle = meshes.Create();
meshAddJobs.emplace_back( MeshAddJob
{
vertexCount,
positions,
texCoords,
tangents,
normals,
indexCount,
indices,
handle
});
return handle;
}
void SHMeshLibrary::RemoveMesh(Handle<SHMesh> mesh)
{
if (!mesh)
throw std::invalid_argument("Attempted to remove a Mesh that did not belong to the Mesh Library!");
meshRemoveJobs.emplace_back(mesh);
isDirty = true;
}
void SHMeshLibrary::BuildBuffers(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer)
{
// No changes
if (!isDirty)
return;
// Remove
if (!meshRemoveJobs.empty())
{
// - Remove from order list
for (const auto& meshToRemove : meshRemoveJobs)
{
auto searchResult = std::find(meshOrder.begin(), meshOrder.end(), meshToRemove);
// Shouldn't happen, ignore
if (searchResult == meshOrder.end())
continue;
// Remove from mesh list
meshOrder.erase(searchResult);
}
meshRemoveJobs.clear();
// - Shift existing elements in to close up the gaps
int32_t nextVertInsertPoint = 0;
uint32_t nextIdxInsertPoint = 0;
for (auto& mesh : meshOrder)
{
// Check if already in the correct place
if (nextVertInsertPoint != mesh->FirstVertex)
{
/* There's a gap, we need to shift */
// Vertices
vertPosStorage.erase(vertPosStorage.begin() + nextVertInsertPoint, vertPosStorage.begin() + mesh->FirstVertex);
vertTexCoordStorage.erase(vertTexCoordStorage.begin() + nextVertInsertPoint, vertTexCoordStorage.begin() + mesh->FirstVertex);
vertTangentStorage.erase(vertTangentStorage.begin() + nextVertInsertPoint, vertTangentStorage.begin() + mesh->FirstVertex);
vertNormalStorage.erase(vertNormalStorage.begin() + nextVertInsertPoint, vertNormalStorage.begin() + mesh->FirstVertex);
// - Update mesh data
mesh->FirstVertex = nextVertInsertPoint;
// Indices
indexStorage.erase(indexStorage.begin() + nextIdxInsertPoint, indexStorage.begin() + mesh->FirstIndex);
// - Update mesh data
mesh->FirstIndex = nextIdxInsertPoint;
// Prepare for next
nextVertInsertPoint += mesh->VertexCount;
nextIdxInsertPoint += mesh->IndexCount;
}
}
}
// Add
if (!meshAddJobs.empty())
{
// - Compute updated size
size_t newVertElems = vertPosStorage.size();
size_t newIdxElems = indexStorage.size();
for (const auto& addJob : meshAddJobs)
{
newVertElems += addJob.VertexCount;
newIdxElems += addJob.IndexCount;
}
// - Reserve new memory
vertPosStorage .reserve(newVertElems);
vertTexCoordStorage.reserve(newVertElems);
vertTangentStorage .reserve(newVertElems);
vertNormalStorage .reserve(newVertElems);
indexStorage .reserve(newIdxElems);
// - Append new data
for (auto& addJob : meshAddJobs)
{
// Update handle
SHMesh& meshData = *addJob.Handle;
meshData = SHMesh
{
.FirstVertex = static_cast<int32_t>(vertPosStorage.size()),
.VertexCount = static_cast<uint32_t>(addJob.VertexCount),
.FirstIndex = static_cast<uint32_t>(indexStorage.size()),
.IndexCount = static_cast<uint32_t>(addJob.IndexCount),
};
// Copy into storage
vertPosStorage.insert
(
vertPosStorage.end(),
addJob.VertexPositions, addJob.VertexPositions + addJob.VertexCount
);
vertTexCoordStorage.insert
(
vertTexCoordStorage.end(),
addJob.VertexTexCoords, addJob.VertexTexCoords + addJob.VertexCount
);
vertTangentStorage.insert
(
vertTangentStorage.end(),
addJob.VertexTangents, addJob.VertexTangents + addJob.VertexCount
);
vertNormalStorage.insert
(
vertNormalStorage.end(),
addJob.VertexNormals, addJob.VertexNormals + addJob.VertexCount
);
indexStorage.insert
(
indexStorage.end(),
addJob.Indices, addJob.Indices + addJob.IndexCount
);
}
meshAddJobs.clear();
}
// Send to GPU
using BuffUsage = vk::BufferUsageFlagBits;
SHVkUtil::EnsureBufferAndCopyData
(
device, cmdBuffer, vertPosBuffer,
vertPosStorage.data(),
static_cast<uint32_t>(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition),
BuffUsage::eVertexBuffer
);
SHVkUtil::EnsureBufferAndCopyData
(
device, cmdBuffer, vertTexCoordBuffer,
vertTexCoordStorage.data(),
static_cast<uint32_t>(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord),
BuffUsage::eVertexBuffer
);
SHVkUtil::EnsureBufferAndCopyData
(
device, cmdBuffer, vertTangentBuffer,
vertTangentStorage.data(),
static_cast<uint32_t>(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent),
BuffUsage::eVertexBuffer
);
SHVkUtil::EnsureBufferAndCopyData
(
device, cmdBuffer, vertNormalBuffer,
vertNormalStorage.data(),
static_cast<uint32_t>(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal),
BuffUsage::eVertexBuffer
);
SHVkUtil::EnsureBufferAndCopyData
(
device, cmdBuffer, indexBuffer,
indexStorage.data(),
static_cast<uint32_t>(indexStorage.size()) * sizeof(SHMesh::Index),
BuffUsage::eIndexBuffer
);
isDirty = false;
}
}

View File

@ -0,0 +1,187 @@
/************************************************************************************//*!
\file SHMeshLibrary.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 30, 2022
\brief Contains definitions for all of the classes that deal with storage and
management of vertex and index buffers of meshes.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <vector>
// Project Includes
#include "Resource/Handle.h"
#include "Resource/ResourceLibrary.h"
#include "SHVertex.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Forward Declarations */
/*---------------------------------------------------------------------------------*/
class SHVkBuffer;
class SHVkLogicalDevice;
class SHVkCommandBuffer;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Represents a single mesh that is stored in a SHMeshLibrary.
*/
/***********************************************************************************/
class SHMesh
{
public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
using Index = uint32_t;
using VertexPosition = SHMathVec3f;
using VertexTexCoord = SHMathVec2f;
using VertexTangent = SHMathVec3f;
using VertexNormal = SHMathVec3f;
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
int32_t FirstVertex;
uint32_t VertexCount;
uint32_t FirstIndex;
uint32_t IndexCount;
};
/***********************************************************************************/
/*!
\brief
Manages storage for all Meshes in the Graphics System as a single set of Vertex
and Index Buffers.
*/
/***********************************************************************************/
class SHMeshLibrary
{
public:
/*-----------------------------------------------------------------------------*/
/* Usage Functions */
/*-----------------------------------------------------------------------------*/
/*******************************************************************************/
/*!
\brief
Adds a mesh to the Mesh Library. But this does not mean that the meshes have
been added yet. A call to "BuildBuffers()" is required to transfer all
meshes into the GPU.
\param vertexCount
Number of vertices in this Mesh.
\param positions
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
positions.
\param texCoords
Pointer to the first in a contiguous array of SHMathVec2s that define vertex
texture coordinates.
\param tangents
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
tangents.
\param normals
Pointer to the first in a contiguous array of SHMathVec3s that define vertex
normals.
\param indexCount
Number of indices in this mesh.
\param indices
Pointer to the first in a contiguous array of uint32_ts that define mesh
indicies.
\return
Handle to the created Mesh. This is not valid to be used until a call to
BuildBuffers().
*/
/*******************************************************************************/
Handle<SHMesh> AddMesh(uint32_t vertexCount, const SHMesh::VertexPosition* const positions, const SHMesh::VertexTexCoord* const texCoords, const const SHMesh::VertexTangent* const tangents, const SHMesh::VertexNormal* const normals, uint32_t indexCount, const SHMesh::Index* const indices);
/*******************************************************************************/
/*!
\brief
Removes a mesh from the MeshLibrary. But this does not mean that the meshes
have been removed yet. A call to "BuildBuffers()" is required to finalise all
changes.
\param mesh
Handle to the mesh to remove.
*/
/*******************************************************************************/
void RemoveMesh(Handle<SHMesh> mesh);
/***************************************************************************/
/*!
\brief
Finalises all changes to the MeshLibrary into the GPU buffers.
\param device
Device used to create and update the buffers.
\param cmdBuffer
Command buffer used to set up transfers of data in the GPU memory. This
call must be preceded by calls to cmdBuffer's BeginRecording() and ended
with EndRecording(). Do recall to also submit the cmdBuffer to a transfer
queue.
*/
/***************************************************************************/
void BuildBuffers(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer);
/*-----------------------------------------------------------------------------*/
/* Getter Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHVkBuffer> GetVertexPositionsBuffer() const noexcept { return vertPosBuffer; }
Handle<SHVkBuffer> GetVertexTexCoordsBuffer() const noexcept { return vertTexCoordBuffer; }
Handle<SHVkBuffer> GetVertexTangentsBuffer() const noexcept { return vertTangentBuffer; }
Handle<SHVkBuffer> GetVertexNormalsBuffer() const noexcept { return vertNormalBuffer; }
Handle<SHVkBuffer> GetIndexBuffer() const { return indexBuffer; }
private:
/*-----------------------------------------------------------------------------*/
/* Type Definition */
/*-----------------------------------------------------------------------------*/
struct MeshAddJob
{
uint32_t VertexCount = 0;
const SHMesh::VertexPosition* VertexPositions = nullptr;
const SHMesh::VertexTexCoord* VertexTexCoords = nullptr;
const SHMesh::VertexTangent * VertexTangents = nullptr;
const SHMesh::VertexNormal * VertexNormals = nullptr;
uint32_t IndexCount = 0;
const SHMesh::Index * Indices = nullptr;
Handle<SHMesh> Handle;
};
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
// Manipulation Queues
std::vector<MeshAddJob> meshAddJobs;
std::vector<Handle<SHMesh>> meshRemoveJobs;
// Tracking
ResourceLibrary<SHMesh> meshes{};
std::vector<Handle<SHMesh>> meshOrder;
// CPU Storage
std::vector<SHMesh::VertexPosition> vertPosStorage;
std::vector<SHMesh::VertexTexCoord> vertTexCoordStorage;
std::vector<SHMesh::VertexTangent> vertTangentStorage;
std::vector<SHMesh::VertexNormal> vertNormalStorage;
std::vector<SHMesh::Index> indexStorage;
// GPU Storage
Handle<SHVkBuffer> vertPosBuffer{};
Handle<SHVkBuffer> vertTexCoordBuffer{};
Handle<SHVkBuffer> vertTangentBuffer{};
Handle<SHVkBuffer> vertNormalBuffer{};
Handle<SHVkBuffer> indexBuffer {};
// Flags
bool isDirty = true;
};
}

View File

@ -1,2 +1,2 @@
#include "SHPch.h"
#include "SHpch.h"
#include "SHRenderTarget.h"

View File

@ -0,0 +1,49 @@
/************************************************************************************//*!
\file SHRenderable.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 19, 2022
\brief Contains the definition of functions of the SHRenderable Component class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHRenderable.h"
#include "ECS_Base/Managers/SHSystemManager.h"
namespace SHADE
{
void SHRenderable::SetMaterial(Handle<SHMaterialInstance> materialInstance)
{
if (material)
{
material.Free();
material = {};
}
sharedMaterial = materialInstance;
}
Handle<SHMaterialInstance> SHRenderable::GetMaterial() const
{
if (material)
return material;
return sharedMaterial;
}
Handle<SHMaterialInstance> SHRenderable::GetModifiableMaterial()
{
// Create a copy if it wasn't created
if (!material)
{
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
material = gfxSystem->AddMaterialInstance(sharedMaterial->GetBaseMaterial());
}
return material;
}
}

View File

@ -0,0 +1,60 @@
/************************************************************************************//*!
\file SHRenderable.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Sep 19, 2022
\brief Contains the definition of the SHRenderable Component class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Project Includes
#include "Resource/Handle.h"
//#include "SHTransform.h"
#include "ECS_Base/Components/SHComponent.h"
#include "Math/SHMatrix.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMaterialInstance;
class SHMesh;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/*************************************************************************************/
/*!
\brief
Represents an object that should be rendered.
*/
/*************************************************************************************/
class SHRenderable : public SHComponent, public ISelfHandle<SHRenderable>
{
public:
/*-------------------------------------------------------------------------------*/
/* Usage Functions */
/*-------------------------------------------------------------------------------*/
void SetMaterial(Handle<SHMaterialInstance> materialInstance);
Handle<SHMaterialInstance> GetMaterial() const;
Handle<SHMaterialInstance> GetModifiableMaterial();
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
Handle<SHMesh> Mesh;
SHMatrix TransformMatrix; // TODO: Replace with Transform component
private:
/*-------------------------------------------------------------------------------*/
/* Data Members */
/*-------------------------------------------------------------------------------*/
Handle<SHMaterialInstance> sharedMaterial;
Handle<SHMaterialInstance> material;
};
}

View File

@ -0,0 +1,57 @@
/************************************************************************************//*!
\file SHRenderer.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 21, 2022
\brief
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHRenderer.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "SHViewport.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Framebuffer/SHVkFramebuffer.h"
#include "SHMaterial.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*---------------------------------------------------------------------------------*/
SHRenderer::SHRenderer(Handle<SHViewport> viewport, ResourceManager& resourceManager)
: renderGraph{resourceManager.Create<SHRenderGraph> ()}
{
}
SHRenderer::~SHRenderer()
{
}
/*-----------------------------------------------------------------------------*/
/* Camera Registration */
/*-----------------------------------------------------------------------------*/
void SHRenderer::SetCamera(Handle<SHCamera> _camera)
{
camera = _camera;
}
/*---------------------------------------------------------------------------------*/
/* Drawing Functions */
/*---------------------------------------------------------------------------------*/
void SHRenderer::Draw(uint32_t frameIndex) const noexcept
{
renderGraph->Execute(frameIndex);
}
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept
{
return renderGraph;
}
}

View File

@ -0,0 +1,81 @@
/************************************************************************************//*!
\file SHRenderer.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 21, 2022
\brief
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <array>
// Project Includes
#include "SHCamera.h"
#include "Resource/Handle.h"
#include "SHGraphicsConstants.h"
#include "Graphics/RenderGraph/SHRenderGraph.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Forward Declarations */
/*---------------------------------------------------------------------------------*/
class SHVkBuffer;
class SHVkRenderpass;
class SHVkFramebuffer;
class SHMaterial;
class SHVkLogicalDevice;
class SHViewport;
class SHVkImageView;
class SHVkCommandBuffer;
class SHCamera;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Brings together a set of Cameras and objects with various Pipelines to render
them as part of a set. Multiple Renderers can exist to render objects differently
in a separate step.
*/
/***********************************************************************************/
class SHRenderer
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/
SHRenderer(Handle<SHViewport> viewport, ResourceManager& resourceManager);
~SHRenderer();
/*-----------------------------------------------------------------------------*/
/* Camera Registration */
/*-----------------------------------------------------------------------------*/
void SetCamera(Handle<SHCamera> _camera);
/*-----------------------------------------------------------------------------*/
/* Drawing Functions */
/*-----------------------------------------------------------------------------*/
void Draw(uint32_t frameIndex) const noexcept;
/*-----------------------------------------------------------------------------*/
/* Setters and Getters */
/*-----------------------------------------------------------------------------*/
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
Handle<SHCamera> camera;
Handle<SHRenderGraph> renderGraph;
};
}

View File

@ -0,0 +1,74 @@
/************************************************************************************//*!
\file SHViewport.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 27, 2022
\brief
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHViewport.h"
#include "Graphics/Commands/SHVkCommandBuffer.h"
#include "Graphics/Instance/SHVkInstance.h"
#include "Tools/SHLogger.h"
#include "SHRenderer.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*---------------------------------------------------------------------------------*/
SHViewport::SHViewport(Handle<SHVkLogicalDevice> device, const vk::Viewport& viewport)
: device { device }
, viewport { viewport }
{}
/*---------------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
void SHViewport::SetUp(Handle<SHVkCommandBuffer> commandBuffer)
{
commandBuffer->SetViewportScissor
(
viewport.x,
viewport.y,
static_cast<int32_t>(viewport.width),
static_cast<int32_t>(viewport.height),
viewport.minDepth,
viewport.maxDepth
);
}
/*---------------------------------------------------------------------------------*/
/* Renderer Registration Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHRenderer> SHViewport::AddRenderer(ResourceManager& resourceManager)
{
// Create the renderer
auto renderer = SHVkInstance::GetResourceManager().Create<SHRenderer>(GetHandle(), resourceManager);
// Store
renderers.emplace_back(renderer);
// Return
return renderer;
}
void SHViewport::RemoveRenderer(Handle<SHRenderer> renderer)
{
auto iter = std::find(renderers.begin(), renderers.end(), renderer);
if (iter == renderers.end())
{
SHLOG_WARNING("Attempted to remove a Renderer that does not belong to a viewport!");
return;
}
// Remove it
iter->Free();
renderers.erase(iter);
}
}

View File

@ -0,0 +1,81 @@
/************************************************************************************//*!
\file SHViewport.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 27, 2022
\brief Contains the class definition of SHViewport.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <vector>
// External Dependencies
#include "Graphics/SHVulkanIncludes.h"
// Project Includes
#include "Resource/Handle.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Forward Declarations */
/*---------------------------------------------------------------------------------*/
class SHRenderer;
class SHVkCommandBuffer;
class SHVkLogicalDevice;
class SHVkImageView;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
Brings together a set of Renderers that render to the same segment of an image.
*/
/***********************************************************************************/
class SHViewport : public ISelfHandle<SHViewport>
{
public:
/*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/
SHViewport(Handle<SHVkLogicalDevice> device, const vk::Viewport& viewport);
/*-----------------------------------------------------------------------------*/
/* Lifecycle Functions */
/*-----------------------------------------------------------------------------*/
void SetUp(Handle<SHVkCommandBuffer> commandBuffer);
/*-----------------------------------------------------------------------------*/
/* Renderers Registration Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHRenderer> AddRenderer(ResourceManager& resourceManager);
void RemoveRenderer(Handle<SHRenderer> renderer);
/*-----------------------------------------------------------------------------*/
/* Getters */
/*-----------------------------------------------------------------------------*/
float GetX() const { return viewport.x; }
float GetY() const { return viewport.y; }
float GetWidth() const { return viewport.width; }
float GetHeight() const { return viewport.height; }
float GetMinDepth() const { return viewport.minDepth; }
float GetMaxDepth() const { return viewport.maxDepth; }
const std::vector<Handle<SHRenderer>>& GetRenderers() const { return renderers; }
private:
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
Handle<SHVkLogicalDevice> device;
vk::Viewport viewport;
std::vector<Handle<SHRenderer>> renderers;
};
}

View File

@ -0,0 +1,52 @@
#include "SHpch.h"
#include "SHPipelineLibrary.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
namespace SHADE
{
Handle<SHVkPipeline> SHPipelineLibrary::CreateDrawPipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, uint32_t subpass, SHVertexInputState const& vertexInput, std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts) noexcept
{
SHPipelineLayoutParams params
{
.shaderModules = {vsFsPair.first, vsFsPair.second},
.globalDescSetLayouts = globalDescSetLayouts
};
// Create the pipeline layout
auto pipelineLayout = logicalDevice->CreatePipelineLayout(params);
// Create the pipeline and configure the default vertex input state
auto newPipeline = logicalDevice->CreatePipeline(pipelineLayout, nullptr, renderpass, subpass, SH_PIPELINE_TYPE::GRAPHICS);
newPipeline->GetPipelineState().SetVertexInputState(vertexInput);
// Actually construct the pipeline
newPipeline->ConstructPipeline();
// Emplace the new pipeline
pipelines.emplace (vsFsPair, newPipeline);
}
void SHPipelineLibrary::Init(Handle<SHVkLogicalDevice> device, SHVertexInputState const* viState, std::vector<Handle<SHVkDescriptorSetLayout>> const* globalLayouts) noexcept
{
logicalDevice = device;
vertexInputState = viState;
globalDescSetLayouts = globalLayouts;
}
Handle<SHVkPipeline> SHPipelineLibrary::GetDrawPipline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept
{
// return the pipeline requested for
if (pipelines.contains(vsFsPair))
return pipelines.at(vsFsPair);
else
return {};
}
bool SHPipelineLibrary::CheckDrawPipelineExistence(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept
{
// Returns if a pipeline exists or not
return pipelines.contains(vsFsPair);
}
}

View File

@ -0,0 +1,57 @@
#pragma once
#include <unordered_map>
#include "Graphics/Shaders/SHVkShaderModule.h"
#include "Graphics/Pipeline/SHVkPipeline.h"
namespace SHADE
{
class SHVRenderpass;
class SHVkDescriptorSetLayouts;
class SHVkPipeline;
// Pipeline library is a PURELY MIDDLE END SYSTEM. It is responsible for only creating pipelines from shaders and caching
// them so that they don't need to be recreated again.
class SHPipelineLibrary
{
private:
// TOOD: Move this somewhere eventually. Can use for other things
struct SHHandlePairHash
{
template <typename T1, typename T2>
std::size_t operator() (std::pair<T1, T2> const& pair) const
{
return std::hash<T1>()(pair.first.GetId()) ^ std::hash<T2>()(pair.second.GetId());
}
};
//! Logical Device required for creation of pipelines
Handle<SHVkLogicalDevice> logicalDevice;
//! a map of pipelines that are hashed using a pair of shader module handles
std::unordered_map<std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>>, Handle<SHVkPipeline>, SHHandlePairHash> pipelines;
//! Default vertex input state for pipeline creation
SHVertexInputState const* vertexInputState;
std::vector<Handle<SHVkDescriptorSetLayout>> const* globalDescSetLayouts;
public:
void Init (Handle<SHVkLogicalDevice> device, SHVertexInputState const* viState, std::vector<Handle<SHVkDescriptorSetLayout>> const* globalLayouts) noexcept;
// Draw pipeline functions. used only when creating pipelines for drawing using a vertex and fragment shader
Handle<SHVkPipeline> CreateDrawPipeline (
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
Handle<SHVkRenderpass> renderpass,
uint32_t subpass,
SHVertexInputState const& vertexInput,
std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts
) noexcept;
Handle<SHVkPipeline> GetDrawPipline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
bool CheckDrawPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
};
}

View File

@ -23,7 +23,7 @@ namespace SHADE
//! used just for textures or lights for example). In that case, we still
//! want to use the layout to initialize the pipeline layout but we do not
//! want to use it for allocating descriptor sets.
std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts = {};
std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts = {};
};
}

View File

@ -189,7 +189,7 @@ namespace SHADE
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
template <typename T, typename = std::enable_if_t <std::is_same_v<std::remove_reference_t<T>, SHVertexInputState>>>
template <typename T, typename = std::enable_if_t <std::is_same_v<std::decay_t<T>, SHVertexInputState>>>
void SetVertexInputState (T&& state) noexcept;
void SetInputAssemblyState(SHInputAssemblyState const& state) noexcept;
void SetRasterizationState(SHRasterizationState const& state) noexcept;

View File

@ -1035,7 +1035,7 @@ namespace SHADE
auto& cmdBuffer = commandBuffers[frameIndex];
cmdBuffer->BeginRecording();
cmdBuffer->SetviewportScissor(1920.0f, 1080.0f, 1920, 1080);
cmdBuffer->SetViewportScissor(1920.0f, 1080.0f, 1920, 1080);
for (auto& node : nodes)
{

View File

@ -6,30 +6,49 @@ namespace SHADE
void SHShaderBlockInterface::AddVariable(std::string name, Variable&& newVariable) noexcept
{
variables.try_emplace (std::move(name), std::move (newVariable));
// Check if this is already inside
if (variableIndexing.contains(name))
{
SHLOG_WARNING("[SHShaderBlockInterface] Attempted to specify a variable with a duplicate name. This will be ignored.");
return;
}
variableIndexing.emplace_back(std::move(newVariable));
variables.try_emplace (std::move(name), static_cast<uint32_t>(variableIndexing.size() - 1));
}
SHShaderBlockInterface::Variable const* const SHShaderBlockInterface::GetVariable(std::string const& variableName) const noexcept
{
if (variables.contains(variableName))
return &variables.at(variableName);
if (variableIndexing.contains(variableName))
return &variables.at(variableIndexing.at(variableName).second);
return nullptr;
}
SHShaderBlockInterface::SHShaderBlockInterface(void) noexcept
: variables{}
, bytesRequired{ 0 }
SHADE::SHShaderBlockInterface::Variable const* const SHShaderBlockInterface::GetVariable(uint32_t index) const noexcept
{
if (variableIndexing.size() < index)
return &variables.at(index);
return nullptr;
}
uint32_t SHShaderBlockInterface::GetVariableIndex(std::string const& variableName) const noexcept
{
if (!variableIndexing.contains(variableName))
throw std::invalid_argument("Attempted to retrieve index to variable that does not exist!");
return variableIndexing.at(variableName).second;
}
SHShaderBlockInterface::SHShaderBlockInterface(void) noexcept
: bytesRequired{ 0 }
{}
SHShaderBlockInterface::SHShaderBlockInterface(SHShaderBlockInterface&& rhs) noexcept
: variables{ std::move(rhs.variables) }
, bytesRequired {std::move (rhs.bytesRequired)}
{
}
: variables { std::move(rhs.variables) }
, variableIndexing { std::move(rhs.variableIndexing) }
, bytesRequired { std::move (rhs.bytesRequired) }
{}
void SHShaderBlockInterface::SetBytesRequired(uint32_t bytes) noexcept
{
@ -48,14 +67,9 @@ namespace SHADE
return *this;
variables = std::move(rhs.variables);
variableIndexing = std::move(rhs.variableIndexing);
bytesRequired = std::move(rhs.bytesRequired);
return *this;
}
SHShaderBlockInterface::~SHShaderBlockInterface(void) noexcept
{
variables.clear();
}
}

View File

@ -15,8 +15,9 @@ namespace SHADE
};
private:
//! container of variable information
std::unordered_map<std::string, Variable> variables;
//! containers of variable information
std::vector<Variable> variables;
std::unordered_map<std::string, uint32_t> variableIndexing;
//! bytes required by the block (includes padding). This variable is required
uint32_t bytesRequired;
@ -24,12 +25,13 @@ namespace SHADE
public:
void AddVariable (std::string name, Variable&& newVariable) noexcept;
Variable const* const GetVariable (std::string const& variableName) const noexcept;
Variable const* const GetVariable(uint32_t index) const noexcept;
uint32_t GetVariableIndex(std::string const& variableName) const;
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHShaderBlockInterface(void) noexcept;
~SHShaderBlockInterface(void) noexcept;
SHShaderBlockInterface(SHShaderBlockInterface&& rhs) noexcept;
SHShaderBlockInterface& operator=(SHShaderBlockInterface&& rhs) noexcept;