6#include <brenta/gl.hpp>
7#include <brenta/camera.hpp>
8#include <brenta/particles.hpp>
9#include <brenta/window.hpp>
10#include <brenta/shader.hpp>
11#include <brenta/texture.hpp>
12#include <brenta/translation.hpp>
17using namespace brenta;
20 glm::vec3(0.0f, 0.0f, 0.0f),
21 glm::vec3(0.0f, 0.0f, 0.0f),
22 glm::vec3(0.0f, 0.0f, 0.0f),
34particle_emitter::particle_emitter(config conf)
36 this->starting_position = conf.starting_position;
37 this->starting_velocity = conf.starting_velocity;
38 this->starting_spread = conf.starting_spread;
39 this->starting_time_to_live = conf.starting_time_to_live;
40 this->num_particles = conf.num_particles;
41 this->spawn_rate = conf.spawn_rate;
42 this->scale = conf.scale;
43 this->atlas_width = conf.atlas_width;
44 this->atlas_height = conf.atlas_height;
45 this->atlas_index = conf.atlas_index;
50 this->
atlas = std::move(
texture(conf.atlas_path,
false));
53 const GLchar *varyings[] = {
"outPosition",
"outVelocity",
"outTTL"};
55 shader::type::vertex,
"src/shaders/particle_update.vs");
57 shader::type::vertex,
"src/shaders/particle_render.vs",
58 shader::type::geometry,
"src/shaders/particle_render.gs",
59 shader::type::fragment,
"src/shaders/particle_render.fs");
62 glEnable(GL_PROGRAM_POINT_SIZE);
69 this->
fbo[0].init(GL_TRANSFORM_FEEDBACK_BUFFER);
70 this->
fbo[1].init(GL_TRANSFORM_FEEDBACK_BUFFER);
72 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, this->
fbo[0].
id);
73 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
74 this->num_particles * 2 *
sizeof(glm::vec3)
75 + this->num_particles *
sizeof(
float),
76 NULL, GL_DYNAMIC_COPY);
77 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, this->
fbo[1].
id);
78 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
79 this->num_particles * 2 *
sizeof(glm::vec3)
80 + this->num_particles *
sizeof(
float),
81 NULL, GL_DYNAMIC_COPY);
85 glBindBuffer(GL_ARRAY_BUFFER, 0);
101 this->starting_time_to_live);
106 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
fbo[
current].
id);
109 glBindBuffer(GL_ARRAY_BUFFER,
fbo[!
current].
id);
110 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
111 2 *
sizeof(glm::vec3) +
sizeof(
float), (
void *) 0);
112 glEnableVertexAttribArray(0);
113 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
114 2 *
sizeof(glm::vec3) +
sizeof(
float),
115 (
void *)
sizeof(glm::vec3));
116 glEnableVertexAttribArray(1);
117 glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE,
118 2 *
sizeof(glm::vec3) +
sizeof(
float),
119 (
void *) (2 *
sizeof(glm::vec3)));
120 glEnableVertexAttribArray(2);
123 glEnable(GL_RASTERIZER_DISCARD);
124 glBeginTransformFeedback(GL_POINTS);
127 glDrawArrays(GL_POINTS, 0, num_particles);
130 glEndTransformFeedback();
131 glDisable(GL_RASTERIZER_DISCARD);
133 glBindVertexArray(0);
134 glBindBuffer(GL_ARRAY_BUFFER, 0);
135 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
141void particle_emitter::render_particles()
143 if (this->cam ==
nullptr)
145 ERROR(
"particle_emitter::render_particles: Camera not set or null for emitter");
153 glBindBuffer(GL_ARRAY_BUFFER,
fbo[
current].
id);
154 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
155 2 *
sizeof(glm::vec3) +
sizeof(
float), (
void *) 0);
156 glEnableVertexAttribArray(0);
157 glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE,
158 2 *
sizeof(glm::vec3) +
sizeof(
float),
159 (
void *) (2 *
sizeof(glm::vec3)));
161 glEnableVertexAttribArray(1);
164 int window_width = window::get_width();
165 int window_height = window::get_height();
167 t.
set_view(this->cam->get_view_matrix());
168 t.
set_projection(this->cam->get_projection_matrix(window_width, window_height));
172 shader::set_int(
"particle_render",
"atlas_height", this->atlas_height);
177 / (
float) window_height);
181 this->
atlas.bind(GL_TEXTURE_2D, GL_REPEAT, GL_NEAREST,
182 GL_NEAREST, GL_TRUE, GL_NEAREST_MIPMAP_NEAREST,
185 glDrawArrays(GL_POINTS, 0, num_particles);
188 glBindBuffer(GL_ARRAY_BUFFER, 0);
189 glBindVertexArray(0);
198particle_emitter::builder::starting_position(glm::vec3 starting_position)
200 this->conf.starting_position = starting_position;
205particle_emitter::builder::starting_velocity(glm::vec3 starting_velocity)
207 this->conf.starting_velocity = starting_velocity;
212particle_emitter::builder::starting_spread(glm::vec3 starting_spread)
214 this->conf.starting_spread = starting_spread;
219 float starting_time_to_live)
221 this->conf.starting_time_to_live = starting_time_to_live;
226particle_emitter::builder::num_particles(
int num_particles)
228 this->conf.num_particles = num_particles;
233particle_emitter::builder::spawn_rate(
float spawn_rate)
235 this->conf.spawn_rate = spawn_rate;
241 this->conf.scale = scale;
246particle_emitter::builder::atlas_path(std::string atlas_path)
248 this->conf.atlas_path = atlas_path;
253particle_emitter::builder::atlas_width(
int atlas_width)
255 this->conf.atlas_width = atlas_width;
260particle_emitter::builder::atlas_height(
int atlas_height)
262 this->conf.atlas_height = atlas_height;
267particle_emitter::builder::atlas_index(
int atlas_index)
269 this->conf.atlas_index = atlas_index;
275 this->conf.cam = cam;
Builder pattern for ParticleEmitter.
int current
Current fbo index.
types::vao vao
Vertex array object.
types::buffer fbo[2]
Feddback buffer objects.
void update_particles(float delta_time)
Update the particles.
texture atlas
Atlas texture.
static bool use(shader::name_t shader_name)
Use the shader.
static bool set_float(shader::name_t shader_name, const GLchar *name, float value)
Set a float in the shader.
static bool set_vec3(shader::name_t shader_name, const GLchar *name, float x, float y, float z)
Set a 3D vector in the shader.
static bool create(const std::string &shader_name, shader::type type, const std::string &path, Args... args)
Create a new shader.
static bool set_int(shader::name_t shader_name, const GLchar *name, int value)
Set an integer in the shader.
static void active_texture(GLenum texture)
Activate a texture unit.
void set_projection(glm::mat4 projection)
Set the projection matrix.
void set_model(glm::mat4 model)
Set the model matrix.
void set_view(glm::mat4 view)
Set the view matrix.
bool set_shader(shader::name_t shader_name)
Set the shader.