Lights WIP
This commit is contained in:
parent
0788084bbd
commit
8fb0eddcc1
|
@ -10,7 +10,7 @@ Collapsed=0
|
|||
|
||||
[Window][Hierarchy Panel]
|
||||
Pos=0,142
|
||||
Size=387,918
|
||||
Size=768,918
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
|
@ -27,7 +27,7 @@ DockId=0x00000006,0
|
|||
|
||||
[Window][Profiler]
|
||||
Pos=0,48
|
||||
Size=387,92
|
||||
Size=768,92
|
||||
Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
|
@ -38,17 +38,17 @@ Collapsed=0
|
|||
DockId=0x00000002,0
|
||||
|
||||
[Window][ Viewport]
|
||||
Pos=389,48
|
||||
Size=1258,1012
|
||||
Pos=770,48
|
||||
Size=877,1012
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X
|
||||
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=387,1036 Split=Y Selected=0x1E6EB881
|
||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=768,1036 Split=Y Selected=0x1E6EB881
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE
|
||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1258,1036 CentralNode=1 Selected=0xB41284E7
|
||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=877,1036 CentralNode=1 Selected=0xB41284E7
|
||||
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ namespace SHADE
|
|||
SHVkDebugMessenger::GenMessengerType(SH_DEBUG_MSG_TYPE::T_GENERAL, SH_DEBUG_MSG_TYPE::T_VALIDATION, SH_DEBUG_MSG_TYPE::T_PERFORMANCE));
|
||||
|
||||
instanceDbgInfo.pfnUserCallback = SHVulkanDebugUtil::GenericDebugCallback;
|
||||
instanceInfo.pNext = static_cast<vk::DebugUtilsMessengerCreateInfoEXT*>(&instanceDbgInfo);
|
||||
//instanceInfo.pNext = static_cast<vk::DebugUtilsMessengerCreateInfoEXT*>(&instanceDbgInfo);
|
||||
}
|
||||
|
||||
// Finally create the instance
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace SHADE
|
|||
{
|
||||
.Type = vk::DescriptorType::eStorageBufferDynamic,
|
||||
.Stage = vk::ShaderStageFlagBits::eFragment,
|
||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::LIGHTS_DATA,
|
||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::DIRECTIONAL_LIGHT_DATA,
|
||||
.DescriptorCount = 1,
|
||||
};
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace SHADE
|
|||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
static constexpr uint32_t LIGHTS_DATA = 0;
|
||||
static constexpr uint32_t DIRECTIONAL_LIGHT_DATA = 0;
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHLightComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
|
||||
void SHLightComponent::OnCreate(void)
|
||||
{
|
||||
lightData.Reset();
|
||||
SetType(SH_LIGHT_TYPE::DIRECTIONAL);
|
||||
indexInBuffer = std::numeric_limits<uint32_t>::max();
|
||||
Unbind();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::OnDestroy(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SHLightComponent::SetPosition(SHVec3 position) noexcept
|
||||
{
|
||||
lightData.position = position;
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::SetType(SH_LIGHT_TYPE type) noexcept
|
||||
{
|
||||
lightData.type = type;
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::SetDirection(SHVec3 direction) noexcept
|
||||
{
|
||||
lightData.direction = direction;
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::SetDiffuseColor(SHVec4 diffuseColor) noexcept
|
||||
{
|
||||
lightData.diffuseColor = diffuseColor;
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
void SHLightComponent::ModifyLayer(uint8_t layerIndex, bool value) noexcept
|
||||
{
|
||||
if (value)
|
||||
lightData.cullingMask |= (1u << layerIndex);
|
||||
else
|
||||
lightData.cullingMask &= ~(1u << layerIndex);
|
||||
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::SetAllLayers(void) noexcept
|
||||
{
|
||||
lightData.cullingMask = std::numeric_limits<uint32_t>::max();
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
|
||||
void SHLightComponent::ClearAllLayers(void) noexcept
|
||||
{
|
||||
lightData.cullingMask = 0;
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
void SHLightComponent::MakeDirty(void) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void SHLightComponent::ClearDirtyFlag(void) noexcept
|
||||
{
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
void SHLightComponent::Unbind(void) noexcept
|
||||
{
|
||||
bound = false;
|
||||
MakeDirty();
|
||||
}
|
||||
|
||||
void SHLightComponent::SetBound(void) noexcept
|
||||
{
|
||||
bound = true;
|
||||
}
|
||||
|
||||
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
||||
{
|
||||
return lightData;
|
||||
}
|
||||
|
||||
bool SHLightComponent::IsDirty(void) const noexcept
|
||||
{
|
||||
return dirty;
|
||||
}
|
||||
|
||||
bool SHLightComponent::GetBound(void) const noexcept
|
||||
{
|
||||
return bound;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
#include "SHLightData.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
class SH_API SHLightComponent final : public SHComponent
|
||||
{
|
||||
private:
|
||||
//! General data for the light. This will purely be CPU bound. Whatever gets sent to the
|
||||
//! GPU depends on the type of the light.
|
||||
SHLightData lightData;
|
||||
|
||||
//! Since the lighting system is gonna be self contained and light weight, we store this
|
||||
//! so that we only write this to the CPU buffer when this light component change, we don't
|
||||
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
||||
uint32_t indexInBuffer;
|
||||
|
||||
//! If the light component changed some value we mark this true.
|
||||
bool dirty;
|
||||
|
||||
//! If the light's data is already in the buffers, this will be set to true.
|
||||
bool bound;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* LIFECYCLE FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void OnCreate (void) override final;
|
||||
void OnDestroy (void) override final;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* SETTERS AND GETTERS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void SetPosition (SHVec3 position) noexcept;
|
||||
void SetType (SH_LIGHT_TYPE type) noexcept;
|
||||
void SetDirection (SHVec3 direction) noexcept;
|
||||
void SetDiffuseColor (SHVec4 diffuseColor) noexcept;
|
||||
void ModifyLayer (uint8_t layerIndex, bool value) noexcept;
|
||||
void SetAllLayers (void) noexcept;
|
||||
void ClearAllLayers (void) noexcept;
|
||||
void MakeDirty (void) noexcept;
|
||||
void ClearDirtyFlag (void) noexcept;
|
||||
void Unbind (void) noexcept;
|
||||
void SetBound (void) noexcept;
|
||||
|
||||
SHLightData const& GetLightData (void) const noexcept;
|
||||
bool IsDirty (void) const noexcept;
|
||||
bool GetBound (void) const noexcept;
|
||||
|
||||
};
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHLightData.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
void SHLightData::Reset(void) noexcept
|
||||
{
|
||||
// no culling is done.
|
||||
cullingMask = std::numeric_limits<uint32_t>::max();
|
||||
|
||||
// reset position to 0
|
||||
position = SHVec3::Zero;
|
||||
|
||||
// direction just point in positive z axis
|
||||
direction = SHVec3::Forward;
|
||||
|
||||
// Diffuse color set to 1
|
||||
diffuseColor = SHVec4::One;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
enum class SH_LIGHT_TYPE : uint32_t
|
||||
{
|
||||
DIRECTIONAL = 0,
|
||||
POINT,
|
||||
SPOT,
|
||||
NUM_TYPES
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\class
|
||||
Every light will essentially be using this struct. However, when passing
|
||||
light data over to the GPU, the light data will be split according to
|
||||
type for more optimal cache access.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
struct SHLightData
|
||||
{
|
||||
//! position of the light
|
||||
SHVec3 position;
|
||||
|
||||
//! Type of the light
|
||||
SH_LIGHT_TYPE type;
|
||||
|
||||
//! direction of the light
|
||||
SHVec3 direction;
|
||||
|
||||
//! Each bit in this 32 bit field will represent a layer. If the bit is set,
|
||||
//! when a fragment is being evaluated, the shader will use the fragment's
|
||||
//! layer value to AND with the light's. If result is 1, do lighting calculations.
|
||||
uint32_t cullingMask;
|
||||
|
||||
//! Diffuse color emitted by the light
|
||||
SHVec4 diffuseColor;
|
||||
|
||||
void Reset (void) noexcept;
|
||||
//! TODO:
|
||||
//! - Add cut off. (inner and outer).
|
||||
//! - Add constant, linear and quadratic for attenuation
|
||||
//! - Specular color if needed. see below.
|
||||
|
||||
//! Specular color
|
||||
//SHVec4 specularColor;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
#include "SHpch.h"
|
||||
#include "SHLightingSubSystem.h"
|
||||
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
|
||||
#include "Tools/SHUtilities.h"
|
||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
#include "SHLightComponent.h"
|
||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Initializes type, intermediate data and buffer. dirty will be true.
|
||||
|
||||
\param lightType
|
||||
type of the light.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::PerTypeData::InitializeData(Handle<SHVkLogicalDevice> logicalDevice, SH_LIGHT_TYPE type) noexcept
|
||||
{
|
||||
// initialize the type
|
||||
lightType = type;
|
||||
|
||||
// we want to write to GPU when system runs
|
||||
dirty = true;
|
||||
|
||||
// boilerplate
|
||||
intermediateData = nullptr;
|
||||
numLights = 0;
|
||||
|
||||
// initialize alignment
|
||||
lightDataAlignmentSize = logicalDevice->PadSSBOSize(GetLightTypeSize(type));
|
||||
|
||||
// So create some data!
|
||||
Expand(logicalDevice);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Expands both the CPU container and the GPU buffer when the number of
|
||||
lights have exceeded
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::PerTypeData::Expand(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||
{
|
||||
// we want to wait for the command buffers to finish using the buffers first
|
||||
logicalDevice->WaitIdle();
|
||||
|
||||
// this is for CPU buffer.
|
||||
uint32_t structSize = GetLightTypeSize(lightType);
|
||||
|
||||
// First time we are initializing lights
|
||||
if (intermediateData == nullptr)
|
||||
{
|
||||
// num lights should start of at STARTING_NUM_LIGHTS lights
|
||||
numLights = STARTING_NUM_LIGHTS;
|
||||
|
||||
// Initialize the data for lights
|
||||
intermediateData = std::make_unique<uint8_t[]>(lightDataAlignmentSize * STARTING_NUM_LIGHTS);
|
||||
|
||||
dataBuffer = logicalDevice->CreateBuffer(numLights * lightDataAlignmentSize, nullptr, numLights * lightDataAlignmentSize, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
// save old number of lights
|
||||
uint32_t const OLD_NUM_LIGHTS = numLights;
|
||||
|
||||
// before we increase the number of lights, create space to store old data.
|
||||
std::unique_ptr<uint8_t[]> oldData = std::make_unique<uint8_t[]>(lightDataAlignmentSize * OLD_NUM_LIGHTS);
|
||||
|
||||
// copy data over.
|
||||
std::memcpy (oldData.get(), intermediateData.get(), lightDataAlignmentSize * OLD_NUM_LIGHTS);
|
||||
|
||||
// now we start to expand....
|
||||
|
||||
// double space for lights
|
||||
numLights *= 2;
|
||||
|
||||
// destroy old data and initialize container for double the amount of data.
|
||||
intermediateData = std::make_unique<uint8_t[]>(lightDataAlignmentSize * numLights);
|
||||
|
||||
// copy old data to new container
|
||||
std::memcpy(intermediateData.get(), oldData.get(), lightDataAlignmentSize * OLD_NUM_LIGHTS);
|
||||
|
||||
// Resize the GPU buffer
|
||||
dataBuffer->ResizeReplace(lightDataAlignmentSize * numLights, oldData.get(), lightDataAlignmentSize * OLD_NUM_LIGHTS);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
This function takes in a light comp in the event that its data has not
|
||||
been placed in the buffer yet. It also checks if the size of the buffer
|
||||
is big enough
|
||||
|
||||
\param lightComp
|
||||
|
||||
\return
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::PerTypeData::AddLight(SHLightComponent* lightComp) noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Gets the size required to store data for a light type.
|
||||
|
||||
\param type
|
||||
Type of a light.
|
||||
|
||||
\return
|
||||
Size required to store a light based on type.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
uint32_t SHLightingSubSystem::PerTypeData::GetLightTypeSize(SH_LIGHT_TYPE type) noexcept
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case SH_LIGHT_TYPE::DIRECTIONAL:
|
||||
// TOOD: Change after creating point light struct
|
||||
return 0;
|
||||
case SH_LIGHT_TYPE::POINT:
|
||||
return sizeof (SHDirectionalLightData);
|
||||
case SH_LIGHT_TYPE::SPOT:
|
||||
// TOOD: Change after creating spot light struct
|
||||
return 0;
|
||||
case SH_LIGHT_TYPE::NUM_TYPES:
|
||||
default:
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Handle<SHVkBuffer> SHLightingSubSystem::PerTypeData::GetDataBuffer(void) const noexcept
|
||||
{
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SHLightingSubSystem::PerTypeData::GetAlignmentSize(void) const noexcept
|
||||
{
|
||||
return lightDataAlignmentSize;
|
||||
}
|
||||
|
||||
void SHLightingSubSystem::UpdateDescSet(uint32_t binding) noexcept
|
||||
{
|
||||
auto buffer = perTypeData[binding].GetDataBuffer();
|
||||
|
||||
// We bind the buffer with the correct desc set binding
|
||||
lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS,
|
||||
binding,
|
||||
{ &buffer, 1 },
|
||||
0,
|
||||
perTypeData[binding].GetAlignmentSize());
|
||||
|
||||
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, binding);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Initializes per light type data. This includes buffers and descriptor
|
||||
sets.
|
||||
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkDescriptorPool> descPool) noexcept
|
||||
{
|
||||
std::vector<uint32_t> variableSizes{ SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES) };
|
||||
std::fill (variableSizes.begin(), variableSizes.end(), 1);
|
||||
|
||||
// Create the descriptor set
|
||||
lightingDataDescSet = descPool->Allocate({SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS]}, variableSizes);
|
||||
|
||||
// initialize all the data first. We add more lights here as we add more types.
|
||||
perTypeData[SHUtilities::ToUnderlying(SH_LIGHT_TYPE::DIRECTIONAL)].InitializeData(logicalDevice, SH_LIGHT_TYPE::DIRECTIONAL);
|
||||
UpdateDescSet(SHGraphicsConstants::DescriptorSetBindings::DIRECTIONAL_LIGHT_DATA);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Loops through every single light component and checks for dirty light
|
||||
data. If light data is dirty, rewrite to the CPU container and do a
|
||||
copy to the GPU data. We also check if the per light type data is too small
|
||||
to handle more lights, if it is, expand buffer (both CPU and GPU).
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::Run(void) noexcept
|
||||
{
|
||||
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
||||
for (auto& light : lightComps)
|
||||
{
|
||||
// First we want to make sure the light is already bound to the system. if it
|
||||
// isn't, we write it to the correct buffer.
|
||||
if (!light.GetBound())
|
||||
{
|
||||
|
||||
|
||||
light.SetBound();
|
||||
}
|
||||
|
||||
// if there was modification to the light data
|
||||
if (light.IsDirty())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief
|
||||
Does nothing for now.
|
||||
|
||||
*/
|
||||
/***************************************************************************/
|
||||
void SHLightingSubSystem::Exit(void) noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
#pragma once
|
||||
|
||||
#include "Resource/SHHandle.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "SHLightData.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
class SHVkLogicalDevice;
|
||||
class SHVkDescriptorPool;
|
||||
class SHVkDescriptorSetGroup;
|
||||
class SHVkDescriptorSetLayout;
|
||||
class SHVkBuffer;
|
||||
|
||||
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
||||
struct SHDirectionalLightData
|
||||
{
|
||||
//! Direction of the light
|
||||
SHVec3 direction;
|
||||
|
||||
//! Each bit in this 32 bit field will represent a layer. If the bit is set,
|
||||
//! when a fragment is being evaluated, the shader will use the fragment's
|
||||
//! layer value to AND with the light's. If result is 1, do lighting calculations.
|
||||
uint32_t cullingMask;
|
||||
|
||||
//! Diffuse color emitted by the light
|
||||
SHVec4 diffuseColor;
|
||||
|
||||
};
|
||||
|
||||
class SHLightingSubSystem
|
||||
{
|
||||
private:
|
||||
|
||||
class PerTypeData
|
||||
{
|
||||
private:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* STATIC MEMBER VARIABLES */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static constexpr uint32_t STARTING_NUM_LIGHTS = 20;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER VARIABLES */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
//! SSBOs need to be aligned. This is to pad lighting structs
|
||||
uint32_t lightDataAlignmentSize;
|
||||
|
||||
//! type of the light. Will be used later when we want to expand
|
||||
SH_LIGHT_TYPE lightType;
|
||||
|
||||
//! number of lights currently alive.
|
||||
uint32_t numLights;
|
||||
|
||||
//! if intermediateData has been modified(i.e. any 1 light's data is changed), set to true.
|
||||
bool dirty;
|
||||
|
||||
//! GPU buffer required to store GPU data
|
||||
Handle<SHVkBuffer> dataBuffer;
|
||||
|
||||
//! Before data gets copied to the GPU, it goes into here first. Data here is aligned to whatever struct is
|
||||
//! used to represent data in this container.
|
||||
std::unique_ptr<uint8_t[]> intermediateData;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void InitializeData (Handle<SHVkLogicalDevice> logicalDevice, SH_LIGHT_TYPE type) noexcept;
|
||||
void Expand (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||
void AddLight (SHLightComponent* lightComp) noexcept;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* GETTERS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static uint32_t GetLightTypeSize (SH_LIGHT_TYPE type) noexcept;
|
||||
Handle<SHVkBuffer> GetDataBuffer (void) const noexcept;
|
||||
uint32_t GetAlignmentSize (void) const noexcept;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
//! logical device used for creation
|
||||
Handle<SHVkLogicalDevice> logicalDevice;
|
||||
|
||||
//! The descriptor set that will hold the lighting data. Each binding will hold a buffer, NUM_FRAMES times the size required.
|
||||
Handle<SHVkDescriptorSetGroup> lightingDataDescSet;
|
||||
|
||||
//! Each type will have some data associated with it for processing
|
||||
std::array<PerTypeData, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PRIVATE MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void UpdateDescSet (uint32_t binding) noexcept;
|
||||
|
||||
public:
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* PUBLIC MEMBER FUNCTIONS */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||
void Run (void) noexcept;
|
||||
void Exit (void) noexcept;
|
||||
|
||||
};
|
||||
}
|
|
@ -42,6 +42,15 @@ namespace SHADE
|
|||
template <IsEnum InputType, IsIntegral OutputType = int>
|
||||
static constexpr OutputType ConvertEnum(InputType enumClassMember) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Converts an enum class member from it's type to the underlying type.
|
||||
* @tparam Enum Restricted to an enum class
|
||||
* @param[in] value A member of the specified enum class.
|
||||
* @returns The value of the enum class member in the output type.
|
||||
*/
|
||||
template<typename Enum>
|
||||
static constexpr typename std::underlying_type_t<Enum> ToUnderlying (Enum value) noexcept;
|
||||
|
||||
};
|
||||
|
||||
} // namespace SHADE
|
||||
|
|
|
@ -25,4 +25,10 @@ namespace SHADE
|
|||
return static_cast<OutputType>(enumClassMember);
|
||||
}
|
||||
|
||||
template<typename Enum>
|
||||
constexpr typename std::underlying_type_t<Enum> SHUtilities::ToUnderlying(Enum value) noexcept
|
||||
{
|
||||
return static_cast<typename std::underlying_type_t<Enum>>(value);
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
Loading…
Reference in New Issue