17 #include <ResourceManager.h> 18 #include "ParticleGenerator.h" 19 #include "constants.h" 20 #include "linmath/float3x3.h" 23 #include "ParticleConf.h" 26 ParticleGenerator::ParticleGenerator(
Texture *texture,
int amount,
27 Camera *camera, chag::float4x4 modelMatrix,
29 : texture(texture), m_amount(amount),
30 m_camera(camera), conf(conf)
32 ResourceManager::loadShader(
"shaders/particle.vert",
"shaders/particle.frag",
"particleShader");
33 shaderProgram = ResourceManager::getShader(
"particleShader");
34 shaderProgram->setUniformBufferObjectBinding(UNIFORM_BUFFER_OBJECT_MATRICES_NAME, UNIFORM_BUFFER_OBJECT_MATRICES_INDEX);
36 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
37 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
38 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
40 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
41 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
42 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
45 glGenVertexArrays(1, &m_vaob);
46 glBindVertexArray(m_vaob);
49 glGenBuffers(1, &pos_vbo);
50 glBindBuffer(GL_ARRAY_BUFFER, pos_vbo);
51 glBufferData(GL_ARRAY_BUFFER,
sizeof(quad), quad, GL_STATIC_DRAW);
53 glEnableVertexAttribArray(0);
54 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 *
sizeof(GLfloat), 0);
56 glEnableVertexAttribArray(1);
57 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 *
sizeof(GLfloat), (
void*)(3 *
sizeof(GLfloat)));
62 for (
int i = 0; i < amount; i++) {
64 this->m_particles.push_back(part);
69 ParticleGenerator::~ParticleGenerator()
74 void ParticleGenerator::setScaleLod(
bool value) {
81 glDisable(GL_CULL_FACE);
83 glBlendFunc(GL_SRC_ALPHA, conf->blendFunc);
85 shaderProgram->backupCurrentShaderProgram();
88 texture->bind(GL_TEXTURE0);
90 shaderProgram->setUniform3f(
"color", chag::make_vector(1.0f, 1.0f, 1.0f));
91 shaderProgram->setUniform1i(
"sprite", 0);
93 chag::float3x3 modelMatrix3x3 = getModelMatrix3x3();
96 float distance = length(this->m_camera->getPosition() - this->owner->getAbsoluteLocation());
97 int maxParticles = (int)(m_amount * LOD_FACTOR / distance );
98 glBindVertexArray(m_vaob);
100 std::vector<Particle*> particles = this->m_particles;
101 std::sort(particles.begin(), particles.end(), [
this](
Particle* p1,
Particle* p2) {
102 float l1 = length(this->m_camera->getPosition() - p1->getPosition());
103 float l2 = length(this->m_camera->getPosition() - p2->getPosition());
109 for (
Particle *particle : particles) {
110 if (iterations > maxParticles) {
break; }
114 if (particle->isAlive()) {
118 scale = chag::make_vector(1.0f, 1.0f, 1.0f);
120 chag::float4x4 modelMatrix4x4 = make_matrix(modelMatrix3x3, particle->getPosition()) * chag::make_scale<chag::float4x4>(scale);
122 shaderProgram->setUniformMatrix4fv(
"modelMatrix", modelMatrix4x4);
124 glDrawArrays(GL_TRIANGLES, 0, 6);
129 glBindVertexArray(0);
130 shaderProgram->restorePreviousShaderProgram();
131 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
134 glEnable(GL_CULL_FACE);
138 float distance = length(m_camera->getPosition() - owner->getAbsoluteLocation());
140 for (
Particle *particle : m_particles) {
141 if (particle->isAlive()){
142 particle->update(dt, distance, conf);
144 else if(conf->
loop(dt)){
145 particle->reset(conf, owner->getModelMatrix());
150 chag::float3x3 ParticleGenerator::getModelMatrix3x3() {
151 chag::float3 u = chag::normalize(m_camera->getUp());
152 chag::float3 n = chag::normalize(m_camera->getLookAt() - m_camera->getPosition());
153 chag::float3 r = chag::normalize(chag::cross(u, n));
155 chag::float3 uprim = chag::cross(n, r);
157 return make_matrix(r, uprim, n);
161 void ParticleGenerator::setLooping(
bool value) {
162 conf->setLooping(value);
virtual bool loop(float dt)=0
virtual chag::float3 calcParticleScale()=0