From cd24aa25d589e0e6b9e9833fe34db6b7750d0da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9au?= <theau.baton@etu.univ-amu.fr> Date: Sat, 7 Dec 2024 16:32:12 +0100 Subject: [PATCH] Add Sprite + Open to add custom graphic object --- assets/textures/Image_Test.png | Bin 0 -> 1396 bytes .../engine/graphics/front/engine/Engine.cpp | 13 +- .../engine/graphics/front/engine/Engine.hpp | 10 +- source/engine/graphics/front/engine/Layer.hpp | 14 +- .../engine/graphics/front/engine/Renderer.cpp | 8 +- .../engine/graphics/front/engine/Renderer.hpp | 16 +- ...BufferModule.cpp => FrameBufferMerger.cpp} | 9 +- ...BufferModule.hpp => FrameBufferMerger.hpp} | 9 +- .../engine/graphics/front/module/Module.hpp | 13 +- .../front/module/QuadGraphicModule.cpp | 16 - .../front/module/QuadGraphicModule.hpp | 16 - .../graphics/front/module/QuadInstanced.cpp | 151 +++++++++ .../graphics/front/module/QuadInstanced.hpp | 26 ++ source/engine/graphics/front/object/Image.cpp | 2 +- .../graphics/front/object/Renderable.hpp | 17 +- .../engine/graphics/front/object/Sprite.cpp | 24 +- .../engine/graphics/front/object/Sprite.hpp | 27 +- .../graphics/utility/isometric_sorter.cpp | 35 +- .../graphics/utility/isometric_sorter.hpp | 10 +- source/engine/graphics/utility/ref_set.hpp | 6 + source/main.cpp | 307 ++---------------- 21 files changed, 307 insertions(+), 422 deletions(-) create mode 100644 assets/textures/Image_Test.png rename source/engine/graphics/front/module/{FrameBufferModule.cpp => FrameBufferMerger.cpp} (78%) rename source/engine/graphics/front/module/{FrameBufferModule.hpp => FrameBufferMerger.hpp} (65%) delete mode 100644 source/engine/graphics/front/module/QuadGraphicModule.cpp delete mode 100644 source/engine/graphics/front/module/QuadGraphicModule.hpp create mode 100644 source/engine/graphics/front/module/QuadInstanced.cpp create mode 100644 source/engine/graphics/front/module/QuadInstanced.hpp create mode 100644 source/engine/graphics/utility/ref_set.hpp diff --git a/assets/textures/Image_Test.png b/assets/textures/Image_Test.png new file mode 100644 index 0000000000000000000000000000000000000000..428fbc85ff234275126068eed22a3f0536537b91 GIT binary patch literal 1396 zcmeAS@N?(olHy`uVBq!ia0y~yV9;V<V36lvV_;yISQ78bz`(#*9OUlAu<o49O9lo8 zmUKs7M+SzC{oH>NSs54@I14-?iy0XB4ude`@%$Aj3=FKCo-U3d5$=1ZYZpBB5NNZm zW@F=KVFE!OCLU&1W<Cii83Pj&3xOBOjcsh)JiL4oEG#S>G8_>K8ypnC@W26u(0xB| zWnH~7O@8*R-TSjn&6-*F=kn#t#?zcnxL&)aCbVYt!+5@&-}_cQw5?fLm;FZ5ht0@C z-0Gh;r?g|v<HH-C?>{6KIHmp4v{sg@9fvd2QjI1n_-@JO+wz(72lp|xZ66a4n9E2t zA9^r%%XYOFw_k1XW&72gvv{I$;;((a*}gJorn_xXU%H1SckTlIc`2nEr6c7f*4dpu zHt(FD%E!pksoZlOu)SKlUpL%0W%c_1a{Kg^In@t~bFZDf<|NxeHPLU2UMcz(X<oip zHSvkMayQSW7bXW6b^6yxds;ABWVr~c9B~tqNUUFK`Z80guv|&V^;dO|PVqjST~_Z{ z8RXprBs?u<-nq8&zG^i`VESSiSK~^lbE<r9xAK{aPbhHvd>5#hWH&`a+vpjGPi+00 zCp`wmbu6FG_&%GRD`U4-MKg8@UxQ_eh@X3@_K&iUtsr}!<+y*HGLf0bWbG05ue_2e zyT5aDE)MA0GoihG_pdEx5C8qk%-!_TdHpuVmCgo}PV_C=b3-{RBTBTbH%IDwY0fmC z{z)c0j}|^FG@p50Wh3i`=f91AxRk#BnQ(xEQKaX|s>@Ri<gT<i#w`(Q*)FB~OJ^EW z+_FxyeQOsfH0xNg<s=H<{$WthHecoM+QTU+y&ERJDQg$H_if4L`L8TIHcju|RI#!u zk6mr=+0xs+TR*N%7M<X_{M9PmoTS?)m_GB1%U9n{3p8-;aY+ncY(8(72HWH)^>=sH z6<#U(X<oBqwcB>Xz2(zRoGsbqx<$wR^~VjXxfL$G%@NL3&X{QOM$q&}%V&cr1{|ed zKN?JnlUXTu+j>Tt72m`~Iuh#=t<IcnlkIdfzPfmu+PZnO{6a+7Ii>i7?z*b?TzeLw zEOD;1+H|{>tSS@J^m2!IS3aF3({~<AEIhw6^Wu7Co|9`%oPShc7RY@2?EBn&orli< zGb}$JZ0h>GbC1rkTi-7~kojX0=n&=O94^@9d-1z}ws4MNd7{eUMK(M39{-TJ=-<gR zzlA#=t*g5&nrR*|Z;8-Z^YAq<|LD7{?0hoAl3k?U%U8H-daGC^bGOoQ|GR0sEi`@n zg68#b^l64#FvoO;iMj=UcX-(PWWo~VnLNM0u6%ZiRcF$qC$|^d%sq8;@#MO>B@;zn z$=#RXSiSa3;lC+64nIBdtKmtk&AQYzX+;7rgQv%)yw)n{d2{XT7VZ-dTG&}t4BG-Z z9ta%&!l*Lw`)tAQo{O@NZ0O9bQK;wHAG*K#fuQ4&b-S+rdX>o<|8&#c!1lHB|4&4F zKY9B%bXw}OzT@pF`77_-`J?!DeR!$&X7}Znr@i?a_<Z{6rOO;&e+pXkdY(|sG;h`2 zRr#LJjbxVp{Jvj{D>_4k%QLKh@oJ509DCBwPpbK^cHVxT{<@{6@AU1T)JAGO?C)PX zX-C;6ySUFT&vpDSR+e`EvMzt$^1Vc6jop&3f-h44?)VX$`grzz>62#9SX?~IZY#;W zy{EA5%!mD6`&X_M_$aTdFq{ADf<SA=rzf}STJJWOYhV5H<&7DOU5X8FYa}h;w79b9 z{Tyk*v!>zxnKjJMCag@6W=>Z5*!h05qf4ab{VTrJU*woJ9gkAI#*uS-w%E<!ecK!& zKgss|+B})ho;fFJ_p7Y?_k_|Hc3$yc`^CrPW)5G+iTz)0MSYqX-|fx7z`)??>gTe~ HDWM4f`XPe8 literal 0 HcmV?d00001 diff --git a/source/engine/graphics/front/engine/Engine.cpp b/source/engine/graphics/front/engine/Engine.cpp index 1cf0531..b8765f4 100644 --- a/source/engine/graphics/front/engine/Engine.cpp +++ b/source/engine/graphics/front/engine/Engine.cpp @@ -4,12 +4,12 @@ namespace megu { GraphicEngine::GraphicEngine(Window & window, float w, float h) - : _window(window), _view(0, 0, w, h) { + : _window(window) { glViewport(0, 0, window.width(), window.height()); } GraphicEngine::GraphicEngine(Window & window) - : _window(window), _view(0, 0, window.width(), window.height()) { + : _window(window) { glViewport(0, 0, window.width(), window.height()); } @@ -17,10 +17,6 @@ namespace megu { this->_layers[priority] = std::make_unique<Layer>(renderer); } - //void GraphicEngine::push(Priority layer_priority, Priority object_priority, GraphicObject & object) { - // this->_layers[layer_priority].get()->push(object_priority, object); - //} - void GraphicEngine::remove(Priority priority) { auto it = this->_layers.find(priority); if(it != this->_layers.end()) { @@ -48,10 +44,7 @@ namespace megu { // Merge Textures FrameBuffer::BindDefaultFrameBuffer(); - glViewport(0, 0, static_cast<GLsizei>(this->_window.width()), static_cast<GLsizei>(this->_window.height())); - glClear(GL_COLOR_BUFFER_BIT); - std::any any = 1; - this->_module.render(textures); + this->_merger.render(this->_window, textures); this->_window.swapBuffers(); } } diff --git a/source/engine/graphics/front/engine/Engine.hpp b/source/engine/graphics/front/engine/Engine.hpp index dc41a4f..84e6e3e 100644 --- a/source/engine/graphics/front/engine/Engine.hpp +++ b/source/engine/graphics/front/engine/Engine.hpp @@ -3,7 +3,7 @@ #include <map> #include <optional> -#include <engine/graphics/front/module/FrameBufferModule.hpp> +#include <engine/graphics/front/module/FrameBufferMerger.hpp> #include <engine/graphics/back/cameras/View.hpp> #include "Layer.hpp" @@ -19,8 +19,8 @@ namespace megu { void push(Priority, Renderer &); template <class T> - void push(Priority layer_priority, Priority object_priority, T & object) { - this->_layers[layer_priority].get()->push<T>(object_priority, object); + void push(Priority layer_priority, Priority object_priority, T & object, Module<T> * modul) { + this->_layers[layer_priority].get()->push<T>(object_priority, object, modul); } void remove(Priority); @@ -35,9 +35,7 @@ namespace megu { private: std::map<Priority, std::unique_ptr<Layer>> _layers; - FrameBufferModule _module; + FrameBufferMerger _merger; Window & _window; - View _view; - }; } \ No newline at end of file diff --git a/source/engine/graphics/front/engine/Layer.hpp b/source/engine/graphics/front/engine/Layer.hpp index 325b144..fc05c6f 100644 --- a/source/engine/graphics/front/engine/Layer.hpp +++ b/source/engine/graphics/front/engine/Layer.hpp @@ -10,7 +10,7 @@ #include <engine/graphics/utility/reference_sorter.hpp> #include <engine/graphics/front/object/Renderable.hpp> -#include <engine/graphics/front/module/QuadGraphicModule.hpp> +#include <engine/graphics/front/module/Module.hpp> #include "Priority.hpp" #include "Renderer.hpp" @@ -26,23 +26,23 @@ namespace megu { inline const Renderer & renderer() const {return this->_renderer;} template <class T> - void push(Priority priority, T & object) { - this->_objects.insert({priority, Renderable(object, this->_module)}); + void push(Priority priority, T & object, Module<T> * modul) { + this->_objects.insert({priority, Renderable{ object, modul }}); } const Texture & draw(const Window & w, const TextureArray & a) { this->_frameBuffer.bind(); + this->_renderer.clear(); for(auto & [type, object] : this->_objects) { this->_renderer.render(w, object, a); } - + return this->_frameBuffer.texture(); } private: - Renderer & _renderer; FrameBuffer _frameBuffer; - QuadGraphicModule _module; - std::map<Priority, Renderable> _objects; + Renderer & _renderer; + std::map<Priority, Renderable> _objects; }; } \ No newline at end of file diff --git a/source/engine/graphics/front/engine/Renderer.cpp b/source/engine/graphics/front/engine/Renderer.cpp index edf40a7..0a47071 100644 --- a/source/engine/graphics/front/engine/Renderer.cpp +++ b/source/engine/graphics/front/engine/Renderer.cpp @@ -7,11 +7,15 @@ namespace megu { glEnable(GL_BLEND); } + void Renderer::setClearColor(float r, float g, float b, float a) const { + glClearColor(r, g, b, a); + } + void Renderer::clear() const { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } - void Renderer::setClearColor(float r, float g, float b, float a) const { - glClearColor(r, g, b, a); + void Renderer::render(const Window & w, Renderable & r, const TextureArray & a) { + render_ext(r, w, this->_view, a); } } \ No newline at end of file diff --git a/source/engine/graphics/front/engine/Renderer.hpp b/source/engine/graphics/front/engine/Renderer.hpp index c366b79..ea5e844 100644 --- a/source/engine/graphics/front/engine/Renderer.hpp +++ b/source/engine/graphics/front/engine/Renderer.hpp @@ -13,21 +13,25 @@ #include <engine/graphics/front/object/Renderable.hpp> namespace megu { - class Renderer { + class Producer { + public: + template <class T> + static Renderable produce(T & object, Module<T> & modul) { + return Renderable{object, modul}; + } + }; + + class Renderer : public Producer { public: Renderer() = delete; Renderer(float, float); ~Renderer() = default; - void render(const Window & w, Renderable & r, const TextureArray & a) { - this->clear(); - render_ext(r, w, this->_view, a); - } - const glm::vec2 dimension() const {return this->_view.dimension();} void clear() const; void setClearColor(float, float, float, float = 1.f) const; + void render(const Window &, Renderable &, const TextureArray &); View & view() {return this->_view;} diff --git a/source/engine/graphics/front/module/FrameBufferModule.cpp b/source/engine/graphics/front/module/FrameBufferMerger.cpp similarity index 78% rename from source/engine/graphics/front/module/FrameBufferModule.cpp rename to source/engine/graphics/front/module/FrameBufferMerger.cpp index 7f4e5a6..8977587 100644 --- a/source/engine/graphics/front/module/FrameBufferModule.cpp +++ b/source/engine/graphics/front/module/FrameBufferMerger.cpp @@ -1,10 +1,10 @@ -#include "FrameBufferModule.hpp" +#include "FrameBufferMerger.hpp" #include <engine/graphics/front/geometry/Plane.hpp> #include <engine/graphics/utility/array_generator.hpp> namespace megu { - FrameBufferModule::FrameBufferModule() + FrameBufferMerger::FrameBufferMerger() : _vbo(this->_vao, Plane::Layout(), Plane::Vertices(), megu::EditMode::STATIC) { megu::Source vert("assets/shaders/FrameBuffer-Instanced.vert", Source::Categorie::VERTEX); this->_program.attach(vert); @@ -18,7 +18,10 @@ namespace megu { frag.release(); } - void FrameBufferModule::render(const TextureArray & textures) { + void FrameBufferMerger::render(const Window & window, const TextureArray & textures) { + glViewport(0, 0, static_cast<GLsizei>(window.width()), static_cast<GLsizei>(window.height())); + glClear(GL_COLOR_BUFFER_BIT); + this->_program.use(); this->_vao.bind(); diff --git a/source/engine/graphics/front/module/FrameBufferModule.hpp b/source/engine/graphics/front/module/FrameBufferMerger.hpp similarity index 65% rename from source/engine/graphics/front/module/FrameBufferModule.hpp rename to source/engine/graphics/front/module/FrameBufferMerger.hpp index 2355abb..c2caea1 100644 --- a/source/engine/graphics/front/module/FrameBufferModule.hpp +++ b/source/engine/graphics/front/module/FrameBufferMerger.hpp @@ -7,16 +7,17 @@ #include <engine/graphics/back/shaders/Program.hpp> #include <engine/graphics/front/object/Image.hpp> +#include <engine/graphics/front/engine/Renderer.hpp> #include "Module.hpp" namespace megu { - class FrameBufferModule { + class FrameBufferMerger { public: - FrameBufferModule(); - ~FrameBufferModule() = default; + FrameBufferMerger(); + ~FrameBufferMerger() = default; - void render(const TextureArray &); + void render(const Window &, const TextureArray &); private: VertexArray _vao; diff --git a/source/engine/graphics/front/module/Module.hpp b/source/engine/graphics/front/module/Module.hpp index 99269ed..950af50 100644 --- a/source/engine/graphics/front/module/Module.hpp +++ b/source/engine/graphics/front/module/Module.hpp @@ -5,6 +5,8 @@ #include <engine/graphics/utility/reference_sorter.hpp> #include <engine/io/Window.hpp> +#include <engine/graphics/utility/ref_set.hpp> + namespace megu { template <class T> class Module { @@ -12,15 +14,6 @@ namespace megu { virtual void draw(T &, const Window &, const Camera &, const TextureArray &) const = 0; }; - template <class ... Ts> - class Multy_Module : public Module<Ts> ... {}; - template <class T> - using ref_set = std::set<std::reference_wrapper<T>, reference_sorter<T>>; - - template <class T> - using Module_Array = Module<ref_set<T>>; - - template <class ... Ts> - class Multy_Module_Array : public Module_Array<Ts> ... {}; + using Instanced_Module = Module<ref_set<T>>; } \ No newline at end of file diff --git a/source/engine/graphics/front/module/QuadGraphicModule.cpp b/source/engine/graphics/front/module/QuadGraphicModule.cpp deleted file mode 100644 index 7135719..0000000 --- a/source/engine/graphics/front/module/QuadGraphicModule.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "QuadGraphicModule.hpp" - -#include <engine/graphics/front/object/Image.hpp> -#include <engine/graphics/front/object/Sprite.hpp> - -#include <iostream> - -namespace megu { - void QuadGraphicModule::draw(Image &, const Window &, const Camera &, const TextureArray &) const { - std::cout << "Image !" << std::endl; - } - - void QuadGraphicModule::draw(Sprite &, const Window &, const Camera &, const TextureArray &) const { - std::cout << "Sprite !" << std::endl; - } -} \ No newline at end of file diff --git a/source/engine/graphics/front/module/QuadGraphicModule.hpp b/source/engine/graphics/front/module/QuadGraphicModule.hpp deleted file mode 100644 index 972c2ad..0000000 --- a/source/engine/graphics/front/module/QuadGraphicModule.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "Module.hpp" - - - -namespace megu { - class Image; - class Sprite; - - class QuadGraphicModule : public Module<Image>, public Module<Sprite> { - public: - void draw(Image &, const Window &, const Camera &, const TextureArray &) const override; - void draw(Sprite &, const Window &, const Camera &, const TextureArray &) const override; - }; -} \ No newline at end of file diff --git a/source/engine/graphics/front/module/QuadInstanced.cpp b/source/engine/graphics/front/module/QuadInstanced.cpp new file mode 100644 index 0000000..8b8c9f4 --- /dev/null +++ b/source/engine/graphics/front/module/QuadInstanced.cpp @@ -0,0 +1,151 @@ +#include "QuadInstanced.hpp" + +#include <engine/graphics/front/object/Image.hpp> +#include <engine/graphics/front/object/Sprite.hpp> + +#include <engine/graphics/utility/array_generator.hpp> + +#include <iostream> + +namespace megu { + QuadInstancedModule::QuadInstancedModule() + : _vbo(this->_vao, Quads::Layout(), Quads::Vertices().size(), megu::EditMode::STATIC) { + { + Source vert("assets/shaders/Image-Instanced-Fat.vert", Source::Categorie::VERTEX); + this->_imageProgram.attach(vert); + + Source frag("assets/shaders/Texture-Fat.frag", Source::Categorie::FRAGMENT); + this->_imageProgram.attach(frag); + + this->_imageProgram.link(); + + vert.release(); + frag.release(); + } + + { + Source vert("assets/shaders/Sprite.vert", Source::Categorie::VERTEX); + this->_spriteProgram.attach(vert); + + Source frag("assets/shaders/Sprite.frag", Source::Categorie::FRAGMENT); + this->_spriteProgram.attach(frag); + + this->_spriteProgram.link(); + + vert.release(); + frag.release(); + } + + this->_vbo << Quads::Vertices(); + } + + void QuadInstancedModule::draw(ref_set<Image> & images, const Window & window, const Camera & camera, const TextureArray &) const { + this->_vao.bind(); + this->_imageProgram.use(); + + this->_imageProgram.setUniform("uProj", camera.projection()); + this->_imageProgram.setUniform("uView", camera.view()); + + std::vector<std::reference_wrapper<const Texture>> textures; + + std::vector<glm::mat4> uModels; + std::vector<GLint> uTextures; + + static auto uSampler = array_generator<GLint, 32>().array; + this->_imageProgram.setUniform("uSampler", uSampler); + + for(auto & image : images) { + + std::vector<std::reference_wrapper<const Texture>>::iterator it = std::find(textures.begin(), textures.end(), image.get().texture()); + if(it != textures.end()) { + uModels.push_back(image.get().transformation().model()); + uTextures.push_back(static_cast<GLint>(it - textures.begin())); + } + else { + if(textures.size() >= 8 || uModels.size() >= 124) { + this->_imageProgram.setUniform("uModel", uModels); + this->_imageProgram.setUniform("uTextures", uTextures); + + glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size())); + + textures.clear(); + uModels.clear(); + uTextures.clear(); + } + + textures.push_back(image.get().texture()); + image.get().texture().bind(static_cast<GLint>(textures.size()-1)); + uTextures.push_back(static_cast<GLint>(textures.size()-1)); + uModels.push_back(image.get().transformation().model()); + } + } + + if(!textures.empty()) { + this->_imageProgram.setUniform("uModel", uModels); + this->_imageProgram.setUniform("uTextures", uTextures); + + glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size())); + } + } + + void QuadInstancedModule::draw(ref_set<Sprite> & sprites, const Window &, const Camera & camera, const TextureArray &) const { + this->_vao.bind(); + this->_spriteProgram.use(); + + this->_spriteProgram.setUniform("uProj", camera.projection()); + this->_spriteProgram.setUniform("uView", camera.view()); + + std::vector<std::reference_wrapper<const Texture>> textures; + + std::vector<glm::mat4> uModels; + std::vector<glm::vec4> uFrames; + std::vector<glm::vec2> uSizes; + std::vector<GLint> uTextures; + + static auto uSampler = array_generator<GLint, 32>().array; + this->_spriteProgram.setUniform("uSampler", uSampler); + + for(auto & image : sprites) { + std::vector<std::reference_wrapper<const Texture>>::iterator it = std::find(textures.begin(), textures.end(), image.get().texture()); + if(it != textures.end()) { + uModels.push_back(image.get().transformation().model()); + uFrames.push_back(image.get().frame()); + uSizes.push_back({it->get().width(), it->get().height()}); + + uTextures.push_back(static_cast<GLint>(it - textures.begin())); + } + else { + if(textures.size() >= 8 || uModels.size() >= 124) { + this->_spriteProgram.setUniform("uModel", uModels); + this->_spriteProgram.setUniform("uTextures", uTextures); + this->_spriteProgram.setUniform("uFrames", uFrames); + this->_spriteProgram.setUniform("uSizes", uSizes); + + glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size())); + + textures.clear(); + uModels.clear(); + uTextures.clear(); + uSizes.clear(); + } + + textures.push_back(image.get().texture()); + image.get().texture().bind(static_cast<GLint>(textures.size()-1)); + uTextures.push_back(static_cast<GLint>(textures.size()-1)); + + uModels.push_back(image.get().transformation().model()); + uFrames.push_back(image.get().frame()); + uSizes.push_back({image.get().texture().width(), image.get().texture().height()}); + } + } + + if(!textures.empty()) { + this->_spriteProgram.setUniform("uModel", uModels); + this->_spriteProgram.setUniform("uTextures", uTextures); + this->_spriteProgram.setUniform("uFrames", uFrames); + this->_spriteProgram.setUniform("uSizes", uSizes); + + glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size())); + } + } +} \ No newline at end of file diff --git a/source/engine/graphics/front/module/QuadInstanced.hpp b/source/engine/graphics/front/module/QuadInstanced.hpp new file mode 100644 index 0000000..734d202 --- /dev/null +++ b/source/engine/graphics/front/module/QuadInstanced.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "Module.hpp" + +#include <engine/graphics/back/buffers/VertexArray.hpp> +#include <engine/graphics/back/buffers/VerticeBuffer.hpp> +#include <engine/graphics/back/shaders/Program.hpp> + +namespace megu { + class Image; + class Sprite; + + class QuadInstancedModule : public Module<ref_set<Image>>, public Module<ref_set<Sprite>> { + public: + QuadInstancedModule(); + + void draw(ref_set<Image> &, const Window &, const Camera &, const TextureArray &) const override; + void draw(ref_set<Sprite> &, const Window &, const Camera &, const TextureArray &) const override; + + private: + VertexArray _vao; + VerticeBuffer _vbo; + Program _imageProgram; + Program _spriteProgram; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/object/Image.cpp b/source/engine/graphics/front/object/Image.cpp index e3873ef..55563ee 100644 --- a/source/engine/graphics/front/object/Image.cpp +++ b/source/engine/graphics/front/object/Image.cpp @@ -2,7 +2,7 @@ namespace megu { Image::Image(const std::filesystem::path & path) { - this->load(path); + this->load(path, true); } Image::Image(const Texture & texture) { diff --git a/source/engine/graphics/front/object/Renderable.hpp b/source/engine/graphics/front/object/Renderable.hpp index d70a3ca..2bb3960 100644 --- a/source/engine/graphics/front/object/Renderable.hpp +++ b/source/engine/graphics/front/object/Renderable.hpp @@ -10,9 +10,9 @@ namespace megu { public: Renderable() = delete; - template <class T, class M> - Renderable(T & object, M & module) - : _pimpl(std::make_unique<RenderableModel<T, M>>(object, module)) {} + template <class T> + Renderable(T & object, Module<T> * module) + : _pimpl(std::make_unique<RenderableModel<T>>(object, module)) {} Renderable(const Renderable & src) { this->_pimpl = src._pimpl->clone(); @@ -34,14 +34,13 @@ namespace megu { virtual std::unique_ptr<RenderableConcept> clone() const = 0; }; - template <class T, class M> + template <class T> struct RenderableModel : public RenderableConcept { - RenderableModel(T & v, M & m) + RenderableModel(T & v, Module<T> * m) : _object{ v }, _module{ m } {} void render(const Window & window, const Camera & camera, const TextureArray & array) const override { - this->_module.draw(this->_object, window, camera, array); - + this->_module->draw(this->_object, window, camera, array); } std::unique_ptr<RenderableConcept> clone() const override { @@ -49,9 +48,9 @@ namespace megu { } T & _object; - M & _module; + Module<T> * _module; }; - + friend void render_ext(Renderable & renderable, const Window & window, const Camera & camera, const TextureArray & array) { renderable._pimpl->render(window, camera, array); } diff --git a/source/engine/graphics/front/object/Sprite.cpp b/source/engine/graphics/front/object/Sprite.cpp index 82283f5..22bcf5f 100644 --- a/source/engine/graphics/front/object/Sprite.cpp +++ b/source/engine/graphics/front/object/Sprite.cpp @@ -1,14 +1,24 @@ #include "Sprite.hpp" namespace megu { - Sprite::Sprite(const Texture & texture) - : _frame(0, 0, texture.width(), texture.height()), _texture(texture) { - this->_transformation.scale(static_cast<float>(texture.width()), static_cast<float>(texture.height())); + Sprite::Sprite(const std::filesystem::path & path) + : _frame(0, 0, 0, 0) { + this->load(path, true); } - Sprite::Sprite(const Texture & texture, const glm::vec4 & frame) - : _frame(frame), _texture(texture) { - this->_transformation.move(frame.x, frame.y); - this->_transformation.scale(frame.z, frame.w); + void Sprite::load(const std::filesystem::path & path, bool flip) { + TextureBuffer buffer; + buffer.load(path, flip); + this->load(buffer); + } + + void Sprite::load(const TextureBuffer & buffer) { + this->setSize({buffer.width(), buffer.height()}); + this->_texture.store(buffer); + } + + void Sprite::link(const Texture & texture) { + this->setSize({texture.width(), texture.height()}); + this->_texture = texture; } } \ No newline at end of file diff --git a/source/engine/graphics/front/object/Sprite.hpp b/source/engine/graphics/front/object/Sprite.hpp index 44ea1e6..0445b10 100644 --- a/source/engine/graphics/front/object/Sprite.hpp +++ b/source/engine/graphics/front/object/Sprite.hpp @@ -4,21 +4,38 @@ #include <engine/graphics/back/textures/Texture.hpp> #include <engine/graphics/front/geometry/Quads.hpp> +#include <engine/graphics/utility/type.hpp> + namespace megu { class Sprite { public: - Sprite(const Texture &); - Sprite(const Texture &, const glm::vec4 &); + using Frame = glm::vec4; + + Sprite(const std::filesystem::path &); + + inline void setFrame(const Frame & frame) {this->_frame = frame;} - inline void setFrame(const glm::vec4 & frame) {this->_frame = frame;} + inline void setPosition(const Vec2 & pos) {this->_transformation.setPosition(pos.x, pos.y);} + inline void setOrigine(const Vec2 & pos) {this->_transformation.setOrigine(pos.x, pos.y);} + inline void setSize(const Vec2 & size) {this->_transformation.setScaling(size.x, size.y);} + inline void setRotation(float a) {this->_transformation.setRotation(a, Transformable::Axis::Z);} + inline void setLayer(float l) {this->_transformation.setZ(l);} - inline const glm::vec4 & frame() const {return this->_frame;} + inline void move(const Vec2 & pos) {this->_transformation.move({pos.x, pos.y, 0.f});} + inline void scale(const Vec2 & size) {this->_transformation.scale({size.x, size.y, 0.f});} + inline void rotate(float a) {this->_transformation.rotate(a, Transformable::Axis::Z);} + + inline const Frame & frame() const {return this->_frame;} inline const Texture & texture() const {return this->_texture;} inline const Quads & geometry() const {return this->_geometry;} inline const Transformable & transformation() const {return this->_transformation;} + void load(const std::filesystem::path &, bool = false); + void load(const TextureBuffer &); + void link(const Texture &); + private: - glm::vec4 _frame; + Frame _frame; Texture _texture; Quads _geometry; Transformable _transformation; diff --git a/source/engine/graphics/utility/isometric_sorter.cpp b/source/engine/graphics/utility/isometric_sorter.cpp index b566738..9710f64 100644 --- a/source/engine/graphics/utility/isometric_sorter.cpp +++ b/source/engine/graphics/utility/isometric_sorter.cpp @@ -1,38 +1,21 @@ #include "isometric_sorter.hpp" -#include <engine/graphics/front/object/Image.hpp> -#include <engine/graphics/front/object/Sprite.hpp> +#include <engine/graphics/back/geometry/Transformable.hpp> namespace megu { - bool isometric_sorter::operator()(const Image & img1, const Image & img2) const { - if(img1.transformation().z() != img2.transformation().z()) { - return img1.transformation().z() > img2.transformation().z(); + bool isometric_sorter::operator()(const Transformable & a, const Transformable & b) const { + if(a.z() != b.z()) { + return a.z() > b.z(); } - if(img1.transformation().y() != img2.transformation().y()) { - return img1.transformation().y() > img2.transformation().y(); + if(a.y() != b.y()) { + return a.y() > b.y(); } - if(img1.transformation().x() != img2.transformation().x()) { - return img1.transformation().x() > img2.transformation().x(); + if(a.x() != b.x()) { + return a.x() > b.x(); } - return &img1 > &img2; - } - - bool isometric_sorter_sprite::operator()(const Sprite & img1, const Sprite & img2) const { - if(img1.transformation().z() != img2.transformation().z()) { - return img1.transformation().z() > img2.transformation().z(); - } - - if(img1.transformation().y() != img2.transformation().y()) { - return img1.transformation().y() > img2.transformation().y(); - } - - if(img1.transformation().x() != img2.transformation().x()) { - return img1.transformation().x() > img2.transformation().x(); - } - - return &img1 > &img2; + return &a > &b; } } \ No newline at end of file diff --git a/source/engine/graphics/utility/isometric_sorter.hpp b/source/engine/graphics/utility/isometric_sorter.hpp index 1e3537d..50ea51b 100644 --- a/source/engine/graphics/utility/isometric_sorter.hpp +++ b/source/engine/graphics/utility/isometric_sorter.hpp @@ -1,16 +1,10 @@ #pragma once namespace megu { - class Image; - class Sprite; + class Transformable; class isometric_sorter { public: - bool operator()(const Image & img1, const Image & img2) const; - }; - - class isometric_sorter_sprite { - public: - bool operator()(const Sprite & img1, const Sprite & img2) const; + bool operator()(const Transformable & img1, const Transformable & img2) const; }; } \ No newline at end of file diff --git a/source/engine/graphics/utility/ref_set.hpp b/source/engine/graphics/utility/ref_set.hpp new file mode 100644 index 0000000..d87601b --- /dev/null +++ b/source/engine/graphics/utility/ref_set.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace megu { + template <class T> + using ref_set = std::set<std::reference_wrapper<T>, reference_sorter<T>>; +} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 2cfef63..0f28b37 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -14,6 +14,8 @@ #include <engine/io/Window.hpp> #include <engine/graphics/back/cameras/View.hpp> #include <engine/graphics/front/object/Image.hpp> +#include <engine/graphics/front/object/Sprite.hpp> +#include <engine/graphics/front/module/QuadInstanced.hpp> #include <engine/graphics/front/engine/Renderer.hpp> #include <engine/graphics/front/engine/Engine.hpp> #include <engine/graphics/errors.hpp> @@ -23,7 +25,7 @@ const float i_y = 0.5f; const float j_x = -1.f; const float j_y = 0.5f; -glm::vec2 to_screen_coordinate(const glm::vec2 & tile, float w, float h, float layer = 0.0f) { +megu::Vec2 to_screen_coordinate(const megu::Vec2 & tile, float w, float h, float layer = 0.0f) { return { (tile.x + layer) * i_x * 0.5f * w + (tile.y + layer) * j_x * 0.5f * w, (tile.x + layer) * i_y * 0.5f * h + (tile.y + layer) * j_y * 0.5f * h @@ -36,280 +38,16 @@ megu::Vertex to_screen_coordinate(int x, int y, unsigned int u, unsigned int v, } */ -//* Isometric : - -int main(int argc, const char * argv[]) { - try { - //? Window - megu::Window window; - window.open("Isometric Window", 360, 360); - megu::error::opengl_error::check(); - - std::cout << "Window Inited" << std::endl; - - std::cout << "Group Inited" << std::endl; - - //? Image 1 - std::vector<int> map = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, - 3, 3, 3, 3, 4, 5, 6, 7, 8, 9, - 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, - 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, - 6, 6, 6, 6, 6, 6, 6, 7, 8, 9, - 7, 7, 7, 7, 7, 7, 7, 7, 8, 9, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - - }; - - size_t x = 0; - size_t y = 0; - - std::vector<std::unique_ptr<megu::Image>> images; - - megu::Texture texture_0; - texture_0.store(megu::TextureBuffer("assets/textures/Cube_Red.png")); - - megu::Texture texture_1; - texture_1.store(megu::TextureBuffer("assets/textures/Cube_Green.png")); - - megu::Texture texture_2; - texture_2.store(megu::TextureBuffer("assets/textures/Cube_Blue.png")); - - megu::Texture texture_3; - texture_3.store(megu::TextureBuffer("assets/textures/Cube_Yellow.png")); - - for(auto id : map) { - if(x == 10) { - x = 0; - ++y; - } - - if(id != 0) { - switch (id % 4) { - case 1: - images.push_back(std::make_unique<megu::Image>(texture_1)); - break; - - case 2: - images.push_back(std::make_unique<megu::Image>(texture_2)); - break; - - case 3: - images.push_back(std::make_unique<megu::Image>(texture_3)); - break; - - default: - images.push_back(std::make_unique<megu::Image>(texture_0)); - break; - } - - glm::vec2 pos = to_screen_coordinate({x, y}, 32.f, 32.f, static_cast<float>(id)-3.f); - - images.back()->setPosition({pos.x + window.width()/2, pos.y + window.height()/8}); - } - - ++x; - } - - /*for(auto & i : images) { - group.add(*i); - i.get()->setSize({32.f, 32.f}); - }*/ - - std::cout << "Images 1 Inited" << std::endl; - - //? Image 2 - std::vector<int> map_2 = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; - - size_t x_2 = 0; - size_t y_2 = 0; - - std::vector<std::unique_ptr<megu::Image>> images_2; - - megu::Texture texture_4; - texture_4.store(megu::TextureBuffer("assets/textures/Cube_White.png")); - - for(auto id : map_2) { - if(x_2 == 10) { - x_2 = 0; - ++y_2; - } - - images_2.push_back(std::make_unique<megu::Image>(texture_4)); - glm::vec2 pos = to_screen_coordinate({x_2, y_2}, 32.f, 32.f, 0.f); - images_2.back()->setPosition({pos.x + window.width()/2 - 16.f, pos.y + window.height()/4}); - - ++x_2; - } - - /*for(auto & i : images_2) { - group_2.add(*i); - i.get()->setSize({32.f, 32.f}); - }*/ - - std::cout << "Images 2 Inited" << std::endl; - - - //? Engines - megu::GraphicEngine engine(window); - megu::Renderer basic_renderer(360, 360); - - engine.push(0, basic_renderer); - - engine.push<megu::Image>(0, 0, *((images.front()).get())); - - //? Render Loop - std::cout << "Render Loop Begin !" << std::endl; - glm::vec2 xy = {0, 0}; - - double previousTime = megu::Window::Time(); - int frameCount = 0; - - while(window.isOpen()) { - double currentTime = megu::Window::Time(); - frameCount++; - - if(currentTime - previousTime >= 1.0) { - window.setTitle(std::to_string(frameCount)); - - frameCount = 0; - previousTime = currentTime; - } - - window.pollEvents(); - engine.step(); - } - std::cout << "Render Loop End !" << std::endl; - } - catch(std::exception & error) { - std::cerr << error.what() << std::endl; - } - - return EXIT_SUCCESS; -} - - -//* Tilemap -/* int main(int argc, const char * argv[]) { try { - //? Window megu::Window window; window.open("Isometric Window", 360, 360); - megu::error::opengl_error::check(); - std::cout << "Window Inited" << std::endl; - //? Group - megu::VertexArrayGroup group; - - std::cout << "Group Inited" << std::endl; - - //? Grids - - megu::Texture texture_1; - texture_1.store(megu::TextureBuffer("assets/textures/Tile_Test_3.png")); - - megu::VerticesArray grid_1(megu::Quads::Primitive(), 4); - - //grid_1[0] = {{0.f, 0.f}, {0.0f, 0.0f}}; - //grid_1[1] = {{16.f, 0.f}, {0.5f, 0.0f}}; - //grid_1[2] = {{16.f, 16.f}, {0.5f, 0.5f}}; - //grid_1[3] = {{0.f, 16.f}, {0.0f, 0.5f}}; - - - - grid_1[0] = to_screen_coordinate(0, 0, 0, 0, texture_1); - grid_1[1] = to_screen_coordinate(16, 0, 16, 0, texture_1); - grid_1[2] = to_screen_coordinate(16, 16, 16, 16, texture_1); - grid_1[3] = to_screen_coordinate(0, 16, 0, 16, texture_1); - - - grid_1.scale(1.f, 1.f); - + megu::Image image("assets/textures/Image_Test.png"); - - group.add(texture_1, grid_1); - - std::cout << "Grid created" << std::endl; - - //? ImGui - //ImGui::CreateContext(); - //ImGui_ImplOpenGL3_Init(); - //ImGui_ImplGlfw_InitForOpenGL(window.ptr(), true); - - //? Engines - megu::GraphicEngine engine(window); - megu::Renderer basic_renderer(100, 100); - - engine.push(0, basic_renderer); - engine.push(0, 0, group); - - //? Render Loop - std::cout << "Render Loop Begin !" << std::endl; - - double previousTime = megu::Window::Time(); - int frameCount = 0; - - while(window.isOpen()) { - double currentTime = megu::Window::Time(); - frameCount++; - - if(currentTime - previousTime >= 1.0) { - window.setTitle(std::to_string(frameCount)); - - frameCount = 0; - previousTime = currentTime; - } - - window.pollEvents(); - engine.step(); - } - std::cout << "Render Loop End !" << std::endl; - } - catch(std::exception & error) { - std::cerr << error.what() << std::endl; - } - - return EXIT_SUCCESS; -}*/ - - -//* Sprite -/* -int main(int argc, const char * argv[]) { - try { - //? Window - megu::Window window; - window.open("Sprite Window", 360, 360); - megu::error::opengl_error::check(); - - std::cout << "Window Inited" << std::endl; - - //? Group - megu::SpriteGroup group; - megu::ImageGroup group_2; - - std::cout << "Group Inited" << std::endl; - - //? Grids - - megu::Texture texture_1; - texture_1.store(megu::TextureBuffer("assets/textures/Neera.png")); + megu::Sprite sprite("assets/textures/Neera.png"); + sprite.setSize({25, 49}); std::vector<glm::vec4> frames; frames.push_back({0, 0, 51, 98}); @@ -320,38 +58,37 @@ int main(int argc, const char * argv[]) { frames.push_back({51, 98, 51, 98}); frames.push_back({102, 98, 51, 98}); - megu::Sprite neera(texture_1, frames[0]); - megu::Image image(texture_1); - //neera.scale(1.f, 1.f); - - - group.add(neera); - group_2.add(image); - - std::cout << "Sprite created" << std::endl; + sprite.setFrame(frames[0]); + sprite.move({32, 0}); - //? Engines megu::GraphicEngine engine(window); megu::Renderer basic_renderer(128, 128); - engine.push(0, basic_renderer); - engine.push(0, 0, group); + megu::ref_set<megu::Image> images_set; + images_set.insert(image); + + megu::ref_set<megu::Sprite> sprites_set; + sprites_set.insert(sprite); - //? Render Loop - std::cout << "Render Loop Begin !" << std::endl; + megu::QuadInstancedModule modul; + + engine.push(0, basic_renderer); + engine.push(0, 1, images_set, &modul); + engine.push(0, 0, sprites_set, &modul); double previousTime = megu::Window::Time(); int frameCount = 0; - std::thread t([&frames, &window, &neera](){ + std::thread t([&frames, &sprite, &window](){ size_t i = 0; while(window.isOpen()) { std::this_thread::sleep_for(std::chrono::milliseconds(30)); - neera.setFrame(frames[i%frames.size()]); + sprite.setFrame(frames[i%frames.size()]); ++i; } }); + std::cout << "Render Loop Start !" << std::endl; while(window.isOpen()) { double currentTime = megu::Window::Time(); frameCount++; @@ -376,5 +113,3 @@ int main(int argc, const char * argv[]) { return EXIT_SUCCESS; } -*/ - -- GitLab