diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp index 85559bc7..2613c832 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp @@ -59,6 +59,12 @@ namespace SHADE {SHPredefinedDescriptorTypes::STATIC_DATA, 0}, {SHPredefinedDescriptorTypes::CAMERA, 1}, }); + + perSystemData[SHUtilities::ConvertEnum(SystemType::PARTICLE_RENEDERING)].descMappings.AddMappings + ({ + {SHPredefinedDescriptorTypes::STATIC_DATA, 0}, + {SHPredefinedDescriptorTypes::CAMERA, 1}, + }); } void SHGraphicsPredefinedData::InitDummyPipelineLayouts(Handle logicalDevice) noexcept @@ -235,6 +241,12 @@ namespace SHADE SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA | SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA ); + + perSystemData[SHUtilities::ConvertEnum(SystemType::PARTICLE_RENEDERING)].descSetLayouts = GetPredefinedDescSetLayouts + ( + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA | + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA + ); } void SHGraphicsPredefinedData::InitPredefinedVertexInputState(void) noexcept diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h index 77307f57..80af6c30 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h @@ -39,6 +39,7 @@ namespace SHADE TEXT_RENDERING, RENDER_GRAPH_NODE_COMPUTE, TRAJECTORY_RENDERING, + PARTICLE_RENEDERING, NUM_TYPES }; static constexpr int SYSTEM_TYPE_COUNT = static_cast(SystemType::NUM_TYPES); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp new file mode 100644 index 00000000..1c7e5a9c --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp @@ -0,0 +1,23 @@ +#include "SHParticleEmitterComponent.h" + +namespace SHADE +{ + + void SHParticleEmitterComponent::OnCreate(void) + { + timeBeforeEmission = emissionInterval; + + // initialize all buffers here + } + + void SHParticleEmitterComponent::OnDestroy(void) + { + + } + + void SHParticleEmitterComponent::Emit(void) noexcept + { + + } + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h new file mode 100644 index 00000000..7f6787aa --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h @@ -0,0 +1,95 @@ +#pragma once + +#include "Resource/SHHandle.h" +#include "Math/Vector/SHVec4.h" +#include "ECS_Base/Components/SHComponent.h" + +namespace SHADE +{ + class SHVkBuffer; + + class SHParticleEmitterComponent : public SHComponent + { + private: + struct GPUEmitterStruct + { + //! Minimum emitting angular range + SHVec4 angularMin; + + //! Maximum emitting angular range + SHVec4 angularMax; + + //! Spawn lifetime and size range (min and max) + SHVec4 lifeAndSizeRange; + }; + + struct GPUParticleStruct + { + //! Position of the particle + SHVec4 position; + + //! Rotation of the particle + SHVec4 rotation; + + //! Velocity of the particle + SHVec4 velocity; + + //! Acceleration of the particle + SHVec4 acceleration; + + //! Scale of the texture + float scale; + + //! Life of the particle + float life; + + //! life decay rate + float lifeDecayRate; + + //! Texture into the desc array that the particle is using + uint32_t textureIndex; + }; + + //! Max number of particles of this emitter + uint32_t maxParticles; + + //! emission count per emit + uint32_t emissionCount; + + //! emission interval of the emitter + float emissionInterval; + + //! Counter that decreases to 0 from emissionInterval. When 0, emit particles. + float timeBeforeEmission; + + //! Data for the emitter + Handle emitterData; + + //! GPU Particle data + Handle particleData; + + //! Freelist data + Handle freelistData; + + //! Freelist data + Handle indicesData; + + //! Freelist data + Handle drawCallData; + + //! Emitter's data on the CPU side. To be copied to GPU. + GPUEmitterStruct emitterDataCPU; + + //! If passive, emitter emits particles based on timer above. + bool isPassive; + + public: + void OnCreate(void) override final; + void OnDestroy(void) override final; + + void Emit (void) noexcept; + + friend class SHParticleSubSystem; + + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSustem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSustem.cpp new file mode 100644 index 00000000..7e2f5115 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSustem.cpp @@ -0,0 +1,84 @@ +#include "SHpch.h" +#include "SHParticleSubSustem.h" +#include "Graphics/Pipeline/SHPipelineLayoutParams.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h" +#include "ECS_Base/Managers/SHComponentManager.h" + +namespace SHADE +{ + + void SHParticleSubSystem::Init(Handle device, Handle compatibleRenderpass, Handle subpass, Handle VS, Handle FS, Handle emitCS, Handle defaultUpdateCS) noexcept + { + /*-----------------------------------------------------------------------*/ + /* INITIALIZE ALL PIPELINES */ + /*-----------------------------------------------------------------------*/ + SHPipelineLayoutParams plParams + { + .shaderModules = {VS, FS}, + .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING).descSetLayouts + }; + + renderingPipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(plParams); + renderingPipelineData.pipeline = logicalDevice->CreateGraphicsPipeline(renderingPipelineData.pipelineLayout, nullptr, compatibleRenderpass, subpass); + + SHPipelineLayoutParams emitPlParams + { + .shaderModules = {emitCS}, + .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING).descSetLayouts + }; + + emittingPipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(emitPlParams); + emittingPipelineData.pipeline = logicalDevice->CreateComputePipeline(emittingPipelineData.pipelineLayout); + + SHPipelineLayoutParams defaultUpdatePlParams + { + .shaderModules = {defaultUpdateCS}, + .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING).descSetLayouts + }; + + defaultUpdatePipelineData.pipelineLayout = logicalDevice->CreatePipelineLayout(defaultUpdatePlParams); + defaultUpdatePipelineData.pipeline = logicalDevice->CreateComputePipeline(defaultUpdatePipelineData.pipelineLayout); + + /*-----------------------------------------------------------------------*/ + /* OTHER INITIALIZATION */ + /*-----------------------------------------------------------------------*/ + SHComponentManager::CreateComponentSparseSet(); + } + + void SHParticleSubSystem::Run(Handle cmdBuffer, uint32_t frameIndex, float dt) noexcept + { + auto& emitters = SHComponentManager::GetDense(); + + for (auto& emitter : emitters) + { + // Emit emitters here if there are ready to be emitted + if (emitter.isPassive) + { + // decrement emission timer + emitter.timeBeforeEmission -= dt; + + // Check if time to emit + if (emitter.timeBeforeEmission <= 0.0f) + { + // reset timer + emitter.timeBeforeEmission = emitter.emissionInterval; + + // Call dispatch here to emit particles + } + } + } + } + + void SHParticleSubSystem::Render(Handle cmdBuffer, Handle renderer, uint32_t frameIndex) noexcept + { + auto& emitters = SHComponentManager::GetDense(); + } + + void SHParticleSubSystem::Exit(void) noexcept + { + + } + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSustem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSustem.h index da806480..44e34237 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSustem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSustem.h @@ -25,14 +25,37 @@ namespace SHADE class SHParticleSubSystem { private: + // To hold data for a pipeline and pipeline layout. + // We want this here because particles require 3 pipeline sets: + // - Rendering + // - Emit Compute + // - Update Compute + struct PipelineData + { + //! Pipeline + Handle pipeline; + //! Pipeline layout for pipeline creation + Handle pipelineLayout; + }; + + //! Logical device for creation and destruction Handle logicalDevice; + //! Pipeline data for rendering particles + PipelineData renderingPipelineData; + + //! Pipeline data for emitting particles + PipelineData emittingPipelineData; + + //! Pipeline data for updating particles + PipelineData defaultUpdatePipelineData; + public: - void Init(Handle device, Handle compatibleRenderpass, Handle subpass) noexcept; + void Init(Handle device, Handle compatibleRenderpass, Handle subpass, Handle VS, Handle FS, Handle emitCS, Handle defaultUpdateCS) noexcept; - void Run(uint32_t frameIndex) noexcept; + void Run(Handle cmdBuffer, uint32_t frameIndex, float dt) noexcept; void Render(Handle cmdBuffer, Handle renderer, uint32_t frameIndex) noexcept; void Exit(void) noexcept; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp deleted file mode 100644 index eb3c4f1a..00000000 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "SHpch.h" -#include "SHParticleSubSustem.h" - -namespace SHADE -{ - -} \ No newline at end of file