diff --git a/assets/shaders/Image-Instanced-Fat.vert b/assets/shaders/Image-Instanced-Fat.vert new file mode 100644 index 0000000000000000000000000000000000000000..5c700fb9fb03a19d4f2db893f107bf5c9ad3f7d9 --- /dev/null +++ b/assets/shaders/Image-Instanced-Fat.vert @@ -0,0 +1,16 @@ +#version 450 core +layout (location = 0) in vec2 aPos; +layout (location = 1) in vec2 aTex; + +uniform mat4 uProj; +uniform mat4 uView; +uniform mat4 uModel[128]; + +out flat int Id; +out vec2 Texture; + +void main() { + Texture = aTex; + Id = gl_InstanceID; + gl_Position = uProj * uView * uModel[gl_InstanceID] * vec4(aPos.x, aPos.y, 0.0, 1.0); +} \ No newline at end of file diff --git a/assets/shaders/Texture-Fat.frag b/assets/shaders/Texture-Fat.frag new file mode 100644 index 0000000000000000000000000000000000000000..37596cc07504422f6970ac898444549dda4b0577 --- /dev/null +++ b/assets/shaders/Texture-Fat.frag @@ -0,0 +1,12 @@ +#version 450 core +out vec4 FragColor; + +in flat int Id; +in vec2 Texture; + +uniform sampler2D uSampler[8]; +uniform int uTextures[128]; + +void main() { + FragColor = texture(uSampler[uTextures[Id]], Texture); +} \ No newline at end of file diff --git a/assets/textures/Cube_Blue_Outlined.png b/assets/textures/Cube_Blue_Outlined.png new file mode 100644 index 0000000000000000000000000000000000000000..7b9880a482b09a1df76a7df636e288472e224130 Binary files /dev/null and b/assets/textures/Cube_Blue_Outlined.png differ diff --git a/assets/textures/Cube_Test.png b/assets/textures/Cube_Test.png new file mode 100644 index 0000000000000000000000000000000000000000..673ea5b784babacfdb93ea407c2db77aed95f6ac Binary files /dev/null and b/assets/textures/Cube_Test.png differ diff --git a/imgui.ini b/imgui.ini index 6b73fe54ff07f17b07d20b210e2d40736cf7919f..ffc607e47918902a2e7f034df5eb6c6acb58de8b 100644 --- a/imgui.ini +++ b/imgui.ini @@ -3,6 +3,6 @@ Pos=60,60 Size=400,400 [Window][Isometric] -Pos=138,21 +Pos=135,21 Size=477,101 diff --git a/source/engine/graphics/back/shaders/Program.cpp b/source/engine/graphics/back/shaders/Program.cpp index 9520109bcac16a39c81a1978afa2155874a85b6e..71a3e7702c01f97fc45d53c34d1e9307dc0eb494 100644 --- a/source/engine/graphics/back/shaders/Program.cpp +++ b/source/engine/graphics/back/shaders/Program.cpp @@ -154,6 +154,10 @@ namespace megu { glUniform1iv(this->_locations.at(name), static_cast<GLsizei>(value.size()), value.data()); } + void Program::setUniform(const std::string & name, const std::vector<GLuint> & value) const { + glUniform1uiv(this->_locations.at(name), static_cast<GLsizei>(value.size()), value.data()); + } + void Program::setUniform(const std::string & name, const std::vector<GLfloat> & value) const { glUniform1fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), value.data()); } diff --git a/source/engine/graphics/back/shaders/Program.hpp b/source/engine/graphics/back/shaders/Program.hpp index 0b5df733d627649646e072c89772f3fe85dc49aa..cd005ddbf509596684218e527ac79e9ecd4c9542 100644 --- a/source/engine/graphics/back/shaders/Program.hpp +++ b/source/engine/graphics/back/shaders/Program.hpp @@ -63,6 +63,7 @@ namespace megu { void setUniform(const std::string &, const glm::mat4 &) const; void setUniform(const std::string &, const std::vector<GLint> &) const; + void setUniform(const std::string &, const std::vector<GLuint> &) const; void setUniform(const std::string &, const std::vector<GLfloat> &) const; void setUniform(const std::string &, const std::vector<glm::vec2> &) const; void setUniform(const std::string &, const std::vector<glm::vec4> &) const; diff --git a/source/engine/graphics/back/textures/Texture.cpp b/source/engine/graphics/back/textures/Texture.cpp index ccc5e95ed5dc8353a7c1e1e6acd6f4fb7ed317f3..4ff4eadaf57fc36c8a572269708803a3d9660f59 100644 --- a/source/engine/graphics/back/textures/Texture.cpp +++ b/source/engine/graphics/back/textures/Texture.cpp @@ -115,9 +115,9 @@ namespace megu { return this->_id == texture._id; } - bool Texture::operator!=(const Texture & texture) const { + /*bool Texture::operator!=(const Texture & texture) const { return this->_id != texture._id; - } + }*/ bool Texture::operator>=(const Texture & texture) const { return this->_id >= texture._id; diff --git a/source/engine/graphics/back/textures/Texture.hpp b/source/engine/graphics/back/textures/Texture.hpp index 39345b128448bf12f63f637969b3b3cd207fe451..85ada6bb7585d955f89e85c0b4a3037f7394b1a6 100644 --- a/source/engine/graphics/back/textures/Texture.hpp +++ b/source/engine/graphics/back/textures/Texture.hpp @@ -55,7 +55,7 @@ namespace megu { bool valid() const; bool operator==(const Texture &) const; - bool operator!=(const Texture &) const; + //bool operator!=(const Texture &) const; bool operator>=(const Texture &) const; bool operator<=(const Texture &) const; bool operator>(const Texture &) const; diff --git a/source/engine/graphics/front/Engine.cpp b/source/engine/graphics/front/Engine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c81b69229305ebcc27ac15a55211ee7298dca44 --- /dev/null +++ b/source/engine/graphics/front/Engine.cpp @@ -0,0 +1,20 @@ +#include "Engine.hpp" + +namespace megu { + GraphicEngine::GraphicEngine(Window & window,float w, float h) + : _renderer(w, h), _window(window) { + glViewport(0, 0, window.width(), window.height()); + glClearColor(0.f, 0.f, 0.f, 1.f); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + } + + void GraphicEngine::step() { + if(this->_window.isOpen()) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + this->_renderer.render(this->_window); + this->_window.swapBuffers(); + } + } +} \ No newline at end of file diff --git a/source/engine/graphics/front/Engine.hpp b/source/engine/graphics/front/Engine.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9493020e963f97790b63077f812df0890b85e418 --- /dev/null +++ b/source/engine/graphics/front/Engine.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "Renderer.hpp" + +namespace megu { + class GraphicEngine { + public: + GraphicEngine() = delete; + GraphicEngine(Window &, float, float); + ~GraphicEngine() = default; + + void step(); + inline void setClearColor(float r, float g, float b, float a = 1.f) const {glClearColor(r, g, b, a);} + + Renderer & tmp_getRenderer() {return this->_renderer;} + + private: + Window & _window; + Renderer _renderer; + + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/Renderer.cpp b/source/engine/graphics/front/Renderer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1c8f589ff988fc7fef785facd1d0eef84a8c68c --- /dev/null +++ b/source/engine/graphics/front/Renderer.cpp @@ -0,0 +1,18 @@ +#include "Renderer.hpp" + +namespace megu { + Renderer::Renderer(float x, float y) + : _view(0, 0, y, x) { + + } + + void Renderer::add(DrawGroup & group) { + this->_groups.insert(&group); + } + + void Renderer::render(const Window & window) const { + for(auto & group : this->_groups) { + group->draw(window, this->_view); + } + } +} \ No newline at end of file diff --git a/source/engine/graphics/front/Renderer.hpp b/source/engine/graphics/front/Renderer.hpp new file mode 100644 index 0000000000000000000000000000000000000000..517585960e964a001f29919925105112364ed86f --- /dev/null +++ b/source/engine/graphics/front/Renderer.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include <set> +#include <any> + +#include <engine/graphics/utility/reference_sorter.hpp> +#include <engine/graphics/back/cameras/View.hpp> +#include <engine/graphics/front/group/DrawGroup.hpp> + +namespace megu { + class Renderer { + public: + Renderer() = delete; + Renderer(float, float); + ~Renderer() = default; + + void add(DrawGroup & group); + + virtual void render(const Window &) const; + + private: + std::set<DrawGroup *> _groups; + View _view; + + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/group/ImageGroup.cpp b/source/engine/graphics/front/group/ImageGroup.cpp index d40ae5f39b8bd114b8f0b6b872ce4ccc8abb681f..0ecd104b0cc91354fe1247600d41adf13b251880 100644 --- a/source/engine/graphics/front/group/ImageGroup.cpp +++ b/source/engine/graphics/front/group/ImageGroup.cpp @@ -6,8 +6,8 @@ namespace megu { ImageGroup::ImageGroup() : _vbo(this->_vao, Quads::Layout(), 400) { { - Source vert("assets/shaders/Image-Instanced.vert", Source::Categorie::VERTEX); - Source frag("assets/shaders/Image.frag", Source::Categorie::FRAGMENT); + Source vert("assets/shaders/Image-Instanced-Fat.vert", Source::Categorie::VERTEX); + Source frag("assets/shaders/Texture-Fat.frag", Source::Categorie::FRAGMENT); this->_program << vert; this->_program << frag; @@ -36,21 +36,51 @@ namespace megu { this->_vao.bind(); this->_program.use(); - std::map<std::reference_wrapper<const Texture>, std::vector<glm::mat4>, std::greater<megu::Texture>> data; - + std::vector<std::reference_wrapper<const Texture>> textures; + + std::vector<glm::mat4> uModels; + std::vector<GLint> uTextures; + for(auto & image : this->_images) { - data[image.get().texture()].push_back(image.get().transformation().model()); + + 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->_program.setUniform("uProj", camera.projection()); + this->_program.setUniform("uView", camera.view()); + this->_program.setUniform("uSampler", std::vector<GLint>({0, 1, 2, 3, 4, 5, 6, 7})); + this->_program.setUniform("uModel", uModels); + this->_program.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()); + } } - for(auto &[texture, models] : data) { - texture.get().bind(0); + //std::cout << "---------------" << std::endl; + if(!textures.empty()) { this->_program.setUniform("uProj", camera.projection()); this->_program.setUniform("uView", camera.view()); - this->_program.setUniform("uSampler", 0); - this->_program.setUniform("uModel", models); + + this->_program.setUniform("uSampler", std::vector<GLint>({0, 1, 2, 3, 4, 5, 6, 7})); + this->_program.setUniform("uModel", uModels); + this->_program.setUniform("uTextures", uTextures); - glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(models.size())); - } + 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/group/ImageGroup.hpp b/source/engine/graphics/front/group/ImageGroup.hpp index ed674ee1b0c496826ba2da7734a4eb16474ac16e..fbdbbd73e11c5633ba37076492bc7cc30b433c06 100644 --- a/source/engine/graphics/front/group/ImageGroup.hpp +++ b/source/engine/graphics/front/group/ImageGroup.hpp @@ -1,13 +1,14 @@ #pragma once #include "DrawGroup.hpp" -#include "reference_sorter.hpp" -#include "isometric_sorter.hpp" + #include <map> #include <list> #include <set> +#include <engine/graphics/utility/isometric_sorter.hpp> + #include <engine/graphics/back/buffers/VertexArray.hpp> #include <engine/graphics/back/buffers/VerticeBuffer.hpp> #include <engine/graphics/back/shaders/Program.hpp> diff --git a/source/engine/graphics/front/group/isometric_sorter.cpp b/source/engine/graphics/utility/isometric_sorter.cpp similarity index 100% rename from source/engine/graphics/front/group/isometric_sorter.cpp rename to source/engine/graphics/utility/isometric_sorter.cpp diff --git a/source/engine/graphics/front/group/isometric_sorter.hpp b/source/engine/graphics/utility/isometric_sorter.hpp similarity index 100% rename from source/engine/graphics/front/group/isometric_sorter.hpp rename to source/engine/graphics/utility/isometric_sorter.hpp diff --git a/source/engine/graphics/front/group/reference_sorter.hpp b/source/engine/graphics/utility/reference_sorter.hpp similarity index 86% rename from source/engine/graphics/front/group/reference_sorter.hpp rename to source/engine/graphics/utility/reference_sorter.hpp index df5a8eab1f5dc1da160646482820fff6ecd467cb..54353b6e9beb6d079c5f7eb16f9384937c884298 100644 --- a/source/engine/graphics/front/group/reference_sorter.hpp +++ b/source/engine/graphics/utility/reference_sorter.hpp @@ -9,6 +9,7 @@ namespace megu { friend bool operator<(const T &, const T &); bool operator()(const T &, const T &) const; + bool operator()(const T *, const T *) const; }; } diff --git a/source/engine/graphics/front/group/reference_sorter.tpp b/source/engine/graphics/utility/reference_sorter.tpp similarity index 68% rename from source/engine/graphics/front/group/reference_sorter.tpp rename to source/engine/graphics/utility/reference_sorter.tpp index 320ee9f694d62abbc1cff1625298176fbce13595..c1226ad6e56d719f5592ee07ef9d18b352635a67 100644 --- a/source/engine/graphics/front/group/reference_sorter.tpp +++ b/source/engine/graphics/utility/reference_sorter.tpp @@ -10,4 +10,9 @@ namespace megu { bool reference_sorter<T>::operator()(const T & obj_1, const T & obj_2) const { return &obj_1 < &obj_2; } + + template <class T> + bool reference_sorter<T>::operator()(const T * obj_1, const T * obj_2) const { + return obj_1 < obj_2; + } } \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index ecd068c0726151c576b2802c2dc6caa12c514ac5..68133f00f0619342fc77e085a13fde9b59b3c920 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -7,13 +7,15 @@ #include <imgui_impl_glfw.h> #include <imgui_impl_opengl3.h> -#define WINDOW_WIDTH 1200 -#define WINDOW_HEIGHT 720 +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 640 #include <engine/io/Window.hpp> #include <engine/graphics/back/cameras/View.hpp> #include <engine/graphics/front/object/Image.hpp> #include <engine/graphics/front/group/ImageGroup.hpp> +#include <engine/graphics/front/Renderer.hpp> +#include <engine/graphics/front/Engine.hpp> #include <engine/graphics/errors.hpp> #define NORMALIZE(X) X/255.f @@ -39,10 +41,6 @@ int main(int argc, const char * argv[]) { std::cout << "Window Inited" << std::endl; - //? Camera - megu::View view(0, 0, 320, 240); - std::cout << "View Initied" << std::endl; - //? Group megu::ImageGroup group; @@ -50,16 +48,16 @@ int main(int argc, const char * argv[]) { //? Image std::vector<int> map = { - 0, 0, 0, 0, 1, 2, 3, 0, 0, 3, - 0, 0, 0, 2, 0, 3, 0, 0, 3, 1, - 0, 0, 1, 3, 3, 0, 0, 0, 2, 2, - 0, 2, 1, 0, 0, 1, 0, 2, 0, 0, - 2, 1, 3, 1, 0, 0, 3, 0, 1, 0, - 1, 3, 0, 2, 3, 0, 0, 1, 0, 0, - 0, 1, 0, 0, 1, 2, 3, 1, 0, 0, - 0, 0, 0, 0, 2, 0, 1, 0, 1, 0, - 0, 0, 0, 2, 0, 0, 0, 1, 3, 0, - 0, 0, 3, 1, 2, 0, 0, 0, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, }; size_t x = 0; @@ -67,8 +65,11 @@ int main(int argc, const char * argv[]) { std::vector<std::unique_ptr<megu::Image>> images; - megu::Texture texture; - texture.store(megu::TextureBuffer("assets/textures/Cube_Grass.png")); + megu::Texture texture_1; + texture_1.store(megu::TextureBuffer("assets/textures/Cube_Blue.png")); + + megu::Texture texture_2; + texture_2.store(megu::TextureBuffer("assets/textures/Cube_Red.png")); for(auto id : map) { if(x == 10) { @@ -76,16 +77,20 @@ int main(int argc, const char * argv[]) { ++y; } - images.push_back(std::make_unique<megu::Image>(texture)); - glm::vec2 pos = to_screen_coordinate({x, y}, 32.f, 32.f); - images.back()->setPosition(pos.x + 160, pos.y); + if(id != 0) { + images.push_back(std::make_unique<megu::Image>(id == 1 ? texture_1 : texture_2)); + glm::vec2 pos = to_screen_coordinate({x, y}, 32.f, 32.f); + + images.back()->setPosition(pos.x + 160, pos.y); + } ++x; } for(auto & i : images) { group.add(*i); + i.get()->setSize(32.f, 32.f); } std::cout << "Image Inited" << std::endl; @@ -95,88 +100,19 @@ int main(int argc, const char * argv[]) { ImGui_ImplOpenGL3_Init(); ImGui_ImplGlfw_InitForOpenGL(window.ptr(), true); - //? Render Loop - glClearColor(1.f, 1.f, 1.f, 1.f); - - double lastTime = glfwGetTime(); - int nbFrames = 0; + //? Engines + megu::GraphicEngine engine(window, 320, 320); + engine.setClearColor(0.f, 0.f, 0.f); + //? Render Loop std::cout << "Render Loop Begin !" << std::endl; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glm::vec2 xy = {0, 0}; - while(window.isOpen()) { - double currentTime = glfwGetTime(); - nbFrames++; - if ( currentTime - lastTime >= 1.0 ){ // If last prinf() was more than 1 sec ago - // printf and reset timer - window.setTitle(std::to_string(nbFrames)); - nbFrames = 0; - lastTime += 1.0; - } + engine.tmp_getRenderer().add(group); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + while(window.isOpen()) { window.pollEvents(); - group.draw(window, view); - - /*ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - if(ImGui::Begin("Isometric")) { - ImGui::Text("Position : %i / %i", static_cast<int>(xy.x), static_cast<int>(xy.y)); - - ImGui::Text("x : "); - ImGui::SameLine(); - if(ImGui::Button("+")) { - ++xy.x; - glm::vec2 pos = to_screen_coordinate(xy, 32, 32, 0.f); - images[1]->setPosition(pos.x, pos.y); - group.update(); - - } - - ImGui::SameLine(); - if(ImGui::Button("-")) { - --xy.x; - glm::vec2 pos = to_screen_coordinate(xy, 32, 32, 0.f); - images[1]->setPosition(pos.x, pos.y); - group.update(); - - } - - ImGui::PushID(1); - - ImGui::Text("y : "); - ImGui::SameLine(); - if(ImGui::Button("+")) { - ++xy.y; - glm::vec2 pos = to_screen_coordinate(xy, 32, 32, 0.f); - images[1]->setPosition(pos.x, pos.y); - group.update(); - - } - - ImGui::SameLine(); - if(ImGui::Button("-")) { - --xy.y; - glm::vec2 pos = to_screen_coordinate(xy, 32, 32, 0.f); - images[1]->setPosition(pos.x, pos.y); - group.update(); - - } - - ImGui::PopID(); - } - ImGui::End(); - - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());*/ - - window.swapBuffers(); + engine.step(); } std::cout << "Render Loop End !" << std::endl; }