diff options
| author | jaroWMR <jarorutjes07@gmail.com> | 2024-10-07 18:07:17 +0200 | 
|---|---|---|
| committer | jaroWMR <jarorutjes07@gmail.com> | 2024-10-07 18:07:17 +0200 | 
| commit | 5f84969c851530ebc430be2cf8e99c945ff7a4a7 (patch) | |
| tree | 9fcd2755dbfd456f20f0ad37c18c7281b81382b1 | |
| parent | 5cf5cf64d6f9597849ed5558da4f1bc201165fed (diff) | |
improved particle system from 90ms to ~ 0.7ms
| -rw-r--r-- | src/crepe/Particle.cpp | 19 | ||||
| -rw-r--r-- | src/crepe/Particle.hpp | 12 | ||||
| -rw-r--r-- | src/crepe/ParticleEmitter.cpp | 17 | ||||
| -rw-r--r-- | src/crepe/ParticleEmitter.hpp | 8 | ||||
| -rw-r--r-- | src/crepe/ParticleSystem.cpp | 42 | ||||
| -rw-r--r-- | src/crepe/SDLApp.cpp | 9 | ||||
| -rw-r--r-- | src/crepe/SDLApp.hpp | 5 | ||||
| -rw-r--r-- | src/crepe/main.cpp | 15 | 
8 files changed, 92 insertions, 35 deletions
| diff --git a/src/crepe/Particle.cpp b/src/crepe/Particle.cpp index 3254b5b..8cf7f7e 100644 --- a/src/crepe/Particle.cpp +++ b/src/crepe/Particle.cpp @@ -1,16 +1,23 @@  #include "Particle.hpp"  #include <iostream> -Particle::Particle(float lifespan, Position position, Position velocity) -    : lifespan(lifespan), position(position), velocity(velocity), timeInLife(0.0f) {} +Particle::Particle() +{ +    this->active = false; +} + +void Particle::reset(float lifespan, Position position, Position velocity) { +    this->timeInLife = 0; +    this->lifespan = lifespan; +    this->position = position; +    this->velocity = velocity; +    this->active = true; +}  void Particle::update(float deltaTime) {      timeInLife += deltaTime;      position.x += velocity.x * deltaTime;      position.y += velocity.y * deltaTime; +    if(timeInLife >= lifespan)this->active = false;  } -bool Particle::isAlive() const { -    std::cout << "lifespan" << lifespan << std::endl; -    return timeInLife < lifespan; -} diff --git a/src/crepe/Particle.hpp b/src/crepe/Particle.hpp index f71fd67..669a8ab 100644 --- a/src/crepe/Particle.hpp +++ b/src/crepe/Particle.hpp @@ -1,18 +1,20 @@  #pragma once -class Particle { -public: -    struct Position { +struct Position {          float x;          float y;      }; +class Particle { +public: +      Position position;      Position velocity;      float lifespan; +    bool active; -    Particle(float lifespan, Position position, Position velocity); +    Particle(); +    void reset(float lifespan, Position position, Position velocity);      void update(float deltaTime); -    bool isAlive() const;      float timeInLife;  }; diff --git a/src/crepe/ParticleEmitter.cpp b/src/crepe/ParticleEmitter.cpp index f5c18db..3c9cc4e 100644 --- a/src/crepe/ParticleEmitter.cpp +++ b/src/crepe/ParticleEmitter.cpp @@ -1,11 +1,24 @@  #include "ParticleEmitter.hpp"  #include <ctime> +#include "Particle.hpp" +#include <iostream>  ParticleEmitter::ParticleEmitter(unsigned int maxParticles, unsigned int emissionRate, unsigned int speed, unsigned int speedOffset, unsigned int angle, unsigned int angleOffset, float m_beginLifespan, float m_endLifespan)      : m_maxParticles(maxParticles), m_emissionRate(emissionRate), m_speed(speed), m_speedOffset(speedOffset), m_position{0, 0}, m_beginLifespan(m_beginLifespan),m_endLifespan(m_endLifespan) {      std::srand(static_cast<unsigned int>(std::time(nullptr))); // initialize random seed - +    std::cout << "Create emitter" << std::endl;      m_minAngle = (360 + angle - (angleOffset % 360)) % 360; // calculate minAngle      m_maxAngle = (360 + angle + (angleOffset % 360)) % 360; // calculate maxAngle +    for (size_t i = 0; i < m_maxParticles; i++) +    { +        this->particles.emplace_back(); +    } +     +} -}
\ No newline at end of file +ParticleEmitter::~ParticleEmitter() { +    std::vector<Particle>::iterator it = this->particles.begin(); +        while (it != this->particles.end()) { +            it = this->particles.erase(it); +        } +} diff --git a/src/crepe/ParticleEmitter.hpp b/src/crepe/ParticleEmitter.hpp index f647c27..5de5e1e 100644 --- a/src/crepe/ParticleEmitter.hpp +++ b/src/crepe/ParticleEmitter.hpp @@ -3,13 +3,12 @@  #include <vector>  #include "Particle.hpp" + +  class ParticleEmitter {  public:      ParticleEmitter(unsigned int maxParticles, unsigned int emissionRate, unsigned int speed, unsigned int speedOffset, unsigned int angle, unsigned int angleOffset,float m_beginLifespan,float m_endLifespan); -    struct Position { //struct to hold position -        float x; -        float y; -    }; +    ~ParticleEmitter();      Position m_position; //position of the emitter      unsigned int m_maxParticles; //maximum number of particles @@ -22,4 +21,5 @@ public:      float m_endLifespan; //begin Lifespan of particle      std::vector<Particle> particles; //collection of particles +  }; diff --git a/src/crepe/ParticleSystem.cpp b/src/crepe/ParticleSystem.cpp index f3cb939..aff7a30 100644 --- a/src/crepe/ParticleSystem.cpp +++ b/src/crepe/ParticleSystem.cpp @@ -9,30 +9,32 @@  ParticleSystem::ParticleSystem() : m_elapsedTime(0.0f) {}  // Initialize m_elapsedTime to 0  void ParticleSystem::update(float deltaTime, std::vector<ParticleEmitter>& emitters) { +    // std::cout << "ParticleSystem update" << std::endl;      for (ParticleEmitter& emitter : emitters) {          float updateAmount = 1/static_cast<float>(emitter.m_emissionRate);          for (float i = 0; i < deltaTime; i += updateAmount)          {              emitParticle(emitter);          } +        //  std::cout << "after emit" << std::endl;          //update/move particles afterwards delete if not alive. -        std::vector<Particle>::iterator it = emitter.particles.begin(); -        while (it != emitter.particles.end()) { -            it->update(deltaTime); -            if (!it->isAlive()) { -                it = emitter.particles.erase(it); -            } else { -                ++it; +        for (size_t j = 0; j <  emitter.particles.size(); j++) +        { +            // std::cout << "update" << std::endl; +            if(emitter.particles[j].active) +            { +                emitter.particles[j].update(deltaTime);              } -        } +        }      +      }  }  void ParticleSystem::emitParticle(ParticleEmitter& emitter) {      // std::cout << "new emitter:" << std::endl; -    Particle::Position initialPosition = { emitter.m_position.x, emitter.m_position.y }; +    Position initialPosition = { emitter.m_position.x, emitter.m_position.y };      float randomAngle = 0.0f;      //check if value is overthe 360 degrees      if(emitter.m_maxAngle < emitter.m_minAngle) @@ -49,11 +51,27 @@ void ParticleSystem::emitParticle(ParticleEmitter& emitter) {      float randomSpeedOffset = (static_cast<float>(std::rand()) / RAND_MAX) * (2 * emitter.m_speedOffset) - emitter.m_speedOffset;      float velocityX = (emitter.m_speed + randomSpeedOffset) * std::cos(angleInRadians);      float velocityY = (emitter.m_speed + randomSpeedOffset) * std::sin(angleInRadians); -    Particle::Position initialVelocity = { +    Position initialVelocity = {          velocityX,          velocityY      };      // std::cout << "emitter.m_endLifespan:" << emitter.m_endLifespan << std::endl; - -    emitter.particles.emplace_back(emitter.m_endLifespan, initialPosition, initialVelocity); +    for (size_t i = 0; i < emitter.particles.size(); i++) +    { +        if(!emitter.particles[i].active) +        { +            // std::cout << "active " << emitter.particles[i].active << std::endl; +            // std::cout << "lifespan " << emitter.particles[i].lifespan << std::endl; +            // std::cout << "timeInLife " << emitter.particles[i].timeInLife << std::endl; +            // std::cout << "emitter.m_endLifespan" << emitter.m_endLifespan << std::endl; +            // std::cout << "initialPositionx" << initialPosition.x << std::endl; +            // std::cout << "initialPositiony" << initialPosition.y << std::endl; +            // std::cout << "initialVelocityx" << initialVelocity.x << std::endl; +            // std::cout << "initialVelocityy" << initialVelocity.y << std::endl; +            emitter.particles[i].reset(emitter.m_endLifespan, initialPosition, initialVelocity); +            break; +        } +    } +     +    //emitter.particles.emplace_back(emitter.m_endLifespan, initialPosition, initialVelocity);  } diff --git a/src/crepe/SDLApp.cpp b/src/crepe/SDLApp.cpp index a5e3621..0779af1 100644 --- a/src/crepe/SDLApp.cpp +++ b/src/crepe/SDLApp.cpp @@ -1,5 +1,8 @@  #include "SDLApp.hpp"  #include <iostream> +#include <vector> +#include "Particle.hpp" +#include "ParticleEmitter.hpp"  SDLApp::SDLApp(int windowWidth, int windowHeight)      : windowWidth(windowWidth), windowHeight(windowHeight), window(nullptr), renderer(nullptr) {} @@ -58,6 +61,12 @@ void SDLApp::drawSquare(int x, int y, int size) {      SDL_RenderFillRect(renderer, &rect);  } +SDL_Texture* squareTexture = nullptr; // Load this with an image or create it + + + + +  void SDLApp::cleanUp() {      if (renderer) {          SDL_DestroyRenderer(renderer); diff --git a/src/crepe/SDLApp.hpp b/src/crepe/SDLApp.hpp index 92a4e27..f95d4bc 100644 --- a/src/crepe/SDLApp.hpp +++ b/src/crepe/SDLApp.hpp @@ -2,6 +2,8 @@  #define SDLAPP_HPP  #include <SDL2/SDL.h> +#include "Particle.hpp" +#include "ParticleEmitter.hpp"  class SDLApp {  public: @@ -14,7 +16,8 @@ public:      void presentScreen();      void drawSquare(int x, int y, int size);      void cleanUp(); - +    void drawParticles(const std::vector<ParticleEmitter>& emitters); +    void drawMultipleSquares(const std::vector<SDL_Rect>& squares);  private:      int windowWidth;      int windowHeight; diff --git a/src/crepe/main.cpp b/src/crepe/main.cpp index 314dbed..58480a9 100644 --- a/src/crepe/main.cpp +++ b/src/crepe/main.cpp @@ -20,7 +20,7 @@ int main(int argc, char* argv[]) {      ParticleSystem particleSystem; -    unsigned int maxParticles = 10;         // maximum number of particles +    unsigned int maxParticles = 100;         // maximum number of particles      unsigned int emissionRate = 1;          // particles created per second      unsigned int speed = 50;                 // base speed of particles      unsigned int speedOffset = 10;           // random offset for particle speed @@ -33,7 +33,7 @@ int main(int argc, char* argv[]) {      std::vector<ParticleEmitter> emitters;      // Loop to create 1000 emitters -    for (unsigned int i = 0; i < 100; ++i) { +    for (unsigned int i = 0; i < 1000; ++i) {          ParticleEmitter emitter(maxParticles, emissionRate, speed, speedOffset, angle, angleOffset, beginLifespan, endLifespan);          // Set a position for each emitter, modifying the position for demonstration @@ -43,7 +43,7 @@ int main(int argc, char* argv[]) {      }      float deltaTime = 0.1f;      bool running = true; - +    std::cout << "start loop " << std::endl;      while (running) {          app.handleEvents(running); @@ -59,15 +59,20 @@ int main(int argc, char* argv[]) {          std::cout << "Update took " << duration.count() << " ms" << std::endl;          app.clearScreen(); +        start = std::chrono::high_resolution_clock::now();          // render particles using the drawSquare method from SDLApp          for (const ParticleEmitter& emitter : emitters) {              for (const Particle& particle : emitter.particles) { - -                app.drawSquare(particle.position.x, particle.position.y, 5); // draw each particle +                if(particle.active)app.drawSquare(particle.position.x, particle.position.y, 5); // draw each particle              }          } +                  app.presentScreen(); +        end = std::chrono::high_resolution_clock::now(); +         duration = end - start; // get duration in milliseconds + +        std::cout << "screen took " << duration.count() << " ms" << std::endl;          std::this_thread::sleep_for(std::chrono::milliseconds(20)); // simulate ~50 FPS      } |