diff --git a/Shader/particle_render.gs b/Shader/particle_render.gs index a904448..9180b7f 100644 --- a/Shader/particle_render.gs +++ b/Shader/particle_render.gs @@ -14,20 +14,20 @@ layout(max_vertices = 4) out; in vec3 color_pass[]; in float lifetime_pass[]; in float size_pass[]; -in int type_pass[]; +in float type_pass[]; smooth out vec2 tex_coords; flat out vec4 color_part; void main() { - if(type_pass[0] != 0) { + if(type_pass[0] != 0.0) { // This is not a generator particle vec3 old_pos = gl_in[0].gl_Position.xyz - camera_pos; float size = size_pass[0]; mat4 view_projection_matrix = projection * view; - color_part = vec4(color_pass[0], lifetime_pass[0]); + color_part = vec4(color_pass[0], 1.0); vec3 pos = old_pos + (-quad1 - quad2) * size; tex_coords = vec2(0.0, 0.0); diff --git a/Shader/particle_render.vs b/Shader/particle_render.vs index 665adc3..f947ec7 100644 --- a/Shader/particle_render.vs +++ b/Shader/particle_render.vs @@ -4,12 +4,12 @@ layout (location = 0) in vec3 position; layout (location = 2) in vec3 color; layout (location = 3) in float lifetime; layout (location = 4) in float size; -layout (location = 5) in int type; +layout (location = 5) in float type; out vec3 color_pass; out float lifetime_pass; out float size_pass; -out int type_pass; +out float type_pass; void main() { diff --git a/Shader/particle_update.gs b/Shader/particle_update.gs index eda92ea..6627ca4 100644 --- a/Shader/particle_update.gs +++ b/Shader/particle_update.gs @@ -10,7 +10,7 @@ in vec3 velocity_pass[]; in vec3 color_pass[]; in float lifetime_pass[]; in float size_pass[]; -in int type_pass[]; +in float type_pass[]; // All that we send further out vec3 position_out; @@ -18,7 +18,7 @@ out vec3 velocity_out; out vec3 color_out; out float lifetime_out; out float size_out; -out int type_out; +out float type_out; uniform vec3 spawn_position; // Position where new particles are spawned uniform vec3 spawn_gravity; // Gravity vector for particles - updates velocity of particles @@ -55,15 +55,15 @@ void main() { position_out = position_pass[0]; velocity_out = velocity_pass[0]; - if(type_pass[0] != 0) position_out += velocity_out * time_passed; - if(type_pass[0] != 0) velocity_out += spawn_gravity * time_passed; + if(type_pass[0] != 0.0) position_out += velocity_out * time_passed; + if(type_pass[0] != 0.0) velocity_out += spawn_gravity * time_passed; color_out = color_pass[0]; lifetime_out = lifetime_pass[0] - time_passed; size_out = size_pass[0]; type_out = type_pass[0]; - if(type_out == 0) { + if(type_out == 0.0) { // This is the emitter particle EmitVertex(); EndPrimitive(); @@ -80,14 +80,50 @@ void main() { color_out = spawn_color; lifetime_out = spawn_lifetime_min + spawn_lifetime_range * random_zero_to_one(); size_out = spawn_size; - type_out = 1; + type_out = 1.0; EmitVertex(); EndPrimitive(); } - } else if(lifetime_out > 0.0) { + } else if (lifetime_out > 0.0) { // This is a normal particle which is still alive EmitVertex(); EndPrimitive(); + } else if (type_out == 1.0) { + // The lifetime is over -- transform this particle in a new one or discard + for(int i = 0; i < 5; i++) { + // Keep the position + velocity_out = spawn_velocity_min + vec3( + spawn_velocity_range.x * random_zero_to_one(), + spawn_velocity_range.y * random_zero_to_one(), + spawn_velocity_range.z * random_zero_to_one() + ); + + color_out = vec3(1.0, 0, 0); + lifetime_out = spawn_lifetime_min + spawn_lifetime_range * random_zero_to_one(); + size_out = spawn_size; + type_out = 2.0; + + EmitVertex(); + EndPrimitive(); + } + } else if (type_out == 2.0) { + // The lifetime is over -- transform this particle in a new one or discard + for(int i = 0; i < 5; i++) { + // Keep the position + velocity_out = spawn_velocity_min + vec3( + spawn_velocity_range.x * random_zero_to_one(), + spawn_velocity_range.y * random_zero_to_one(), + spawn_velocity_range.z * random_zero_to_one() + ); + + color_out = vec3(0.0, 1.0, 0); + lifetime_out = spawn_lifetime_min + spawn_lifetime_range * random_zero_to_one(); + size_out = spawn_size; + type_out = 3.0; + + EmitVertex(); + EndPrimitive(); + } } } \ No newline at end of file diff --git a/Shader/particle_update.vs b/Shader/particle_update.vs index a243001..dd75e7a 100644 --- a/Shader/particle_update.vs +++ b/Shader/particle_update.vs @@ -5,14 +5,14 @@ layout (location = 1) in vec3 velocity; layout (location = 2) in vec3 color; layout (location = 3) in float lifetime; layout (location = 4) in float size; -layout (location = 5) in int type; +layout (location = 5) in float type; out vec3 position_pass; out vec3 velocity_pass; out vec3 color_pass; out float lifetime_pass; out float size_pass; -out int type_pass; +out float type_pass; void main() { position_pass = position; diff --git a/cpp/ParticleSystem.cpp b/cpp/ParticleSystem.cpp index 7b633aa..c7a045c 100644 --- a/cpp/ParticleSystem.cpp +++ b/cpp/ParticleSystem.cpp @@ -42,7 +42,7 @@ ParticleSystem::ParticleSystem() { glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid *)24); // Color glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid *)36); // Lifetime glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid *)40); // Size - glVertexAttribPointer(5, 1, GL_INT, GL_FALSE, sizeof(Particle), (const GLvoid *)44); // Type + glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid *)44); // Type } current_read_buffer = 0; diff --git a/cpp/RenderBackend.cpp b/cpp/RenderBackend.cpp index 7391265..ecc5a0f 100644 --- a/cpp/RenderBackend.cpp +++ b/cpp/RenderBackend.cpp @@ -16,10 +16,10 @@ void RenderBackend::initialize_window(unsigned int width, unsigned int height, S glfwMakeContextCurrent(window); gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); - glEnable(GL_DEPTH_TEST); - // glEnable(GL_CULL_FACE); - // glEnable(GL_BLEND); - // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // FIXME: Disabled because of a bug with particles: they're discarded as if the floor moves with the camera + // glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } bool RenderBackend::is_window_created() { diff --git a/include/Gedeng/ParticleSystem.h b/include/Gedeng/ParticleSystem.h index 223d24c..1f9be85 100644 --- a/include/Gedeng/ParticleSystem.h +++ b/include/Gedeng/ParticleSystem.h @@ -53,7 +53,7 @@ class ParticleSystem { int current_read_buffer; int current_particle_count; - const int max_particle_count = 1000; // FIXME: Increase + const int max_particle_count = 1000000; glm::mat4 projection_matrix, view_matrix; glm::vec3 quad1, quad2; @@ -82,7 +82,7 @@ class ParticleSystem { glm::vec3 color; float lifetime; float size; - int type; + float type; }; }; diff --git a/test/particle-demo/main.cpp b/test/particle-demo/main.cpp index 9e220fc..4732ee3 100644 --- a/test/particle-demo/main.cpp +++ b/test/particle-demo/main.cpp @@ -20,12 +20,12 @@ class ParticleApp : public Gedeng::Application { quad_mesh(Gedeng::QuadMesh(10.0)) { particles.set_position(glm::vec3(0.0f, 0.0f, -5.0f)); particles.set_velocity(glm::vec3(-1, 0, -1), glm::vec3(1, 5, 1)); - particles.set_gravity(glm::vec3(0, -1, 0)); + particles.set_gravity(glm::vec3(0, -2, 0)); particles.set_color(glm::vec3(0.0f, 0.5f, 1.0f)); - particles.set_lifetime(5.0f, 10.0f); + particles.set_lifetime(1.0f, 1.5f); particles.set_size(0.1); particles.set_interval(0.05f); - particles.set_number_of_particles(50); + particles.set_number_of_particles(1); particles.set_texture(&albedo); camera.translate(glm::vec3(0.0, 2.0, 1.0));