diff --git a/assets/fonts/Jupiteroid.ttf b/assets/fonts/Jupiteroid.ttf new file mode 100644 index 0000000..2892699 Binary files /dev/null and b/assets/fonts/Jupiteroid.ttf differ diff --git a/include/JGL/JGL.h b/include/JGL/JGL.h index 693a0de..aea0437 100644 --- a/include/JGL/JGL.h +++ b/include/JGL/JGL.h @@ -3,16 +3,15 @@ // #pragma once -#include -#include -#include #include #include #include +#include +#include +#include #include #include #include - // OpenGL Wrapper for rendering 2D graphics primitives in both a 2D and 3D context namespace JGL { @@ -50,7 +49,8 @@ namespace JGL { }; bool InitTextEngine(); - + int LoadFont(const std::string& font_path); + void UnloadFont(int font_index); // TODO: implement correct coloring namespace J2D { @@ -68,7 +68,7 @@ namespace JGL { void FillTexturedPolygon2D(); void DrawSprite2D(); void DrawPartialSprite2D(); - void DrawString2D(const Color3& color, std::string text, float x, float y, float scale, u32 size = 16); + void DrawString2D(const Color3& color, std::string text, float x, float y, float scale, u32 size, unsigned int font_index); void FillRect2D(const Color3 &color, const Vector2 &pos, const Vector2 &size); void OutlineRect2D ( const Color3& color, const Vector2& pos, const Vector2& size, float thickness = 1); void FillRoundedRect2D (const Color3& color, const Vector2& pos, const Vector2& size, float radius); @@ -87,7 +87,7 @@ namespace JGL { void WireframeCapsule3D(const Color3& color, const Capsule& cap, float thickness = 1); void FillTriangleMesh3D(const Color3& color, const TriangleMesh& mesh); void WireframeTriangleMesh3D(const Color3& color, const TriangleMesh& mesh, float thickness = 1); - void DrawString3D(const Color3& color, const std::string& text, const Vector3& pos, float scale, u32 size = 12); + void DrawString3D(const Color3& color, const std::string& text, const Vector3& pos, float scale, u32 size, unsigned int font_index); void DrawMatrixGizmo (const Matrix3x3&, const Vector3&); void DrawMatrixGizmo (const Matrix4x4&); diff --git a/main.cpp b/main.cpp index eb5d9dc..12c335c 100644 --- a/main.cpp +++ b/main.cpp @@ -26,6 +26,9 @@ struct point { GLfloat t; }; +int FreeSans; +int Jupiteroid; + class JGLDemoWindow : public ReWindow::RWindow { public: @@ -53,12 +56,13 @@ public: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); - JGL::InitTextEngine(); + JGL::InitTextEngine(); + FreeSans = JGL::LoadFont("assets/fonts/FreeSans.ttf"); + Jupiteroid = JGL::LoadFont("assets/fonts/Jupiteroid.ttf"); } - void display() - { + void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); @@ -76,15 +80,13 @@ public: {105, 100} }; JGL::J2D::FillTriangle2D(JGL::Colors::Yellow, tri); - - - JGL::J3D::DrawString3D(JGL::Colors::Red, "JGL Sample Text", {1, -120, 0.5f}, 2.f); - JGL::J2D::DrawString2D(JGL::Colors::Green, "William J. Tomasine II ", 0.f, -120.f, 1.f); - JGL::J2D::DrawLine2D(JGL::Colors::Greens::DarkGreen, {10, 10}, {200, 300}); JGL::J3D::DrawLine3D(JGL::Colors::Red, {0,0,0}, {1,0,0}); JGL::J3D::DrawLine3D(JGL::Colors::Red, {0,0,0}, {1,0,0}); + JGL::J3D::DrawString3D(JGL::Colors::Red, "JGL Sample Text", {1, -32, 0.5f}, 1.f, 32, FreeSans); + JGL::J2D::DrawString2D(JGL::Colors::Green, "Jupiteroid Font", 0.f, -48.f, 1.f, 16, Jupiteroid); + //glFlush(); } diff --git a/src/JGL.cpp b/src/JGL.cpp index 9fcfcfd..fa52c4a 100644 --- a/src/JGL.cpp +++ b/src/JGL.cpp @@ -6,41 +6,59 @@ #include #include #include - #if __linux__ #include #include FT_FREETYPE_H #endif - #if _WIN32 #include #include FT_FREETYPE_H #endif GLuint program; - namespace JGL { - FT_Face face; FT_Library ft; + struct Font { + int index = 0; + FT_Face face; + }; + + std::vector faces; + using namespace J3ML; - bool InitTextEngine() { - constexpr u32 default_font_size = 16; if (FT_Init_FreeType(&ft)) - { - std::cout << "Error::FREETYPE: " << std::endl; - return false; - } + return true; + return false; + } - if (FT_New_Face(ft, "assets/fonts/FreeSans.ttf", 0, &face)) - { + int LoadFont(const std::string &font_path) { + if (ft == nullptr) + return -1; + Font font; + if (FT_New_Face(ft, font_path.c_str(), 0, &font.face)) { std::cout << "Error::FREETYPE: Failed to load font!" << std::endl; - return false; + return -1; } - return true; + unsigned int newIndex = 0; + for (const auto& f : faces) + if (f.index >= newIndex) + newIndex = f.index + 1; + font.index = newIndex; + faces.push_back(font); + + std::cout << "Loaded font from " << font_path << " with index " << newIndex << std::endl; + return newIndex; + } + + void UnloadFont(int font_index) { + for (int i = 0; i < faces.size(); i++) + if (faces[i].index == font_index) + FT_Done_Face(faces[i].face), + faces.erase(faces.begin() + i); } namespace J2D @@ -152,23 +170,32 @@ namespace JGL glEnd(); } - void DrawString2D(const Color3& color, std::string text, float x, float y, float scale, u32 size) { + void DrawString2D(const Color3& color, std::string text, float x, float y, float scale, u32 size, unsigned int font_index) { glUseProgram(0); // Fixed-function pipeline. + Font font{}; + for (const auto& f : faces) + if (f.index == font_index) + font = f; + if (font.face == NULL) { + std::cout << "null font" << std::endl; + return; + } + GLfloat currentColor[4]; glGetFloatv(GL_CURRENT_COLOR, currentColor); glColor3f(color.r/255.f, color.g/255.f, color.b/255.f); - FT_Set_Pixel_Sizes(face, 0, size); + FT_Set_Pixel_Sizes(font.face, 0, size); std::vector textures(text.length()); for (int i = 0; i < text.length(); i++) { - if (FT_Load_Char(face, text.c_str()[i], FT_LOAD_RENDER)) + if (FT_Load_Char(font.face, text.c_str()[i], FT_LOAD_RENDER)) continue; - FT_GlyphSlot g = face->glyph; + FT_GlyphSlot g = font.face->glyph; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glActiveTexture(GL_TEXTURE0); @@ -236,7 +263,7 @@ namespace JGL glEnd(); } - void DrawString3D(const Color3& color, const std::string& text, const Vector3& pos, float scale, u32 size) + void DrawString3D(const Color3& color, const std::string& text, const Vector3& pos, float scale, u32 size, unsigned int font_index) { float x = pos.x; float y = pos.y; @@ -247,15 +274,25 @@ namespace JGL glUseProgram(0); // Fixed-function pipeline. glColor4f(color.r, color.g, color.b, 1.0f); - FT_Set_Pixel_Sizes(face, 0, size); + Font font; + for (auto& f : faces) + if (f.index == font_index) + font = f; + if (font.face == NULL) { + std::cout << "null font" << std::endl; + return; + } + + + FT_Set_Pixel_Sizes(font.face, 0, size); //for (c = text.c_str(); *c; c++) for (int i = 0; i < text.length(); i++) { - if (FT_Load_Char(face, text.c_str()[i], FT_LOAD_RENDER)) + if (FT_Load_Char(font.face, text.c_str()[i], FT_LOAD_RENDER)) continue; - FT_GlyphSlot g = face->glyph; + FT_GlyphSlot g = font.face->glyph; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glActiveTexture(GL_TEXTURE0);