diff --git a/ParticleGenerator/res/config/imgui.ini b/ParticleGenerator/res/config/imgui.ini index c73bc2c82017b90530f57a049ba2e361cc9f7941..939246695ffecd7b6ae20543e01e46ce04dcdeb1 100644 --- a/ParticleGenerator/res/config/imgui.ini +++ b/ParticleGenerator/res/config/imgui.ini @@ -23,6 +23,6 @@ Pos=10,4 Size=674,754 [Window][Particle Generator Settings] -Pos=10,11 -Size=362,377 +Pos=3,8 +Size=622,572 diff --git a/ParticleGenerator/src/Interface/Generator/PhysicGeneratorInterface.cpp b/ParticleGenerator/src/Interface/Generator/PhysicGeneratorInterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d90245a344a8c257c113995e408b322050bb9d51 --- /dev/null +++ b/ParticleGenerator/src/Interface/Generator/PhysicGeneratorInterface.cpp @@ -0,0 +1,54 @@ +#pragma once + +#include "PhysicGeneratorInterface.hpp" + +#include <imgui.h> + +#include "../../Particle/generator/PhysicsParticleGenerator.hpp" + +namespace pg { + PhysicGeneratorInterface::PhysicGeneratorInterface(PhysicsParticleGenerator * generator) + : _generator(generator) {} + + void PhysicGeneratorInterface::render(double) { + if(ImGui::CollapsingHeader("Generator Information")) { + ImGui::Text("Physic generator at %f / %f / %f (x, y, z) - variation : %f.", this->_generator->m_position.x, this->_generator->m_position.y, this->_generator->m_position.z, this->_generator->m_positionVariation); + ImGui::SeparatorText("Velocity"); + ImGui::Text("X : %f - variation : [%f , %f].", this->_generator->m_velocity.x, this->_generator->m_velocityVariation.lower.x, this->_generator->m_velocityVariation.upper.x); + ImGui::Text("Y : %f - variation : [%f , %f].", this->_generator->m_velocity.y, this->_generator->m_velocityVariation.lower.y, this->_generator->m_velocityVariation.upper.y); + ImGui::Text("Z : %f - variation : [%f , %f].", this->_generator->m_velocity.z, this->_generator->m_velocityVariation.lower.z, this->_generator->m_velocityVariation.upper.z); + ImGui::SeparatorText("Acceleration"); + ImGui::Text("X : %f - variation : [%f , %f].", this->_generator->m_acceleration.x, this->_generator->m_accelerationVariation.lower.x, this->_generator->m_accelerationVariation.upper.x); + ImGui::Text("Y : %f - variation : [%f , %f].", this->_generator->m_acceleration.y, this->_generator->m_accelerationVariation.lower.y, this->_generator->m_accelerationVariation.upper.y); + ImGui::Text("Z : %f - variation : [%f , %f].", this->_generator->m_acceleration.z, this->_generator->m_accelerationVariation.lower.z, this->_generator->m_accelerationVariation.upper.z); + ImGui::SeparatorText("Friction"); + ImGui::Text("X : %f - variation : [0 , %f].", this->_generator->m_friction.x, this->_generator->m_frictionVariation.x); + ImGui::Text("Y : %f - variation : [0 , %f].", this->_generator->m_friction.y, this->_generator->m_frictionVariation.y); + ImGui::Text("Z : %f - variation : [0 , %f].", this->_generator->m_friction.z, this->_generator->m_frictionVariation.z); + } + + if(ImGui::CollapsingHeader("Generator Position")) { + ImGui::DragFloat3("Generator Position (x, y, z)", &this->_generator->m_position[0], 0.1); + ImGui::InputFloat("Position Variation", &this->_generator->m_positionVariation, 0.f, 5.f, "%.4f"); + } + + if(ImGui::CollapsingHeader("Generation Settings")) { + ImGui::InputFloat3("Velocity (x, y, z)", &this->_generator->m_velocity[0], "%.4f"); + ImGui::InputFloat3("Acceleration (x, y, z)", &this->_generator->m_acceleration[0], "%.4f"); + ImGui::InputFloat3("Friction (x, y, z)", &this->_generator->m_friction[0], "%.4f"); + } + + if(ImGui::CollapsingHeader("Variation")) { + ImGui::SeparatorText("Velocity"); + ImGui::InputFloat3("Upper Boundary (x, y, z)", &this->_generator->m_velocityVariation.upper[0], "%.4f"); + ImGui::InputFloat3("Lower Boundary (x, y, z)", &this->_generator->m_velocityVariation.lower[0], "%.4f"); + ImGui::SeparatorText("Acceleration"); + ImGui::PushID(1); + ImGui::InputFloat3("Upper Boundary (x, y, z)", &this->_generator->m_accelerationVariation.upper[0], "%.4f"); + ImGui::InputFloat3("Lower Boundary (x, y, z)", &this->_generator->m_accelerationVariation.lower[0], "%.4f"); + ImGui::PopID(); + ImGui::SeparatorText("Friction"); + ImGui::InputFloat3("Variation", &this->_generator->m_frictionVariation[0], "%.4f"); + } + } +} diff --git a/ParticleGenerator/src/Interface/Generator/PhysicGeneratorInterface.hpp b/ParticleGenerator/src/Interface/Generator/PhysicGeneratorInterface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1b3944cceef783c4a4f466712dc54f9f45c80827 --- /dev/null +++ b/ParticleGenerator/src/Interface/Generator/PhysicGeneratorInterface.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "../Interface.hpp" + +namespace pg { + class PhysicsParticleGenerator; + class PhysicGeneratorInterface : public Interface { + private: + PhysicsParticleGenerator * _generator; + + public: + PhysicGeneratorInterface(PhysicsParticleGenerator *); + + inline PhysicsParticleGenerator * getGenerator() const {return this->_generator;} + + virtual void render(double); + }; +} \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/GlobalInterface.cpp b/ParticleGenerator/src/Interface/GlobalInterface.cpp index 5b1144dae314e1a8be91072933a8e2200d96a220..394f8dab976094dcd3894cfa63a1a4a5eff36040 100644 --- a/ParticleGenerator/src/Interface/GlobalInterface.cpp +++ b/ParticleGenerator/src/Interface/GlobalInterface.cpp @@ -8,7 +8,7 @@ namespace pg { GlobalInterface::GlobalInterface(Window & window, SceneManager & manager, const std::string & title) - : _window(window), _title(title), _manager(manager) { + : _title(title), _manager(manager), _historical() { if(this->_title.empty()) { this->_title = window.title(); } @@ -34,6 +34,8 @@ namespace pg { ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); + this->_historical.count(current_time); + if(ImGui::Begin(this->_title.c_str())) { if(ImGui::BeginTabBar("")) { if(ImGui::BeginTabItem("Scene")) { @@ -41,8 +43,8 @@ namespace pg { ImGui::EndTabItem(); } - if(ImGui::BeginTabItem("Window")) { - ImGui::Text("Window !"); + if(ImGui::BeginTabItem("Performance")) { + this->_historical.render(current_time); ImGui::EndTabItem(); } ImGui::EndTabBar(); diff --git a/ParticleGenerator/src/Interface/GlobalInterface.hpp b/ParticleGenerator/src/Interface/GlobalInterface.hpp index 01f4b9f0bf541699f94bdd238cc653bc5aca019b..fe6169d7e439823a6bcbb812fc47b3cb5c3f0fc3 100644 --- a/ParticleGenerator/src/Interface/GlobalInterface.hpp +++ b/ParticleGenerator/src/Interface/GlobalInterface.hpp @@ -4,15 +4,16 @@ #include "../System/Window.hpp" #include "../Scene/SceneManager.hpp" +#include "../System/FrameHistorical.hpp" namespace pg { class GlobalInterface : public Interface { private: - Window & _window; std::string _title; SceneManager & _manager; - + FrameHistorical _historical; + public: GlobalInterface(Window &, SceneManager &, const std::string & = ""); ~GlobalInterface(); diff --git a/ParticleGenerator/src/Interface/Scene/PathSceneInterface.cpp b/ParticleGenerator/src/Interface/Scene/PathSceneInterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..945ed871ff5c4342dadeea7698ed9f56cc4407d9 --- /dev/null +++ b/ParticleGenerator/src/Interface/Scene/PathSceneInterface.cpp @@ -0,0 +1,41 @@ +#include "PathSceneInterface.hpp" + +#include <imgui.h> + +#include "../../Scene/PathScene.hpp" + +namespace pg { + PathSceneInterface::PathSceneInterface(PathScene * scene) + : _scene(scene), + _max(1024), + _spawnFrequence(500), + _spawnCount(5), + _lifetime(5), + _color(1.f, 1.f, 1.f, 1.f), + _enableRender(true), + _enableSpawning(true) {} + + void PathSceneInterface::render(double current_time) { + ImGui::Text("Particles Number : %i / %i.", this->_scene->_particles.size(), this->_max); + ImGui::Checkbox("Enable Rendering", &this->_enableRender); + ImGui::Separator(); + ImGui::Checkbox("Enable Spawning", &this->_enableSpawning); + ImGui::SliderInt("Spawning Number", &this->_spawnCount, 1, 1024); + ImGui::InputInt("Spawn Frequence (ms)", &this->_spawnFrequence, 25, 100); + ImGui::Separator(); + ImGui::InputInt("Particles Lifetime (s)", &this->_lifetime, 1, 5); + ImGui::ColorEdit4("GlobalColor", &this->_color[0]); + + if(ImGui::Button("Clear")) { + this->_scene->_particles.clear(); + } + + ImGui::SameLine(); + + if(ImGui::Button("Spawn")) { + std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_scene->_generator.generate(1, static_cast<size_t>(current_time)); + this->_scene->_particles.insert(this->_scene->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end())); + } + + } +} \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Scene/PathSceneInterface.hpp b/ParticleGenerator/src/Interface/Scene/PathSceneInterface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2739682e5e6ee31e081b450b04436d1dc0b5729c --- /dev/null +++ b/ParticleGenerator/src/Interface/Scene/PathSceneInterface.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "../Interface.hpp" + +#include <glm/vec4.hpp> + +namespace pg { + class PathScene; + class PathSceneInterface : public Interface { + private: + PathScene * _scene; + + int _max; + int _spawnFrequence; + int _spawnCount; + int _lifetime; + + glm::vec4 _color; + + bool _enableRender; + bool _enableSpawning; + + public: + PathSceneInterface(PathScene *); + + inline int getMaxParticle() const {return this->_max;} + inline int getSpawnFrequence() const {return this->_spawnFrequence;} + inline int getSpawnCount() const {return this->_spawnCount;} + inline int getLifeTime() const {return this->_lifetime;} + + inline const glm::vec4 & getColor() const {return this->_color;} + + inline bool isRenderEnable() {return this->_enableRender;} + inline bool isSpawningEnable() {return this->_enableSpawning;} + + inline void setSpawnFrequence(int freq) {this->_spawnFrequence = freq;} + inline void setSpawnCount(int count) {this->_spawnCount = count;} + inline void setGlobalColor(const glm::vec4 & color) {this->_color = color;} + inline void setRenderEnable(bool state) {this->_enableRender = state;} + inline void setEnableSpawning(bool state) {this->_enableSpawning = state;} + + virtual void render(double); + }; +} \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Scene/PhysicSceneInterface.cpp b/ParticleGenerator/src/Interface/Scene/PhysicSceneInterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb0a3e603611f8857a59a57888547312561e5574 --- /dev/null +++ b/ParticleGenerator/src/Interface/Scene/PhysicSceneInterface.cpp @@ -0,0 +1,45 @@ +#include "PhysicSceneInterface.hpp" + +#include <imgui.h> + +#include "../../Scene/PhysicScene.hpp" + +namespace pg { + PhysicSceneInterface::PhysicSceneInterface(PhysicScene * scene) + : _scene(scene), + _generator(&scene->_generator), + _max(1024), + _spawnFrequence(500), + _spawnCount(5), + _lifetime(5), + _color(1.f, 1.f, 1.f, 1.f), + _enableRender(true), + _enableSpawning(true) {} + + void PhysicSceneInterface::render(double current_time) { + ImGui::Text("Particles Number : %i / %i.", this->_scene->_particles.size(), this->_max); + //ImGui::Text("Frame Per Second : %f.", this->_fps); + ImGui::Checkbox("Enable Rendering", &this->_enableRender); + ImGui::Separator(); + ImGui::Checkbox("Enable Spawning", &this->_enableSpawning); + ImGui::SliderInt("Spawning Number", &this->_spawnCount, 1, 1024); + ImGui::InputInt("Spawn Frequence (ms)", &this->_spawnFrequence, 25, 100); + ImGui::Separator(); + ImGui::InputInt("Particles Lifetime (s)", &this->_lifetime, 1, 5); + ImGui::ColorEdit4("GlobalColor", &this->_color[0]); + + if(ImGui::Button("Clear")) { + this->_scene->_particles.clear(); + } + + ImGui::SameLine(); + + if(ImGui::Button("Spawn")) { + std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_scene->_generator.generate(1, static_cast<size_t>(current_time)); + this->_scene->_particles.insert(this->_scene->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end())); + } + + + this->_generator.render(current_time); + } +} \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Scene/PhysicSceneInterface.hpp b/ParticleGenerator/src/Interface/Scene/PhysicSceneInterface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..09dd7b6e4adb987f375ff433436b2e7cba8646f7 --- /dev/null +++ b/ParticleGenerator/src/Interface/Scene/PhysicSceneInterface.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include "../Interface.hpp" +#include "../Generator/PhysicGeneratorInterface.hpp" + +#include <glm/vec4.hpp> + +namespace pg { + class PhysicScene; + class PhysicSceneInterface : public Interface { + private: + PhysicScene * _scene; + PhysicGeneratorInterface _generator; + + int _max; + int _spawnFrequence; + int _spawnCount; + int _lifetime; + + glm::vec4 _color; + + bool _enableRender; + bool _enableSpawning; + + public: + PhysicSceneInterface(PhysicScene *); + + inline int getMaxParticle() const {return this->_max;} + inline int getSpawnFrequence() const {return this->_spawnFrequence;} + inline int getSpawnCount() const {return this->_spawnCount;} + inline int getLifeTime() const {return this->_lifetime;} + + inline const glm::vec4 & getColor() const {return this->_color;} + + inline bool isRenderEnable() {return this->_enableRender;} + inline bool isSpawningEnable() {return this->_enableSpawning;} + + inline void setSpawnFrequence(int freq) {this->_spawnFrequence = freq;} + inline void setSpawnCount(int count) {this->_spawnCount = count;} + inline void setGlobalColor(const glm::vec4 & color) {this->_color = color;} + inline void setRenderEnable(bool state) {this->_enableRender = state;} + inline void setEnableSpawning(bool state) {this->_enableSpawning = state;} + + virtual void render(double); + }; +} \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/SceneManagerInterface.cpp b/ParticleGenerator/src/Interface/SceneManagerInterface.cpp index 0d57d544b1b4fb5aa9c16ebebd00760a6f168757..bc7c9a4f75caefeddceeb60176e856875a3f48e7 100644 --- a/ParticleGenerator/src/Interface/SceneManagerInterface.cpp +++ b/ParticleGenerator/src/Interface/SceneManagerInterface.cpp @@ -5,20 +5,19 @@ #include "../Scene/SceneManager.hpp" namespace pg { - SceneManagerInterface::SceneManagerInterface(Window & window, SceneManager * manager) - : _manager(manager), _window(window) { + SceneManagerInterface::SceneManagerInterface(SceneManager * manager) + : _manager(manager) { } void SceneManagerInterface::render(double current_time) { if(!this->_manager->scenes().empty()) { - std::string current = this->_manager->current() == nullptr ? this->_manager->scenes().front()->name() : this->_manager->current()->name(); - - if(ImGui::BeginCombo("Current Scene", current.c_str())) { + std::string name = this->_manager->current() == nullptr ? this->_manager->scenes().front()->name() : this->_manager->current()->name(); + if(ImGui::BeginCombo("Current Scene", name.c_str())) { for(auto & scene : this->_manager->_scenes) { bool is_selected = (scene == this->_manager->current()); if(ImGui::Selectable(scene->name().c_str(), is_selected)) { - this->_manager->switchScene(this->_window, scene); + this->_manager->setScene(scene); } } ImGui::EndCombo(); diff --git a/ParticleGenerator/src/Interface/SceneManagerInterface.hpp b/ParticleGenerator/src/Interface/SceneManagerInterface.hpp index 255ed08cd2b5992c9f39025c631b99b80b1dd7ab..870a67075f3519b0f9c341abb00d4f6131fe3632 100644 --- a/ParticleGenerator/src/Interface/SceneManagerInterface.hpp +++ b/ParticleGenerator/src/Interface/SceneManagerInterface.hpp @@ -9,10 +9,9 @@ namespace pg { class SceneManagerInterface : public Interface { private: SceneManager * _manager; - Window & _window; public: - SceneManagerInterface(Window &, SceneManager *); + SceneManagerInterface(SceneManager *); virtual void render(double = 0.0); }; diff --git a/ParticleGenerator/src/Interface/TestInterface.hpp b/ParticleGenerator/src/Interface/TestInterface.hpp deleted file mode 100644 index 4f990aba59cff04ee3717dacca5ffdce7d6a3b66..0000000000000000000000000000000000000000 --- a/ParticleGenerator/src/Interface/TestInterface.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "Interface.hpp" - -#include <imgui.h> - -namespace pg { - class TestInterface : public Interface { - public: - virtual void render(double) { - ImGui::Text("Hello Scene !"); - } - }; -} \ No newline at end of file diff --git a/ParticleGenerator/src/Particle/Particle.hpp b/ParticleGenerator/src/Particle/Particle.hpp index b72fee3e5181a1a9db892c770086f776aadf6cf5..1f6097e0e480df1b0ce6fb3ad1b33de39f0a9e3c 100644 --- a/ParticleGenerator/src/Particle/Particle.hpp +++ b/ParticleGenerator/src/Particle/Particle.hpp @@ -27,7 +27,7 @@ namespace pg inline void setPosition(const ct::Point& position) {this->m_position = position;} inline void translate(const ct::Point& position) {this->m_position += position;} - virtual void update(double) = 0; + virtual void update(double = 0.0) = 0; inline friend bool operator==(const Particle & p1, const Particle & p2) {return p1.m_position == p2.m_position && p1.m_born == p2.m_born;} inline friend bool operator!=(const Particle & p1, const Particle & p2) {return !(p1 == p2);} diff --git a/ParticleGenerator/src/Particle/PathParticle.cpp b/ParticleGenerator/src/Particle/PathParticle.cpp index 39769daa3f9b462dcae9817c882fd0a77fd7d955..86d11a65caf99fecbe1607bd9410c3969e735b4f 100644 --- a/ParticleGenerator/src/Particle/PathParticle.cpp +++ b/ParticleGenerator/src/Particle/PathParticle.cpp @@ -1,5 +1,7 @@ #include "PathParticle.hpp" +#include <iostream> + namespace pg { PathParticle::PathParticle(ct::CurveGenerator* generator, const ct::Curve& path, double u, double inc) : Particle(), m_generator(generator), m_ctrlPoints(path), m_positionVariation(), m_u(u), m_increment(inc), m_limitor(0.0) @@ -19,9 +21,11 @@ namespace pg { { this->m_u += this->m_increment; - if(this->m_u > this->m_limitor && this->m_limitor != 0.0) { + if(this->m_u > this->m_limitor && this->m_limitor > 0.0) { this->setBorn(0.0); + return; } + this->setPosition(this->m_generator->operator()(this->m_ctrlPoints, this->m_u) + this->m_positionVariation); } } diff --git a/ParticleGenerator/src/Particle/generator/PathParticleGenerator.hpp b/ParticleGenerator/src/Particle/generator/PathParticleGenerator.hpp index a0b21c3dd67deeefcd232653b36bb2834063d1b1..955095c3ec930b2fd179e19ae88fa5ee104e8ada 100644 --- a/ParticleGenerator/src/Particle/generator/PathParticleGenerator.hpp +++ b/ParticleGenerator/src/Particle/generator/PathParticleGenerator.hpp @@ -4,7 +4,7 @@ #include "../PathParticle.hpp" namespace pg { - class PathConfig; + class PathGeneratorInterface; class PathParticleGenerator : public ParticleGenerator { private: @@ -30,6 +30,6 @@ namespace pg { std::vector<std::unique_ptr<Particle>> generate(size_t count, size_t birth = 0) const override; - friend class PathConfig; + friend class PathGeneratorInterface; }; } \ No newline at end of file diff --git a/ParticleGenerator/src/Particle/generator/PhysicsParticleGenerator.hpp b/ParticleGenerator/src/Particle/generator/PhysicsParticleGenerator.hpp index 59f5283fba4b8d946e5fb07bcf3cba301d2c4ef3..a2f2141715004012b73e2add6f6de3e2ea56b24b 100644 --- a/ParticleGenerator/src/Particle/generator/PhysicsParticleGenerator.hpp +++ b/ParticleGenerator/src/Particle/generator/PhysicsParticleGenerator.hpp @@ -3,9 +3,9 @@ #include "ParticleGenerator.hpp" #include "../PhysicsParticle.hpp" -namespace pg { - class PhysicConfig; +#include "../../Interface/Generator/PhysicGeneratorInterface.hpp" +namespace pg { template <typename T> struct Interval { T upper; @@ -40,7 +40,7 @@ namespace pg { inline void setFrictionVariation(const glm::vec3 & frictionVariation) {this->m_frictionVariation = frictionVariation;} std::vector<std::unique_ptr<Particle>> generate(size_t count, size_t birth = 0) const override; - - friend class PhysicConfig; + + friend class PhysicGeneratorInterface; }; } \ No newline at end of file diff --git a/ParticleGenerator/src/Scene/PathScene.cpp b/ParticleGenerator/src/Scene/PathScene.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f294d9285d33d7003769091efa9c846b9b8a011c --- /dev/null +++ b/ParticleGenerator/src/Scene/PathScene.cpp @@ -0,0 +1,145 @@ +#include "PathScene.hpp" + +#include <chrono> +#include <glm/gtc/matrix_transform.hpp> + +namespace pg { + PathScene::PathScene(ct::CurveGenerator * generator, const ct::Curve & ctrlpoint) + : _ubo(0), + _program(), + _vao(), + _vbo(this->_vao, {layout::POSITION, layout::TEXTURE}, 1, GL_STATIC_DRAW), + _ebo(this->_vao, 1, GL_STATIC_DRAW), + _texture(), + _generator(generator, ctrlpoint), + _particles(), + _interface(this) {} + + void PathScene::initialize() { + if(!this->_program.usable()) { + pg::Source vertices("../../res/shaders/Instanced-Fat.vert", pg::Source::Categorie::VERTEX); + pg::Source fragment("../../res/shaders/Instanced-Fat.frag", pg::Source::Categorie::FRAGMENT); + + this->_program << vertices; + this->_program << fragment; + + this->_program.link(); + + vertices.release(); + fragment.release(); + } + + pg::error::OpenGLError::check(); + + std::vector<float> Vertices = { + -1.0f, -1.0f, 0.f, 0.0f, 0.0f, + 1.0f, -1.0f, 0.f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.f, 1.0f, 1.0f, + -1.0f, 1.0f, 0.f, 0.0f, 1.0f + }; + + std::vector<unsigned int> Indices = { + 0, 1, 2, + 0, 2, 3 + }; + + this->_vbo.set(Vertices); + this->_ebo.set(Indices); + + pg::error::OpenGLError::check(); + + 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->_program.id(), "uModels_t"); + glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, this->_ubo); + + pg::error::OpenGLError::check(); + + this->_texture.load("../../res/textures/smoke1.png"); + this->_texture.bind(0); + + pg::error::OpenGLError::check(); + + this->_generator.setPosition({0.f, 0.f, 0.f}); + this->_generator.setPositionVariation(0.5); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glClearColor(0.25f, 0.f, 0.15f, 1.0f); + } + + void PathScene::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), this->_interface.getLifeTime()); + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= this->_interface.getSpawnFrequence()) { + start = std::chrono::high_resolution_clock::now(); + if((this->_interface.getSpawnCount() + this->_particles.size()) <= this->_interface.getMaxParticle() && this->_interface.isSpawningEnable()) { + std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_generator.generate(this->_interface.getSpawnCount(), 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 PathScene::render(const Camera & camera, double current_time) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + const glm::mat4 VIEW_MATRIX = camera.getViewMatrix(); + const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix(); + + 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); + } + + pg::error::OpenGLError::check(); + + glBindBuffer(GL_UNIFORM_BUFFER, this->_ubo); + glBufferSubData(GL_UNIFORM_BUFFER, 0, models.size() * sizeof(glm::mat4), models.data()); + + pg::error::OpenGLError::check(); + + static GLint slot = 0; + + this->_program.use(); + + this->_program.setUniform("uView", VIEW_MATRIX); + this->_program.setUniform("uProj", PROJECTION_MATRIX); + this->_program.setUniform("uSlot", slot); + this->_program.setUniform("uColor", this->_interface.getColor()); + + pg::error::OpenGLError::check(); + + this->_vao.bind(); + this->_vbo.bind(); + + if(this->_interface.isRenderEnable()) { + glDrawElementsInstanced(GL_TRIANGLES, static_cast<GLsizei>(this->_ebo.size()), GL_UNSIGNED_INT, 0, static_cast<GLsizei>(this->_particles.size())); + } + + pg::error::OpenGLError::check(); + } + + void PathScene::destroy() { + glDeleteBuffers(1, &this->_ubo); + + this->_vbo.destroy(); + this->_ebo.destroy(); + + this->_particles.clear(); + + pg::error::OpenGLError::check(); + } +} \ No newline at end of file diff --git a/ParticleGenerator/src/Scene/PathScene.hpp b/ParticleGenerator/src/Scene/PathScene.hpp new file mode 100644 index 0000000000000000000000000000000000000000..aff71e2865dd5821636099d6ff958cfddb9cee40 --- /dev/null +++ b/ParticleGenerator/src/Scene/PathScene.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include "Scene.hpp" + +#include "../Renderer/Renderer.hpp" +#include "../Particle/generator/PathParticleGenerator.hpp" +#include "../Interface/Scene/PathSceneInterface.hpp" + +#include "../System/Window.hpp" + +namespace pg { + class PathScene : public Scene { + private: + GLuint _ubo; + + pg::Program _program; + pg::VertexArray _vao; + pg::VerticeBuffer _vbo; + pg::ElementBuffer _ebo; + pg::Material _texture; + pg::PathParticleGenerator _generator; + std::vector<std::unique_ptr<pg::Particle>> _particles; + + PathSceneInterface _interface; + + public: + PathScene(ct::CurveGenerator *, const ct::Curve &); + + virtual void initialize(); + virtual void render(const Camera &, double); + virtual void update(double); + virtual void destroy(); + + virtual std::string name() const {return "Path Scene";} + virtual Interface & interface() {return this->_interface;} + + friend class PathSceneInterface; + }; +} \ No newline at end of file diff --git a/ParticleGenerator/src/Scene/PhysicScene.cpp b/ParticleGenerator/src/Scene/PhysicScene.cpp index a708b2be50aa7adb5de4f4d1d88b9f45d638539c..b086c3095095e440eb65f27ffd649486bb74e96e 100644 --- a/ParticleGenerator/src/Scene/PhysicScene.cpp +++ b/ParticleGenerator/src/Scene/PhysicScene.cpp @@ -6,7 +6,6 @@ namespace pg { PhysicScene::PhysicScene() : _ubo(0), - _camera({0, 0, 3}), _program(), _vao(), _vbo(this->_vao, {layout::POSITION, layout::TEXTURE}, 1, GL_STATIC_DRAW), @@ -14,40 +13,9 @@ namespace pg { _texture(), _generator(), _particles(), - _color(1.f, 1.f, 1.f, 1.f) {} + _interface(this) {} - void PhysicScene::initialize(Window & window) { - std::cout << "Physic Scene Init Start : "; - //? Camera - glfwSetWindowUserPointer(window.address(), (void *)&this->_camera); - - glfwSetCursorPosCallback(window.address(), [](GLFWwindow* window, double xpos, double ypos) { - pg::OrbitCamera* camera = static_cast<pg::OrbitCamera*>(glfwGetWindowUserPointer(window)); - camera->onMove(static_cast<unsigned int>(xpos), static_cast<unsigned int>(ypos)); - }); - - glfwSetMouseButtonCallback(window.address(), [](GLFWwindow* window, int button, int action, int mods) { - pg::OrbitCamera* camera = static_cast<pg::OrbitCamera*>(glfwGetWindowUserPointer(window)); - - if (button == GLFW_MOUSE_BUTTON_RIGHT) { - if(action == GLFW_PRESS) { - camera->onMoveBegin(); - } - else if(action == GLFW_RELEASE) { - camera->onMoveEnd(); - } - } - }); - - glfwSetScrollCallback(window.address(), [](GLFWwindow* window, double xoffset, double yoffset) { - pg::OrbitCamera* camera = static_cast<pg::OrbitCamera*>(glfwGetWindowUserPointer(window)); - camera->onScroll(static_cast<int>(yoffset)); - }); - - std::cout << "Camera, "; - pg::error::OpenGLError::check(); - - //? Shaders + void PhysicScene::initialize() { if(!this->_program.usable()) { pg::Source vertices("../../res/shaders/Instanced-Fat.vert", pg::Source::Categorie::VERTEX); pg::Source fragment("../../res/shaders/Instanced-Fat.frag", pg::Source::Categorie::FRAGMENT); @@ -61,10 +29,8 @@ namespace pg { fragment.release(); } - std::cout << "Shader, "; pg::error::OpenGLError::check(); - //? Buffer std::vector<float> Vertices = { -1.0f, -1.0f, 0.f, 0.0f, 0.0f, 1.0f, -1.0f, 0.f, 1.0f, 0.0f, @@ -80,35 +46,27 @@ namespace pg { this->_vbo.set(Vertices); this->_ebo.set(Indices); - std::cout << "Buffer, "; pg::error::OpenGLError::check(); - //? UBO 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->_program.id(), "uModels_t"); glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, this->_ubo); - - std::cout << "Uniforme Buffer, "; + pg::error::OpenGLError::check(); - //? Texture this->_texture.load("../../res/textures/smoke1.png"); this->_texture.bind(0); - std::cout << "Texture, "; pg::error::OpenGLError::check(); - //? Generator this->_generator.setPosition({0.f, 0.f, 0.f}); this->_generator.setPositionVariation(0.5); this->_generator.setVelocity({0, 0.01, 0}); this->_generator.setAcceleration({0.0, 0.0001, 0}); - std::cout << "Generator." << std::endl; - glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0.25f, 0.f, 0.15f, 1.0f); @@ -118,11 +76,11 @@ namespace pg { 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), 5); - if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 500) { + pg::Particle::purge(this->_particles, static_cast<size_t>(current_time), this->_interface.getLifeTime()); + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= this->_interface.getSpawnFrequence()) { start = std::chrono::high_resolution_clock::now(); - if((10 + this->_particles.size()) <= 1024) { - std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_generator.generate(10, static_cast<size_t>(current_time)); + if((this->_interface.getSpawnCount() + this->_particles.size()) <= this->_interface.getMaxParticle() && this->_interface.isSpawningEnable()) { + std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_generator.generate(this->_interface.getSpawnCount(), static_cast<size_t>(current_time)); this->_particles.insert(this->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end())); } } @@ -134,11 +92,11 @@ namespace pg { } } - void PhysicScene::render(double current_time) { + void PhysicScene::render(const Camera & camera, double current_time) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - const glm::mat4 VIEW_MATRIX = this->_camera.getViewMatrix(); - const glm::mat4 PROJECTION_MATRIX = this->_camera.getViewFrustum().getProjectionMatrix(); + const glm::mat4 VIEW_MATRIX = camera.getViewMatrix(); + const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix(); std::vector<glm::mat4> models; @@ -162,14 +120,16 @@ namespace pg { this->_program.setUniform("uView", VIEW_MATRIX); this->_program.setUniform("uProj", PROJECTION_MATRIX); this->_program.setUniform("uSlot", slot); - this->_program.setUniform("uColor", this->_color); + this->_program.setUniform("uColor", this->_interface.getColor()); pg::error::OpenGLError::check(); this->_vao.bind(); this->_vbo.bind(); - glDrawElementsInstanced(GL_TRIANGLES, static_cast<GLsizei>(this->_ebo.size()), GL_UNSIGNED_INT, 0, static_cast<GLsizei>(this->_particles.size())); + if(this->_interface.isRenderEnable()) { + glDrawElementsInstanced(GL_TRIANGLES, static_cast<GLsizei>(this->_ebo.size()), GL_UNSIGNED_INT, 0, static_cast<GLsizei>(this->_particles.size())); + } pg::error::OpenGLError::check(); } @@ -180,6 +140,8 @@ namespace pg { this->_vbo.destroy(); this->_ebo.destroy(); + this->_particles.clear(); + pg::error::OpenGLError::check(); } } \ No newline at end of file diff --git a/ParticleGenerator/src/Scene/PhysicScene.hpp b/ParticleGenerator/src/Scene/PhysicScene.hpp index 564fffabd3c2775e237282c8c95bf2900c85e938..371d46abde998f0d05eba2eccd1097e325b219b1 100644 --- a/ParticleGenerator/src/Scene/PhysicScene.hpp +++ b/ParticleGenerator/src/Scene/PhysicScene.hpp @@ -1,16 +1,18 @@ #pragma once -#include "../Renderer/Renderer.hpp" #include "Scene.hpp" + +#include "../Renderer/Renderer.hpp" #include "../Particle/generator/PhysicsParticleGenerator.hpp" -#include "../Interface/TestInterface.hpp" +#include "../Interface/Scene/PhysicSceneInterface.hpp" + +#include "../System/Window.hpp" namespace pg { class PhysicScene : public Scene { private: GLuint _ubo; - pg::OrbitCamera _camera; pg::Program _program; pg::VertexArray _vao; pg::VerticeBuffer _vbo; @@ -19,18 +21,19 @@ namespace pg { pg::PhysicsParticleGenerator _generator; std::vector<std::unique_ptr<pg::Particle>> _particles; - glm::vec4 _color; - TestInterface _interface; + PhysicSceneInterface _interface; public: PhysicScene(); - virtual void initialize(Window &); + virtual void initialize(); + virtual void render(const Camera &, double); virtual void update(double); - virtual void render(double); virtual void destroy(); virtual std::string name() const {return "Physic Scene";} virtual Interface & interface() {return this->_interface;} + + friend class PhysicSceneInterface; }; } \ No newline at end of file diff --git a/ParticleGenerator/src/Scene/Scene.hpp b/ParticleGenerator/src/Scene/Scene.hpp index e193875d3a0af6fd7167303a79d71a4e4d5aead0..45d6ce8282846ac0cb83678870c0adb74922c046 100644 --- a/ParticleGenerator/src/Scene/Scene.hpp +++ b/ParticleGenerator/src/Scene/Scene.hpp @@ -2,15 +2,15 @@ #include <string> -#include "../System/Window.hpp" #include "../Interface/Interface.hpp" +#include "../Renderer/Camera/Camera.hpp" namespace pg { class Scene { public: - virtual void initialize(Window &) = 0; + virtual void initialize() = 0; virtual void update(double) = 0; - virtual void render(double) = 0; + virtual void render(const Camera &, double) = 0; virtual void destroy() = 0; virtual std::string name() const = 0; diff --git a/ParticleGenerator/src/Scene/SceneManager.cpp b/ParticleGenerator/src/Scene/SceneManager.cpp index bc99f267243b40ad1c08c388ad9ca0e89dc5b7a8..bf70ae2ca191521107b71c42c5a3d7a81869f47a 100644 --- a/ParticleGenerator/src/Scene/SceneManager.cpp +++ b/ParticleGenerator/src/Scene/SceneManager.cpp @@ -3,10 +3,10 @@ #include <imgui.h> namespace pg { - SceneManager::SceneManager(Window & window, Scene * defaultScene) - : _current(defaultScene), _scenes(), _chronometer(), _accumulator(0.f), _timestep(1.f / 60.f), _interface(window, this) { - if(this->_current != nullptr) { - this->_current->initialize(window); + SceneManager::SceneManager(Scene * scene) + : _current(scene), _scenes(), _chronometer(), _accumulator(0.f), _timestep(1.f / 60.f), _interface(this) { + if(scene != nullptr) { + scene->initialize(); } } @@ -16,16 +16,16 @@ namespace pg { } } - void SceneManager::switchScene(Window & window, Scene * new_scene) { + void SceneManager::setScene(Scene * scene) { if(this->_current != nullptr) { this->_current->destroy(); } - - this->_current = new_scene; - this->_current->initialize(window); + + this->_current = scene; + this->_current->initialize(); } - void SceneManager::render(double current_time) { + void SceneManager::render(const Camera & camera, double current_time) { if(this->_current != nullptr) { double deltaTime = this->_chronometer.getElapsedTime().seconds; this->_chronometer.restart(); @@ -36,7 +36,7 @@ namespace pg { this->_accumulator -= this->_timestep; } - this->_current->render(current_time); + this->_current->render(camera, current_time); } } } \ No newline at end of file diff --git a/ParticleGenerator/src/Scene/SceneManager.hpp b/ParticleGenerator/src/Scene/SceneManager.hpp index 74559de7298c9738e051e939f6cd5ad21df613a1..a8e8004b9e228dd32a40860403921131a53d290a 100644 --- a/ParticleGenerator/src/Scene/SceneManager.hpp +++ b/ParticleGenerator/src/Scene/SceneManager.hpp @@ -8,6 +8,8 @@ #include "../System/Window.hpp" #include "../System/Chronometer.hpp" +#include "../Renderer/Camera/Camera.hpp" + #include "../Interface/SceneManagerInterface.hpp" namespace pg { @@ -22,7 +24,7 @@ namespace pg { SceneManagerInterface _interface; public: - SceneManager(Window &, Scene * = nullptr); + SceneManager(Scene * = nullptr); ~SceneManager(); inline Scene * current() const {return this->_current;} @@ -31,9 +33,9 @@ namespace pg { inline void add(Scene & scene) {this->_scenes.push_back(&scene);} - void switchScene(Window &, Scene *); + void setScene(Scene *); - virtual void render(double); + virtual void render(const Camera &, double); friend class SceneManagerInterface; }; diff --git a/ParticleGenerator/src/System/FrameCounter.hpp b/ParticleGenerator/src/System/FrameCounter.hpp index e42f6f03b683dc5476176cb39d41acd1150caccf..a57cc34ae468a06e7b40273dbfc1a79ad646162b 100644 --- a/ParticleGenerator/src/System/FrameCounter.hpp +++ b/ParticleGenerator/src/System/FrameCounter.hpp @@ -9,6 +9,7 @@ namespace pg { double _fps; double _previous; double _cfps; + bool _update; public: FrameCounter() : _fps(0),_previous(),_cfps() {} @@ -19,9 +20,16 @@ namespace pg { this->_previous = current; this->_cfps = this->_fps; this->_fps = 0; + this->_update = true; } } + inline bool isUpdated() { + bool current = this->_update; + this->_update = false; + return current; + } + inline double getFramePerSecond() const { return this->_cfps; } diff --git a/ParticleGenerator/src/System/FrameHistorical.cpp b/ParticleGenerator/src/System/FrameHistorical.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49196f6c361365214f688aa14ac3b6fde081d2e8 --- /dev/null +++ b/ParticleGenerator/src/System/FrameHistorical.cpp @@ -0,0 +1,27 @@ +#include "FrameHistorical.hpp" + +#include <imgui.h> +#include <algorithm> + +namespace pg { + FrameHistorical::FrameHistorical() { + for(short i = 0; i < 100; i++) { + this->_frames.push_back(0); + } + } + + void FrameHistorical::render(double current_time) { + if(this->isUpdated()) { + this->_frames.push_back(this->getFramePerSecond()); + if(this->_frames.size() > 100) { + this->_frames.erase(this->_frames.begin()); + } + } + + if(!this->_frames.empty()) { + float max = *std::max_element(this->_frames.begin(), this->_frames.end()); + ImGui::Text("Frame Per Second : %f", this->getFramePerSecond()); + ImGui::PlotLines("", this->_frames.data(), static_cast<int>(this->_frames.size()), 0, NULL, 0.0f, max * 1.1f, ImVec2(0, 80)); + } + } +} \ No newline at end of file diff --git a/ParticleGenerator/src/System/FrameHistorical.hpp b/ParticleGenerator/src/System/FrameHistorical.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f1154c12f11a3f6efbdbcec277465889844d0204 --- /dev/null +++ b/ParticleGenerator/src/System/FrameHistorical.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "FrameCounter.hpp" +#include "../Interface/Interface.hpp" + +#include <vector> + +namespace pg { + class FrameHistorical : public FrameCounter, public Interface { + private: + std::vector<float> _frames; + + public: + FrameHistorical(); + + virtual void render(double); + }; +} \ No newline at end of file diff --git a/ParticleGenerator/src/System/Window.cpp b/ParticleGenerator/src/System/Window.cpp index d6a3d0c9c2d64f07348d3a17d5f6b8cf7364949f..658e954dde32692847d263dd4e42c9b72d9bd4cd 100644 --- a/ParticleGenerator/src/System/Window.cpp +++ b/ParticleGenerator/src/System/Window.cpp @@ -4,8 +4,8 @@ #include <stdexcept> namespace pg { - Window::Window(const std::string & title, uint16_t width, uint16_t height) - : _window(), _title(title), _width(width), _height(height) { + Window::Window(const std::string & title, uint16_t width, uint16_t height, bool doubleBuffering) + : _window(), _title(title), _width(width), _height(height), _doubleBuffering(doubleBuffering) { if(glfwInit() == GLFW_FALSE) { throw std::runtime_error("GLFW Init Error"); } @@ -95,7 +95,8 @@ namespace pg { glfwSetWindowSizeCallback(this->_window.value(), [](GLFWwindow * window, int w, int h) -> void {glViewport(0, 0, w, h);}); this->makeContextCurrent(); - glfwSwapInterval(1); + + glfwSwapInterval(this->_doubleBuffering); } } diff --git a/ParticleGenerator/src/System/Window.hpp b/ParticleGenerator/src/System/Window.hpp index 83b5b1c3388cca740de74589fc246d934777dd4e..53503e7bfc39db7c975363e914adc68df4ac8b45 100644 --- a/ParticleGenerator/src/System/Window.hpp +++ b/ParticleGenerator/src/System/Window.hpp @@ -12,16 +12,10 @@ namespace pg { std::optional<GLFWwindow *> _window; std::string _title; uint16_t _width, _height; + bool _doubleBuffering; public: - enum Properties { - VISIBLE = 1, - RESIZABLE = 2, - DECORATED = 4, - DOUBLE_BUFFER = 8, - }; - - Window(const std::string & , uint16_t, uint16_t); + Window(const std::string & , uint16_t, uint16_t, bool = true); ~Window(); inline GLFWwindow * address() const {return this->_window.has_value() ? this->_window.value() : NULL;} @@ -34,12 +28,15 @@ namespace pg { void setTitle(const std::string &); void setFullscreen(bool); + inline void setDoubleBuffering(bool state) {this->_doubleBuffering = state;} void swapBuffer() const; void pollEvents() const; void makeContextCurrent() const; + inline bool isDoubleBuffering() const {return this->_doubleBuffering;} + void open(bool = false); void close(); diff --git a/ParticleGenerator/src/main.cpp b/ParticleGenerator/src/main.cpp index 3da4aa3ecdc27c42e6ac7e8756687e7535463673..f4854fb2de7ad72260ce0285595c3b24a3df52c9 100644 --- a/ParticleGenerator/src/main.cpp +++ b/ParticleGenerator/src/main.cpp @@ -5,10 +5,13 @@ #include "System/Window.hpp" #include "Scene/SceneManager.hpp" #include "Scene/PhysicScene.hpp" +#include "Scene/PathScene.hpp" #include "Interface/GlobalInterface.hpp" #include "Renderer/Error/OpenGLError.hpp" +#include <CurveTools/CPU/BezierGenerator.hpp> + #define WINDOW_DEFAULT_WIDTH 1600 #define WINDOW_DEFAULT_HEIGHT 900 @@ -25,18 +28,48 @@ int main(int argc, const char * argv[]) { glViewport(0, 0, WINDOW_DEFAULT_WIDTH, WINDOW_DEFAULT_HEIGHT); pg::error::OpenGLError::check(); - pg::PhysicScene scene; + pg::OrbitCamera camera({0, 0, 3}); - pg::SceneManager manager(window, &scene); - pg::GlobalInterface interface(window, manager, "Particle Generator Settings"); + { + glfwSetWindowUserPointer(window.address(), (void *)&camera); + + glfwSetCursorPosCallback(window.address(), [](GLFWwindow* window, double xpos, double ypos) { + pg::OrbitCamera* camera = static_cast<pg::OrbitCamera*>(glfwGetWindowUserPointer(window)); + camera->onMove(static_cast<unsigned int>(xpos), static_cast<unsigned int>(ypos)); + }); - manager.add(scene); + glfwSetMouseButtonCallback(window.address(), [](GLFWwindow* window, int button, int action, int mods) { + pg::OrbitCamera* camera = static_cast<pg::OrbitCamera*>(glfwGetWindowUserPointer(window)); + if (button == GLFW_MOUSE_BUTTON_RIGHT) { + if(action == GLFW_PRESS) { + camera->onMoveBegin(); + } + else if(action == GLFW_RELEASE) { + camera->onMoveEnd(); + } + } + }); + + glfwSetScrollCallback(window.address(), [](GLFWwindow* window, double xoffset, double yoffset) { + pg::OrbitCamera* camera = static_cast<pg::OrbitCamera*>(glfwGetWindowUserPointer(window)); + camera->onScroll(static_cast<int>(yoffset)); + }); + } + + pg::PhysicScene physic_scene; + //pg::PathScene path_scene; + + pg::SceneManager manager(&physic_scene); + manager.add(physic_scene); + //manager.add(path_scene); + + pg::GlobalInterface interface(window, manager, "Particle Generator Settings"); while(window.isOpen()) { window.pollEvents(); double current_time = glfwGetTime(); - manager.render(current_time); + manager.render(camera, current_time); interface.render(current_time); window.swapBuffer(); diff --git a/ParticleGenerator/src/main.cpp.old b/ParticleGenerator/src/main.cpp.old deleted file mode 100644 index c483f2651bf588f718e8a740c14cea5323a660ac..0000000000000000000000000000000000000000 --- a/ParticleGenerator/src/main.cpp.old +++ /dev/null @@ -1,277 +0,0 @@ -#include <GL/glew.h> - -#include <iostream> -#include <vector> -#include <chrono> -#include <thread> - -#include <glm/gtc/matrix_transform.hpp> -#include <CurveTools/CPU/BezierGenerator.hpp> -#include <CurveTools/CPU/BSplineGenerator.hpp> - -#include "Renderer/Renderer.hpp" -#include "Renderer/Mesh/Mesh.hpp" - -#include "System/Window.hpp" -#include "System/Chronometer.hpp" -#include "System/FrameCounter.hpp" - -#include "Particle/generator/PhysicsParticleGenerator.hpp" -#include "Particle/generator/PathParticleGenerator.hpp" - -#include "Interface/Interface.hpp" -#include "Interface/PhysicConfig.hpp" -#include "Interface/PathConfig.hpp" - -#define WINDOW_DEFAULT_WIDTH 1600 -#define WINDOW_DEFAULT_HEIGHT 900 - -int main(int argc, const char * argv[]) { - try { - //? GLFW - pg::Window window("Scene", WINDOW_DEFAULT_WIDTH, WINDOW_DEFAULT_HEIGHT); - window.open(); - - std::cout << "GLFW" << std::endl; - - //? GLEW - if (glewInit()) { - std::cout << "Failed to initialize GLEW" << std::endl; - return EXIT_FAILURE; - } - - std::cout << "GLEW" << std::endl; - pg::error::OpenGLError::check(); - - //? Camera - pg::OrbitCamera camera({0, 0, 3}, {0, 0, 0}); - glfwSetWindowUserPointer(window.address(), (void *)&camera); - - glfwSetCursorPosCallback(window.address(), [](GLFWwindow* window, double xpos, double ypos) { - pg::OrbitCamera* camera = static_cast<pg::OrbitCamera*>(glfwGetWindowUserPointer(window)); - camera->onMove(static_cast<unsigned int>(xpos), static_cast<unsigned int>(ypos)); - }); - - glfwSetMouseButtonCallback(window.address(), [](GLFWwindow* window, int button, int action, int mods) { - pg::OrbitCamera* camera = static_cast<pg::OrbitCamera*>(glfwGetWindowUserPointer(window)); - - if (button == GLFW_MOUSE_BUTTON_RIGHT) { - if(action == GLFW_PRESS) { - camera->onMoveBegin(); - } - else if(action == GLFW_RELEASE) { - camera->onMoveEnd(); - } - } - }); - - glfwSetScrollCallback(window.address(), [](GLFWwindow* window, double xoffset, double yoffset) { - pg::OrbitCamera* camera = static_cast<pg::OrbitCamera*>(glfwGetWindowUserPointer(window)); - camera->onScroll(static_cast<int>(yoffset)); - }); - - std::cout << "Camera" << std::endl; - pg::error::OpenGLError::check(); - - //? Shaders - pg::Source vertices("../../res/shaders/Instanced-Fat.vert", pg::Source::Categorie::VERTEX); - pg::Source fragment("../../res/shaders/Instanced-Fat.frag", pg::Source::Categorie::FRAGMENT); - - pg::Program program; - - program << vertices; - program << fragment; - - program.link(); - - std::cout << "Shader" << std::endl; - pg::error::OpenGLError::check(); - - //? Buffer - pg::Mesh mesh("../../res/models/DolSoccerball.obj"); - - pg::VertexArray vao; - pg::VerticeBuffer vbo(vao, {pg::layout::Value::POSITION, pg::layout::Value::NORMAL}); - pg::ElementBuffer ebo(vao); - - vbo << mesh._vertices; - ebo << mesh._indices; - - //mesh.getTextures().at(0).bind(0); - - std::cout << "Mesh" << std::endl; - pg::error::OpenGLError::check(); - - //? UBO - - vao.bind(); - GLuint model_ubo; - - glCreateBuffers(1, &model_ubo); - glBindBuffer(GL_UNIFORM_BUFFER, model_ubo); - glBufferData(GL_UNIFORM_BUFFER, 1024 * sizeof(glm::mat4), nullptr, GL_DYNAMIC_DRAW); - - GLuint uniforme_index = glGetUniformBlockIndex(program.id(), "uModels_t"); - glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, model_ubo); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - vao.unbind(); - - std::cout << "UBO" << std::endl; - pg::error::OpenGLError::check(); - - //? Texture - //pg::Material A("../../res/textures/smoke1.png", true); - //A.bind(0); - - pg::error::OpenGLError::check(); - - //? Viewport - glViewport(0, 0, WINDOW_DEFAULT_WIDTH, WINDOW_DEFAULT_HEIGHT); - pg::error::OpenGLError::check(); - - //? Particle - pg::PhysicsParticleGenerator physic_generator({0.0, 0.0, 0.0}, 0.5, {0, 0.0001, 0}); - physic_generator.setAcceleration({0, 0.0001, 0}); - - ct::BezierGenerator bezier_generator; - std::vector<ct::Point> ctrlPoints = { - {-10.0, 0.0, 0.0}, - { 10.0, 0.0, 0.0} - }; - - pg::PathParticleGenerator path_generator(&bezier_generator, ctrlPoints); - path_generator.setParameterLifeLimitor(1.0f); - path_generator.setParameterIncrement(0.01); - - pg::ParticleGenerator * generator = &physic_generator; - - std::vector<std::unique_ptr<pg::Particle>> particles = generator->generate(5); - - //? Interface - pg::PhysicConfig physic_config(&physic_generator); - pg::PathConfig path_config(&path_generator); - std::vector<pg::Config *> configs; - configs.push_back(&physic_config); - configs.push_back(&path_config); - - pg::Interface interface(window.address(), &physic_config); - - //? Render Loop - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - - std::cout << "Render Loop Start" << std::endl; - - pg::Chronometer chronometer; - float accumulator = 0.0f; - float timeStep = 1.0f / 60.0f; - - GLint slot = 0; - auto start = std::chrono::high_resolution_clock::now(); - - pg::FrameCounter counter; - - while(window.isOpen()) { - //? Updating - double current_time = glfwGetTime(); - window.pollEvents(); - - double deltaTime = chronometer.getElapsedTime().seconds; - chronometer.restart(); - - accumulator += static_cast<float>(deltaTime); - - while (accumulator >= timeStep) { - auto end = std::chrono::high_resolution_clock::now(); - pg::Particle::purge(particles, static_cast<size_t>(current_time), interface.getLifeTime()); - if (duration_cast<std::chrono::milliseconds>(end - start).count() >= interface.getSpawnFrequence()) { - start = std::chrono::high_resolution_clock::now(); - - if((interface.getSpawnCount() + particles.size()) <= 1024 && interface.isSpawningEnable()) { - std::vector<std::unique_ptr<pg::Particle>> newParticles = generator->generate(interface.getSpawnCount(), static_cast<size_t>(current_time)); - particles.insert(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 : particles) { - particle->update(0.0); - } - } - - accumulator -= timeStep; - } - - //? Rendering - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - const glm::mat4 VIEW_MATRIX = camera.getViewMatrix(); - const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix(); - - std::vector<glm::mat4> models; - std::vector<float> lifetimes; - - for(auto & particle : particles) { - glm::mat4 model = glm::mat4(1.0); - model = glm::translate(model, glm::vec3(particle->getPosition())); - models.push_back(model); - - lifetimes.push_back(static_cast<float>(particle->getBorn())); - } - - pg::error::OpenGLError::check(true); - - glBindBuffer(GL_UNIFORM_BUFFER, model_ubo); - glBufferSubData(GL_UNIFORM_BUFFER, 0, models.size() * sizeof(glm::mat4), models.data()); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - - { - program.use(); - - program.setUniform("uView", VIEW_MATRIX); - program.setUniform("uProj", PROJECTION_MATRIX); - - program.setUniform("uSlots", slot); - program.setUniform("uColor", interface.getColor()); - - pg::error::OpenGLError::check(); - - vao.bind(); - vbo.bind(); - - if(interface.isRenderEnable()) { - glDrawElementsInstanced(GL_TRIANGLES, static_cast<GLsizei>(ebo.size()), GL_UNSIGNED_INT, 0, static_cast<GLsizei>(particles.size())); - } - } - - counter.count(glfwGetTime()); - - interface.setFps(counter.getFramePerSecond()); - interface.render(particles, configs, glfwGetTime()); - - if(interface.getConfig() == &path_config) { - generator = &path_generator; - } - else if(interface.getConfig() == &physic_config) { - generator = &physic_generator; - } - - window.swapBuffer(); - } - - glDeleteBuffers(1, &model_ubo); - - pg::error::OpenGLError::check(); - std::cout << "Render Loop End" << std::endl; - } - catch(std::exception & error) { - std::cerr << error.what() << std::endl; - } - - std::cout << "Program End" << std::endl; - - return EXIT_SUCCESS; -} \ No newline at end of file