init
This commit is contained in:
85
engine/include/hd2d/Particles.h
Normal file
85
engine/include/hd2d/Particles.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
#include "hd2d/GL.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
|
||||
namespace hd2d {
|
||||
|
||||
struct PointLight;
|
||||
|
||||
// High-resolution (non pixel-art) particles: ambient fields (fireflies, dust),
|
||||
// fire emitters (flames, embers, smoke, glow + flickering light) and bursts.
|
||||
class ParticleSystem {
|
||||
public:
|
||||
// Must match the kind ids in particles.vert / particles.frag.
|
||||
enum class Kind : int {
|
||||
Firefly = 0, // blinking emissive glow, wanders near the ground
|
||||
Mote = 1, // dust speck only visible where sunlight hits it (god rays)
|
||||
Spark = 2, // ballistic burst particle (footstep dust, rain splashes, ...)
|
||||
Flame = 3, // additive tongue of fire, eroded by noise as it ages
|
||||
Ember = 4, // tiny hot spark drifting up on turbulent air
|
||||
Smoke = 5, // alpha-blended puff rising above a fire
|
||||
Glow = 6, // large soft halo around a fire (one per emitter per frame)
|
||||
};
|
||||
|
||||
struct Field { // region that keeps a constant population of ambient particles
|
||||
Kind kind;
|
||||
glm::vec3 min, max;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct Fire {
|
||||
glm::vec3 pos; // base of the flames
|
||||
float scale = 1.0f; // overall size / intensity
|
||||
float flameAccum = 0.0f, emberAccum = 0.0f, smokeAccum = 0.0f;
|
||||
float flicker = 1.0f; // current light flicker multiplier
|
||||
float phase = 0.0f;
|
||||
};
|
||||
|
||||
~ParticleSystem();
|
||||
void addField(Kind kind, glm::vec3 min, glm::vec3 max, int count);
|
||||
int addFire(glm::vec3 pos, float scale = 1.0f);
|
||||
void burst(glm::vec3 pos, int count, glm::vec3 color, float speed, float size, float life);
|
||||
void update(float dt, float time);
|
||||
void draw() const;
|
||||
// Appends fire lights first, then up to `maxFireflies` firefly lights.
|
||||
void collectLights(std::vector<PointLight>& out, int maxFireflies) const;
|
||||
const std::vector<Fire>& fires() const { return fires_; }
|
||||
|
||||
glm::vec3 fireflyColor{2.6f, 3.2f, 0.9f};
|
||||
glm::vec3 moteColor{1.0f, 0.95f, 0.8f};
|
||||
float fireflyLightRadius = 2.2f;
|
||||
glm::vec3 fireLightColor{4.0f, 1.75f, 0.55f};
|
||||
float fireLightRadius = 7.0f;
|
||||
glm::vec3 wind{0.0f}; // world-space drift applied to smoke and embers
|
||||
float ambientFade = 1.0f; // scales fireflies + motes (Weather lowers it in rain)
|
||||
|
||||
private:
|
||||
struct Particle {
|
||||
glm::vec3 pos, vel;
|
||||
glm::vec3 color;
|
||||
float size, age, life, phase;
|
||||
Kind kind;
|
||||
int field; // ambient field index, or -1
|
||||
int fire; // owning fire, or -1
|
||||
};
|
||||
struct GpuParticle {
|
||||
glm::vec4 posSize;
|
||||
glm::vec4 color; // rgb, a = alpha
|
||||
glm::vec4 params; // x = kind, y = age / life, z = random seed
|
||||
};
|
||||
void spawnInField(Particle& p, int fieldIndex, bool randomAge);
|
||||
void spawnFire(const Fire& f, int fireIndex, Kind kind);
|
||||
|
||||
std::vector<Field> fields_;
|
||||
std::vector<Fire> fires_;
|
||||
std::vector<Particle> particles_;
|
||||
std::vector<GpuParticle> gpu_;
|
||||
std::mt19937 rng_{1337};
|
||||
GLuint vao_ = 0, vbo_ = 0;
|
||||
size_t capacity_ = 0;
|
||||
};
|
||||
|
||||
} // namespace hd2d
|
||||
Reference in New Issue
Block a user