From 54d668a694c01c6c1cc7ef7c919ba69524ddd5f9 Mon Sep 17 00:00:00 2001 From: Nigel Date: Thu, 20 Oct 2022 14:13:25 +0200 Subject: [PATCH] Particle --- particle.fs | 11 ++++ particle.vs | 17 ++++++ src/game.cpp | 11 ++++ src/particle.h | 11 ++++ src/particleGenerator.cpp | 111 ++++++++++++++++++++++++++++++++++++++ src/particleGenerator.h | 29 ++++++++++ textures/particle.png | 3 ++ 7 files changed, 193 insertions(+) create mode 100644 particle.fs create mode 100644 particle.vs create mode 100644 src/particle.h create mode 100644 src/particleGenerator.cpp create mode 100644 src/particleGenerator.h create mode 100644 textures/particle.png diff --git a/particle.fs b/particle.fs new file mode 100644 index 0000000..64ce01d --- /dev/null +++ b/particle.fs @@ -0,0 +1,11 @@ +#version 330 core +in vec2 TexCoords; +in vec4 ParticleColor; +out vec4 color; + +uniform sampler2D sprite; + +void main() +{ + color = (texture(sprite, TexCoords) * ParticleColor); +} \ No newline at end of file diff --git a/particle.vs b/particle.vs new file mode 100644 index 0000000..cb4b4ef --- /dev/null +++ b/particle.vs @@ -0,0 +1,17 @@ +#version 330 core +layout (location = 0) in vec4 vertex; + +out vec2 TexCoords; +out vec4 ParticleColor; + +uniform mat4 projection; +uniform vec2 offset; +uniform vec4 color; + +void main() +{ + float scale = 10.0; + TexCoords = vertex.zw; + ParticleColor = color; + gl_Position = projection * vec4((vertex.xy * scale) + offset, 0.0, 1.0); +} \ No newline at end of file diff --git a/src/game.cpp b/src/game.cpp index abc3550..4f8e63e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,9 +1,11 @@ #include "game.h" +#include "particleGenerator.h" #include #include typedef std::tuple Collision; +ParticleGenerator* Particles; SpriteRenderer* Renderer; // Initial size of the player paddle @@ -86,6 +88,7 @@ Game::~Game() delete Renderer; delete player; delete ball; + delete Particles; } Game::Game(unsigned int width, unsigned int height) @@ -98,10 +101,12 @@ void Game::Init() { // Load shaders ResourceManager::LoadShader("shader.vs", "shader.fs", nullptr, "sprite"); + ResourceManager::LoadShader("particle.vs", "particle.fs", nullptr, "particle"); // configure shaders glm::mat4 projection = glm::ortho(0.0f, static_cast(this->Width), static_cast(this->Height), 0.0f, -1.0f, 1.0f); ResourceManager::GetShader("sprite").Use().SetInteger("image", 0); ResourceManager::GetShader("sprite").SetMatrix4("projection", projection); + ResourceManager::GetShader("particle").Use().SetMatrix4("projection", projection); // set render-specific controls Renderer = new SpriteRenderer(ResourceManager::GetShader("sprite")); // load textures @@ -110,6 +115,7 @@ void Game::Init() ResourceManager::LoadTexture("textures/block.png", false, "block"); ResourceManager::LoadTexture("textures/block_solid.png", false, "block_solid"); ResourceManager::LoadTexture("textures/paddle.png", true, "paddle"); + ResourceManager::LoadTexture("textures/particle.png", true, "particle"); // Load levels GameLevel one; one.Load("levels/one.lvl", this->Width, this->Height / 2); GameLevel two; two.Load("levels/two.lvl", this->Width, this->Height / 2); @@ -129,6 +135,8 @@ void Game::Init() ball = new BallObject(ballPos, BALL_RADIUS, INITIAL_BALL_VELOCITY, ResourceManager::GetTexture("face")); + Particles = new ParticleGenerator(ResourceManager::GetShader("particle"), ResourceManager::GetTexture("particle"), 500); + } @@ -227,6 +235,8 @@ void Game::Update(float dt) ball->Move(dt, this->Width); this->DoCollisions(); + Particles->Update(dt, *ball, 2, glm::vec2(ball->Radius /2.0f)); + if(ball->Position.y >= this->Height) { this->ResetLevel(); @@ -246,6 +256,7 @@ void Game::Render() this->Levels[this->Level].Draw(*Renderer); player->Draw(*Renderer); + Particles->Draw(); ball->Draw(*Renderer); } } diff --git a/src/particle.h b/src/particle.h new file mode 100644 index 0000000..10f71b1 --- /dev/null +++ b/src/particle.h @@ -0,0 +1,11 @@ +#pragma once +#include + + +struct Particle { + glm::vec2 Position, Velocity; + glm::vec4 Color; + float Life; + + Particle(): Position(0.0f), Velocity(0.0f), Color(1.0f), Life(0.0f){} +}; \ No newline at end of file diff --git a/src/particleGenerator.cpp b/src/particleGenerator.cpp new file mode 100644 index 0000000..1c15945 --- /dev/null +++ b/src/particleGenerator.cpp @@ -0,0 +1,111 @@ +#include "particleGenerator.h" +#include +ParticleGenerator::ParticleGenerator (Shader shader, Texture2D texture, unsigned int amount) +: shader(shader), texture(texture), amount(amount) +{ + this->init(); +} + +void ParticleGenerator::Update (float dt, GameObject& object, unsigned int newParticles, glm::vec2 offset) +{ + for (unsigned int i = 0; i < newParticles; ++i) + { + int unusedParticle = this->firstUnusedParticles(); + this->respawnParticle(this->particles[unusedParticle], object, offset); + } + + for (unsigned int i = 0; i < this->amount; ++i) + { + Particle& p = this->particles[i]; + p.Life -= dt; + if(p.Life > 0.0f) + { + p.Position -= p.Velocity * dt; + p.Color.a -= dt * 2.5f; + } + } +} + +void ParticleGenerator::Draw() +{ + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + this->shader.Use(); + for (Particle particle : this->particles) + { + if( particle.Life > 0.0f) + { + this->shader.SetVector2f("offset", particle.Position); + this->shader.SetVector4f("color", particle.Color); + this->texture.Bind(); + glBindVertexArray(this->VAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + } + } + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); +} + +void ParticleGenerator::init() +{ + unsigned int VBO; + float particle_quad[] = { + 0.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + + 0.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 0.0f + }; + + glGenVertexArrays(1, &this->VAO); + glGenBuffers(1, &VBO); + glBindVertexArray(this->VAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(particle_quad), particle_quad, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0,4,GL_FLOAT,GL_FALSE, 4 * sizeof(float), (void*)0); + glBindVertexArray(0); + + for(unsigned int i =0; i < this->amount; ++i) + this->particles.push_back(Particle()); +} + +unsigned int lastUsedParticle = 0; +unsigned int ParticleGenerator::firstUnusedParticles() +{ + for(unsigned int i = lastUsedParticle; i < this->amount; ++i) + { + if( this->particles[i].Life <= 0.0f) + { + lastUsedParticle = i; + return i; + } + } + + for(unsigned int i = 0; i < lastUsedParticle; ++i) + { + if(this->particles[i].Life <= 0.0f) + { + lastUsedParticle = i; + return i; + } + } + + lastUsedParticle = 0; + return 0; + +} + +void ParticleGenerator::respawnParticle(Particle& particle, GameObject& object , glm::vec2 offset) +{ + float random = ((rand()%100) - 50) / 10.0f; + float rColor = 0.5f + ((rand() % 100) / 100.0f); + particle.Position = object.Position + random + offset; + particle.Color = glm::vec4(rColor, rColor, rColor, 1.0f); + particle.Life = 1.0f; + particle.Velocity = object.Velocity * 0.1f; +} \ No newline at end of file diff --git a/src/particleGenerator.h b/src/particleGenerator.h new file mode 100644 index 0000000..5e06c46 --- /dev/null +++ b/src/particleGenerator.h @@ -0,0 +1,29 @@ +#pragma once +#include "particle.h" +#include "gameobject.h" +#include +#include +#include + +class ParticleGenerator +{ + public: + ParticleGenerator (Shader shader, Texture2D texture, unsigned int amount); + void Update (float dt, GameObject& gameobject, unsigned int newParticles, glm::vec2 offset = glm::vec2(0.0f, 0.0f)); + + void Draw(); + + private: + std::vector particles; + unsigned int amount; + Shader shader; + Texture2D texture; + unsigned int VAO; + + void init(); + + unsigned int firstUnusedParticles(); + + void respawnParticle(Particle& particle, GameObject& object , glm::vec2 offset = glm::vec2(0.0f, 0.0f)); + +}; \ No newline at end of file diff --git a/textures/particle.png b/textures/particle.png new file mode 100644 index 0000000..b31b42f --- /dev/null +++ b/textures/particle.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73e11c79477fb17b12992f21f365c596bbbad12b1de37818fae6aadd2fe41234 +size 18912