]> git.lizzy.rs Git - dragonblocks_alpha.git/blobdiff - src/client/font.c
Use MinGW ANSI stdio
[dragonblocks_alpha.git] / src / client / font.c
index ac3c251cbc9df1d38b664c0b75c3b3c2e302a313..56c6e07f1fa30d0ec724cec47df76cc3a37012cd 100644 (file)
 #include FT_FREETYPE_H
 #include "client/client.h"
 #include "client/font.h"
-#include "client/hud.h"
+#include "client/gl_debug.h"
+#include "client/texture.h"
 
 #define NUM_CHARS 128
 
-
-typedef struct
-{
-       Texture *texture;
+typedef struct {
+       Texture texture;
        v2s32 bearing;
        u32 advance;
 } Character;
 
-static struct
-{
-       FT_Library library;
-       FT_Face face;
-       Character chars[NUM_CHARS];
-       GLfloat height;
-} font;
-
-typedef struct
-{
-       GLfloat x, y;
-} __attribute__((packed)) VertexFontPosition;
-
-typedef struct
-{
-       GLfloat s, t;
-} __attribute__((packed)) VertexFontTextureCoordinates;
-
-typedef struct
-{
-       VertexFontPosition position;
-       VertexFontTextureCoordinates textureCoordinates;
-} __attribute__((packed)) VertexFont;
-
-static VertexAttribute vertex_attributes[2] = {
-       // position
-       {
-               .type = GL_FLOAT,
-               .length = 2,
-               .size = sizeof(VertexFontPosition),
-       },
-       // textureCoordinates
-       {
-               .type = GL_FLOAT,
-               .length = 2,
-               .size = sizeof(VertexFontTextureCoordinates),
+static FT_Library font_library;
+static FT_Face font_face;
+static Character font_chars[NUM_CHARS];
+static GLfloat font_height;
+
+typedef struct {
+       v2f32 position;
+       v2f32 textureCoordinates;
+} __attribute__((packed)) FontVertex;
+static VertexLayout font_vertex_layout = {
+       .attributes = (VertexAttribute[]) {
+               {GL_FLOAT, 2, sizeof(v2f32)}, // position
+               {GL_FLOAT, 2, sizeof(v2f32)}, // textureCoordinates
        },
-};
-
-static VertexLayout vertex_layout = {
-       .attributes = vertex_attributes,
        .count = 2,
-       .size = sizeof(VertexFont),
+       .size = sizeof(FontVertex),
 };
 
-bool font_init()
+void font_init()
 {
-       if (FT_Init_FreeType(&font.library)) {
-               fprintf(stderr, "Failed to initialize Freetype\n");
-               return false;
+       if (FT_Init_FreeType(&font_library)) {
+               fprintf(stderr, "[error] failed to initialize Freetype\n");
+               abort();
        }
 
-       if (FT_New_Face(font.library, RESSOURCEPATH "fonts/Minecraftia.ttf", 0, &font.face)) {
-               fprintf(stderr, "Failed to load Minecraftia.ttf\n");
-               return false;
+       if (FT_New_Face(font_library, ASSET_PATH "fonts/Minecraftia.ttf", 0, &font_face)) {
+               fprintf(stderr, "[error] failed to load Minecraftia.ttf\n");
+               abort();
        }
 
-       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-       FT_Set_Pixel_Sizes(font.face, 0, 16);
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1); GL_DEBUG
+       FT_Set_Pixel_Sizes(font_face, 0, 16);
 
        for (unsigned char c = 0; c < NUM_CHARS; c++) {
-               if (FT_Load_Char(font.face, c, FT_LOAD_RENDER)) {
-                       fprintf(stderr, "Failed to load glyph %c\n", c);
-
-                       font.chars[c] = (Character) {
-                               .texture = NULL,
-                               .bearing = {0, 0},
-                               .advance = 0,
-                       };
-               } else {
-                       font.chars[c] = (Character) {
-                               .texture = texture_create(font.face->glyph->bitmap.buffer, font.face->glyph->bitmap.width, font.face->glyph->bitmap.rows, GL_RED),
-                               .bearing = {font.face->glyph->bitmap_left, font.face->glyph->bitmap_top},
-                               .advance = font.face->glyph->advance.x,
-                       };
+               if (FT_Load_Char(font_face, c, FT_LOAD_RENDER)) {
+                       fprintf(stderr, "[warning] failed to load glyph %c\n", c);
+                       font_chars[c].texture.txo = 0;
+                       continue;
                }
-       }
 
-       font.height = font.chars['|'].texture->height;
+               font_chars[c].texture.width = font_face->glyph->bitmap.width;
+               font_chars[c].texture.height = font_face->glyph->bitmap.rows;
+               texture_upload(&font_chars[c].texture, font_face->glyph->bitmap.buffer, GL_RED, false);
+
+               font_chars[c].bearing = (v2s32) {font_face->glyph->bitmap_left, font_face->glyph->bitmap_top};
+               font_chars[c].advance = font_face->glyph->advance.x;
+       }
 
-       FT_Done_Face(font.face);
-       FT_Done_FreeType(font.library);
+       font_height = font_chars['|'].texture.height;
 
-       return true;
+       FT_Done_Face(font_face);
+       FT_Done_FreeType(font_library);
 }
 
 void font_deinit()
 {
-       for (unsigned char c = 0; c < NUM_CHARS; c++) {
-               if (font.chars[c].texture)
-                       texture_delete(font.chars[c].texture);
-       }
+       for (unsigned char c = 0; c < NUM_CHARS; c++)
+               texture_destroy(&font_chars[c].texture);
 }
 
-Font *font_create(char *text)
+Font *font_create(const char *text)
 {
-       Font *fnt = malloc(sizeof(fnt));
-
-       size_t len = strlen(text);
+       Font *font = malloc(sizeof *font);
 
-       fnt->meshes = malloc(sizeof(Mesh *) * len);
-       fnt->meshes_count = len;
+       font->count = strlen(text);
+       font->meshes = malloc(font->count * sizeof *font->meshes);
+       font->textures = malloc(font->count * sizeof *font->textures);
 
        GLfloat offset = 0.0f;
 
-       for (size_t i = 0; i < len; i++) {
+       for (size_t i = 0; i < font->count; i++) {
                unsigned char c = text[i];
 
-               if (c >= NUM_CHARS || ! font.chars[c].texture)
+               if (c >= NUM_CHARS || !font_chars[c].texture.txo)
                        c = '?';
 
-               Character *ch = &font.chars[c];
+               Character *ch = &font_chars[c];
 
-               GLfloat width = ch->texture->width;
-        GLfloat height = ch->texture->height;
+               GLfloat width = ch->texture.width;
+               GLfloat height = ch->texture.height;
 
                GLfloat x = ch->bearing.x + offset;
-        GLfloat y = font.height - ch->bearing.y;
-
-        VertexFont vertices[6] = {
-            {{x,         y         }, {0.0f, 0.0f}},
-            {{x,         y + height}, {0.0f, 1.0f}},
-            {{x + width, y + height}, {1.0f, 1.0f}},
-            {{x,         y         }, {0.0f, 0.0f}},
-            {{x + width, y + height}, {1.0f, 1.0f}},
-            {{x + width, y         }, {1.0f, 0.0f}},
-        };
-
-               Mesh *mesh = fnt->meshes[i] = mesh_create();
-               mesh->textures = &ch->texture->id;
-               mesh->textures_count = 1;
-               mesh->free_textures = false;
-               mesh->vertices = vertices;
-               mesh->vertices_count = 6;
-               mesh->free_vertices = false;
-               mesh->layout = &vertex_layout;
-               mesh_configure(mesh);
+               GLfloat y = font_height - ch->bearing.y;
+
+               // this is art
+               // selling this as NFT starting price is 10 BTC
+               font->meshes[i].data = (FontVertex[]) {
+                       {{x,         y         }, {0.0f, 0.0f}},
+                       {{x,         y + height}, {0.0f, 1.0f}},
+                       {{x + width, y + height}, {1.0f, 1.0f}},
+                       {{x,         y         }, {0.0f, 0.0f}},
+                       {{x + width, y + height}, {1.0f, 1.0f}},
+                       {{x + width, y         }, {1.0f, 0.0f}},
+               };
+               font->meshes[i].count = 6;
+               font->meshes[i].layout = &font_vertex_layout;
+               font->meshes[i].vao = font->meshes[i].vbo = 0;
+               font->meshes[i].free_data = false;
+               mesh_upload(&font->meshes[i]);
+
+               font->textures[i] = ch->texture.txo;
 
                offset += ch->advance >> 6;
        }
 
-       return fnt;
+       font->size = (v2f32) {offset, font_height};
+
+       return font;
 }
 
-void font_delete(Font *fnt)
+void font_delete(Font *font)
 {
-       for (size_t i = 0; i < fnt->meshes_count; i++)
-               mesh_delete(fnt->meshes[i]);
+       for (size_t i = 0; i < font->count; i++)
+               mesh_destroy(&font->meshes[i]);
 
-       free(fnt);
+       free(font->meshes);
+       free(font->textures);
+       free(font);
 }
 
-void font_render(Font *fnt)
+void font_render(Font *font)
 {
-       for (size_t i = 0; i < fnt->meshes_count; i++)
-               mesh_render(fnt->meshes[i]);
+       for (size_t i = 0; i < font->count; i++) {
+               glBindTextureUnit(0, font->textures[i]); GL_DEBUG
+               mesh_render(&font->meshes[i]);
+       }
 }