Skip to content
Snippets Groups Projects
Commit 0d311e68 authored by BATON Theau's avatar BATON Theau
Browse files

Add mesh generator scene

parent cc68450a
No related branches found
No related tags found
No related merge requests found
#include "MeshGenerator.hpp"
#include "../../Mesh/Model.hpp"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/normal.hpp>
#include <glm/gtc/matrix_transform.hpp>
namespace pg::scene {
MeshGenerator::MeshGenerator()
: _mesh(),
_meshProgram(),
_meshPosition(0.f),
_meshRotation(0.f),
_generators(),
_particles(),
_billboard(),
_billboardTexture(),
_billboardProgram(),
_ubo(0) {}
void MeshGenerator::initialize() {
if(!this->_mesh.isGenerated()) {
Model model("res/models/sphere.obj");
MeshGeometry geometry = model.getMeshGeometry();
this->_mesh.generate(geometry.vertices, geometry.indices);
auto & vertices = geometry.vertices;
auto & indices = geometry.indices;
for(size_t i = 0; i < geometry.indices.size(); i+= 3) {
PhysicsParticleGenerator generator;
glm::vec3 & p1 = vertices[indices[i]].position, p2 = vertices[indices[i+1]].position, p3 = vertices[indices[i+2]].position;
glm::vec3 baricenter = (p1 + p2 + p3) / 3.f;
generator.setPosition(baricenter);
glm::vec3 normal = glm::triangleNormal(p1, p2, p3);
generator.setVelocity(glm::normalize(normal) / 50.f);
this->_generators.push_back(generator);
}
}
if(!this->_meshProgram.usable()) {
Source vert("res/shaders/scene/Color.vert", Source::Categorie::VERTEX);
Source frag("res/shaders/scene/Color.frag", Source::Categorie::FRAGMENT);
this->_meshProgram << vert;
this->_meshProgram << frag;
this->_meshProgram.link();
vert.release();
frag.release();
}
this->_billboard.initialize();
this->_billboardTexture.load("res/textures/smoke1.png");
if(!this->_billboardProgram.usable()) {
Source vert("res/shaders/scene/Billboard.vert", Source::Categorie::VERTEX);
Source frag("res/shaders/scene/Billboard.frag", Source::Categorie::FRAGMENT);
this->_billboardProgram << vert;
this->_billboardProgram << frag;
this->_billboardProgram.link();
vert.release();
frag.release();
}
{
glCreateBuffers(1, &this->_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, this->_ubo);
glBufferData(GL_UNIFORM_BUFFER, 1024 * sizeof(glm::mat4), nullptr, GL_DYNAMIC_DRAW);
GLuint uniforme_index = glGetUniformBlockIndex(this->_billboardProgram.id(), "uModels_t");
glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, this->_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
}
void MeshGenerator::update(double current_time) {
static auto start = std::chrono::high_resolution_clock::now();
auto end = std::chrono::high_resolution_clock::now();
pg::Particle::purge(this->_particles, static_cast<size_t>(current_time), 2);
if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 2500) {
start = std::chrono::high_resolution_clock::now();
for(auto & generator : this->_generators) {
if((1 + this->_particles.size()) <= 1024) {
std::vector<std::unique_ptr<pg::Particle>> newParticles = generator.generate(1, static_cast<size_t>(current_time));
this->_particles.insert(this->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end()));
}
}
}
if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 10) {
for(auto& particle : this->_particles) {
particle->update(0.0);
}
}
}
void MeshGenerator::render(const Camera & camera, double current_time) {
const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix();
// --------
this->_meshProgram.use();
this->_meshProgram.setUniform("uModel", glm::mat4(1.f));
this->_meshProgram.setUniform("uView", VIEW_MATRIX);
this->_meshProgram.setUniform("uProj", PROJECTION_MATRIX);
this->_meshProgram.setUniform("uColor", glm::vec4(0.6f, 0.2f, 0.4f, 1.f));
pg::error::OpenGLError::check();
this->_mesh.draw();
pg::error::OpenGLError::check();
// --------
std::vector<glm::mat4> models;
for(auto & particle : this->_particles) {
glm::mat4 model = glm::mat4(1.0);
model = glm::translate(model, glm::vec3(particle->getPosition()));
models.push_back(model);
}
glBindBuffer(GL_UNIFORM_BUFFER, this->_ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, models.size() * sizeof(glm::mat4), models.data());
pg::error::OpenGLError::check();
this->_billboardTexture.bind(0);
this->_billboardProgram.use();
this->_billboardProgram.setUniform("uView", VIEW_MATRIX);
this->_billboardProgram.setUniform("uProj", PROJECTION_MATRIX);
this->_billboardProgram.setUniform("uSlot", 0);
this->_billboardProgram.setUniform("uColor", glm::vec4(1.f, 1.f, 1.f, 1.f));
pg::error::OpenGLError::check();
this->_billboard.draw(this->_particles.size());
pg::error::OpenGLError::check();
// --------
}
void MeshGenerator::destroy() {
glDeleteBuffers(1, &this->_ubo);
this->_billboard.destroy();
this->_particles.clear();
}
}
\ No newline at end of file
#pragma once
#include "Scene.hpp"
#include <vector>
#include <memory>
#include "../../Mesh/Mesh.hpp"
#include "../../Mesh/Billboard.hpp"
#include "../../Renderer/Renderer.hpp"
#include "../../Particle/generator/PhysicsParticleGenerator.hpp"
namespace pg::scene {
class MeshGenerator : public Scene {
private:
Mesh _mesh;
Program _meshProgram;
glm::vec3 _meshPosition;
glm::vec3 _meshRotation;
std::vector<PhysicsParticleGenerator> _generators;
std::vector<std::unique_ptr<Particle>> _particles;
Billboard _billboard;
Material _billboardTexture;
Program _billboardProgram;
GLuint _ubo;
public:
MeshGenerator();
virtual void initialize();
virtual void update(double);
virtual void render(const Camera &, double);
virtual void destroy();
virtual std::string name() const {return "Mesh Generator Scene";};
virtual Interface * interface() {return nullptr;};
};
}
\ No newline at end of file
......@@ -8,6 +8,7 @@
#include "Scene/Scenes/Physic.hpp"
#include "Scene/Scenes/Path.hpp"
#include "Scene/Scenes/Mesh.hpp"
#include "Scene/Scenes/MeshGenerator.hpp"
#include "Interface/GlobalInterface.hpp"
......@@ -79,13 +80,16 @@ int main(int argc, const char * argv[]) {
};
pg::scene::Physic physicScene;
pg::scene::MeshGenerator meshGeneratorScene;
pg::scene::Path pathScene(&bezier, ctrlPoints);
pg::scene::Mesh meshScene(&bezier, ctrlPoints);
pg::Manager manager(window, &physicScene);
manager.add(physicScene);
manager.add(pathScene);
manager.add(meshScene);
manager.add(meshGeneratorScene);
pg::GlobalInterface interface(window, manager, "Particle Generator Settings");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment