diff --git a/ParticleGenerator/res/config/imgui.ini b/ParticleGenerator/res/config/imgui.ini index 1e77131901dcf5b7e126f8d05fb0515ea7ed300a..36effb4dfb9021f787afd278a3c641a86ae0c1bb 100644 --- a/ParticleGenerator/res/config/imgui.ini +++ b/ParticleGenerator/res/config/imgui.ini @@ -2,7 +2,11 @@ Pos=60,60 Size=400,400 +[Window][Dear ImGui Demo] +Pos=891,315 +Size=550,680 + [Window][Particle Generator] Pos=60,60 -Size=838,505 +Size=263,184 diff --git a/ParticleGenerator/res/fonts/Tahoma/tahoma.ttf b/ParticleGenerator/res/fonts/Tahoma/tahoma.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aad8819efbd6a4988ec0f371e0f1c03f10963f0b Binary files /dev/null and b/ParticleGenerator/res/fonts/Tahoma/tahoma.ttf differ diff --git a/ParticleGenerator/res/shaders/scene/Billboard-Sprite.frag b/ParticleGenerator/res/shaders/scene/Billboard-Sprite.frag new file mode 100644 index 0000000000000000000000000000000000000000..1c629490342c04b8b7c63a4d4141a8fe06e2e877 --- /dev/null +++ b/ParticleGenerator/res/shaders/scene/Billboard-Sprite.frag @@ -0,0 +1,17 @@ +#version 330 core +out vec4 FragColor; + +in vec2 zTex; +in vec4 zFrame; + +uniform sampler2D uTexture; +uniform vec2 uSize; +uniform vec4 uColor; + +void main() { + vec2 coord = vec2( + (zFrame.x / uSize.x) + (zFrame.z / uSize.x) * zTex.x, + (zFrame.y / uSize.y) + (zFrame.w / uSize.y) * zTex.y + ); + FragColor = texture(uTexture, coord) * uColor; +} \ No newline at end of file diff --git a/ParticleGenerator/res/shaders/scene/Billboard-Sprite.vert b/ParticleGenerator/res/shaders/scene/Billboard-Sprite.vert new file mode 100644 index 0000000000000000000000000000000000000000..3acbb234179a87c363012f9c5d854d2d5ae19886 --- /dev/null +++ b/ParticleGenerator/res/shaders/scene/Billboard-Sprite.vert @@ -0,0 +1,28 @@ +#version 460 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTex; + +layout(std140) uniform uParticle_t { + mat4 models[512]; + vec4 frames[512]; +}; + +uniform mat4 uView; +uniform mat4 uProj; + +out vec2 zTex; +out vec4 zFrame; + +void main() { + vec3 cameraRight = vec3(uView[0][0], uView[1][0], uView[2][0]); + vec3 cameraUp = vec3(uView[0][1], uView[1][1], uView[2][1]); + vec3 particlePosition = vec3(models[gl_InstanceID][0][3], models[gl_InstanceID][1][3], models[gl_InstanceID][2][3]); + vec2 particleSize = vec2(1.0, 1.0); + + vec3 vertexPosition = particlePosition + cameraRight * aPos.x * particleSize.x + cameraUp * aPos.y * particleSize.y; + + gl_Position = uProj * uView * models[gl_InstanceID] * vec4(vertexPosition, 1.0); + zTex = aTex; + zFrame = frames[gl_InstanceID]; +} \ No newline at end of file diff --git a/ParticleGenerator/res/textures/SpriteParticleTest.png b/ParticleGenerator/res/textures/SpriteParticleTest.png new file mode 100644 index 0000000000000000000000000000000000000000..2a56e53e96e3cebb4d0d7535c1c81d103c870570 Binary files /dev/null and b/ParticleGenerator/res/textures/SpriteParticleTest.png differ diff --git a/ParticleGenerator/res/textures/cube.png b/ParticleGenerator/res/textures/cube.png index 5b57aaa3e14e27edaa312ebd78a7a3cb98d935d9..119762be282e6e41c5e08f8b7dd2cab920b6bc5e 100644 Binary files a/ParticleGenerator/res/textures/cube.png and b/ParticleGenerator/res/textures/cube.png differ diff --git a/ParticleGenerator/src/Interface/Generator/PathGenerator.cpp b/ParticleGenerator/src/Interface/Generator/PathGenerator.cpp index 7b542eca33928fe23174c9efb7bb55bab275b8ef..188915407ac088b51884bb1c1c3107ad82935c34 100644 --- a/ParticleGenerator/src/Interface/Generator/PathGenerator.cpp +++ b/ParticleGenerator/src/Interface/Generator/PathGenerator.cpp @@ -13,33 +13,29 @@ namespace pg::interface { _next(0.f, 0.f, 0.f), _index(0) {} - void PathGenerator::draw(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::Separator(); - ImGui::Text("Default u : %f", this->_generator->m_u); - ImGui::Text("u increment : %f", this->_generator->m_increment); - ImGui::Separator(); - ImGui::Text("Spacing : %f", this->_generator->m_spacing); - ImGui::Text("Life Limitor : %f", this->_generator->m_limitor); - } + void PathGenerator::draw(double current_time) { + ImGui::Text("Physic generator at %f / %f / %f (x, y, z) - variation : %f.", this->parent()->m_position.x, this->parent()->m_position.y, this->parent()->m_position.z, this->parent()->m_positionVariation); + ImGui::Text("Default u : %f", this->parent()->m_u); + ImGui::Text("u increment : %f", this->parent()->m_increment); + ImGui::Text("Spacing : %f", this->parent()->m_spacing); + ImGui::Text("Life Limitor : %f", this->parent()->m_limitor); if(ImGui::CollapsingHeader("Generator Position")) { - ImGui::DragFloat3("Generator Position (x, y, z)", &this->_generator->m_position[0], 0.1f); - ImGui::SliderFloat3("Generator Roation (x, y, z)", &this->_generator->m_rotation[0], -360.f, 360.f); - ImGui::DragFloat("Position Variation", &this->_generator->m_positionVariation, 0.001f, 0.f, 0.f, "%.4f"); + ImGui::DragFloat3("Generator Position (x, y, z)", &this->parent()->m_position[0], 0.1f); + ImGui::SliderFloat3("Generator Roation (x, y, z)", &this->parent()->m_rotation[0], -360.f, 360.f); + ImGui::DragFloat("Position Variation", &this->parent()->m_positionVariation, 0.001f, 0.f, 0.f, "%.4f"); } if(ImGui::CollapsingHeader("Parameter")) { - ImGui::InputFloat("Parameter Default Value", &this->_generator->m_u, 0.1f, 0.5f); - ImGui::DragFloat("Parameter Increment Value", &this->_generator->m_increment, 0.01f); - ImGui::DragFloat("Spacing", &this->_generator->m_spacing, 0.001f); - ImGui::InputFloat("Life Limitor", &this->_generator->m_limitor, 1.0f, 2.0f); + ImGui::InputFloat("Parameter Default Value", &this->parent()->m_u, 0.1f, 0.5f); + ImGui::DragFloat("Parameter Increment Value", &this->parent()->m_increment, 0.01f); + ImGui::DragFloat("Spacing", &this->parent()->m_spacing, 0.001f); + ImGui::InputFloat("Life Limitor", &this->parent()->m_limitor, 1.0f, 2.0f); } if(ImGui::CollapsingHeader("Control Points")) { - for(size_t i = 0; i < this->_generator->m_controlPoints.size(); ++i) { - glm::vec3 current = static_cast<glm::vec3>(this->_generator->m_controlPoints[i]); + for(size_t i = 0; i < this->parent()->m_controlPoints.size(); ++i) { + glm::vec3 current = static_cast<glm::vec3>(this->parent()->m_controlPoints[i]); ImGui::Text("%i : %f / %f / %f.", i, current.x, current.y, current.z); } @@ -50,40 +46,38 @@ namespace pg::interface { ImGui::TextColored(ImVec4(0.75f, 0.f, 0.f, 1.f), "Negative index !"); } else { - if(this->_index > this->_generator->getControlPoint().size()) { + if(this->_index > this->parent()->getControlPoint().size()) { ImGui::TextColored(ImVec4(1.f, 1.f, 0.f, 1.f), "Index out of range, new point will be at the back !"); } if(ImGui::Button("Push Point")) { - if(this->_index > this->_generator->getControlPoint().size()) { - this->_generator->m_controlPoints.push_back(static_cast<ct::Point>(this->_next)); + if(this->_index > this->parent()->getControlPoint().size()) { + this->parent()->m_controlPoints.push_back(static_cast<ct::Point>(this->_next)); } else { - this->_generator->m_controlPoints.insert(this->_generator->m_controlPoints.begin() + this->_index, static_cast<ct::Point>(this->_next)); + this->parent()->m_controlPoints.insert(this->parent()->m_controlPoints.begin() + this->_index, static_cast<ct::Point>(this->_next)); } if(this->_trajectory != nullptr) { - this->_trajectory->update(); + this->_trajectory->update(current_time); } } ImGui::SameLine(); if(ImGui::Button("Pop Point")) { - if(this->_index > this->_generator->getControlPoint().size()) { - this->_generator->m_controlPoints.pop_back(); + if(this->_index > this->parent()->getControlPoint().size()) { + this->parent()->m_controlPoints.pop_back(); } else { - this->_generator->m_controlPoints.erase(this->_generator->m_controlPoints.begin() + this->_index); + this->parent()->m_controlPoints.erase(this->parent()->m_controlPoints.begin() + this->_index); } if(this->_trajectory != nullptr) { - this->_trajectory->update(); + this->_trajectory->update(current_time); } } } - }*/ - - ImGui::Text("Path Generator : %i", this->parent()); + } } } diff --git a/ParticleGenerator/src/Interface/Generator/PhysicGenerator.cpp b/ParticleGenerator/src/Interface/Generator/PhysicGenerator.cpp index 1749e46b5f3d85f830387eebe65a5803a609fa82..cf3cdb0114b86869d3e2b733b9a61e5d1ed34870 100644 --- a/ParticleGenerator/src/Interface/Generator/PhysicGenerator.cpp +++ b/ParticleGenerator/src/Interface/Generator/PhysicGenerator.cpp @@ -11,50 +11,48 @@ namespace pg::interface { : Generator(parent) {} void PhysicGenerator::draw(double) { - /*if(this->_generator == nullptr) { + if(this->parent() == nullptr) { return; } - 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); - } + ImGui::Text("Physic generator at %f / %f / %f (x, y, z) - variation : %f.", this->parent()->m_position.x, this->parent()->m_position.y, this->parent()->m_position.z, this->parent()->m_positionVariation); + ImGui::SeparatorText("Velocity"); + ImGui::Text("X : %f - variation : [%f , %f].", this->parent()->m_velocity.x, this->parent()->m_velocityVariation.lower.x, this->parent()->m_velocityVariation.upper.x); + ImGui::Text("Y : %f - variation : [%f , %f].", this->parent()->m_velocity.y, this->parent()->m_velocityVariation.lower.y, this->parent()->m_velocityVariation.upper.y); + ImGui::Text("Z : %f - variation : [%f , %f].", this->parent()->m_velocity.z, this->parent()->m_velocityVariation.lower.z, this->parent()->m_velocityVariation.upper.z); + ImGui::SeparatorText("Acceleration"); + ImGui::Text("X : %f - variation : [%f , %f].", this->parent()->m_acceleration.x, this->parent()->m_accelerationVariation.lower.x, this->parent()->m_accelerationVariation.upper.x); + ImGui::Text("Y : %f - variation : [%f , %f].", this->parent()->m_acceleration.y, this->parent()->m_accelerationVariation.lower.y, this->parent()->m_accelerationVariation.upper.y); + ImGui::Text("Z : %f - variation : [%f , %f].", this->parent()->m_acceleration.z, this->parent()->m_accelerationVariation.lower.z, this->parent()->m_accelerationVariation.upper.z); + ImGui::SeparatorText("Friction"); + ImGui::Text("X : %f - variation : [0 , %f].", this->parent()->m_friction.x, this->parent()->m_frictionVariation.x); + ImGui::Text("Y : %f - variation : [0 , %f].", this->parent()->m_friction.y, this->parent()->m_frictionVariation.y); + ImGui::Text("Z : %f - variation : [0 , %f].", this->parent()->m_friction.z, this->parent()->m_frictionVariation.z); if(ImGui::CollapsingHeader("Generator Position")) { - ImGui::DragFloat3("Generator Position (x, y, z)", &this->_generator->m_position[0], 0.1f); - ImGui::SliderFloat3("Generator Roation (x, y, z)", &this->_generator->m_rotation[0], -360.f, 360.f); - ImGui::DragFloat("Position Variation", &this->_generator->m_positionVariation, 0.01f, 0.f, 0.f, "%.4f"); + ImGui::DragFloat3("Generator Position (x, y, z)", &this->parent()->m_position[0], 0.1f); + ImGui::SliderFloat3("Generator Roation (x, y, z)", &this->parent()->m_rotation[0], -360.f, 360.f); + ImGui::DragFloat("Position Variation", &this->parent()->m_positionVariation, 0.01f, 0.f, 0.f, "%.4f"); } if(ImGui::CollapsingHeader("Generation Settings")) { - ImGui::DragFloat3("Velocity (x, y, z)", &this->_generator->m_velocity[0], 0.0001f, 0.f, 0.f, "%.4f"); - ImGui::DragFloat3("Acceleration (x, y, z)", &this->_generator->m_acceleration[0], 0.0001f, 0.f, 0.f, "%.4f"); - ImGui::DragFloat3("Friction (x, y, z)", &this->_generator->m_friction[0], 0.0001f, 0.f, 0.f, "%.4f"); + ImGui::DragFloat3("Velocity (x, y, z)", &this->parent()->m_velocity[0], 0.0001f, 0.f, 0.f, "%.4f"); + ImGui::DragFloat3("Acceleration (x, y, z)", &this->parent()->m_acceleration[0], 0.0001f, 0.f, 0.f, "%.4f"); + ImGui::DragFloat3("Friction (x, y, z)", &this->parent()->m_friction[0], 0.0001f, 0.f, 0.f, "%.4f"); } if(ImGui::CollapsingHeader("Variation")) { ImGui::SeparatorText("Velocity"); - ImGui::DragFloat3("Upper Boundary (x, y, z)", &this->_generator->m_velocityVariation.upper[0], 0.0001f, 0.f, 0.f, "%.4f"); - ImGui::DragFloat3("Lower Boundary (x, y, z)", &this->_generator->m_velocityVariation.lower[0], 0.0001f, 0.f, 0.f, "%.4f"); + ImGui::DragFloat3("Upper Boundary (x, y, z)", &this->parent()->m_velocityVariation.upper[0], 0.0001f, 0.f, 0.f, "%.4f"); + ImGui::DragFloat3("Lower Boundary (x, y, z)", &this->parent()->m_velocityVariation.lower[0], 0.0001f, 0.f, 0.f, "%.4f"); ImGui::SeparatorText("Acceleration"); ImGui::PushID(1); - ImGui::DragFloat3("Upper Boundary (x, y, z)", &this->_generator->m_accelerationVariation.upper[0], 0.0001f, 0.f, 0.f, "%.4f"); - ImGui::DragFloat3("Lower Boundary (x, y, z)", &this->_generator->m_accelerationVariation.lower[0], 0.0001f, 0.f, 0.f, "%.4f"); + ImGui::DragFloat3("Upper Boundary (x, y, z)", &this->parent()->m_accelerationVariation.upper[0], 0.0001f, 0.f, 0.f, "%.4f"); + ImGui::DragFloat3("Lower Boundary (x, y, z)", &this->parent()->m_accelerationVariation.lower[0], 0.0001f, 0.f, 0.f, "%.4f"); ImGui::PopID(); ImGui::SeparatorText("Friction"); - ImGui::DragFloat3("Variation", &this->_generator->m_frictionVariation[0], 0.0001f, 0.f, 0.f, "%.4f"); - }*/ + ImGui::DragFloat3("Variation", &this->parent()->m_frictionVariation[0], 0.0001f, 0.f, 0.f, "%.4f"); + } ImGui::Text("Physic Generator : %i", this->parent()); } } diff --git a/ParticleGenerator/src/Interface/Interface.hpp b/ParticleGenerator/src/Interface/Interface.hpp index 2c94bf6feddd55f5e1836a5777c889593a641c2e..e8fada937cad3caafd3e47335476351ae1cb5d6a 100644 --- a/ParticleGenerator/src/Interface/Interface.hpp +++ b/ParticleGenerator/src/Interface/Interface.hpp @@ -42,5 +42,6 @@ namespace pg::interface { virtual ~Generator() = default; inline T * parent() const {return this->_parent;} + inline void setParent(T * parent) {this->_parent = parent;} }; } \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Manager.cpp b/ParticleGenerator/src/Interface/Manager.cpp index 11bbdd73b51d5e47d446c112bb7338888ba36ec1..bdb1403fef97fcf9e45ff363b773049b301b414e 100644 --- a/ParticleGenerator/src/Interface/Manager.cpp +++ b/ParticleGenerator/src/Interface/Manager.cpp @@ -1,6 +1,7 @@ #include "Manager.hpp" #include "../Scene/Manager.hpp" +#include "Style/Red.hpp" #include <imgui.h> #include <imgui_impl_glfw.h> @@ -14,6 +15,10 @@ namespace pg::interface { ImGui_ImplGlfw_InitForOpenGL(window.address(), true); ImGui_ImplOpenGL3_Init("#version 330 core"); + + ImGuiStyle & style = ImGui::GetStyle(); + style::Red red; + red.apply(style); } Manager::~Manager() { @@ -29,38 +34,31 @@ namespace pg::interface { ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); + ImGui::ShowDemoWindow(); + this->_historical.count(current_time); if(ImGui::Begin(this->_title.c_str())) { + if(ImGui::CollapsingHeader("Performaces")) { + this->_historical.draw(current_time); + } + auto current = this->_manager.current(); - if(ImGui::BeginTabBar("")) { - if(ImGui::BeginTabItem("Scene")) { - if(!this->_manager.getScenes().empty()) { - std::string name = !current.has_value() ? (*this->_manager.getScenes().begin())->name() : (*current)->name(); - if(ImGui::BeginCombo("Current Scene", name.c_str())) { - for(auto & scene : this->_manager.getScenes()) { - bool is_selected = (scene->name() == name); - if(ImGui::Selectable(scene->name().c_str(), is_selected)) { - this->_manager.setCurrent(*scene); - } - } - ImGui::EndCombo(); + if(!this->_manager.getScenes().empty()) { + std::string name = !current.has_value() ? (*this->_manager.getScenes().begin())->name() : (*current)->name(); + if(ImGui::BeginCombo("Current Scene", name.c_str())) { + for(auto & scene : this->_manager.getScenes()) { + bool is_selected = (scene->name() == name); + if(ImGui::Selectable(scene->name().c_str(), is_selected)) { + this->_manager.setCurrent(*scene); } - ImGui::Separator(); } - - if(current.has_value() && (*current)->interface().has_value()) { - (*(*current)->interface())->draw(current_time); - } - - ImGui::EndTabItem(); + ImGui::EndCombo(); } + } - if(ImGui::BeginTabItem("Performance")) { - this->_historical.draw(current_time); - ImGui::EndTabItem(); - } - ImGui::EndTabBar(); + if(current.has_value() && (*current)->interface().has_value()) { + (*(*current)->interface())->draw(current_time); } } ImGui::End(); diff --git a/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp b/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp index b42950a9c222b941efd4cd1625a1f0aa2c75b785..aeff43f665a9d239e1c23aad0b9a35799436866e 100644 --- a/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp +++ b/ParticleGenerator/src/Interface/Scene/MeshGenerator.cpp @@ -9,52 +9,38 @@ namespace pg::interface { : Scene(parent), SceneParticle(parent), _interface(nullptr) {} void MeshGenerator::draw(double current_time) { - /*ImGui::Text("Particles Number : %i / %i.", this->_scene->_particles.size(), this->_max); - ImGui::SameLine(); - if(ImGui::Button("Spawn")) { - this->_scene->spawn(1, current_time); - } - - ImGui::SameLine(); - if(ImGui::Button("Clear")) { - this->_scene->_particles.clear(); - } - - ImGui::Text("Particles Batchs : %i", static_cast<int>(this->_scene->_particles.size() / 1024) + 1); - ImGui::Separator(); - ImGui::Checkbox("Enable Rendering", &this->_enableRender); - ImGui::Checkbox("Enable Spawning", &this->_enableSpawn); - ImGui::Separator(); - ImGui::InputInt("Lifetime (s)", &this->_lifetime, 1, 2); - ImGui::InputInt("Spawn Frequence (ms)", &this->_spawnFrequence, 100, 500); - ImGui::SliderInt("Spawning Number", &this->_spawnCount, 1, static_cast<int>(this->_max)); - + SceneParticle::draw(current_time); ImGui::SeparatorText("Model"); if(ImGui::Button("Change Model")) { char const * imagePatterns[1] = {"*.obj"}; std::string path = tinyfd_openFileDialog("Model Browser", "", 1, imagePatterns, "Model File", false); - this->_scene->changeMesh(path); + this->parent()->changeMesh(path); } - if(ImGui::CollapsingHeader("Global Genrator Parameter")) { - if(ImGui::Button("Apply")) { - - } + ImGui::SameLine(); + + if(ImGui::Button("Texture")) { + char const * imagePatterns[1] = {"*.png"}; + std::string path = tinyfd_openFileDialog("Model Browser", "", 1, imagePatterns, "Image File", false); + this->parent()->changeTexture(path); } + ImGui::SameLine(); + ImGui::ColorEdit4("Color : ", &this->parent()->_color[0]); + ImGui::SeparatorText("Generators"); - if(!this->_scene->_generators.empty()) { - std::string name = std::to_string(reinterpret_cast<intptr_t>(&this->_scene->_generators.front())); - if(this->_interface.getGenerator() != nullptr) { - name = std::to_string(reinterpret_cast<intptr_t>(this->_interface.getGenerator())); + if(!this->parent()->_generators.empty()) { + std::string name = std::to_string(reinterpret_cast<intptr_t>(&this->parent()->_generators.front())); + if(this->_interface.parent() != nullptr) { + name = std::to_string(reinterpret_cast<intptr_t>(this->_interface.parent())); } if(ImGui::BeginCombo("Current Generator", name.c_str())) { - for(auto & generator : this->_scene->_generators) { - bool is_selected = std::to_string(reinterpret_cast<intptr_t>(&generator)) == std::to_string(reinterpret_cast<intptr_t>(this->_interface.getGenerator())); + for(auto & generator : this->parent()->_generators) { + bool is_selected = std::to_string(reinterpret_cast<intptr_t>(&generator)) == std::to_string(reinterpret_cast<intptr_t>(this->_interface.parent())); if(ImGui::Selectable(std::to_string(reinterpret_cast<intptr_t>(&generator)).c_str(), is_selected)) { - this->_interface.setGenerator(&generator); + this->_interface.setParent(&generator); } if (is_selected) { @@ -64,11 +50,6 @@ namespace pg::interface { ImGui::EndCombo(); } } - - this->_interface.render(current_time);*/ - - SceneParticle::draw(current_time); this->_interface.draw(current_time); - ImGui::Text("Mesh Generator : %i", this->parent()); } } \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Scene/Path.cpp b/ParticleGenerator/src/Interface/Scene/Path.cpp index c533e32d8155f9888218a071e634d9caae874c8a..93678aa620878cc089b4292c79c3252ff9c9091e 100644 --- a/ParticleGenerator/src/Interface/Scene/Path.cpp +++ b/ParticleGenerator/src/Interface/Scene/Path.cpp @@ -6,49 +6,32 @@ #include "../../tfd/tinyfiledialogs.h" namespace pg::interface { - Path::Path(scene::Path * parent, pg::PathParticleGenerator * generator) - : Scene(parent), SceneParticle(parent), _interface(generator) {} + Path::Path(scene::Path * parent, pg::PathParticleGenerator * generator, pg::scene::Trajectory * trajectory) + : Scene(parent), SceneParticle(parent), _interface(generator, trajectory) {} void Path::draw(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(); - } + SceneParticle::draw(current_time); - ImGui::SameLine(); + ImGui::SeparatorText("Texture"); - 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())); + ImGui::Image((void*)(intptr_t)this->parent()->getTexture().identifier(), ImVec2(128, 128), ImVec2(0, 1), ImVec2(1, 0)); + if(ImGui::Button("Change Texture", ImVec2(128, 25))) { + char const * imagePatterns[1] = {"*.png"}; + std::string path = tinyfd_openFileDialog("Image Browser", "", 1, imagePatterns, "Image File", false); + this->parent()->changeParticletexture(path); } + ImGui::SameLine(); + ImGui::ColorEdit4("Color", &this->parent()->_color[0]); - ImGui::Separator(); + ImGui::SeparatorText("Generator"); + + this->_interface.draw(current_time); - if(ImGui::CollapsingHeader("Texture")) { - ImGui::Image((void*)(intptr_t)this->_scene->getTexture().identifier(), ImVec2(256, 256), ImVec2(0, 1), ImVec2(1, 0)); - if(ImGui::Button("Change Texture")) { - char const * imagePatterns[1] = {"*.png"}; - std::string path = tinyfd_openFileDialog("Image Browser", "", 1, imagePatterns, "Image Files", false); - this->_scene->changeParticletexture(path); - } - } + ImGui::SeparatorText("Trajectory"); - this->_interface.render(current_time);*/ - SceneParticle::draw(current_time); - this->_interface.draw(current_time); auto tinterface = this->parent()->_trajectory.interface(); if(tinterface.has_value()) { (*tinterface)->draw(current_time); } - ImGui::Text("Path Scene : %i", this->parent()); } } \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Scene/Path.hpp b/ParticleGenerator/src/Interface/Scene/Path.hpp index c66c3cb4cb17ec23abab89d91089fc3762a424ec..edd89764fe6ad88937b8bcde62ff79398234b5e6 100644 --- a/ParticleGenerator/src/Interface/Scene/Path.hpp +++ b/ParticleGenerator/src/Interface/Scene/Path.hpp @@ -3,6 +3,7 @@ #include "../Interface.hpp" #include "SceneParticle.hpp" #include "../Generator/PathGenerator.hpp" +#include "../../Scene/Scenes/Trajectory.hpp" #include <glm/vec4.hpp> @@ -17,7 +18,7 @@ namespace pg::interface { PathGenerator _interface; public: - Path(scene::Path *, pg::PathParticleGenerator *); + Path(scene::Path *, pg::PathParticleGenerator *, pg::scene::Trajectory * = nullptr); virtual ~Path() = default; virtual void draw(double); diff --git a/ParticleGenerator/src/Interface/Scene/Physic.cpp b/ParticleGenerator/src/Interface/Scene/Physic.cpp index 69d28e69d5d6e0744df745e9421f14557b8754df..4981e663b7e71239b22e6918f527a223f37c1c62 100644 --- a/ParticleGenerator/src/Interface/Scene/Physic.cpp +++ b/ParticleGenerator/src/Interface/Scene/Physic.cpp @@ -12,42 +12,21 @@ namespace pg::interface { : Scene(parent), SceneParticle(parent), _interface(generator) {} void Physic::draw(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())); - } + SceneParticle::draw(current_time); - ImGui::Separator(); + ImGui::SeparatorText("Texture"); - if(ImGui::CollapsingHeader("Texture")) { - ImGui::Image((void*)(intptr_t)this->_scene->getTexture().identifier(), ImVec2(256, 256), ImVec2(0, 1), ImVec2(1, 0)); - if(ImGui::Button("Change Texture")) { - char const * imagePatterns[1] = {"*.png"}; - std::string path = tinyfd_openFileDialog("Image Browser", "", 1, imagePatterns, "Image File", false); - this->_scene->changeParticletexture(path); - } + ImGui::Image((void*)(intptr_t)this->parent()->getTexture().identifier(), ImVec2(128, 128), ImVec2(0, 1), ImVec2(1, 0)); + if(ImGui::Button("Change Texture", ImVec2(128, 25))) { + char const * imagePatterns[1] = {"*.png"}; + std::string path = tinyfd_openFileDialog("Image Browser", "", 1, imagePatterns, "Image File", false); + this->parent()->changeParticletexture(path); } + ImGui::SameLine(); + ImGui::ColorEdit4("Color", &this->parent()->_color[0]); - this->_generator.render(current_time);*/ - SceneParticle::draw(current_time); + ImGui::SeparatorText("Generator"); + this->_interface.draw(current_time); - ImGui::Text("Phsyic Interface : %i", this->parent()); } } \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Scene/SceneParticle.cpp b/ParticleGenerator/src/Interface/Scene/SceneParticle.cpp index 68d169e8035ae8f23cc5522291a4f3507b93676c..52a7e85d36ec5cbaea5452bf0eb4f4fdd280965d 100644 --- a/ParticleGenerator/src/Interface/Scene/SceneParticle.cpp +++ b/ParticleGenerator/src/Interface/Scene/SceneParticle.cpp @@ -8,8 +8,44 @@ namespace pg::interface { SceneParticle::SceneParticle(scene::SceneParticle * scene) : _scene(scene) {} - void SceneParticle::draw(double) { - ImGui::Text("Particule Number : %i / %i", this->_scene->_particles.size(), this->_scene->_max); - ImGui::Text("Scene Particle Interface !"); + void SceneParticle::draw(double current_time) { + ImGui::SeparatorText("Scene Particles"); + int count = static_cast<int>(this->_scene->_particles.size()); + int max = this->_scene->_max; + + ImVec2 size = ImGui::GetWindowSize(); + ImGui::Bullet(); + ImGui::SameLine(); + + ImVec4 color = ImVec4(1.f, 1.f, 1.f, 1.f); + float pc = static_cast<float>(count) / static_cast<float>(max); + if(pc > 0.9f) { + color = ImVec4(0.75f, 0.15f, 0.15f, 1.f); + } + else if(pc > 0.7f) { + color = ImVec4(0.75f, 0.75f, 0.15f, 1.f); + } + + ImGui::TextColored(color, "Particule Number : %i / %i", count, max); + ImGui::ProgressBar(pc); + if(ImGui::Button("Spawn", ImVec2(size.x * 0.5f, 25))) { + this->_scene->spawn(1, current_time); + } + + ImGui::SameLine(); + + if(ImGui::Button("Clear", ImVec2(size.x * 0.5f, 25))) { + this->_scene->_particles.clear(); + } + + ImGui::SeparatorText("Spawning Settings"); + + ImGui::SliderInt("Spawning Numbers", &this->_scene->_spawn, 1, max); + ImGui::DragInt("Spawning Frequence (ms)", &this->_scene->_frequence); + ImGui::DragInt("Lifetime", &this->_scene->_lifetime); + + ImGui::Checkbox("Enable Spawning", &this->_scene->_enableSpawn); + ImGui::Checkbox("Enable Rendering", &this->_scene->_enableRender); + ImGui::Checkbox("Freezing", &this->_scene->_enableFreeze); } } \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Scene/SceneParticle.hpp b/ParticleGenerator/src/Interface/Scene/SceneParticle.hpp index 10f24bc49ca02f636d98a4f215e90496c317bf5a..526d866e1a186382010f54789ee9abea5d51959a 100644 --- a/ParticleGenerator/src/Interface/Scene/SceneParticle.hpp +++ b/ParticleGenerator/src/Interface/Scene/SceneParticle.hpp @@ -9,7 +9,7 @@ namespace pg::scene { namespace pg::interface { class SceneParticle : virtual public Interface { private: - const scene::SceneParticle * _scene; + scene::SceneParticle * _scene; public: SceneParticle(scene::SceneParticle *); diff --git a/ParticleGenerator/src/Interface/Scene/Trajectory.cpp b/ParticleGenerator/src/Interface/Scene/Trajectory.cpp index 18ff7771bb155fbb092b28764311081b71fe6773..78e4fb4c2ec3c8f96256ea1113e79ee3adf5312f 100644 --- a/ParticleGenerator/src/Interface/Scene/Trajectory.cpp +++ b/ParticleGenerator/src/Interface/Scene/Trajectory.cpp @@ -2,11 +2,16 @@ #include <imgui.h> +#include "../../Scene/Scenes/Trajectory.hpp" + namespace pg::interface { Trajectory::Trajectory(scene::Trajectory * parent) : Scene(parent) {} void Trajectory::draw(double) { - ImGui::Text("Trajectory Interface : %i", this->parent()); + ImGui::ColorEdit4("Curve Color", &this->parent()->_color[0]); + ImGui::SliderFloat("Point Size", &this->parent()->_pointSize, 1.f, 512.f); + ImGui::SliderFloat("Line Size", &this->parent()->_lineSize, 1.f, 512.f); + ImGui::Checkbox("Show Control Line", &this->parent()->_controlLine); } } \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Style/Red.cpp b/ParticleGenerator/src/Interface/Style/Red.cpp new file mode 100644 index 0000000000000000000000000000000000000000..96e1c12f78ed0172b5a174ee228f56159d960e71 --- /dev/null +++ b/ParticleGenerator/src/Interface/Style/Red.cpp @@ -0,0 +1,54 @@ +#include "Red.hpp" + +namespace pg::interface::style { + void Red::apply(ImGuiStyle & style) const { + // Window Size + style.WindowPadding = ImVec2(10, 5); + style.FramePadding = ImVec2(5, 5); + style.ItemSpacing = ImVec2(10, 2); + style.ItemInnerSpacing = ImVec2(10, 5); + style.FrameBorderSize = 1.f; + + style.WindowRounding = 2.f; + style.FrameRounding = 1.f; + style.ScrollbarRounding = 0.f; + + style.WindowTitleAlign = ImVec2(0.5f, 0.5f); + style.SeparatorTextAlign = ImVec2(0.5f, 0.5f); + + // Window Color + ImVec4 * colors = style.Colors; + colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.47f, 0.48f, 0.43f, 1.00f); + colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.50f); + colors[ImGuiCol_FrameBg] = ImVec4(0.48f, 0.16f, 0.29f, 0.54f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.98f, 0.26f, 0.36f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.98f, 0.26f, 0.42f, 0.67f); + colors[ImGuiCol_TitleBg] = ImVec4(0.21f, 0.09f, 0.13f, 1.00f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.36f, 0.10f, 0.17f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(1.00f, 0.77f, 0.00f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.98f, 0.26f, 0.40f, 0.40f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.98f, 0.26f, 0.36f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.98f, 0.06f, 0.31f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.98f, 0.26f, 0.50f, 0.31f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.98f, 0.26f, 0.50f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.98f, 0.26f, 0.56f, 1.00f); + colors[ImGuiCol_Separator] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.75f, 0.10f, 0.37f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.75f, 0.10f, 0.24f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.98f, 0.26f, 0.52f, 0.20f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.98f, 0.26f, 0.60f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.98f, 0.26f, 0.46f, 0.95f); + colors[ImGuiCol_Tab] = ImVec4(0.58f, 0.18f, 0.33f, 0.86f); + colors[ImGuiCol_TabHovered] = ImVec4(0.98f, 0.26f, 0.62f, 0.80f); + colors[ImGuiCol_TabActive] = ImVec4(0.68f, 0.20f, 0.37f, 1.00f); + colors[ImGuiCol_TabUnfocused] = ImVec4(0.15f, 0.07f, 0.11f, 0.97f); + colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.42f, 0.14f, 0.29f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 0.97f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.84f, 0.84f, 0.20f, 0.78f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.98f, 0.26f, 0.62f, 0.35f); + colors[ImGuiCol_NavHighlight] = ImVec4(0.98f, 0.26f, 0.65f, 1.00f); + } +} \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Style/Red.hpp b/ParticleGenerator/src/Interface/Style/Red.hpp new file mode 100644 index 0000000000000000000000000000000000000000..681ee539c8fde1fed6143a1d73584a1c7da9ec67 --- /dev/null +++ b/ParticleGenerator/src/Interface/Style/Red.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "Style.hpp" + +namespace pg::interface::style { + class Red : public Style { + public: + Red() = default; + virtual ~Red() = default; + + void apply(ImGuiStyle &) const override; + inline std::string name() const {return "Red";} + }; +} \ No newline at end of file diff --git a/ParticleGenerator/src/Interface/Style/Style.hpp b/ParticleGenerator/src/Interface/Style/Style.hpp new file mode 100644 index 0000000000000000000000000000000000000000..26e9d653744b0775046c032eccc5f05dfe213c6f --- /dev/null +++ b/ParticleGenerator/src/Interface/Style/Style.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include <string> +#include <imgui.h> + +namespace pg::interface::style { + class Style { + public: + Style() = default; + virtual ~Style() = default; + + virtual void apply(ImGuiStyle &) const = 0; + virtual std::string name() const = 0; + + }; +} \ No newline at end of file diff --git a/ParticleGenerator/src/Particle/generator/PathParticleGenerator.hpp b/ParticleGenerator/src/Particle/generator/PathParticleGenerator.hpp index 9efcc9e973dea2e4c0aacc054702e3229a39425e..477f1eb198661991c2ddfe9b41797364a8036efc 100644 --- a/ParticleGenerator/src/Particle/generator/PathParticleGenerator.hpp +++ b/ParticleGenerator/src/Particle/generator/PathParticleGenerator.hpp @@ -31,7 +31,7 @@ namespace pg { inline void setParameterIncrement(float inc) {this->m_increment = inc;} inline void setParameterLifeLimitor(float limitor) {this->m_limitor = limitor;} - std::vector<std::unique_ptr<Particle>> generate(size_t count, size_t birth = 0) const override; + virtual std::vector<std::unique_ptr<Particle>> generate(size_t count, size_t birth = 0) const = 0; friend class interface::PathGenerator; }; diff --git a/ParticleGenerator/src/Scene/Scene.cpp b/ParticleGenerator/src/Scene/Scene.cpp index ba88cc6bde14e996e993b5b0b55ff38a46d33e10..5e8ded00c7f5c0e90567ce02d68a0bfc0fe9fb88 100644 --- a/ParticleGenerator/src/Scene/Scene.cpp +++ b/ParticleGenerator/src/Scene/Scene.cpp @@ -1,6 +1,6 @@ #include "Scene.hpp" namespace pg::scene { - SceneParticle::SceneParticle(size_t max) - : Scene(), _max(max), _spawn(1), _frequence(500), _lifetime(5), _enableRender(true), _enableSpawn(true) {} + SceneParticle::SceneParticle(int max) + : Scene(), _max(max), _spawn(1), _frequence(500), _lifetime(5), _enableRender(true), _enableSpawn(true), _enableFreeze(false) {} } \ No newline at end of file diff --git a/ParticleGenerator/src/Scene/Scene.hpp b/ParticleGenerator/src/Scene/Scene.hpp index 60f161fd42bf9d67ac6acd67e04d8452dc87440a..0539574465327c2745155fc5e4ceb4630afa7149 100644 --- a/ParticleGenerator/src/Scene/Scene.hpp +++ b/ParticleGenerator/src/Scene/Scene.hpp @@ -28,35 +28,38 @@ namespace pg::scene { class SceneParticle : public Scene { private: - const size_t _max; - size_t _spawn; - unsigned int _frequence; - unsigned int _lifetime; + const int _max; + int _spawn; + int _frequence; + int _lifetime; bool _enableRender; bool _enableSpawn; + bool _enableFreeze; protected: ParticleContainer _particles; public: - SceneParticle(size_t max); + SceneParticle(int max); virtual ~SceneParticle() = default; inline const ParticleContainer & getParticles() const {return this->_particles;} - inline size_t getMaxParticles() const {return this->_max;} - inline size_t getSpawnCount() const {return this->_spawn;} - inline unsigned int getSpawnFrequence() const {return this->_frequence;} - inline unsigned int getLifetime() const {return this->_lifetime;} + inline int getMaxParticles() const {return this->_max;} + inline int getSpawnCount() const {return this->_spawn;} + inline int getSpawnFrequence() const {return this->_frequence;} + inline int getLifetime() const {return this->_lifetime;} inline bool isRenderEnable() {return this->_enableRender;} inline bool isSpawnEnable() {return this->_enableSpawn;} + inline bool isFreezeEnable() {return this->_enableFreeze;} - inline void setSpawnCount(size_t sc) {this->_spawn = sc;} - inline void setSpawnFrequence(unsigned int sf) {this->_frequence = sf;} - inline void setLifetime(unsigned int lt) {this->_lifetime = lt;} + inline void setSpawnCount(int sc) {this->_spawn = sc;} + inline void setSpawnFrequence(int sf) {this->_frequence = sf;} + inline void setLifetime(int lt) {this->_lifetime = lt;} inline void enableRender(bool state) {this->_enableRender = state;} inline void enableSpawn(bool state) {this->_enableSpawn = state;} + inline void enableFreeze(bool state) {this->_enableFreeze = state;} - virtual void spawn(size_t, double) = 0; + virtual void spawn(int, double) = 0; friend class interface::SceneParticle; }; diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp index 71bc6d607df055bc56d561079b9c91fcd0bd12a9..8294c0ef06f5a32200a711a7da45fcdab8c6beaa 100644 --- a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp +++ b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.cpp @@ -18,6 +18,7 @@ namespace pg::scene { _billboardTexture(), _billboardProgram(), _ubo(0), + _color(1.f), _interface(this) {} void MeshGenerator::initialize() { @@ -64,24 +65,29 @@ namespace pg::scene { glBindBuffer(GL_UNIFORM_BUFFER, 0); } - this->_particles.reserve(2048); + this->_particles.reserve(16384); + this->setSpawnCount(1); + this->setSpawnFrequence(3000); + this->setLifetime(3); } 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), 3); - if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 3000) { - start = std::chrono::high_resolution_clock::now(); - if(true) { - this->spawn(1, current_time); + if(!this->isFreezeEnable()) { + pg::Particle::purge(this->_particles, static_cast<size_t>(current_time), this->getLifetime()); + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= this->getSpawnFrequence()) { + start = std::chrono::high_resolution_clock::now(); + if(this->isSpawnEnable()) { + this->spawn(this->getSpawnCount(), current_time); + } } - } - if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 10) { - for(auto& particle : this->_particles) { - particle->update(0.0); + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 10) { + for(auto& particle : this->_particles) { + particle->update(0.0); + } } } } @@ -130,11 +136,11 @@ namespace pg::scene { 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)); + this->_billboardProgram.setUniform("uColor", this->_color); pg::error::OpenGLError::check(); - if(true) { + if(this->isRenderEnable()) { this->_billboard.draw(this->_particles.size()); } @@ -178,9 +184,9 @@ namespace pg::scene { } } - void MeshGenerator::spawn(size_t count, double current_time) { + void MeshGenerator::spawn(int count, double current_time) { for(auto & generator : this->_generators) { - if((count + this->_particles.size()) <= 2048) { + if((count + this->_particles.size()) <= this->getMaxParticles()) { std::vector<std::unique_ptr<pg::Particle>> newParticles = generator.generate(count, static_cast<size_t>(current_time)); this->_particles.insert(this->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end())); } diff --git a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp index 298501b87377a2c1f85f945fdcd21e323099ed5c..428d93e0b7642d370aba2cd2a2b3ad7a1e683ab6 100644 --- a/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp +++ b/ParticleGenerator/src/Scene/Scenes/MeshGenerator.hpp @@ -25,6 +25,8 @@ namespace pg::scene { Program _billboardProgram; GLuint _ubo; + glm::vec4 _color; + interface::MeshGenerator _interface; public: @@ -42,7 +44,7 @@ namespace pg::scene { void changeMesh(const std::string &); void changeTexture(const std::string &); - void spawn(size_t count, double current_time); + void spawn(int count, double current_time); friend class pg::interface::MeshGenerator; diff --git a/ParticleGenerator/src/Scene/Scenes/Path.cpp b/ParticleGenerator/src/Scene/Scenes/Path.cpp index 48bd6ee1480ac77fb189b6a94d2d527fef7a6254..cf776fb61e1b653d8c6d5174a9a48f0a70eec2ee 100644 --- a/ParticleGenerator/src/Scene/Scenes/Path.cpp +++ b/ParticleGenerator/src/Scene/Scenes/Path.cpp @@ -11,7 +11,8 @@ namespace pg::scene { _texture(), _generator(generator, ctrlpoint), _trajectory(&this->_generator), - _interface(this, &this->_generator) {} + _color(1.f), + _interface(this, &this->_generator, &this->_trajectory) {} void Path::initialize() { this->_billboard.initialize(); @@ -58,17 +59,19 @@ namespace pg::scene { 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) { - start = std::chrono::high_resolution_clock::now(); - if((5 + this->_particles.size() <= 1024) && true) { - this->spawn(5, current_time); + if(!this->isFreezeEnable()) { + pg::Particle::purge(this->_particles, static_cast<size_t>(current_time), this->getLifetime()); + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 500) { + start = std::chrono::high_resolution_clock::now(); + if(this->isSpawnEnable()) { + this->spawn(this->getSpawnCount(), current_time); + } } - } - if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 10) { - for(auto& particle : this->_particles) { - particle->update(0.0); + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 10) { + for(auto& particle : this->_particles) { + particle->update(0.0); + } } } } @@ -99,12 +102,12 @@ namespace pg::scene { this->_program.setUniform("uView", VIEW_MATRIX); this->_program.setUniform("uProj", PROJECTION_MATRIX); this->_program.setUniform("uSlot", 0); - this->_program.setUniform("uColor", glm::vec4(1.f)); + this->_program.setUniform("uColor", this->_color); pg::error::OpenGLError::check(); this->_texture.bind(); - if(true) { + if(this->isRenderEnable()) { this->_billboard.draw(this->_particles.size()); } @@ -123,8 +126,11 @@ namespace pg::scene { this->_texture.load(path); } - void Path::spawn(size_t count, double current_time) { - std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_generator.generate(count, static_cast<size_t>(current_time)); - this->_particles.insert(this->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end())); + void Path::spawn(int count, double current_time) { + if((count + this->_particles.size()) <= this->getMaxParticles()) { + std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_generator.generate(count, static_cast<size_t>(current_time)); + this->_particles.insert(this->_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/Scene/Scenes/Path.hpp b/ParticleGenerator/src/Scene/Scenes/Path.hpp index e6a85f291fce1f92f0ba01824b2a7e20c551ac8e..246a6ddd00b67a29351acf7796641f7e2c4c0adf 100644 --- a/ParticleGenerator/src/Scene/Scenes/Path.hpp +++ b/ParticleGenerator/src/Scene/Scenes/Path.hpp @@ -19,6 +19,7 @@ namespace pg::scene { Trajectory _trajectory; Material _texture; PathParticleGenerator _generator; + glm::vec4 _color; interface::Path _interface; @@ -40,7 +41,7 @@ namespace pg::scene { virtual std::string name() const {return "Path Scene";} virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>(&this->_interface);} - virtual void spawn(size_t, double); + virtual void spawn(int, double); friend class pg::interface::Path; }; diff --git a/ParticleGenerator/src/Scene/Scenes/Physic.cpp b/ParticleGenerator/src/Scene/Scenes/Physic.cpp index 14248da54cc39763c7d90a3504ca3ae377d12fcb..eee1755e79fa6f42c9d3dcd1fc63658cc9eac5ac 100644 --- a/ParticleGenerator/src/Scene/Scenes/Physic.cpp +++ b/ParticleGenerator/src/Scene/Scenes/Physic.cpp @@ -10,6 +10,7 @@ namespace pg::scene { _program(), _texture(), _generator(), + _color(1.f), _interface(this, &this->_generator) {} void Physic::initialize() { @@ -54,17 +55,19 @@ namespace pg::scene { 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) { - start = std::chrono::high_resolution_clock::now(); - if((5 + this->_particles.size()) <= 1024 && true) { - this->spawn(5, current_time); + if(!this->isFreezeEnable()) { + pg::Particle::purge(this->_particles, static_cast<size_t>(current_time), this->getLifetime()); + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= this->getSpawnFrequence()) { + start = std::chrono::high_resolution_clock::now(); + if(this->isSpawnEnable()) { + this->spawn(this->getSpawnCount(), current_time); + } } - } - if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 10) { - for(auto& particle : this->_particles) { - particle->update(0.0); + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 10) { + for(auto& particle : this->_particles) { + particle->update(0.0); + } } } } @@ -94,11 +97,11 @@ namespace pg::scene { this->_program.setUniform("uView", VIEW_MATRIX); this->_program.setUniform("uProj", PROJECTION_MATRIX); this->_program.setUniform("uSlot", 0); - this->_program.setUniform("uColor", glm::vec4(1.f)); + this->_program.setUniform("uColor", this->_color); pg::error::OpenGLError::check(); - if(true) { + if(this->isRenderEnable()) { this->_billboards.draw(this->_particles.size()); } @@ -117,8 +120,10 @@ namespace pg::scene { this->_texture.load(path); } - void Physic::spawn(size_t count, double current_time) { - std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_generator.generate(count, static_cast<size_t>(current_time)); - this->_particles.insert(this->_particles.begin(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end())); + void Physic::spawn(int count, double current_time) { + if((count + this->_particles.size()) <= this->getMaxParticles()) { + std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_generator.generate(count, static_cast<size_t>(current_time)); + this->_particles.insert(this->_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/Scene/Scenes/Physic.hpp b/ParticleGenerator/src/Scene/Scenes/Physic.hpp index 6694086238e5bfcb9fdc39005d96db85860b26a9..17c9bf1c8ba2de13ebe5c7b1097ccb69781a5f80 100644 --- a/ParticleGenerator/src/Scene/Scenes/Physic.hpp +++ b/ParticleGenerator/src/Scene/Scenes/Physic.hpp @@ -17,6 +17,7 @@ namespace pg::scene { Material _texture; Billboard _billboards; PhysicsParticleGenerator _generator; + glm::vec4 _color; interface::Physic _interface; @@ -38,7 +39,7 @@ namespace pg::scene { virtual void update(double); virtual void destroy(); - virtual void spawn(size_t, double); + virtual void spawn(int, double); friend class pg::interface::Physic; }; diff --git a/ParticleGenerator/src/Scene/Scenes/PhysicSprite.cpp b/ParticleGenerator/src/Scene/Scenes/PhysicSprite.cpp new file mode 100644 index 0000000000000000000000000000000000000000..494c2f6d59ef5cef624823de6c6e5dd5ac4ea863 --- /dev/null +++ b/ParticleGenerator/src/Scene/Scenes/PhysicSprite.cpp @@ -0,0 +1,141 @@ +#include "PhysicSprite.hpp" + +#include <chrono> +#include <cmath> +#include <glm/gtc/matrix_transform.hpp> + +namespace pg::scene { + PhysicSprite::PhysicSprite() + : SceneParticle(512), + _ubo(0), + _program(), + _texture(), + _generator(), + _color(1.f) {} + + void PhysicSprite::initialize() { + this->_billboards.initialize(); + if(!this->_program.usable()) { + pg::Source vertices("res/shaders/scene/Billboard-Sprite.vert", pg::Source::Categorie::VERTEX); + pg::Source fragment("res/shaders/scene/Billboard-Sprite.frag", pg::Source::Categorie::FRAGMENT); + + this->_program << vertices; + this->_program << fragment; + + this->_program.link(); + + vertices.release(); + fragment.release(); + } + + pg::error::OpenGLError::check(); + + glCreateBuffers(1, &this->_ubo); + glBindBuffer(GL_UNIFORM_BUFFER, this->_ubo); + glBufferData(GL_UNIFORM_BUFFER, 512 * sizeof(glm::mat4) + 512 * sizeof(glm::vec4), nullptr, GL_DYNAMIC_DRAW); + + GLuint uniforme_index = glGetUniformBlockIndex(this->_program.id(), "uParticle_t"); + glBindBufferBase(GL_UNIFORM_BUFFER, uniforme_index, this->_ubo); + + pg::error::OpenGLError::check(); + + this->_texture.load("res/textures/SpriteParticleTest.png"); + this->_frames.clear(); + this->_frames.push_back(glm::vec4(0, 32, 32, 32)); + this->_frames.push_back(glm::vec4(32, 32, 32, 32)); + this->_frames.push_back(glm::vec4(0, 0, 32, 32)); + this->_frames.push_back(glm::vec4(32, 0, 32, 32)); + + pg::error::OpenGLError::check(); + + 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}); + + glClearColor(0.25f, 0.f, 0.15f, 1.0f); + } + + void PhysicSprite::update(double current_time) { + static auto start = std::chrono::high_resolution_clock::now(); + auto end = std::chrono::high_resolution_clock::now(); + + if(!this->isFreezeEnable()) { + pg::Particle::purge(this->_particles, static_cast<size_t>(current_time), this->getLifetime()); + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= this->getSpawnFrequence()) { + start = std::chrono::high_resolution_clock::now(); + if(this->isSpawnEnable()) { + this->spawn(this->getSpawnCount(), current_time); + } + } + + if(duration_cast<std::chrono::milliseconds>(end - start).count() >= 10) { + for(auto& particle : this->_particles) { + particle->update(0.0); + } + } + } + } + + void PhysicSprite::render(const Camera & camera, double current_time) { + const glm::mat4 VIEW_MATRIX = camera.getViewMatrix(); + const glm::mat4 PROJECTION_MATRIX = camera.getViewFrustum().getProjectionMatrix(); + + std::vector<glm::mat4> models; + std::vector<glm::vec4> slots; + + size_t i = 0; + for(auto & particle : this->_particles) { + glm::mat4 model = glm::mat4(1.0); + model = glm::translate(model, glm::vec3(particle->getPosition())); + models.push_back(model); + + slots.push_back(this->_frames.at(static_cast<int>(current_time-particle->getBorn())%this->_frames.size())); + } + + pg::error::OpenGLError::check(); + + glBindBuffer(GL_UNIFORM_BUFFER, this->_ubo); + glBufferSubData(GL_UNIFORM_BUFFER, 0, models.size() * sizeof(glm::mat4), models.data()); + glBufferSubData(GL_UNIFORM_BUFFER, 512 * sizeof(glm::mat4), slots.size() * sizeof(glm::vec4), slots.data()); + + pg::error::OpenGLError::check(); + + this->_texture.bind(0); + this->_program.use(); + + this->_program.setUniform("uView", VIEW_MATRIX); + this->_program.setUniform("uProj", PROJECTION_MATRIX); + + this->_program.setUniform("uSlot", 0); + this->_program.setUniform("uSize", glm::vec2(64.f, 64.f)); + this->_program.setUniform("uColor", this->_color); + + pg::error::OpenGLError::check(); + + if(this->isRenderEnable()) { + this->_billboards.draw(this->_particles.size()); + } + + pg::error::OpenGLError::check(); + } + + void PhysicSprite::destroy() { + glDeleteBuffers(1, &this->_ubo); + this->_billboards.destroy(); + this->_particles.clear(); + + pg::error::OpenGLError::check(); + } + + void PhysicSprite::changeParticletexture(const std::string & path) { + this->_texture.load(path); + } + + void PhysicSprite::spawn(int count, double current_time) { + if((count + this->_particles.size()) <= this->getMaxParticles()) { + std::vector<std::unique_ptr<pg::Particle>> newParticles = this->_generator.generate(count, static_cast<size_t>(current_time)); + this->_particles.insert(this->_particles.end(), std::make_move_iterator(newParticles.begin()), std::make_move_iterator(newParticles.end())); + } + } +} \ No newline at end of file diff --git a/ParticleGenerator/src/Scene/Scenes/PhysicSprite.hpp b/ParticleGenerator/src/Scene/Scenes/PhysicSprite.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8a7d74c8e463ba4ba32e967a4e70903104519c32 --- /dev/null +++ b/ParticleGenerator/src/Scene/Scenes/PhysicSprite.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include "../Scene.hpp" + +#include "../../Renderer/Renderer.hpp" +#include "../../Particle/generator/PhysicsParticleGenerator.hpp" +#include "../../Interface/Scene/Physic.hpp" +#include "../../Mesh/Billboard.hpp" + +#include "../../System/Window.hpp" + +namespace pg::scene { + class PhysicSprite : public SceneParticle { + private: + GLuint _ubo; + Program _program; + Material _texture; + Billboard _billboards; + std::vector<glm::vec4> _frames; + PhysicsParticleGenerator _generator; + glm::vec4 _color; + + public: + PhysicSprite(); + virtual ~PhysicSprite() = default; + + inline const Program & getProgram() const {return this->_program;} + inline const Material & getTexture() const {return this->_texture;} + inline const PhysicsParticleGenerator & getGenerator() const {return this->_generator;} + + void changeParticletexture(const std::string &); + + virtual std::string name() const {return "Physic Sprite Scene";} + virtual std::optional<interface::Interface *> interface() {return std::optional<interface::Interface *>();} + + virtual void initialize(); + virtual void render(const Camera &, double); + virtual void update(double); + virtual void destroy(); + + virtual void spawn(int, double); + + friend class pg::interface::Physic; + }; +} \ No newline at end of file diff --git a/ParticleGenerator/src/Scene/Scenes/Trajectory.cpp b/ParticleGenerator/src/Scene/Scenes/Trajectory.cpp index 9d1c0b86c317aac5ffce69cb4134b8026dc133f9..3038418eb3a8a73a0c6567ab6cc4d154e94a196b 100644 --- a/ParticleGenerator/src/Scene/Scenes/Trajectory.cpp +++ b/ParticleGenerator/src/Scene/Scenes/Trajectory.cpp @@ -8,8 +8,9 @@ namespace pg::scene { : _generator(generator), _vbo(this->_vao, {layout::POSITION, layout::COLOR}), _increment(increment), - _color(0.15f, 0.25f, 1.f, 1.f), + _color(0.0f, 1.f, 0.f, 1.f), _pointSize(8.f), + _lineSize(1.f), _controlLine(false), _interface(this) {} @@ -36,9 +37,9 @@ namespace pg::scene { traj.push_back(static_cast<float>(point.y)); traj.push_back(static_cast<float>(point.z)); - traj.push_back(0.75f); - traj.push_back(0.75f); - traj.push_back(0.75f); + traj.push_back(0.25f); + traj.push_back(0.25f); + traj.push_back(0.25f); } std::vector<double> ps; @@ -63,6 +64,7 @@ namespace pg::scene { void Trajectory::render(const Camera & camera, double current_time) { glEnable(GL_LINE_SMOOTH); + glLineWidth(this->_lineSize); this->_vao.bind(); glEnable(GL_PROGRAM_POINT_SIZE); @@ -75,8 +77,8 @@ namespace pg::scene { GLsizei raw = static_cast<GLsizei>(this->_generator->getControlPoint().size()); GLsizei total = static_cast<GLsizei>(this->_vbo.vertices()); - glDrawArrays(this->_controlLine ? GL_LINE_STRIP : GL_POINTS, 0, static_cast<GLsizei>(this->_generator->getControlPoint().size())); glDrawArrays(GL_LINE_STRIP, raw, total - raw); + glDrawArrays(this->_controlLine ? GL_LINE_STRIP : GL_POINTS, 0, static_cast<GLsizei>(this->_generator->getControlPoint().size())); } void Trajectory::destroy() { diff --git a/ParticleGenerator/src/Scene/Scenes/Trajectory.hpp b/ParticleGenerator/src/Scene/Scenes/Trajectory.hpp index 8783be090908b4806272a025e7e5b7ed4bb37668..9baa8216a1f045623f62aa2b046cdbf6b641502f 100644 --- a/ParticleGenerator/src/Scene/Scenes/Trajectory.hpp +++ b/ParticleGenerator/src/Scene/Scenes/Trajectory.hpp @@ -16,6 +16,7 @@ namespace pg::scene { glm::vec4 _color; float _pointSize; + float _lineSize; bool _controlLine; interface::Trajectory _interface; diff --git a/ParticleGenerator/src/main.cpp b/ParticleGenerator/src/main.cpp index 806a76da55b4e97833415e2c284ac97e44ec6599..2e5fbd422c3b123d0ba408d061f4b346d7be2ebe 100644 --- a/ParticleGenerator/src/main.cpp +++ b/ParticleGenerator/src/main.cpp @@ -11,6 +11,7 @@ #include "Scene/Scenes/Path.hpp" #include "Scene/Scenes/MeshGenerator.hpp" #include "Scene/Scenes/Grid.hpp" +#include "Scene/Scenes/PhysicSprite.hpp" #include "Interface/Manager.hpp" @@ -71,9 +72,10 @@ int main(int argc, const char * argv[]) { {-10.f, 0.f, 0.f} }; - ct::BezierGenerator bezier(ctrlPoints.size()); + ct::BezierGenerator bezier(static_cast<unsigned int>(ctrlPoints.size())); pg::scene::Physic physic; + pg::scene::PhysicSprite physicSprite; pg::scene::MeshGenerator meshGenerator; pg::scene::Path path(&bezier, ctrlPoints); @@ -82,6 +84,7 @@ int main(int argc, const char * argv[]) { manager.add(&path); manager.add(&physic); + manager.add(&physicSprite); manager.add(&meshGenerator); while(window.isOpen()) {