aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjaroWMR <jarorutjes07@gmail.com>2024-10-07 18:07:17 +0200
committerjaroWMR <jarorutjes07@gmail.com>2024-10-07 18:07:17 +0200
commit5f84969c851530ebc430be2cf8e99c945ff7a4a7 (patch)
tree9fcd2755dbfd456f20f0ad37c18c7281b81382b1 /src
parent5cf5cf64d6f9597849ed5558da4f1bc201165fed (diff)
improved particle system from 90ms to ~ 0.7ms
Diffstat (limited to 'src')
-rw-r--r--src/crepe/Particle.cpp19
-rw-r--r--src/crepe/Particle.hpp12
-rw-r--r--src/crepe/ParticleEmitter.cpp17
-rw-r--r--src/crepe/ParticleEmitter.hpp8
-rw-r--r--src/crepe/ParticleSystem.cpp42
-rw-r--r--src/crepe/SDLApp.cpp9
-rw-r--r--src/crepe/SDLApp.hpp5
-rw-r--r--src/crepe/main.cpp15
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
}