ajout du composant lumière basique
This commit is contained in:
@@ -26,6 +26,7 @@ private:
|
|||||||
struct CameraUBOData {
|
struct CameraUBOData {
|
||||||
glm::mat4 view;
|
glm::mat4 view;
|
||||||
glm::mat4 projection;
|
glm::mat4 projection;
|
||||||
|
glm::vec4 position;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::array<VMABuffer, MAX_FRAMES_IN_FLIGHT> m_uniformBuffers;
|
std::array<VMABuffer, MAX_FRAMES_IN_FLIGHT> m_uniformBuffers;
|
||||||
@@ -127,7 +128,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateUniformBuffer(uint32_t frameIndex, const CTransform& transform) {
|
void updateUniformBuffer(uint32_t frameIndex, const CTransform& transform) {
|
||||||
CameraUBOData data{ getView(transform), m_projection };
|
glm::mat4 worldTransform = transform.getInheritedTransformation();
|
||||||
|
glm::vec3 worldPosition = glm::vec3(worldTransform[3]);
|
||||||
|
CameraUBOData data{ getView(transform), m_projection, glm::vec4(worldPosition, 1.0f)};
|
||||||
memcpy(m_mappedData[frameIndex], &data, sizeof(data));
|
memcpy(m_mappedData[frameIndex], &data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ namespace CosmicCore {
|
|||||||
|
|
||||||
ELightType type = ELightType::Directional;
|
ELightType type = ELightType::Directional;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
CLight(CEntity& entity, ELightType type = ELightType::Directional)
|
CLight(CEntity& entity, ELightType type = ELightType::Directional)
|
||||||
: CAbstractComponent(entity), type(type) {}
|
: CAbstractComponent(entity), type(type) {}
|
||||||
|
|
||||||
@@ -35,7 +37,25 @@ namespace CosmicCore {
|
|||||||
CLight(const CLight&) = delete;
|
CLight(const CLight&) = delete;
|
||||||
CLight& operator=(const CLight&) = delete;
|
CLight& operator=(const CLight&) = delete;
|
||||||
|
|
||||||
nlohmann::json to_json() const {
|
|
||||||
|
const glm::vec3& getColor() const {return color;};
|
||||||
|
float getRange(){return range;};
|
||||||
|
float getIntensity(){return intensity;};
|
||||||
|
float getInnerAngle(){return innerAngle;};
|
||||||
|
float getOuterAngle(){return outerAngle;};
|
||||||
|
float getAttenuation(){return attenuation;}
|
||||||
|
ELightType getType(){return type;}
|
||||||
|
|
||||||
|
void setColor(const glm::vec3& c) { color = c; }
|
||||||
|
void setRange(float r) { range = r; }
|
||||||
|
void setIntensity(float i) { intensity = i; }
|
||||||
|
void setInnerAngle(float angle) { innerAngle = angle; }
|
||||||
|
void setOuterAngle(float angle) { outerAngle = angle; }
|
||||||
|
void setAttenuation(float a) { attenuation = a; }
|
||||||
|
void setType(ELightType t) { type = t; }
|
||||||
|
void setCastShadow(bool shadow) { castShadow = shadow; }
|
||||||
|
|
||||||
|
nlohmann::json to_json() {
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
j["type"] = (int)type;
|
j["type"] = (int)type;
|
||||||
j["color"] = {color.r, color.g, color.b};
|
j["color"] = {color.r, color.g, color.b};
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "../../Utils/Factory/CEntityFactory.hpp"
|
#include "../../Utils/Factory/CEntityFactory.hpp"
|
||||||
#include "../../Utils/Factory/ComponentFactory.hpp"
|
#include "../../Utils/Factory/ComponentFactory.hpp"
|
||||||
|
|
||||||
|
#include "Core/Component/Light/CLight.hpp"
|
||||||
#include "glm/ext/vector_float3.hpp"
|
#include "glm/ext/vector_float3.hpp"
|
||||||
#include "glm/gtc/type_ptr.hpp"
|
#include "glm/gtc/type_ptr.hpp"
|
||||||
#include "nlohmann/json_fwd.hpp"
|
#include "nlohmann/json_fwd.hpp"
|
||||||
@@ -18,6 +19,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "../Systems/Graphics/Data/Light/CLightsBuffer.hpp"
|
||||||
namespace CosmicCore {
|
namespace CosmicCore {
|
||||||
|
|
||||||
CScene::CScene(std::string name) : CSerializable(),
|
CScene::CScene(std::string name) : CSerializable(),
|
||||||
@@ -29,6 +31,7 @@ namespace CosmicCore {
|
|||||||
m_tangibleWorld.initWorld();
|
m_tangibleWorld.initWorld();
|
||||||
m_audioWorld.initWorld();
|
m_audioWorld.initWorld();
|
||||||
m_scriptWorld.initWorld();
|
m_scriptWorld.initWorld();
|
||||||
|
m_lightsBuffer.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -58,6 +61,38 @@ namespace CosmicCore {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CScene::collectLights(vk::raii::CommandBuffer& cmd, uint32_t frameIndex) {
|
||||||
|
auto& registry = m_ecManager.registry;
|
||||||
|
auto view = registry.view<CLight, CTransform>();
|
||||||
|
|
||||||
|
SLightsUBOData lightsData{};
|
||||||
|
|
||||||
|
for (auto entity : view) {
|
||||||
|
if (lightsData.lightCount >= MAX_LIGHTS) break;
|
||||||
|
|
||||||
|
auto& light = registry.get<CLight>(entity);
|
||||||
|
auto& transform = registry.get<CTransform>(entity);
|
||||||
|
|
||||||
|
SLightData data{};
|
||||||
|
glm::vec3 pos = transform.getCenter();
|
||||||
|
glm::vec3 dir = transform.getOrientation() * glm::vec3(0, -1, 0);
|
||||||
|
|
||||||
|
data.position = {pos.x, pos.y, pos.z, (float)light.getType()};
|
||||||
|
data.direction = {dir.x, dir.y, dir.z, light.getRange()};
|
||||||
|
data.color = {light.getColor().x, light.getColor().y,
|
||||||
|
light.getColor().z, light.getIntensity()};
|
||||||
|
data.innerCosAngle = glm::cos(glm::radians(light.getInnerAngle()));
|
||||||
|
data.outerCosAngle = glm::cos(glm::radians(light.getOuterAngle()));
|
||||||
|
data.attenuation = light.getAttenuation();
|
||||||
|
|
||||||
|
lightsData.lights[lightsData.lightCount++] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// upload dans le SSBO
|
||||||
|
m_lightsBuffer.update(frameIndex, lightsData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CScene::render(vk::raii::CommandBuffer& cmd, uint32_t frameIndex){
|
void CScene::render(vk::raii::CommandBuffer& cmd, uint32_t frameIndex){
|
||||||
auto entities = m_ecManager.registry.view<CRenderer, CTransform>();
|
auto entities = m_ecManager.registry.view<CRenderer, CTransform>();
|
||||||
VulkanImpl* api = dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get());
|
VulkanImpl* api = dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get());
|
||||||
@@ -65,6 +100,8 @@ namespace CosmicCore {
|
|||||||
auto& camera = m_ecManager.registry.get<CCamera>(cam.front());
|
auto& camera = m_ecManager.registry.get<CCamera>(cam.front());
|
||||||
auto& transform = m_ecManager.registry.get<CTransform>(cam.front());
|
auto& transform = m_ecManager.registry.get<CTransform>(cam.front());
|
||||||
|
|
||||||
|
collectLights(cmd, frameIndex);
|
||||||
|
|
||||||
camera.updateUniformBuffer(frameIndex, transform);
|
camera.updateUniformBuffer(frameIndex, transform);
|
||||||
|
|
||||||
cmd.bindDescriptorSets(
|
cmd.bindDescriptorSets(
|
||||||
@@ -75,6 +112,12 @@ namespace CosmicCore {
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//bind lumières (set 3)
|
||||||
|
cmd.bindDescriptorSets(vk::PipelineBindPoint::eGraphics,
|
||||||
|
api->getDefaultPipelineLayout(), 3,
|
||||||
|
*m_lightsBuffer.getDescriptorSet(frameIndex), {});
|
||||||
|
|
||||||
|
|
||||||
for (auto& entity : entities) {
|
for (auto& entity : entities) {
|
||||||
auto model = m_ecManager.registry.get<CRenderer>(entity).getModel();
|
auto model = m_ecManager.registry.get<CRenderer>(entity).getModel();
|
||||||
auto& transform = m_ecManager.registry.get<CTransform>(entity);
|
auto& transform = m_ecManager.registry.get<CTransform>(entity);
|
||||||
@@ -147,6 +190,7 @@ namespace CosmicCore {
|
|||||||
nlohmann::json& renderer = components[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Component_Renderer)];
|
nlohmann::json& renderer = components[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Component_Renderer)];
|
||||||
nlohmann::json& speaker = components[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Component_Speaker)];
|
nlohmann::json& speaker = components[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Component_Speaker)];
|
||||||
nlohmann::json& script = components[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Component_Script)];
|
nlohmann::json& script = components[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Component_Script)];
|
||||||
|
nlohmann::json& light = components[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Component_Light)];
|
||||||
|
|
||||||
auto trConfig(!transform.is_null() ? std::optional<CosmicUtils::ComponentFactory::TransformConfig>({
|
auto trConfig(!transform.is_null() ? std::optional<CosmicUtils::ComponentFactory::TransformConfig>({
|
||||||
glm::make_vec3(transform[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Transform_Position)].get<std::vector<float>>().data()),
|
glm::make_vec3(transform[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Transform_Position)].get<std::vector<float>>().data()),
|
||||||
@@ -205,6 +249,18 @@ namespace CosmicCore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto lightConfig(!light.is_null() ? std::optional<CosmicUtils::ComponentFactory::LightConfig>(
|
||||||
|
{
|
||||||
|
static_cast<ELightType>(light[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Light_Type)].get<unsigned int>()),
|
||||||
|
glm::make_vec3(light[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Light_Color)].get<std::vector<float>>().data()),
|
||||||
|
light[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Light_Intensity)].get<float>(),
|
||||||
|
light[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Light_Range)].get<float>(),
|
||||||
|
light[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Light_Attenuation)].get<float>(),
|
||||||
|
light[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Light_InnerAngle)].get<float>(),
|
||||||
|
light[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Light_OuterAngle)].get<float>(),
|
||||||
|
light[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Light_CastShadow)].get<bool>()
|
||||||
|
}) : std::nullopt);
|
||||||
|
|
||||||
CosmicUtils::CEntityFactory::EntityConfig config = {
|
CosmicUtils::CEntityFactory::EntityConfig config = {
|
||||||
entityObj[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Entity_Name)],
|
entityObj[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Entity_Name)],
|
||||||
entityObj[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Entity_Description)],
|
entityObj[CosmicUtils::JsonKeyRegistry::key(CosmicUtils::EJsonKeys::Entity_Description)],
|
||||||
@@ -214,7 +270,8 @@ namespace CosmicCore {
|
|||||||
colliderConfig,
|
colliderConfig,
|
||||||
rigidbodyConfig,
|
rigidbodyConfig,
|
||||||
speakerConfig,
|
speakerConfig,
|
||||||
scriptConfig
|
scriptConfig,
|
||||||
|
lightConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
auto entityHandle = CosmicUtils::CEntityFactory::create(scene.get(), config);
|
auto entityHandle = CosmicUtils::CEntityFactory::create(scene.get(), config);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "../Systems/Physics/CTangibleWorld.hpp"
|
#include "../Systems/Physics/CTangibleWorld.hpp"
|
||||||
#include "../Systems/Audio/CAudioWorld.hpp"
|
#include "../Systems/Audio/CAudioWorld.hpp"
|
||||||
#include "../Systems/Scripts/CScriptWorld.hpp"
|
#include "../Systems/Scripts/CScriptWorld.hpp"
|
||||||
|
#include "Core/Systems/Graphics/Data/Light/CLightsBuffer.hpp"
|
||||||
|
|
||||||
namespace CosmicCore {
|
namespace CosmicCore {
|
||||||
class CEntity;
|
class CEntity;
|
||||||
@@ -19,6 +20,7 @@ namespace CosmicCore {
|
|||||||
CTangibleWorld m_tangibleWorld;
|
CTangibleWorld m_tangibleWorld;
|
||||||
CAudioWorld m_audioWorld;
|
CAudioWorld m_audioWorld;
|
||||||
CScriptWorld m_scriptWorld;
|
CScriptWorld m_scriptWorld;
|
||||||
|
CLightsBuffer m_lightsBuffer;
|
||||||
public:
|
public:
|
||||||
CScene() = delete;
|
CScene() = delete;
|
||||||
CScene(std::string name);
|
CScene(std::string name);
|
||||||
@@ -85,6 +87,7 @@ namespace CosmicCore {
|
|||||||
//unsigned int getMask();
|
//unsigned int getMask();
|
||||||
|
|
||||||
void render(vk::raii::CommandBuffer& cmd, uint32_t frameIndex);
|
void render(vk::raii::CommandBuffer& cmd, uint32_t frameIndex);
|
||||||
|
void collectLights(vk::raii::CommandBuffer& cmd, uint32_t frameIndex);
|
||||||
//void updateScript();
|
//void updateScript();
|
||||||
|
|
||||||
nlohmann::json to_json();
|
nlohmann::json to_json();
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ void VulkanImpl::cleanup(){
|
|||||||
cameraLayout = nullptr;
|
cameraLayout = nullptr;
|
||||||
transformLayout = nullptr;
|
transformLayout = nullptr;
|
||||||
materialLayout = nullptr;
|
materialLayout = nullptr;
|
||||||
|
lightLayout = nullptr;
|
||||||
|
|
||||||
VmaTotalStatistics stats;
|
VmaTotalStatistics stats;
|
||||||
vmaCalculateStatistics(allocator, &stats);
|
vmaCalculateStatistics(allocator, &stats);
|
||||||
@@ -587,7 +588,7 @@ void VulkanImpl::createDescriptorSetLayouts()
|
|||||||
0, // binding
|
0, // binding
|
||||||
vk::DescriptorType::eUniformBuffer, // type
|
vk::DescriptorType::eUniformBuffer, // type
|
||||||
1, // count
|
1, // count
|
||||||
vk::ShaderStageFlagBits::eVertex, // stage
|
vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment, // stage
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
cameraLayout = vk::raii::DescriptorSetLayout(
|
cameraLayout = vk::raii::DescriptorSetLayout(
|
||||||
@@ -621,10 +622,24 @@ void VulkanImpl::createDescriptorSetLayouts()
|
|||||||
materialBindings.data()}
|
materialBindings.data()}
|
||||||
);
|
);
|
||||||
|
|
||||||
std::array<vk::DescriptorSetLayout, 3> layouts{
|
//set 3 - Light : un storage buffer en fragmentshader
|
||||||
|
vk::DescriptorSetLayoutBinding lightBinding{
|
||||||
|
0,
|
||||||
|
vk::DescriptorType::eStorageBuffer,
|
||||||
|
1,
|
||||||
|
vk::ShaderStageFlagBits::eFragment,
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
lightLayout = vk::raii::DescriptorSetLayout(
|
||||||
|
device,
|
||||||
|
vk::DescriptorSetLayoutCreateInfo{{}, 1, &lightBinding}
|
||||||
|
);
|
||||||
|
|
||||||
|
std::array<vk::DescriptorSetLayout, 4> layouts{
|
||||||
*cameraLayout,
|
*cameraLayout,
|
||||||
*transformLayout,
|
*transformLayout,
|
||||||
*materialLayout
|
*materialLayout,
|
||||||
|
*lightLayout
|
||||||
};
|
};
|
||||||
vk::PipelineLayoutCreateInfo layoutInfo{{},
|
vk::PipelineLayoutCreateInfo layoutInfo{{},
|
||||||
static_cast<uint32_t>(layouts.size()),
|
static_cast<uint32_t>(layouts.size()),
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class DescriptorAllocator {
|
|||||||
std::vector<vk::DescriptorPoolSize> sizes = {
|
std::vector<vk::DescriptorPoolSize> sizes = {
|
||||||
{vk::DescriptorType::eUniformBuffer, size * 2},
|
{vk::DescriptorType::eUniformBuffer, size * 2},
|
||||||
{vk::DescriptorType::eCombinedImageSampler, size * 2},
|
{vk::DescriptorType::eCombinedImageSampler, size * 2},
|
||||||
|
{vk::DescriptorType::eStorageBuffer, size * 2},
|
||||||
};
|
};
|
||||||
Pool p;
|
Pool p;
|
||||||
p.capacity = size;
|
p.capacity = size;
|
||||||
@@ -136,6 +137,7 @@ class VulkanImpl: public GraphicsAPI{
|
|||||||
vk::raii::DescriptorSetLayout cameraLayout = nullptr; // set 0
|
vk::raii::DescriptorSetLayout cameraLayout = nullptr; // set 0
|
||||||
vk::raii::DescriptorSetLayout transformLayout = nullptr; // set 1
|
vk::raii::DescriptorSetLayout transformLayout = nullptr; // set 1
|
||||||
vk::raii::DescriptorSetLayout materialLayout = nullptr; // set 2
|
vk::raii::DescriptorSetLayout materialLayout = nullptr; // set 2
|
||||||
|
vk::raii::DescriptorSetLayout lightLayout = nullptr; // set 3
|
||||||
|
|
||||||
DescriptorAllocator descriptorPoolManager;
|
DescriptorAllocator descriptorPoolManager;
|
||||||
vk::raii::PipelineLayout defaultPipelineLayoutInfo = nullptr;
|
vk::raii::PipelineLayout defaultPipelineLayoutInfo = nullptr;
|
||||||
@@ -194,6 +196,7 @@ class VulkanImpl: public GraphicsAPI{
|
|||||||
vk::raii::DescriptorSetLayout& getCameraLayout() { return cameraLayout; }
|
vk::raii::DescriptorSetLayout& getCameraLayout() { return cameraLayout; }
|
||||||
vk::raii::DescriptorSetLayout& getTransformLayout() { return transformLayout; }
|
vk::raii::DescriptorSetLayout& getTransformLayout() { return transformLayout; }
|
||||||
vk::raii::DescriptorSetLayout& getMaterialLayout() { return materialLayout; }
|
vk::raii::DescriptorSetLayout& getMaterialLayout() { return materialLayout; }
|
||||||
|
vk::raii::DescriptorSetLayout& getLightLayout() { return lightLayout; }
|
||||||
|
|
||||||
vk::raii::ImageView createImageView(vk::raii::Image& image, vk::Format format, vk::ImageAspectFlags aspectFlags);
|
vk::raii::ImageView createImageView(vk::raii::Image& image, vk::Format format, vk::ImageAspectFlags aspectFlags);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#include "CLightsBuffer.hpp"
|
||||||
|
#include "Core/Systems/Graphics/API/VulkanImplementation/VulkanImpl.hpp"
|
||||||
|
|
||||||
|
namespace CosmicCore {
|
||||||
|
void CLightsBuffer::init() {
|
||||||
|
VulkanImpl* api = dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get());
|
||||||
|
auto* device = static_cast<vk::raii::Device*>(api->getDevice());
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||||
|
// SSBO
|
||||||
|
VkBufferCreateInfo bufferInfo{};
|
||||||
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
bufferInfo.size = sizeof(SLightsUBOData);
|
||||||
|
bufferInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo allocInfo{};
|
||||||
|
allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
|
||||||
|
allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||||
|
|
||||||
|
VmaAllocationInfo info{};
|
||||||
|
vmaCreateBuffer(api->getAllocator(), &bufferInfo, &allocInfo,
|
||||||
|
&m_buffers[i].buffer,
|
||||||
|
&m_buffers[i].allocation,
|
||||||
|
&info);
|
||||||
|
m_mappedData[i] = info.pMappedData;
|
||||||
|
|
||||||
|
// descriptor set (set 3)
|
||||||
|
m_descriptorSets[i] = api->getDescriptorPoolManager().allocate(
|
||||||
|
*api->getLightLayout()
|
||||||
|
);
|
||||||
|
|
||||||
|
vk::DescriptorBufferInfo descriptorBufferInfo{
|
||||||
|
vk::Buffer(m_buffers[i].buffer),
|
||||||
|
0,
|
||||||
|
sizeof(SLightsUBOData)
|
||||||
|
};
|
||||||
|
vk::WriteDescriptorSet descriptorWrite{
|
||||||
|
*m_descriptorSets[i].set,
|
||||||
|
0, 0, 1,
|
||||||
|
vk::DescriptorType::eStorageBuffer,
|
||||||
|
{}, &descriptorBufferInfo
|
||||||
|
};
|
||||||
|
device->updateDescriptorSets(descriptorWrite, {});
|
||||||
|
}
|
||||||
|
m_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLightsBuffer::update(uint32_t frameIndex, const SLightsUBOData& data) {
|
||||||
|
if (!m_initialized) return;
|
||||||
|
memcpy(m_mappedData[frameIndex], &data, sizeof(SLightsUBOData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLightsBuffer::destroy() {
|
||||||
|
if (!m_initialized) return;
|
||||||
|
VulkanImpl* api = dynamic_cast<VulkanImpl*>(GraphicsAPI::getAPI().get());
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||||
|
api->getDeletionQueue().push(api->getCurrentFrameIndex(),
|
||||||
|
[alloc = api->getAllocator(),
|
||||||
|
buf = m_buffers[i].buffer,
|
||||||
|
mem = m_buffers[i].allocation]() {
|
||||||
|
vmaDestroyBuffer(alloc, buf, mem);
|
||||||
|
});
|
||||||
|
api->destroyDescriptorSet(m_descriptorSets[i],
|
||||||
|
api->getCurrentFrameIndex());
|
||||||
|
}
|
||||||
|
m_initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::raii::DescriptorSet& CLightsBuffer::getDescriptorSet(uint32_t frameIndex) {
|
||||||
|
return m_descriptorSets[frameIndex].set;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// CLightsBuffer.hpp
|
||||||
|
#ifndef CLIGHTSBUFFER_HPP
|
||||||
|
#define CLIGHTSBUFFER_HPP
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "../../API/VulkanImplementation/VMABuffer.hpp"
|
||||||
|
#include "../../API/VulkanImplementation/ManagedDescriptorSet.hpp"
|
||||||
|
|
||||||
|
constexpr uint32_t MAX_LIGHTS = 32;
|
||||||
|
|
||||||
|
namespace CosmicCore {
|
||||||
|
|
||||||
|
struct SLightData {
|
||||||
|
glm::vec4 position; // xyz = pos, w = type (0=dir, 1=point, 2=spot)
|
||||||
|
glm::vec4 direction; // xyz = dir, w = range
|
||||||
|
glm::vec4 color; // xyz = color, w = intensity
|
||||||
|
float innerCosAngle;
|
||||||
|
float outerCosAngle;
|
||||||
|
float attenuation;
|
||||||
|
float padding; // alignement 16 bytes
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SLightsUBOData {
|
||||||
|
SLightData lights[MAX_LIGHTS];
|
||||||
|
int lightCount = 0;
|
||||||
|
glm::vec3 padding;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CLightsBuffer {
|
||||||
|
std::array<VMABuffer, MAX_FRAMES_IN_FLIGHT> m_buffers;
|
||||||
|
std::array<void*, MAX_FRAMES_IN_FLIGHT> m_mappedData{};
|
||||||
|
std::array<ManagedDescriptorSet, MAX_FRAMES_IN_FLIGHT> m_descriptorSets;
|
||||||
|
bool m_initialized = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CLightsBuffer() = default;
|
||||||
|
~CLightsBuffer() { destroy(); }
|
||||||
|
|
||||||
|
CLightsBuffer(const CLightsBuffer&) = delete;
|
||||||
|
CLightsBuffer& operator=(const CLightsBuffer&) = delete;
|
||||||
|
CLightsBuffer(CLightsBuffer&&) = default;
|
||||||
|
CLightsBuffer& operator=(CLightsBuffer&&) = default;
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void update(uint32_t frameIndex, const SLightsUBOData& data);
|
||||||
|
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
vk::raii::DescriptorSet& getDescriptorSet(uint32_t frameIndex);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace CosmicCore
|
||||||
|
#endif
|
||||||
@@ -40,13 +40,14 @@ void CMaterial::build()
|
|||||||
vk::DynamicState::eScissor};
|
vk::DynamicState::eScissor};
|
||||||
vk::PipelineDynamicStateCreateInfo dynamicState{{}, static_cast<uint32_t>(dynamicStates.size()), dynamicStates.data()};
|
vk::PipelineDynamicStateCreateInfo dynamicState{{}, static_cast<uint32_t>(dynamicStates.size()), dynamicStates.data()};
|
||||||
|
|
||||||
std::array<vk::DescriptorSetLayout, 3> layouts{
|
std::array<vk::DescriptorSetLayout, 4> layouts{
|
||||||
*api->getCameraLayout(), // set 0
|
*api->getCameraLayout(), // set 0
|
||||||
*api->getTransformLayout(), // set 1
|
*api->getTransformLayout(), // set 1
|
||||||
*api->getMaterialLayout() // set 2
|
*api->getMaterialLayout(), // set 2
|
||||||
|
*api->getLightLayout() //set 3
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::PipelineLayoutCreateInfo pipelineLayoutInfo{{},3,layouts.data(), 0};
|
vk::PipelineLayoutCreateInfo pipelineLayoutInfo{{},4,layouts.data(), 0};
|
||||||
|
|
||||||
pipelineLayout = vk::raii::PipelineLayout(*static_cast<vk::raii::Device*>(api->getDevice()), pipelineLayoutInfo);
|
pipelineLayout = vk::raii::PipelineLayout(*static_cast<vk::raii::Device*>(api->getDevice()), pipelineLayoutInfo);
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ namespace CosmicCore {
|
|||||||
static InputAction registerAction(const std::string& name);
|
static InputAction registerAction(const std::string& name);
|
||||||
|
|
||||||
static std::optional<InputAction> getAction(const std::string& name) {
|
static std::optional<InputAction> getAction(const std::string& name) {
|
||||||
std::cout << &m_nameToId << std::endl;
|
|
||||||
return (m_nameToId.find(name) != m_nameToId.end() ? std::optional<InputAction>(m_nameToId[name]) : std::nullopt);};
|
return (m_nameToId.find(name) != m_nameToId.end() ? std::optional<InputAction>(m_nameToId[name]) : std::nullopt);};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ CEntity create(CScene* scene, EntityConfig& config) {
|
|||||||
auto& renderer = config.rendererConfig;
|
auto& renderer = config.rendererConfig;
|
||||||
auto& speaker = config.speakerConfig;
|
auto& speaker = config.speakerConfig;
|
||||||
auto& script = config.scriptConfig;
|
auto& script = config.scriptConfig;
|
||||||
|
auto& light = config.lightConfig;
|
||||||
auto& relationship = config.relationshipConfig;
|
auto& relationship = config.relationshipConfig;
|
||||||
|
|
||||||
if(transform.has_value())
|
if(transform.has_value())
|
||||||
@@ -47,6 +48,11 @@ CEntity create(CScene* scene, EntityConfig& config) {
|
|||||||
ComponentFactory::addScript(entity, *script);
|
ComponentFactory::addScript(entity, *script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(light.has_value())
|
||||||
|
{
|
||||||
|
ComponentFactory::addLight(entity, *light);
|
||||||
|
}
|
||||||
|
|
||||||
if(relationship.has_value())
|
if(relationship.has_value())
|
||||||
{
|
{
|
||||||
ComponentFactory::addRelationship(entity, *relationship);
|
ComponentFactory::addRelationship(entity, *relationship);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "../../Core/Scene/CScene.hpp"
|
#include "../../Core/Scene/CScene.hpp"
|
||||||
#include "../../Core/Entity/CEntity.hpp"
|
#include "../../Core/Entity/CEntity.hpp"
|
||||||
#include "ComponentFactory.hpp"
|
#include "ComponentFactory.hpp"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace CosmicUtils {
|
namespace CosmicUtils {
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ namespace CosmicUtils {
|
|||||||
std::optional<RigidBodyConfig> rigidBodyConfig = std::nullopt;
|
std::optional<RigidBodyConfig> rigidBodyConfig = std::nullopt;
|
||||||
std::optional<SpeakerConfig> speakerConfig = std::nullopt;
|
std::optional<SpeakerConfig> speakerConfig = std::nullopt;
|
||||||
std::optional<ScriptConfig> scriptConfig = std::nullopt;
|
std::optional<ScriptConfig> scriptConfig = std::nullopt;
|
||||||
|
std::optional<LightConfig> lightConfig = std::nullopt;
|
||||||
std::optional<RelationshipConfig> relationshipConfig = std::nullopt;
|
std::optional<RelationshipConfig> relationshipConfig = std::nullopt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "ComponentFactory.hpp"
|
#include "ComponentFactory.hpp"
|
||||||
#include "../../Core/Systems/Graphics/Data/CModelLoader.hpp"
|
#include "../../Core/Systems/Graphics/Data/CModelLoader.hpp"
|
||||||
#include "../../Core/Systems/Resources/API/CResourceAPI.hpp"
|
#include "../../Core/Systems/Resources/API/CResourceAPI.hpp"
|
||||||
|
#include "Core/Component/Light/CLight.hpp"
|
||||||
|
|
||||||
namespace CosmicUtils {
|
namespace CosmicUtils {
|
||||||
|
|
||||||
@@ -167,5 +168,25 @@ namespace CosmicUtils {
|
|||||||
return scriptMan;
|
return scriptMan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLight& addLight(CEntity& entity, LightConfig& lightConfig)
|
||||||
|
{
|
||||||
|
auto& rm = CResourceAPI::resources();
|
||||||
|
auto& reg = entity.getRegistry();
|
||||||
|
if (!reg.registry.all_of<CTransform>(*entity))
|
||||||
|
throw std::runtime_error("addLight requires a CTransform on the entity");
|
||||||
|
|
||||||
|
auto& light = reg.registry.emplace<CLight>(*entity, entity);
|
||||||
|
light.setType(lightConfig.type);
|
||||||
|
light.setColor(lightConfig.color);
|
||||||
|
light.setAttenuation(lightConfig.attenuation);
|
||||||
|
light.setInnerAngle(lightConfig.innerAngle);
|
||||||
|
light.setRange(lightConfig.range);
|
||||||
|
light.setOuterAngle(lightConfig.outerAngle);
|
||||||
|
light.setIntensity(lightConfig.intensity);
|
||||||
|
light.setCastShadow(lightConfig.castShadow);
|
||||||
|
return light;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,9 @@
|
|||||||
#include "../../Core/Component/Meta/CMetaData.hpp"
|
#include "../../Core/Component/Meta/CMetaData.hpp"
|
||||||
#include "../../Core/Component/Speaker/CSpeaker.hpp"
|
#include "../../Core/Component/Speaker/CSpeaker.hpp"
|
||||||
#include "../../Core/Component/Relationships/CRelationship.hpp"
|
#include "../../Core/Component/Relationships/CRelationship.hpp"
|
||||||
|
#include "Core/Component/Light/CLight.hpp"
|
||||||
#include "Core/Component/Script/CScriptManager.hpp"
|
#include "Core/Component/Script/CScriptManager.hpp"
|
||||||
|
#include "glm/ext/vector_float3.hpp"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -71,6 +73,18 @@ namespace CosmicUtils {
|
|||||||
std::vector<std::string> scriptNames;
|
std::vector<std::string> scriptNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LightConfig{
|
||||||
|
ELightType type = ELightType::Directional;
|
||||||
|
glm::vec3 color = {1.0f, 1.0f, 1.0f};
|
||||||
|
float intensity = 1.0f;
|
||||||
|
float range = 10.0f;
|
||||||
|
float attenuation = 1.0f;
|
||||||
|
float innerAngle = 15.0f;
|
||||||
|
float outerAngle = 30.0f;
|
||||||
|
bool castShadow = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// crée et initialise un CTransform sur une entité existante
|
// crée et initialise un CTransform sur une entité existante
|
||||||
CTransform& addTransform(CEntity& entity, TransformConfig& transformConfig);
|
CTransform& addTransform(CEntity& entity, TransformConfig& transformConfig);
|
||||||
|
|
||||||
@@ -94,6 +108,7 @@ namespace CosmicUtils {
|
|||||||
|
|
||||||
CScriptManager& addScript(CEntity& entity, ScriptConfig& scriptConfig);
|
CScriptManager& addScript(CEntity& entity, ScriptConfig& scriptConfig);
|
||||||
|
|
||||||
|
CLight& addLight(CEntity& entity, LightConfig& lightConfig);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ namespace CosmicUtils {
|
|||||||
Component_Rigidbody = 2065,
|
Component_Rigidbody = 2065,
|
||||||
Component_Speaker = 2066,
|
Component_Speaker = 2066,
|
||||||
Component_Script = 2067,
|
Component_Script = 2067,
|
||||||
|
Component_Light = 2068,
|
||||||
|
|
||||||
// Transform
|
// Transform
|
||||||
Transform_Position = 3011,
|
Transform_Position = 3011,
|
||||||
@@ -66,7 +67,17 @@ namespace CosmicUtils {
|
|||||||
Speaker_Gain = 30612,
|
Speaker_Gain = 30612,
|
||||||
Speaker_Pitch = 30613,
|
Speaker_Pitch = 30613,
|
||||||
Speaker_Loop = 30614,
|
Speaker_Loop = 30614,
|
||||||
Speaker_Spatial = 30615
|
Speaker_Spatial = 30615,
|
||||||
|
|
||||||
|
// Speaker
|
||||||
|
Light_Type = 3071,
|
||||||
|
Light_Color = 3072,
|
||||||
|
Light_Intensity = 3073,
|
||||||
|
Light_Range = 3074,
|
||||||
|
Light_Attenuation = 3075,
|
||||||
|
Light_InnerAngle = 3076,
|
||||||
|
Light_OuterAngle = 3077,
|
||||||
|
Light_CastShadow = 3078
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user