From f4833afa1afa56def5a6d54fa8ce22d3a9b4eb55 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 18 Nov 2021 12:17:14 +0100 Subject: Move glyph creation for text to render function instead of in set string, clear font glyph background before rendering the text --- src/graphics/font.c | 26 +++++++++++++------------- src/graphics/text.c | 25 +++++++++++++++---------- 2 files changed, 28 insertions(+), 23 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/font.c b/src/graphics/font.c index 17362f6..aa349a6 100644 --- a/src/graphics/font.c +++ b/src/graphics/font.c @@ -4,8 +4,8 @@ #define STB_TRUETYPE_IMPLEMENTATION #include "../../external/stb_truetype.h" -/* Need padding so filtering doesn't touch pixels in another glyphs area. TODO: Decrease this */ -#define GLYPH_PADDING 4 +/* Need padding so filtering doesn't touch pixels in another glyphs area */ +#define GLYPH_PADDING 2 #define GLYPH_UPSAMPLE 1 int mgl_font_load_from_file(mgl_font *self, const mgl_memory_mapped_file *mapped_file, unsigned int character_size) { @@ -36,11 +36,6 @@ int mgl_font_load_from_file(mgl_font *self, const mgl_memory_mapped_file *mapped return -1; } - if(mgl_texture_init(&self->texture) != 0) { - mgl_font_unload(self); - return -1; - } - /* TODO: Use stbtt_GetCodepointSDF */ return 0; } @@ -130,12 +125,16 @@ static void mgl_font_handle_new_render_position(mgl_font *self, int glyph_width) int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph) { if(self->font_atlas.width == 0) { + if(self->texture.id == 0 && mgl_texture_init(&self->texture) != 0) + return -1; + const int initial_atlas_size = align_up_to_next_value_of(128, self->character_size); /* TODO: Scale by character size */ mgl_texture_load_options load_options = { .compressed = false, .pixel_coordinates = true }; + if(mgl_texture_load_from_memory(&self->texture, NULL, initial_atlas_size, initial_atlas_size, MGL_IMAGE_FORMAT_ALPHA, &load_options) == 0) { /*fprintf(stderr, "Error: failed to create font atlas texture, error: mgl_texture_load_from_memory failed\n");*/ self->font_atlas.width = initial_atlas_size; @@ -176,12 +175,13 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph int yoff = y0; /* TODO: Use stbtt_MakeGlyphBitmapSubpixelPrefilter instead for better text quality */ - const size_t pixels_size = (width + GLYPH_PADDING * 2) * (height + GLYPH_PADDING * 2); - unsigned char *pixels = malloc(pixels_size); + const size_t pixels_width = (width + GLYPH_PADDING * 2); + const size_t pixels_height = (height + GLYPH_PADDING * 2); + const size_t pixels_size = pixels_width * pixels_height; + unsigned char *pixels = calloc(pixels_size, 1); if(pixels) { - /* TODO: Is this needed? */ - /*memset(pixels, 0, pixels_size);*/ - stbtt_MakeGlyphBitmapSubpixel(self->font_info, pixels, width, height, width, font_scale, font_scale, GLYPH_PADDING, GLYPH_PADDING, glyph_index); + const int top_padding = GLYPH_PADDING; + stbtt_MakeGlyphBitmap(self->font_info, pixels + pixels_width * top_padding + GLYPH_PADDING, width, height, pixels_width, font_scale, font_scale, glyph_index); } mgl_vec2i render_offset; @@ -223,7 +223,7 @@ int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph } } - const int res = mgl_texture_update(&self->texture, pixels, render_offset.x, render_offset.y, width, height, MGL_IMAGE_FORMAT_ALPHA); + const int res = mgl_texture_update(&self->texture, pixels, render_offset.x - GLYPH_PADDING, render_offset.y - GLYPH_PADDING, pixels_width, pixels_height, MGL_IMAGE_FORMAT_ALPHA); free(pixels); return res; } diff --git a/src/graphics/text.c b/src/graphics/text.c index 3620659..66ef7e3 100644 --- a/src/graphics/text.c +++ b/src/graphics/text.c @@ -90,6 +90,7 @@ void mgl_text_init(mgl_text *self, mgl_font *font, const char *str, size_t str_s self->position = (mgl_vec2f){ 0.0f, 0.0f }; self->text = NULL; self->text_size = 0; + self->bounds_dirty = true; mgl_text_set_string(self, str, str_size); } @@ -105,19 +106,13 @@ void mgl_text_set_string(mgl_text *self, const char *str, size_t str_size) { self->text = str; self->text_size = str_size; if(self->text && self->text_size > 0 && self->font) - self->bounds = mgl_text_calculate_bounds(self); - else - self->bounds = (mgl_vec2f){ 0.0f, 0.0f }; + self->bounds_dirty = true; } void mgl_text_set_font(mgl_text *self, mgl_font *font) { self->font = font; - if(self->font) { - if(self->bounds.x < 0.001f && self->bounds.y < 0.001f && self->text && self->text_size > 0) - self->bounds = mgl_text_calculate_bounds(self); - } else { - self->bounds = (mgl_vec2f){ 0.0f, 0.0f }; - } + if(self->text && self->text_size > 0 && self->font) + self->bounds_dirty = true; } void mgl_text_set_position(mgl_text *self, mgl_vec2f position) { @@ -128,7 +123,14 @@ void mgl_text_set_color(mgl_text *self, mgl_color color) { self->color = color; } -mgl_vec2f mgl_text_get_bounds(const mgl_text *self) { +mgl_vec2f mgl_text_get_bounds(mgl_text *self) { + if(self->bounds_dirty) { + self->bounds_dirty = false; + if(self->text && self->text_size > 0 && self->font) + self->bounds = mgl_text_calculate_bounds(self); + else + self->bounds = (mgl_vec2f){ 0.0f, 0.0f }; + } return self->bounds; } @@ -210,6 +212,9 @@ void mgl_text_draw(mgl_context *context, mgl_text *text) { if(!text->text || text->text_size == 0 || !text->font) return; + /* Calculate bounds beforehand if needed, which also generates glyphs because opengl outputs an error if that is done inside glBegin/glEnd */ + mgl_text_get_bounds(text); + TextDrawUserdata text_draw_userdata; text_draw_userdata.position = (mgl_vec2f){ text->position.x, text->position.y + text->font->character_size }; text_draw_userdata.text = text; -- cgit v1.2.3