Skip to content

Commit

Permalink
ADD - particle shaders and class
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreLamure committed Jan 19, 2020
1 parent d006e0a commit cba5893
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 0 deletions.
16 changes: 16 additions & 0 deletions shaders/particle/fragment.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#version 450

in VS_OUT
{
vec2 tex_coords;
vec4 color;
} fs_in;

out vec4 output_color;

uniform sampler2D sprite;

void main()
{
output_color = fs_in.color * vec4(1);//texture(sprite, fs_in.tex_coords)
}
28 changes: 28 additions & 0 deletions shaders/particle/vertex.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#version 450

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 tex_coords;

out VS_OUT
{
vec2 tex_coords;
vec4 color;
} vs_out;

uniform mat4 projection;
uniform mat4 view;
uniform vec3 offset;
uniform vec4 color;

void main()
{
const float scale = 2;
vs_out.tex_coords = tex_coords;
vs_out.color = color;
gl_ClipDistance[0] = 0;
gl_Position = projection * view * vec4((position * scale) + offset, 1);

vec3 camera_right = vec3(view[0][0], view[1][0], view[2][0]);
vec3 camera_up = vec3(view[0][1], view[1][1], view[2][1]);
gl_Position = projection * view * vec4((offset + (camera_right * position.x * scale) + (camera_up * position.y * scale)), 1);
}
130 changes: 130 additions & 0 deletions src/particle.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include <iostream>
#include "particle.hh"
#include "model.hh"

Particle::Particle(const glm::vec3& origin)
{
init(origin);
}

void Particle::init(const glm::vec3& origin)
{
// positions [-5, 5]
float random_x = ((std::rand() % 100) - 50) / 10.0f;
float random_y = ((std::rand() % 100) - 50) / 10.0f;
float random_z = ((std::rand() % 100) - 50) / 10.0f;
float red = 0.3 + ((std::rand() % 100) / 100.0f);
position = origin + glm::vec3(random_x, random_y, random_z);
velocity = glm::vec3(0,10,0);
color = glm::vec4(red, 0, 0, 1.0f);
life = 1.0f;
}

ParticleGenerator::ParticleGenerator(int nb_particles, const std::string& texture_path)
{
last_used = 0;
for (int i = 0; i < nb_particles; ++i)
particles.emplace_back(Particle(glm::vec3(0))); // FIXME

setup_mesh(texture_path);
}

void ParticleGenerator::setup_mesh(const std::string& texture_path)
{
texture_id = Model::texture_from_file(texture_path.c_str(), ".");
std::cout << "texture_id " << texture_id << std::endl;

float particle_quad[] = {
// positions tex coords
-0.5f, 0.5f, 0.f, 0.0f, 1.0f,
0.5f, -0.5f, 0.f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.f, 0.0f, 0.0f,

-0.5f, 0.5f, 0.f, 0.0f, 1.0f,
0.5f, 0.5f, 0.f, 1.0f, 1.0f,
0.5f, -0.5f, 0.f, 1.0f, 0.0f
};

glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);

glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

glBufferData(GL_ARRAY_BUFFER, sizeof(particle_quad), particle_quad, GL_STATIC_DRAW);

// vertex positions
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
// vertex texture coords
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));

glBindVertexArray(0);
}

int ParticleGenerator::get_first_dead()
{
// Search from last used particle
for (int i = last_used; i < particles.size(); ++i){
if (particles[i].life <= 0)
{
last_used = i;
return i;
}
}
// Otherwise, do a linear search
for (int i = 0; i < last_used; ++i)
{
if (particles[i].life <= 0)
{
last_used = i;
return i;
}
}
// Override first particle if all others are alive
std::cerr << "Particle lived too long" << std::endl;
last_used = 0;
return 0;
}

void ParticleGenerator::update(float delta_time, int nb_new)
{
// Add new particles
for (int i = 0; i < nb_new; ++i)
{
int dead_id = get_first_dead();
particles[dead_id].init(glm::vec3(0)); // FIXME : get origin pos from lava
}

for (int i = 0; i < particles.size(); ++i)
{
Particle& p = particles[i];
p.life -= delta_time * 2; // reduce life
if (p.life > 0)
{
p.position += p.velocity * delta_time;
//p.color.a -= delta_time * 2.5;
}
}
}

void ParticleGenerator::draw(Program& program)
{
for (Particle& p : particles)
{
if (p.life > 0.0f)
{
program.set_vec3("offset", p.position + glm::vec3(0,0,-10));
program.set_vec4("color", p.color);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_id);
program.set_int("sprite", 0);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
}
}
34 changes: 34 additions & 0 deletions src/particle.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <vector>
#include <glm/glm.hpp>
#include <glad/glad.h>
#include "program.hh"
#include "mesh.hh"

class Particle {
public:
glm::vec3 position;
glm::vec3 velocity;
glm::vec4 color;
float life;

explicit Particle(const glm::vec3& origin);
void init(const glm::vec3& origin);
};

class ParticleGenerator {
private:
std::vector<Particle> particles;
unsigned int texture_id;
unsigned int VAO, VBO;
int last_used;

void setup_mesh(const std::string& texture_path);
int get_first_dead();

public:
ParticleGenerator(int nb_particles, const std::string& texture_path);
void update(float delta_time, int nb_new);
void draw(Program& program);
};

0 comments on commit cba5893

Please sign in to comment.