diff --git a/CMakelists.txt b/CMakelists.txt index 2de7e4f48d328208dc9c2562ce80b1536c03bc65..e7bfb4c887764963f55edb078f61e8ff9350583c 100644 --- a/CMakelists.txt +++ b/CMakelists.txt @@ -59,17 +59,21 @@ set_property(TARGET ${CURRENT_TARGET} PROPERTY RUNTIME_OUTPUT_DIRECTORY $<1:${CM target_include_directories(${CURRENT_TARGET} PRIVATE ${INCLUDE}) -list(APPEND CMAKE_PREFIX_PATH "/amuhome/b20017738/Bureau/vcpkg/packages/glew_x64-linux") -list(APPEND CMAKE_PREFIX_PATH "/amuhome/b20017738/Bureau/vcpkg/packages/glm_x64-linux") -list(APPEND CMAKE_PREFIX_PATH "/amuhome/b20017738/Bureau/vcpkg/packages/imgui_x64-linux") +#list(APPEND CMAKE_PREFIX_PATH "/amuhome/b20017738/Bureau/vcpkg/packages/glew_x64-linux") +#list(APPEND CMAKE_PREFIX_PATH "/amuhome/b20017738/Bureau/vcpkg/packages/glm_x64-linux") +#list(APPEND CMAKE_PREFIX_PATH "/amuhome/b20017738/Bureau/vcpkg/packages/imgui_x64-linux") -find_package(glfw3 REQUIRED) -find_package(GLEW REQUIRED) -find_package(glm CONFIG REQUIRED) -find_package(imgui REQUIRED) +list(APPEND CMAKE_PREFIX_PATH "C:/vcpkg/packages/freetype_x64-windows") + +find_package(glfw3 REQUIRED) +find_package(GLEW REQUIRED) +find_package(glm CONFIG REQUIRED) +find_package(imgui REQUIRED) +find_package(Freetype REQUIRED) target_link_libraries(${CURRENT_TARGET} PRIVATE glfw) target_link_libraries(${CURRENT_TARGET} PRIVATE GLEW::GLEW) target_link_libraries(${CURRENT_TARGET} PRIVATE glm::glm-header-only) target_link_libraries(${CURRENT_TARGET} PRIVATE imgui::imgui) +target_link_libraries(${CURRENT_TARGET} PRIVATE Freetype::Freetype) diff --git a/arial.ttf b/arial.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ff0815cd8c64b0a245ec780eb8d21867509155b5 Binary files /dev/null and b/arial.ttf differ diff --git a/assets/shaders/Text.frag b/assets/shaders/Text.frag new file mode 100644 index 0000000000000000000000000000000000000000..2c90f2d235b2ebd41fe634b87e2bb4405e0e0424 --- /dev/null +++ b/assets/shaders/Text.frag @@ -0,0 +1,17 @@ +#version 330 core +out vec4 FragColor; + +in vec2 Texture; + +uniform sampler2D uSampler; +uniform vec4 uGlyphFrame; +uniform vec2 uSize; + +void main() { + vec2 coord = vec2( + (uGlyphFrame.x / uSize.x) + (uGlyphFrame.z / uSize.x) * Texture.x, + (uGlyphFrame.y / uSize.y) + (uGlyphFrame.w / uSize.y) * Texture.y + ); + + FragColor = texture(uSampler, coord); +} \ No newline at end of file diff --git a/assets/shaders/Text.vert b/assets/shaders/Text.vert new file mode 100644 index 0000000000000000000000000000000000000000..d1fd061936383f140ce073ae5c8fed33a14d6e5d --- /dev/null +++ b/assets/shaders/Text.vert @@ -0,0 +1,10 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTex; + +out vec2 Texture; + +void main() { + Texture = aTex; + gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); +} \ No newline at end of file diff --git a/assets/textures/letters.png b/assets/textures/letters.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae52871e931f300419edcd0971ee378ddd0c9f0 Binary files /dev/null and b/assets/textures/letters.png differ diff --git a/source/engine/graphics/front/module/QuadInstanced.cpp b/old2/Quad_Module.cpp similarity index 86% rename from source/engine/graphics/front/module/QuadInstanced.cpp rename to old2/Quad_Module.cpp index 8b8c9f48e2b0812165aed280ba5eee0ee27d167f..d39aea104e12e1c71fd52be4082ae6f40924137e 100644 --- a/source/engine/graphics/front/module/QuadInstanced.cpp +++ b/old2/Quad_Module.cpp @@ -2,6 +2,7 @@ #include <engine/graphics/front/object/Image.hpp> #include <engine/graphics/front/object/Sprite.hpp> +#include <engine/graphics/front/object/Text.hpp> #include <engine/graphics/utility/array_generator.hpp> @@ -36,6 +37,19 @@ namespace megu { frag.release(); } + { + Source vert("assets/shaders/Text.vert", Source::Categorie::VERTEX); + this->_textProgram.attach(vert); + + Source frag("assets/shaders/Text.frag", Source::Categorie::FRAGMENT); + this->_textProgram.attach(frag); + + this->_textProgram.link(); + + vert.release(); + frag.release(); + } + this->_vbo << Quads::Vertices(); } @@ -148,4 +162,19 @@ namespace megu { glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size())); } } + + void QuadInstancedModule::draw(Text & text, const Window &, const Camera & camera, const TextureArray &) const { + this->_vao.bind(); + this->_textProgram.use(); + + text.texture().bind(); + this->_textProgram.setUniform("uSampler", 0); + + glm::vec4 glyphFrame = text['w']; + + this->_textProgram.setUniform("uSize", glm::vec2{text.texture().width(), text.texture().height()}); + this->_textProgram.setUniform("uGlyphFrame", glyphFrame); + + glDrawArrays(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size())); + } } \ No newline at end of file diff --git a/source/engine/graphics/back/textures/Texture.cpp b/source/engine/graphics/back/textures/Texture.cpp index 319764835c56cd87b5c7e03a901598531a3bc2ab..658169ba697730bcd1716eeb762c3ffe5d84f9b3 100644 --- a/source/engine/graphics/back/textures/Texture.cpp +++ b/source/engine/graphics/back/textures/Texture.cpp @@ -85,7 +85,7 @@ namespace megu { glTexParameteri(this->_type, GL_TEXTURE_MAG_FILTER, state ? GL_LINEAR : GL_NEAREST); } - void Texture::store(GLsizei width, GLsizei height, const GLubyte * data, GLuint format) { + void Texture::store(GLsizei width, GLsizei height, const GLubyte * data, uint32_t format) { if(this->valid()) { glDeleteTextures(1, &this->_id); glGenTextures(1, &this->_id); @@ -148,4 +148,8 @@ namespace megu { glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &units); return units; } + + void Texture::SetDisabelingByteAligment(bool state) { + glPixelStorei(GL_UNPACK_ALIGNMENT, state); + } } \ No newline at end of file diff --git a/source/engine/graphics/back/textures/Texture.hpp b/source/engine/graphics/back/textures/Texture.hpp index 7fe4124a59ce452f1117d7ce0d027109043cb1be..221d6286d9b1367a3f3630ffbde63f59d0cd49f7 100644 --- a/source/engine/graphics/back/textures/Texture.hpp +++ b/source/engine/graphics/back/textures/Texture.hpp @@ -47,10 +47,10 @@ namespace megu { inline GLuint identifier() const {return this->_id;} void changeSlot(GLuint); - void setWraping(Wraping, uint32_t = S | T); + void setWraping(Wraping, uint32_t axis = S | T); void setSmoothing(bool); - void store(GLsizei, GLsizei, const GLubyte *, GLuint = RGBA); + void store(GLsizei, GLsizei, const GLubyte *, uint32_t = RGBA); void store(const TextureBuffer &); bool valid() const; @@ -65,6 +65,8 @@ namespace megu { static void Unbind(GLuint = GL_TEXTURE_2D); static GLint CountSlots(); + static void SetDisabelingByteAligment(bool); + private: GLuint _id; diff --git a/source/engine/graphics/front/engine/FrameBufferMerger.cpp b/source/engine/graphics/front/engine/FrameBufferMerger.cpp index 89775875783875d30c6f0b4038f483a1ce19f732..03b86d1e24b088d48e4c51ea993404aee40c2a16 100644 --- a/source/engine/graphics/front/engine/FrameBufferMerger.cpp +++ b/source/engine/graphics/front/engine/FrameBufferMerger.cpp @@ -29,7 +29,7 @@ namespace megu { textures[i].get().bind(static_cast<GLuint>(i)); } - static auto uSampler = array_generator<GLint, 32>().array; + static auto uSampler = array_generator::Generate<GLint, 0, 32>(); this->_program.setUniform("uSampler", uSampler); this->_program.setUniform("uTexturesCount", static_cast<GLuint>(textures.size())); diff --git a/source/engine/graphics/front/module/Image_Module.cpp b/source/engine/graphics/front/module/Image_Module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..888f516095a81cbe512593af5d80258606e075b5 --- /dev/null +++ b/source/engine/graphics/front/module/Image_Module.cpp @@ -0,0 +1,67 @@ +#include "Image_Module.hpp" + +#include <engine/graphics/back/cameras/Camera.hpp> +#include <engine/graphics/utility/array_generator.hpp> + +namespace megu { + Image_Module::Image_Module() + : _vbo(this->_vao, Image::Layout(), Image::Vertices(), EditMode::STATIC) { + megu::Source vert_source("assets/shaders/Image-Instanced-Fat.vert", Source::Categorie::VERTEX); + this->_program << vert_source; + + megu::Source frag_source("assets/shaders/Texture-Fat.frag", Source::Categorie::FRAGMENT); + this->_program << frag_source; + + this->_program.link(); + vert_source.release(); + frag_source.release(); + } + + void Image_Module::draw(const ref_set<Image> & images, const Camera & camera, const Window & window) const { + 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::Generate<GLint, 0, 32>(); + this->_program.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->_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()); + } + } + + if(!textures.empty()) { + 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())); + } + } +} \ No newline at end of file diff --git a/source/engine/graphics/front/module/Image_Module.hpp b/source/engine/graphics/front/module/Image_Module.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6cbea51e919e5be9f17e55a12b4f8ebb3b5e20e2 --- /dev/null +++ b/source/engine/graphics/front/module/Image_Module.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> + +#include <engine/graphics/front/object/Image.hpp> +#include <engine/graphics/utility/ref_set.hpp> + +namespace megu { + class Image_Module : public Module<ref_set<Image>> { + public: + Image_Module(); + + void draw(const ref_set<Image> &, const Camera &, const Window &) const override; + + private: + VertexArray _vao; + VerticeBuffer _vbo; + Program _program; + }; + + +} \ No newline at end of file diff --git a/source/engine/graphics/front/module/Module.hpp b/source/engine/graphics/front/module/Module.hpp index 950af50ba55d20f76f1097f79ecb48fd8fa688fb..3a890508c9ca8f1dbe305863b941581b09f308e0 100644 --- a/source/engine/graphics/front/module/Module.hpp +++ b/source/engine/graphics/front/module/Module.hpp @@ -1,19 +1,12 @@ #pragma once -#include <engine/graphics/back/cameras/Camera.hpp> -#include <engine/graphics/front/engine/TextureArray.hpp> -#include <engine/graphics/utility/reference_sorter.hpp> -#include <engine/io/Window.hpp> - -#include <engine/graphics/utility/ref_set.hpp> - namespace megu { + class Camera; + class Window; + template <class T> class Module { public: - virtual void draw(T &, const Window &, const Camera &, const TextureArray &) const = 0; + virtual void draw(const T &, const Camera &, const Window &) const = 0; }; - - template <class T> - using Instanced_Module = Module<ref_set<T>>; } \ No newline at end of file diff --git a/source/engine/graphics/front/module/QuadInstanced.hpp b/source/engine/graphics/front/module/QuadInstanced.hpp deleted file mode 100644 index 734d2029eb8dfd3a1ada9c86ca2fecabf8c0a8f9..0000000000000000000000000000000000000000 --- a/source/engine/graphics/front/module/QuadInstanced.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#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/module/Quad_Module.hpp b/source/engine/graphics/front/module/Quad_Module.hpp new file mode 100644 index 0000000000000000000000000000000000000000..cb8f305deb2fcfbe3130971b4c8d753572396170 --- /dev/null +++ b/source/engine/graphics/front/module/Quad_Module.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "Image_Module.hpp" +#include "Sprite_Module.hpp" +#include "Text_Module.hpp" + +namespace megu { + class Quad_Module : public Image_Module, public Sprite_Module, public Text_Module { + // ... + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/module/Sprite_Module.cpp b/source/engine/graphics/front/module/Sprite_Module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2975d5ceeed5ee05b801722fa3c50c6a8208fb83 --- /dev/null +++ b/source/engine/graphics/front/module/Sprite_Module.cpp @@ -0,0 +1,80 @@ +#include "Sprite_Module.hpp" + +#include <engine/graphics/back/cameras/Camera.hpp> +#include <engine/graphics/utility/array_generator.hpp> + +namespace megu { + Sprite_Module::Sprite_Module() + : _vbo(this->_vao, Sprite::Layout(), Sprite::Vertices(), EditMode::STATIC) { + Source vert_source("assets/shaders/Sprite.vert", Source::Categorie::VERTEX); + this->_program << vert_source; + + Source frag_source("assets/shaders/Sprite.frag", Source::Categorie::FRAGMENT); + this->_program << frag_source; + + this->_program.link(); + vert_source.release(); + frag_source.release(); + } + + void Sprite_Module::draw(const ref_set<Sprite> & sprites, const Camera & camera, const Window &) const { + 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<glm::vec4> uFrames; + std::vector<glm::vec2> uSizes; + std::vector<GLint> uTextures; + + static auto uSampler = array_generator::Generate<GLint, 0, 32>(); + this->_program.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->_program.setUniform("uModel", uModels); + this->_program.setUniform("uTextures", uTextures); + this->_program.setUniform("uFrames", uFrames); + this->_program.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->_program.setUniform("uModel", uModels); + this->_program.setUniform("uTextures", uTextures); + this->_program.setUniform("uFrames", uFrames); + this->_program.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/Sprite_Module.hpp b/source/engine/graphics/front/module/Sprite_Module.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ebc7f92ea3e3f62994b85e1be0b126e2b5699321 --- /dev/null +++ b/source/engine/graphics/front/module/Sprite_Module.hpp @@ -0,0 +1,24 @@ +#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> + +#include <engine/graphics/front/object/Sprite.hpp> +#include <engine/graphics/utility/ref_set.hpp> + +namespace megu { + class Sprite_Module : public Module<ref_set<Sprite>> { + public: + Sprite_Module(); + + void draw(const ref_set<Sprite> &, const Camera &, const Window &) const override; + + private: + VertexArray _vao; + VerticeBuffer _vbo; + Program _program; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/module/Text_Module.cpp b/source/engine/graphics/front/module/Text_Module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..15b73c309f3219bd9a820fd2a82b58217c0fd112 --- /dev/null +++ b/source/engine/graphics/front/module/Text_Module.cpp @@ -0,0 +1,34 @@ +#include "Text_Module.hpp" + +#include <engine/graphics/back/cameras/Camera.hpp> +#include <engine/graphics/utility/array_generator.hpp> + +namespace megu { + Text_Module::Text_Module() + : _vbo(this->_vao, Text::Layout(), Text::Vertices(), EditMode::STATIC) { + Source vert_source("assets/shaders/Text.vert", Source::Categorie::VERTEX); + this->_program << vert_source; + + Source frag_source("assets/shaders/Text.frag", Source::Categorie::FRAGMENT); + this->_program << frag_source; + + this->_program.link(); + vert_source.release(); + frag_source.release(); + } + + void Text_Module::draw(const Text & text, const Camera & camera, const Window &) const { + this->_vao.bind(); + this->_program.use(); + + text.texture().bind(); + this->_program.setUniform("uSampler", 0); + + glm::vec4 glyphFrame = text['w']; + + this->_program.setUniform("uSize", glm::vec2{text.texture().width(), text.texture().height()}); + this->_program.setUniform("uGlyphFrame", glyphFrame); + + glDrawArrays(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size())); + } +} \ No newline at end of file diff --git a/source/engine/graphics/front/module/Text_Module.hpp b/source/engine/graphics/front/module/Text_Module.hpp new file mode 100644 index 0000000000000000000000000000000000000000..78effb7ad89fb0b17d80c44da3c7b258649cdbd5 --- /dev/null +++ b/source/engine/graphics/front/module/Text_Module.hpp @@ -0,0 +1,24 @@ +#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> + +#include <engine/graphics/front/object/Text.hpp> +#include <engine/graphics/utility/ref_set.hpp> + +namespace megu { + class Text_Module : public Module<Text> { + public: + Text_Module(); + + virtual void draw(const Text &, const Camera &, const Window &) const override; + + private: + VertexArray _vao; + VerticeBuffer _vbo; + Program _program; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/object/Image.hpp b/source/engine/graphics/front/object/Image.hpp index f6bd8d5c1a147fd31d4f95a93261cd3c605a743e..e6abd9670c624d99d150ed5e9b0916f201757c22 100644 --- a/source/engine/graphics/front/object/Image.hpp +++ b/source/engine/graphics/front/object/Image.hpp @@ -9,7 +9,7 @@ #include <engine/graphics/utility/type.hpp> namespace megu { - class Image { + class Image : public Quads { public: Image() = default; Image(const std::filesystem::path &); @@ -26,7 +26,6 @@ namespace megu { inline float getLayer() const {return this->_transformation.z();} inline const Texture & texture() const {return this->_texture;} - inline const Quads & geometry() const {return this->_geometry;} inline const Transformable & transformation() const {return this->_transformation;} inline void setPosition(const Vec2 & pos) {this->_transformation.setPosition(pos.x, pos.y);} @@ -45,7 +44,6 @@ namespace megu { private: Texture _texture; - Quads _geometry; Transformable _transformation; }; } \ No newline at end of file diff --git a/source/engine/graphics/front/object/Renderable.hpp b/source/engine/graphics/front/object/Renderable.hpp index 2bb39606a7e927c8d89b45654eb7dea51411e555..9b7d0f3a545007cbad5a490b4606f33d2123677b 100644 --- a/source/engine/graphics/front/object/Renderable.hpp +++ b/source/engine/graphics/front/object/Renderable.hpp @@ -3,7 +3,10 @@ #include <memory> #include <iostream> +#include <engine/graphics/back/cameras/Camera.hpp> #include <engine/graphics/front/module/Module.hpp> +#include <engine/graphics/front/engine/TextureArray.hpp> +#include <engine/io/Window.hpp> namespace megu { class Renderable { @@ -30,7 +33,7 @@ namespace megu { struct RenderableConcept { virtual ~RenderableConcept() {}; - virtual void render(const Window &, const Camera &, const TextureArray &) const = 0; + virtual void render(const Window &, const Camera &) const = 0; virtual std::unique_ptr<RenderableConcept> clone() const = 0; }; @@ -39,8 +42,8 @@ namespace megu { 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); + void render(const Window & window, const Camera & camera) const override { + this->_module->draw(this->_object, camera, window); } std::unique_ptr<RenderableConcept> clone() const override { @@ -52,7 +55,7 @@ namespace megu { }; friend void render_ext(Renderable & renderable, const Window & window, const Camera & camera, const TextureArray & array) { - renderable._pimpl->render(window, camera, array); + renderable._pimpl->render(window, camera); } std::unique_ptr<RenderableConcept> _pimpl; diff --git a/source/engine/graphics/front/object/Sprite.hpp b/source/engine/graphics/front/object/Sprite.hpp index 0445b107adfea95fdf0d424bf923bce34ebd8cad..96b508ef605877e9fb13cb22df0065096eeb3cd2 100644 --- a/source/engine/graphics/front/object/Sprite.hpp +++ b/source/engine/graphics/front/object/Sprite.hpp @@ -7,7 +7,7 @@ #include <engine/graphics/utility/type.hpp> namespace megu { - class Sprite { + class Sprite : public Quads { public: using Frame = glm::vec4; @@ -27,7 +27,6 @@ namespace megu { 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); @@ -37,7 +36,6 @@ namespace megu { private: Frame _frame; Texture _texture; - Quads _geometry; Transformable _transformation; }; } \ No newline at end of file diff --git a/source/engine/graphics/front/object/Text.cpp b/source/engine/graphics/front/object/Text.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ff65d548093719b444a2fd8d2b8ae9ce5fe20996 --- /dev/null +++ b/source/engine/graphics/front/object/Text.cpp @@ -0,0 +1,31 @@ +#include "Text.hpp" + +#include <exception> +#include <ft2build.h> +#include FT_FREETYPE_H + +#include <iostream> + +namespace megu { + Text::Text(const std::string & text) + : _text(text) {} + + Text::Text(const Text & src) + : _text(src._text), _characters(src._characters), _transformation(src._transformation) {} + + Text & Text::operator=(const Text & src) { + this->_text = src._text; + this->_characters = src._characters; + this->_transformation = src._transformation; + return *this; + } + + void Text::loadFont(const std::filesystem::path & file, bool smoothing) { + if(!std::filesystem::exists(file) || std::filesystem::is_directory(file)) { + throw std::runtime_error("Cannot load font file" + file.string() + "."); + } + + TextureBuffer buffer(file); + this->_texture.store(buffer); + } +} diff --git a/source/engine/graphics/front/object/Text.hpp b/source/engine/graphics/front/object/Text.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1e3a070a7dae5ae314c2e6a2a0b60aa17fda6b19 --- /dev/null +++ b/source/engine/graphics/front/object/Text.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include <string> +#include <filesystem> +#include <map> + +#include <engine/graphics/back/geometry/Transformable.hpp> +#include <engine/graphics/back/textures/Texture.hpp> +#include <engine/graphics/front/geometry/Quads.hpp> +#include <engine/graphics/utility/type.hpp> + +namespace megu { + class Text : public Quads { + public: + using Frame = Vec4Int; + using CharacterMap = std::map<unsigned char, Frame>; + + Text(const std::string & = ""); + Text(const Text &); + Text & operator=(const Text &); + ~Text() = default; + + inline Vec2 getPosition() const {return Vec2(this->_transformation.x(), this->_transformation.y());} + inline Vec2 getOrigine() const {return Vec2(this->_transformation.origine().x, this->_transformation.origine().y);} + inline Vec2 getSize() const {return Vec2(this->_transformation.scaling().x, this->_transformation.scaling().y);} + inline float getRotation() const {return this->_transformation.roll();} + inline float getLayer() const {return this->_transformation.z();} + + inline const Texture & texture() const {return this->_texture;} + inline const Transformable & transformation() const {return this->_transformation;} + inline const std::string & text() const {return this->_text;} + inline const CharacterMap & characters() const {return this->_characters;} + + 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 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 void addGlyph(unsigned char c, Frame f) {this->_characters.insert(std::pair<unsigned char, Frame>(c, f));} + inline void removeGlyph(unsigned char c) {this->_characters.erase(c);} + inline void clearGlyph() {return this->_characters.clear();} + + void loadFont(const std::filesystem::path &, bool = true); + + inline const Frame & operator[](unsigned char c) const {return this->_characters.at(c);} + + private: + std::string _text; + Texture _texture; + CharacterMap _characters; + Transformable _transformation; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/utility/array_generator.hpp b/source/engine/graphics/utility/array_generator.hpp index 9b867f5edd57ab34f2bcbb5e287b995dfe30a7ca..b3d29fb0a5ce739fca247069cd18c8b71f6cf62f 100644 --- a/source/engine/graphics/utility/array_generator.hpp +++ b/source/engine/graphics/utility/array_generator.hpp @@ -3,14 +3,15 @@ #include <vector> namespace megu { - template <typename T, T C> struct array_generator { public: - constexpr array_generator() { - for(T i = 0; i < C; ++i) { - this->array.push_back(i); + template <typename T, T From, T To> + static constexpr std::vector<T> Generate() { + std::vector<T> array; + for(T i = From; i < To; ++i) { + array.push_back(i); } + return array; } - std::vector<T> array; }; } \ No newline at end of file diff --git a/source/engine/graphics/utility/ref_set.hpp b/source/engine/graphics/utility/ref_set.hpp index d87601b27507d89808b3b687adbfa5981cdb8840..b394253f12c2b2bc7841c59118c74fd6544bd0ac 100644 --- a/source/engine/graphics/utility/ref_set.hpp +++ b/source/engine/graphics/utility/ref_set.hpp @@ -1,5 +1,8 @@ #pragma once +#include <set> +#include "reference_sorter.hpp" + namespace megu { template <class T> using ref_set = std::set<std::reference_wrapper<T>, reference_sorter<T>>; diff --git a/source/engine/graphics/utility/type.hpp b/source/engine/graphics/utility/type.hpp index cacaae63afb3c6c026c5241618c89416619e49b0..c1b5340cdc62058750b05941a7db72cf79073a05 100644 --- a/source/engine/graphics/utility/type.hpp +++ b/source/engine/graphics/utility/type.hpp @@ -9,6 +9,10 @@ namespace megu { using Vec4 = glm::vec4; using Color = glm::vec4; + using Vec2Int = glm::ivec2; + using Vec3Int = glm::ivec3; + using Vec4Int = glm::ivec4; + using Mat3 = glm::mat3; using Mat4 = glm::mat4; } \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 0f28b37b5b212f1372da5030f8e85a7e67bf1d21..a0077912b2927fe2a5985ab3e40109d34ce7c142 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -15,7 +15,8 @@ #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/object/Text.hpp> +#include <engine/graphics/front/module/Quad_Module.hpp> #include <engine/graphics/front/engine/Renderer.hpp> #include <engine/graphics/front/engine/Engine.hpp> #include <engine/graphics/errors.hpp> @@ -61,6 +62,23 @@ int main(int argc, const char * argv[]) { sprite.setFrame(frames[0]); sprite.move({32, 0}); + megu::Text text("Hello World !"); + text.loadFont("assets/textures/letters.png"); + + char chars[36] = { + ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + float x = 0; + for(auto c : chars) { + text.addGlyph(c, {x, 0, 9, 11}); + x += 9; + } + + std::cout << "Using " << text.characters().size() << " characters !" << std::endl; + + text.scale({200, 200}); + megu::GraphicEngine engine(window); megu::Renderer basic_renderer(128, 128); @@ -70,11 +88,12 @@ int main(int argc, const char * argv[]) { megu::ref_set<megu::Sprite> sprites_set; sprites_set.insert(sprite); - megu::QuadInstancedModule modul; + megu::Quad_Module modul; engine.push(0, basic_renderer); engine.push(0, 1, images_set, &modul); engine.push(0, 0, sprites_set, &modul); + engine.push(0, 2, text, &modul); double previousTime = megu::Window::Time(); int frameCount = 0; diff --git a/vcpkg.json b/vcpkg.json index ade0a95183bb2ebcdbe220e91ab34ac57ebd38d7..2181942bea9815eff83e77f7dcd4910b4229b6e9 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,7 @@ { "dependencies": [ "opengl", + "freetype", "glew", "glfw3", "glm",