diff --git a/assets/shaders/FrameBuffer-Instanced.frag b/assets/shaders/FrameBuffer-Instanced.frag index 2db481d44a28552df09447eaef2b7c0599f25e9f..736ee8af5ef35a1e439fb7f70d95a5bd34f4fac3 100644 --- a/assets/shaders/FrameBuffer-Instanced.frag +++ b/assets/shaders/FrameBuffer-Instanced.frag @@ -6,20 +6,21 @@ in vec2 Texture; uniform sampler2D uSampler[32]; uniform uint uTexturesCount; +uniform vec3 uClearColor; void main() { vec4 color = vec4(0.0, 0.0, 0.0, 1.0); for(uint i = 0; i < uTexturesCount; ++i) { vec4 tcolor = texture(uSampler[i], Texture); - if(tcolor.r != 0.0) { + if(tcolor.r != uClearColor.r) { color.r = tcolor.r; } - if(tcolor.g != 0.0) { + if(tcolor.g != uClearColor.g) { color.g = tcolor.g; } - if(tcolor.b != 0.0) { + if(tcolor.b != uClearColor.b) { color.b = tcolor.b; } } diff --git a/assets/shaders/Grid-Instanced.frag b/assets/shaders/Grid-Instanced.frag new file mode 100644 index 0000000000000000000000000000000000000000..6860880d0c6f65028f82e3377aa9c3aa3d3b433b --- /dev/null +++ b/assets/shaders/Grid-Instanced.frag @@ -0,0 +1,10 @@ +#version 450 core +out vec4 FragColor; + +in vec2 Texture; + +uniform sampler2D uSampler; + +void main() { + FragColor = texture(uSampler, Texture); +} \ No newline at end of file diff --git a/assets/shaders/Grid-Instanced.vert b/assets/shaders/Grid-Instanced.vert new file mode 100644 index 0000000000000000000000000000000000000000..f9d3622cc311e5de7f0f57017b6f650d626f27d0 --- /dev/null +++ b/assets/shaders/Grid-Instanced.vert @@ -0,0 +1,19 @@ +#version 450 core +layout (location = 0) in vec2 aPos; +layout (location = 1) in vec2 aTex; + +uniform mat4 uProj; +uniform mat4 uView; +uniform mat4 uModel; + +uniform vec4 uData[254]; + +out vec2 Texture; +out vec2 Color; + +void main() { + vec4 usedData = uData[gl_VertexID]; + Texture = usedData.zw; + + gl_Position = uProj * uView * uModel * vec4(aPos.x + usedData.x, aPos.y + usedData.y, 0.0, 1.0); +} \ No newline at end of file diff --git a/assets/textures/Test.png b/assets/textures/Test.png deleted file mode 100644 index 5900cdb901de8ec21b580869c01c70d32e764dae..0000000000000000000000000000000000000000 Binary files a/assets/textures/Test.png and /dev/null differ diff --git a/assets/textures/Tile_Test.png b/assets/textures/Tile_Test.png new file mode 100644 index 0000000000000000000000000000000000000000..d25e9e0324403cbccc67e1a0eed3fdbb9b63e694 Binary files /dev/null and b/assets/textures/Tile_Test.png differ diff --git a/assets/textures/Tile_Test_2.png b/assets/textures/Tile_Test_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6193471ba9f044adff524fb9b3afa01ee664c806 Binary files /dev/null and b/assets/textures/Tile_Test_2.png differ diff --git a/assets/textures/Tile_Test_3.png b/assets/textures/Tile_Test_3.png new file mode 100644 index 0000000000000000000000000000000000000000..5b6bb5cbd73647990fa99bac0513a38665b877c3 Binary files /dev/null and b/assets/textures/Tile_Test_3.png differ diff --git a/source/engine/graphics/back/geometry/Geometry.hpp b/source/engine/graphics/back/geometry/Geometry.hpp index c34f8fd5890d7aeba60c1d1dc73b7adac9c94f6a..2ba0d917bd1b8abd5a8d336585dd73e059124c80 100644 --- a/source/engine/graphics/back/geometry/Geometry.hpp +++ b/source/engine/graphics/back/geometry/Geometry.hpp @@ -59,7 +59,8 @@ namespace megu { const Vertices_t & vertices() const {return Static_Geometry<T, P>::Vertices();} static Layout_t Layout() {return Counter<megu::layout::Value>::Count<L...>();} - static const Vertices_t & Vertices() {return T::Vertices();} + static const Vertices_t & Vertices() {return T::Vertices();} + static const size_t & Count() {return T::Count();} }; template <class T, Primitive_t P, layout::Value ... L> diff --git a/source/engine/graphics/back/shaders/Program.cpp b/source/engine/graphics/back/shaders/Program.cpp index 71a3e7702c01f97fc45d53c34d1e9307dc0eb494..a06d4f343b31fc36a84ab4aa5cf79d7422f959bd 100644 --- a/source/engine/graphics/back/shaders/Program.cpp +++ b/source/engine/graphics/back/shaders/Program.cpp @@ -181,4 +181,15 @@ namespace megu { void Program::setUniform(const std::string & name, const std::set<std::reference_wrapper<const glm::mat4>> & value) const { glUniformMatrix4fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), GL_FALSE, glm::value_ptr(value.begin()->get())); } + + void Program::setUniform(const std::string & name, const void * data, size_t size, GLenum type) const { + switch (type) { + case GL_FLOAT: + glUniform4fv(this->_locations.at(name), static_cast<GLsizei>(size), static_cast<const float*>(data)); + break; + + default: + break; + } + } } \ No newline at end of file diff --git a/source/engine/graphics/back/shaders/Program.hpp b/source/engine/graphics/back/shaders/Program.hpp index cd005ddbf509596684218e527ac79e9ecd4c9542..42e0011c55edb5bff2fd5af63b7d938fdcb5cdcd 100644 --- a/source/engine/graphics/back/shaders/Program.hpp +++ b/source/engine/graphics/back/shaders/Program.hpp @@ -71,5 +71,7 @@ namespace megu { void setUniform(const std::string &, const std::vector<std::reference_wrapper<const glm::mat4>> &) const; void setUniform(const std::string &, const std::set<std::reference_wrapper<const glm::mat4>> &) const; + + void setUniform(const std::string &, const void *, size_t, GLenum = GL_FLOAT) const; }; } \ No newline at end of file diff --git a/source/engine/graphics/front/engine/Engine.cpp b/source/engine/graphics/front/engine/Engine.cpp index 46822d920f44bb954dc7f1898649a7a5721c03b8..75516564d9101baae959c1437d2e1fc32162a120 100644 --- a/source/engine/graphics/front/engine/Engine.cpp +++ b/source/engine/graphics/front/engine/Engine.cpp @@ -57,7 +57,6 @@ namespace megu { if(this->_window.isOpen()) { // Draw Layers TextureArray textures; - for(auto & [priority, layer] : this->_layers) { if(!layer.get()->empty()) { const glm::vec2 & dimension = layer->renderer().dimension(); @@ -73,4 +72,12 @@ namespace megu { this->_window.swapBuffers(); } } + + void GraphicEngine::setClearColor(float x, float y, float z) { + this->_renderer.setClearColor(x, y, z); + this->_group.setClearColor(x, y, z); + for(auto & [priority, layer] : this->_layers) { + layer.get()->renderer().setClearColor(x, y, z); + } + } } \ No newline at end of file diff --git a/source/engine/graphics/front/engine/Engine.hpp b/source/engine/graphics/front/engine/Engine.hpp index b9a88bc84659a6a157a72b53ee07dc4d1cdc1828..aa721f03c90e134ca2fc746c1cae78f5a3f2b24c 100644 --- a/source/engine/graphics/front/engine/Engine.hpp +++ b/source/engine/graphics/front/engine/Engine.hpp @@ -30,6 +30,7 @@ namespace megu { inline const std::map<Priority, std::unique_ptr<Layer>> & layers() const {return this->_layers;} void step(); + void setClearColor(float, float, float); private: std::map<Priority, std::unique_ptr<Layer>> _layers; diff --git a/source/engine/graphics/front/geometry/Plane.hpp b/source/engine/graphics/front/geometry/Plane.hpp index 373e367a08d435e7a4ed1bcc0c338399370e78e0..023e399ac74399261c98b10480ec87b37a533a9e 100644 --- a/source/engine/graphics/front/geometry/Plane.hpp +++ b/source/engine/graphics/front/geometry/Plane.hpp @@ -6,6 +6,7 @@ namespace megu { class Plane : public Static_Geometry<Plane, QUADS, layout::FLAT, layout::TEXTURE> { public: inline static const Vertices_t & Vertices() {return Plane::_Vertices;} + inline static const size_t & Count() {return 4;} private: static Vertices_t _Vertices; diff --git a/source/engine/graphics/front/geometry/Quads.cpp b/source/engine/graphics/front/geometry/Quads.cpp index fccb8871cb6f30fb070e1fc8b834732c6ccb5547..e4550c4c86e982eb358eb10fc8460aff7bc9b637 100644 --- a/source/engine/graphics/front/geometry/Quads.cpp +++ b/source/engine/graphics/front/geometry/Quads.cpp @@ -5,6 +5,6 @@ namespace megu { 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 1.f, 1.f, 1.f, - 0.f, 1.f, 0.f, 1.f - }; + 0.f, 1.f, 0.f, 1.f + }; } \ No newline at end of file diff --git a/source/engine/graphics/front/geometry/Quads.hpp b/source/engine/graphics/front/geometry/Quads.hpp index 2e70bc67aef40de435784c07c6bc3d1ef07852e1..f36888aed3e063b3a746e7ebe4b45361ad510787 100644 --- a/source/engine/graphics/front/geometry/Quads.hpp +++ b/source/engine/graphics/front/geometry/Quads.hpp @@ -6,6 +6,7 @@ namespace megu { class Quads : public Static_Geometry<Quads, QUADS, layout::FLAT, layout::TEXTURE> { public: inline static const Vertices_t & Vertices() {return Quads::_Vertices;} + inline static const size_t & Count() {return 4;} private: static Vertices_t _Vertices; diff --git a/source/engine/graphics/front/geometry/Vertex.hpp b/source/engine/graphics/front/geometry/Vertex.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4c3eed9b6badb0cc0441f3094d7700fd439fd20d --- /dev/null +++ b/source/engine/graphics/front/geometry/Vertex.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include <glm/glm.hpp> + +namespace megu { + struct Vertex { + glm::vec2 _position; + glm::vec2 _texture; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/group/FrameBufferGroup.cpp b/source/engine/graphics/front/group/FrameBufferGroup.cpp index 6653a7c71709eac75061683075d736721f24e445..c9052ed04238ca2171840a9ef99cbe1e50529f35 100644 --- a/source/engine/graphics/front/group/FrameBufferGroup.cpp +++ b/source/engine/graphics/front/group/FrameBufferGroup.cpp @@ -6,7 +6,7 @@ namespace megu { FrameBufferGroup::FrameBufferGroup() - : _vbo(this->_vao, Plane::Layout(), Plane::Vertices().size(), megu::EditMode::STATIC) { + : _vbo(this->_vao, Plane::Layout(), Plane::Vertices(), megu::EditMode::STATIC), _clear(0.f) { megu::Source vert("assets/shaders/FrameBuffer-Instanced.vert", Source::Categorie::VERTEX); this->_program.attach(vert); @@ -15,8 +15,6 @@ namespace megu { this->_program.link(); - this->_vbo << Plane::Vertices(); - vert.release(); frag.release(); } @@ -33,6 +31,7 @@ namespace megu { this->_program.setUniform("uSampler", uSampler); this->_program.setUniform("uTexturesCount", static_cast<GLuint>(textures.size())); + this->_program.setUniform("uClearColor", this->_clear); glDrawArrays(Plane::Primitive(), 0, static_cast<GLsizei>(Plane::Vertices().size())); } } \ No newline at end of file diff --git a/source/engine/graphics/front/group/FrameBufferGroup.hpp b/source/engine/graphics/front/group/FrameBufferGroup.hpp index c4ee336cfe3aedc5ba0d0cc4a052e8c190169c7c..40858d40a627c4e6ea776a4dc4828002156cb064 100644 --- a/source/engine/graphics/front/group/FrameBufferGroup.hpp +++ b/source/engine/graphics/front/group/FrameBufferGroup.hpp @@ -13,10 +13,12 @@ namespace megu { ~FrameBufferGroup() = default; virtual void draw(const Window &, const Camera &, const TextureArray &) const; + inline void setClearColor(float x, float y, float z) {this->_clear = {x, y, z};} private: VertexArray _vao; VerticeBuffer _vbo; Program _program; + glm::vec3 _clear; }; } \ 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 8730cb99266fcba713627330571c6c30faf2165f..32db99152336298094a7d1329bb0ec24d53416c4 100644 --- a/source/engine/graphics/front/group/ImageGroup.cpp +++ b/source/engine/graphics/front/group/ImageGroup.cpp @@ -37,12 +37,16 @@ namespace megu { this->_vao.bind(); this->_program.use(); + this->_program.setUniform("uProj", camera.projection()); + this->_program.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; + static auto uSampler = array_generator<GLint, 32>().array; + this->_program.setUniform("uSampler", uSampler); for(auto & image : this->_images) { @@ -53,9 +57,6 @@ namespace megu { } else { if(textures.size() >= 8 || uModels.size() >= 124) { - this->_program.setUniform("uProj", camera.projection()); - this->_program.setUniform("uView", camera.view()); - this->_program.setUniform("uSampler", uSampler); this->_program.setUniform("uModel", uModels); this->_program.setUniform("uTextures", uTextures); @@ -74,11 +75,6 @@ namespace megu { } if(!textures.empty()) { - this->_program.setUniform("uProj", camera.projection()); - this->_program.setUniform("uView", camera.view()); - - - this->_program.setUniform("uSampler", uSampler); this->_program.setUniform("uModel", uModels); this->_program.setUniform("uTextures", uTextures); diff --git a/source/engine/graphics/front/group/VertexArrayGroup.cpp b/source/engine/graphics/front/group/VertexArrayGroup.cpp new file mode 100644 index 0000000000000000000000000000000000000000..26c5bda5795e047fa1853a77ee088eb2b1f4eb7f --- /dev/null +++ b/source/engine/graphics/front/group/VertexArrayGroup.cpp @@ -0,0 +1,42 @@ +#include "VertexArrayGroup.hpp" + +#include <engine/graphics/utility/array_generator.hpp> + +namespace megu { + VertexArrayGroup::VertexArrayGroup() + : _vbo(this->_vao, Quads::Layout(), Quads::Vertices(), megu::EditMode::STATIC) { + Source vert("assets/shaders/Grid-Instanced.vert", Source::Categorie::VERTEX); + this->_program.attach(vert); + + Source frag("assets/shaders/Grid-Instanced.frag", Source::Categorie::FRAGMENT); + this->_program.attach(frag); + + this->_program.link(); + + vert.release(); + frag.release(); + } + + void VertexArrayGroup::add(const Texture & texture, const VerticesArray & grid) { + this->_objects[texture].push_back(grid); + } + + void VertexArrayGroup::draw(const Window &, const Camera & camera, const TextureArray &) const { + this->_vao.bind(); + this->_program.use(); + + this->_program.setUniform("uProj", camera.projection()); + this->_program.setUniform("uView", camera.view()); + + for(const auto & [texture, grids] : this->_objects) { + texture.get().bind(0); + for(const auto & grid : grids) { + this->_program.setUniform("uModel", grid.get().transformation().model()); + this->_program.setUniform("uSampler", 0); + this->_program.setUniform("uData", static_cast<const void *>(grid.get().vertices().data()), grid.get().size()); + + glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(grid.get().size())); + } + } + } +} \ No newline at end of file diff --git a/source/engine/graphics/front/group/VertexArrayGroup.hpp b/source/engine/graphics/front/group/VertexArrayGroup.hpp new file mode 100644 index 0000000000000000000000000000000000000000..65efa658edb1b1780f3e7f4c025296d8a4700367 --- /dev/null +++ b/source/engine/graphics/front/group/VertexArrayGroup.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "DrawGroup.hpp" + +#include <map> +#include <optional> + +#include <engine/graphics/back/textures/Texture.hpp> +#include <engine/graphics/back/buffers/VertexArray.hpp> +#include <engine/graphics/back/buffers/VerticeBuffer.hpp> +#include <engine/graphics/back/shaders/Program.hpp> + +#include <engine/graphics/front/object/VerticesArray.hpp> + +#include <engine/graphics/utility/texture_comparator.hpp> + +namespace megu { + class VertexArrayGroup : public DrawGroup { + public: + VertexArrayGroup(); + ~VertexArrayGroup() = default; + + void add(const Texture &, const VerticesArray &); + void draw(const Window &, const Camera &, const TextureArray &) const override; + + private: + std::map<std::reference_wrapper<const Texture>, std::vector<std::reference_wrapper<const VerticesArray>>, texture_comparator> _objects; + + VertexArray _vao; + VerticeBuffer _vbo; + Program _program; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/object/VerticesArray.cpp b/source/engine/graphics/front/object/VerticesArray.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a576ed543f618453bc8939910edfd16e5f4e44b --- /dev/null +++ b/source/engine/graphics/front/object/VerticesArray.cpp @@ -0,0 +1,20 @@ +#include "VerticesArray.hpp" + +namespace megu { + VerticesArray::VerticesArray(Primitive_t primitive, size_t size) + : _primitive(primitive), _vertices(size) {} + + VerticesArray::VerticesArray(const VerticesArray & src) + : _transformation(src._transformation), _primitive(src._primitive), _vertices(src._vertices) {} + + VerticesArray VerticesArray::operator=(const VerticesArray & src) { + this->_transformation = src._transformation; + this->_primitive = src._primitive; + this->_vertices = src._vertices; + return *this; + } + + void VerticesArray::append(const Vertex & vertex) { + this->_vertices.push_back(vertex); + } +} \ No newline at end of file diff --git a/source/engine/graphics/front/object/VerticesArray.hpp b/source/engine/graphics/front/object/VerticesArray.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bbceaa9c19e51842c5acbb625d45ab971c48f6a3 --- /dev/null +++ b/source/engine/graphics/front/object/VerticesArray.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include <array> + +#include <engine/graphics/back/geometry/Transformable.hpp> +#include <engine/graphics/back/textures/Texture.hpp> + +#include <engine/graphics/front/geometry/Quads.hpp> +#include <engine/graphics/front/geometry/Vertex.hpp> + +namespace megu { + class VerticesArray { + public: + VerticesArray(Primitive_t, size_t); + VerticesArray(const VerticesArray &); + VerticesArray operator=(const VerticesArray &); + ~VerticesArray() = default; + + inline size_t size() const {return this->_vertices.size();} + + void scale(float x, float y) {this->_transformation.scale(x, y);} + + void append(const Vertex &); + + const Transformable & transformation() const {return this->_transformation;} + const Primitive_t & primitive() const {return this->_primitive;} + const std::vector<Vertex> & vertices() const {return this->_vertices;} + + Vertex & operator[](size_t index) {return this->_vertices[index];} + const Vertex & operator[](size_t index) const {return this->_vertices[index];} + + private: + Transformable _transformation; + Primitive_t _primitive; + std::vector<Vertex> _vertices; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/utility/texture_comparator.hpp b/source/engine/graphics/utility/texture_comparator.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cdb9f9a2d93b65ee061beab4591f9b6dda1f32e3 --- /dev/null +++ b/source/engine/graphics/utility/texture_comparator.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include <engine/graphics/back/textures/Texture.hpp> + +namespace megu { + struct texture_comparator { + bool operator()(const Texture & t1, const Texture & t2) const { + return t1.identifier() > t2.identifier(); + } + }; +} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index c4abc5e6ec3f81f70f782650f1d9db4e5a4acf95..67c44ffcf6fbff4c2726e3bad23ccfcc3162933a 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -16,6 +16,7 @@ #include <engine/graphics/front/group/ImageGroup.hpp> #include <engine/graphics/front/engine/Renderer.hpp> #include <engine/graphics/front/engine/Engine.hpp> +#include <engine/graphics/front/group/VertexArrayGroup.hpp> #include <engine/graphics/errors.hpp> const float i_x = 1.f; @@ -30,6 +31,12 @@ glm::vec2 to_screen_coordinate(const glm::vec2 & tile, float w, float h, float l }; } +megu::Vertex to_screen_coordinate(int x, int y, unsigned int u, unsigned int v, const megu::Texture & texture) { + return {{x, y}, {static_cast<float>(u) / static_cast<float>(texture.width()), static_cast<float>(v) / static_cast<float>(texture.height())}}; +} + +//* Isometric : +/* int main(int argc, const char * argv[]) { try { //? Window @@ -201,4 +208,89 @@ int main(int argc, const char * argv[]) { } return EXIT_SUCCESS; -} \ No newline at end of file +} +*/ + +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); + + + + 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; +} +