6#include <brenta/camera.hpp>
7#include <brenta/particles.hpp>
8#include <brenta/window.hpp>
9#include <brenta/shader.hpp>
10#include <brenta/texture.hpp>
11#include <brenta/translation.hpp>
16using namespace brenta;
19 glm::vec3(0.0f, 0.0f, 0.0f),
20 glm::vec3(0.0f, 0.0f, 0.0f),
21 glm::vec3(0.0f, 0.0f, 0.0f),
33particle_emitter::particle_emitter(config conf)
35 this->starting_position = conf.starting_position;
36 this->starting_velocity = conf.starting_velocity;
37 this->starting_spread = conf.starting_spread;
38 this->starting_time_to_live = conf.starting_time_to_live;
39 this->num_particles = conf.num_particles;
40 this->spawn_rate = conf.spawn_rate;
41 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;
53 const GLchar *varyings[] = {
"outPosition",
"outVelocity",
"outTTL"};
55 GL_VERTEX_SHADER,
"src/shaders/particle_update.vs");
57 GL_VERTEX_SHADER,
"src/shaders/particle_render.vs",
58 GL_GEOMETRY_SHADER,
"src/shaders/particle_render.gs",
59 GL_FRAGMENT_SHADER,
"src/shaders/particle_render.fs");
62 glEnable(GL_PROGRAM_POINT_SIZE);
66 check_opengl_error(
"vao bind");
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);
82 check_opengl_error(
"glBindBufferBase A");
85 glBindBuffer(GL_ARRAY_BUFFER, 0);
90particle_emitter::~particle_emitter()
103 shader::set_vec3(
"particle_update",
"emitterSpread", this->starting_spread);
107 this->starting_time_to_live);
108 check_opengl_error(
"settin update shader");
112 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
fbo[
current].
id);
113 check_opengl_error(
"glBindBufferBase B");
115 glBindBuffer(GL_ARRAY_BUFFER,
fbo[!
current].
id);
116 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
117 2 *
sizeof(glm::vec3) +
sizeof(
float), (
void *) 0);
118 glEnableVertexAttribArray(0);
119 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
120 2 *
sizeof(glm::vec3) +
sizeof(
float),
121 (
void *)
sizeof(glm::vec3));
122 glEnableVertexAttribArray(1);
123 glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE,
124 2 *
sizeof(glm::vec3) +
sizeof(
float),
125 (
void *) (2 *
sizeof(glm::vec3)));
126 glEnableVertexAttribArray(2);
129 glEnable(GL_RASTERIZER_DISCARD);
130 glBeginTransformFeedback(GL_POINTS);
131 check_opengl_error(
"glBeginTransformFeedback");
133 glDrawArrays(GL_POINTS, 0, num_particles);
134 check_opengl_error(
"glDrawTransformFeedback");
136 glEndTransformFeedback();
137 glDisable(GL_RASTERIZER_DISCARD);
139 glBindVertexArray(0);
140 glBindBuffer(GL_ARRAY_BUFFER, 0);
141 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
147void particle_emitter::render_particles()
149 if (this->cam ==
nullptr)
151 ERROR(
"particle_emitter::render_particles: Camera not set or null for emitter");
159 glBindBuffer(GL_ARRAY_BUFFER,
fbo[
current].
id);
160 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
161 2 *
sizeof(glm::vec3) +
sizeof(
float), (
void *) 0);
162 glEnableVertexAttribArray(0);
163 glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE,
164 2 *
sizeof(glm::vec3) +
sizeof(
float),
165 (
void *) (2 *
sizeof(glm::vec3)));
166 check_opengl_error(
"glVertexAttribPointer");
167 glEnableVertexAttribArray(1);
170 int window_width = window::get_width();
171 int window_height = window::get_height();
173 t.
set_view(this->cam->get_view_matrix());
174 t.
set_projection(this->cam->get_projection_matrix(window_width, window_height));
178 shader::set_int(
"particle_render",
"atlas_height", this->atlas_height);
183 / (
float) window_height);
188 GL_NEAREST, GL_TRUE, GL_NEAREST_MIPMAP_NEAREST,
191 glDrawArrays(GL_POINTS, 0, num_particles);
192 check_opengl_error(
"glDrawArrays");
194 glBindBuffer(GL_ARRAY_BUFFER, 0);
195 glBindVertexArray(0);
199void particle_emitter::check_opengl_error(
const std::string &function_name)
202 while ((error = glGetError()) != GL_NO_ERROR)
204 std::cerr <<
"OpenGL Error after " << function_name <<
": " << error
214particle_emitter::builder::starting_position(glm::vec3 starting_position)
216 this->conf.starting_position = starting_position;
221particle_emitter::builder::starting_velocity(glm::vec3 starting_velocity)
223 this->conf.starting_velocity = starting_velocity;
228particle_emitter::builder::starting_spread(glm::vec3 starting_spread)
230 this->conf.starting_spread = starting_spread;
235 float starting_time_to_live)
237 this->conf.starting_time_to_live = starting_time_to_live;
242particle_emitter::builder::num_particles(
int num_particles)
244 this->conf.num_particles = num_particles;
249particle_emitter::builder::spawn_rate(
float spawn_rate)
251 this->conf.spawn_rate = spawn_rate;
257 this->conf.scale = scale;
262particle_emitter::builder::atlas_path(std::string atlas_path)
264 this->conf.atlas_path = atlas_path;
269particle_emitter::builder::atlas_width(
int atlas_width)
271 this->conf.atlas_width = atlas_width;
276particle_emitter::builder::atlas_height(
int atlas_height)
278 this->conf.atlas_height = atlas_height;
283particle_emitter::builder::atlas_index(
int atlas_index)
285 this->conf.atlas_index = atlas_index;
291 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 deltaTime)
Update the particles.
static bool set_vec3(types::shader_name_t shader_name, const GLchar *name, float x, float y, float z)
Set a 3D vector in the shader.
static bool create(std::string shader_name, GLenum type, std::string path, Args... args)
Create a new shader.
static bool set_int(types::shader_name_t shader_name, const GLchar *name, int value)
Set an integer in the shader.
static bool use(types::shader_name_t shader_name)
Use the shader.
static bool set_float(types::shader_name_t shader_name, const GLchar *name, float value)
Set a float in the shader.
static void active_texture(GLenum texture)
Activate a texture unit.
static unsigned int load_texture(std::string path, bool flip=true)
Load a texture from a file.
static void bind_texture(GLenum target, unsigned int texture, GLint wrapping=GL_REPEAT, GLint filtering_min=GL_NEAREST, GLint filtering_mag=GL_NEAREST, GLboolean hasMipmap=GL_TRUE, GLint mipmap_min=GL_LINEAR_MIPMAP_LINEAR, GLint mipmap_mag=GL_LINEAR)
Bind a texture.
Buffer wrapper around OpenGL buffer objects.
void destroy()
Delete the buffer object.
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(types::shader_name_t shader_name)
Set the shader.
void unbind()
Unbind the VAO.
void init()
Init Constructor.