// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
#if COMPILE_WITH_GPU_PARTICLES
#include "Engine/Core/Collections/Array.h"
#include "Engine/Graphics/Materials/MaterialParams.h"
// Forward declarations
class MemoryReadStream;
class ParticleEmitterInstance;
class ParticleEffect;
class ParticleEmitter;
class GPUContext;
class GPUBuffer;
class GPUShader;
class GPUShaderProgramCS;
///
/// The GPU particles execution utility.
///
class GPUParticles
{
private:
GPUShader* _shader = nullptr;
GPUShaderProgramCS* _mainCS = nullptr;
Array _cbData;
MaterialParams _params;
public:
///
/// The custom data size (in bytes) required by the nodes to store the additional global state for the simulation in the particles buffer on a GPU.
///
int32 CustomDataSize;
///
/// Determines whether this instance is initialized.
///
/// true if this instance is initialized; otherwise, false.
FORCE_INLINE bool IsInitialized() const
{
return _shader != nullptr;
}
///
/// Initializes the GPU particles simulation runtime.
///
/// The owning emitter.
/// The stream with the compiled shader data.
/// The stream with the parameters data.
/// The custom data size (in bytes) required by the nodes to store the additional global state for the simulation in the particles buffer on a GPU.
/// True if failed, otherwise false.
bool Init(ParticleEmitter* owner, MemoryReadStream& shaderCacheStream, ReadStream* materialParamsStream, int32 customDataSize);
///
/// Releases the resources.
///
void Dispose();
///
/// Updates the particles simulation (the GPU simulation). The actual simulation is performed during Execute during rendering. This method accumulates the simulation delta time and other properties.
///
/// The owning emitter.
/// The instance effect.
/// The instance data.
/// The delta time (in seconds).
/// True if can spawn new particles, otherwise will just perform an update.
void Update(ParticleEmitter* emitter, ParticleEffect* effect, ParticleEmitterInstance& data, float dt, bool canSpawn);
///
/// Copies the GPU particles count from the particles data on a GPU to another GPU buffer (counter value is uint32).
///
/// The GPU context that supports Compute.
/// The owning emitter.
/// The instance effect.
/// The instance data.
/// The destination buffer to copy the counter (uint32).
/// The destination buffer offset from start (in bytes) to copy the counter (uint32).
void CopyParticlesCount(GPUContext* context, ParticleEmitter* emitter, ParticleEffect* effect, ParticleEmitterInstance& data, GPUBuffer* dstBuffer, uint32 dstOffset);
///
/// Performs the GPU particles simulation update using the graphics device.
///
/// The GPU context that supports Compute.
/// The owning emitter.
/// The instance effect.
/// The index of the emitter in the particle system.
/// The instance data.
void Execute(GPUContext* context, ParticleEmitter* emitter, ParticleEffect* effect, int32 emitterIndex, ParticleEmitterInstance& data);
};
#endif