Support for multiple fonts

This commit is contained in:
2024-07-05 05:20:42 -04:00
parent c53fa52f6f
commit 608e9e29f5
4 changed files with 76 additions and 37 deletions

BIN
assets/fonts/Jupiteroid.ttf Normal file

Binary file not shown.

View File

@@ -3,16 +3,15 @@
// //
#pragma once #pragma once
#include <J3ML/LinearAlgebra.h>
#include <J3ML/LinearAlgebra/Vector2.h>
#include <J3ML/LinearAlgebra/Vector3.h>
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <JGL/Color3.h> #include <JGL/Color3.h>
#include <J3ML/LinearAlgebra.h>
#include <J3ML/LinearAlgebra/Vector2.h>
#include <J3ML/LinearAlgebra/Vector3.h>
#include <J3ML/Geometry/Sphere.h> #include <J3ML/Geometry/Sphere.h>
#include <J3ML/Geometry/Capsule.h> #include <J3ML/Geometry/Capsule.h>
#include <J3ML/Geometry/TriangleMesh.h> #include <J3ML/Geometry/TriangleMesh.h>
// OpenGL Wrapper for rendering 2D graphics primitives in both a 2D and 3D context // OpenGL Wrapper for rendering 2D graphics primitives in both a 2D and 3D context
namespace JGL { namespace JGL {
@@ -50,7 +49,8 @@ namespace JGL {
}; };
bool InitTextEngine(); bool InitTextEngine();
int LoadFont(const std::string& font_path);
void UnloadFont(int font_index);
// TODO: implement correct coloring // TODO: implement correct coloring
namespace J2D { namespace J2D {
@@ -68,7 +68,7 @@ namespace JGL {
void FillTexturedPolygon2D(); void FillTexturedPolygon2D();
void DrawSprite2D(); void DrawSprite2D();
void DrawPartialSprite2D(); 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 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 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); 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 WireframeCapsule3D(const Color3& color, const Capsule& cap, float thickness = 1);
void FillTriangleMesh3D(const Color3& color, const TriangleMesh& mesh); void FillTriangleMesh3D(const Color3& color, const TriangleMesh& mesh);
void WireframeTriangleMesh3D(const Color3& color, const TriangleMesh& mesh, float thickness = 1); 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 Matrix3x3&, const Vector3&);
void DrawMatrixGizmo (const Matrix4x4&); void DrawMatrixGizmo (const Matrix4x4&);

View File

@@ -26,6 +26,9 @@ struct point {
GLfloat t; GLfloat t;
}; };
int FreeSans;
int Jupiteroid;
class JGLDemoWindow : public ReWindow::RWindow class JGLDemoWindow : public ReWindow::RWindow
{ {
public: public:
@@ -53,12 +56,13 @@ public:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D); 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); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
@@ -76,15 +80,13 @@ public:
{105, 100} {105, 100}
}; };
JGL::J2D::FillTriangle2D(JGL::Colors::Yellow, tri); 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::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::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(); //glFlush();
} }

View File

@@ -6,41 +6,59 @@
#include <glad/glad.h> #include <glad/glad.h>
#include <JGL/JGL.h> #include <JGL/JGL.h>
#include <JGL/Color3.h> #include <JGL/Color3.h>
#if __linux__ #if __linux__
#include <freetype2/ft2build.h> #include <freetype2/ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#endif #endif
#if _WIN32 #if _WIN32
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#endif #endif
GLuint program; GLuint program;
namespace JGL namespace JGL
{ {
FT_Face face;
FT_Library ft; FT_Library ft;
struct Font {
int index = 0;
FT_Face face;
};
std::vector<Font> faces;
using namespace J3ML; using namespace J3ML;
bool InitTextEngine() { bool InitTextEngine() {
constexpr u32 default_font_size = 16;
if (FT_Init_FreeType(&ft)) if (FT_Init_FreeType(&ft))
{ return true;
std::cout << "Error::FREETYPE: " << std::endl; return false;
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; 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 namespace J2D
@@ -152,23 +170,32 @@ namespace JGL
glEnd(); 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. 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]; GLfloat currentColor[4];
glGetFloatv(GL_CURRENT_COLOR, currentColor); glGetFloatv(GL_CURRENT_COLOR, currentColor);
glColor3f(color.r/255.f, color.g/255.f, color.b/255.f); 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<GLuint> textures(text.length()); std::vector<GLuint> textures(text.length());
for (int i = 0; i < text.length(); i++) 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; continue;
FT_GlyphSlot g = face->glyph; FT_GlyphSlot g = font.face->glyph;
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
@@ -236,7 +263,7 @@ namespace JGL
glEnd(); 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 x = pos.x;
float y = pos.y; float y = pos.y;
@@ -247,15 +274,25 @@ namespace JGL
glUseProgram(0); // Fixed-function pipeline. glUseProgram(0); // Fixed-function pipeline.
glColor4f(color.r, color.g, color.b, 1.0f); 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 (c = text.c_str(); *c; c++)
for (int i = 0; i < text.length(); i++) 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; continue;
FT_GlyphSlot g = face->glyph; FT_GlyphSlot g = font.face->glyph;
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);