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

Add SpritePhysicScene

parent ef4888f9
No related branches found
No related tags found
No related merge requests found
Showing
with 284 additions and 68 deletions
......@@ -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;
};
......
#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
......@@ -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;
};
......
......@@ -18,6 +18,7 @@ namespace pg::scene {
_billboardTexture(),
_billboardProgram(),
_ubo(0),
_color(1.f),
_interface(this) {}
void MeshGenerator::initialize() {
......@@ -64,18 +65,22 @@ 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) {
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(true) {
this->spawn(1, current_time);
if(this->isSpawnEnable()) {
this->spawn(this->getSpawnCount(), current_time);
}
}
......@@ -85,6 +90,7 @@ namespace pg::scene {
}
}
}
}
void MeshGenerator::render(const Camera & camera, double current_time) {
const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
......@@ -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()));
}
......
......@@ -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;
......
......@@ -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,11 +59,12 @@ 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(!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((5 + this->_particles.size() <= 1024) && true) {
this->spawn(5, current_time);
if(this->isSpawnEnable()) {
this->spawn(this->getSpawnCount(), current_time);
}
}
......@@ -72,6 +74,7 @@ namespace pg::scene {
}
}
}
}
void Path::render(const Camera & camera, double current_time) {
const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
......@@ -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) {
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
......@@ -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;
};
......
......@@ -10,6 +10,7 @@ namespace pg::scene {
_program(),
_texture(),
_generator(),
_color(1.f),
_interface(this, &this->_generator) {}
void Physic::initialize() {
......@@ -54,11 +55,12 @@ 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) {
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((5 + this->_particles.size()) <= 1024 && true) {
this->spawn(5, current_time);
if(this->isSpawnEnable()) {
this->spawn(this->getSpawnCount(), current_time);
}
}
......@@ -68,6 +70,7 @@ namespace pg::scene {
}
}
}
}
void Physic::render(const Camera & camera, double current_time) {
const glm::mat4 VIEW_MATRIX = camera.getViewMatrix();
......@@ -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) {
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
......@@ -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;
};
......
#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
#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
......@@ -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() {
......
......@@ -16,6 +16,7 @@ namespace pg::scene {
glm::vec4 _color;
float _pointSize;
float _lineSize;
bool _controlLine;
interface::Trajectory _interface;
......
......@@ -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()) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment