From a3c6774f211ee765f910df76837548bdadd4e959 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 15 Nov 2021 08:20:13 +0100 Subject: Add dynamic font atlas creation (not finished) --- tests/main.c | 181 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 104 insertions(+), 77 deletions(-) (limited to 'tests/main.c') diff --git a/tests/main.c b/tests/main.c index ad6113c..3dc8c98 100644 --- a/tests/main.c +++ b/tests/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -11,13 +12,16 @@ #include #include #include +#include + +#define require_equals(a, b) do { if((a) != (b)) { fprintf(stderr, "Assert failed on line %d: %s == %s\n", __LINE__, #a, #b); abort(); } } while(0) +#define require_not_equals(a, b) do { if((a) == (b)) { fprintf(stderr, "Assert failed on line %d: %s != %s\n", __LINE__, #a, #b); abort(); } } while(0) typedef struct { mgl_texture *texture; mgl_font *font; mgl_font *cjk_font; mgl_vertex_buffer *vertex_buffer1; - mgl_vertex_buffer *vertex_buffer2; mgl_shader_program *shader_program; mgl_clock clock; int fps; @@ -28,13 +32,6 @@ static void draw(mgl_window *window, void *userdata) { mgl_context *context = mgl_get_context(); Userdata *u = userdata; - mgl_rectangle rect = { - .color = { 255, 0, 0, 255 }, - .position = { window->cursor_position.x, window->cursor_position.y }, - .size = { 100.0f, 500.0f } - }; - mgl_rectangle_draw(context, &rect); - mgl_shader_program_set_uniform_vec2f(u->shader_program, "resolution", (mgl_vec2f){ u->texture->width, u->texture->height }); mgl_sprite sprite; @@ -49,16 +46,24 @@ static void draw(mgl_window *window, void *userdata) { mgl_clock_restart(&u->clock); u->fps = u->fps_counter; u->fps_counter = 0; + fprintf(stderr, "fps: %d\n", u->fps); } char str[255]; - snprintf(str, sizeof(str), "hello|world\nfps: %d", u->fps); + snprintf(str, sizeof(str), "hello|fps\nåäö: %d", u->fps); mgl_text text; mgl_text_init(&text, u->font, str, strlen(str)); mgl_text_draw(context, &text); mgl_text_deinit(&text); - const char *cjk_str = "一丏"; + const char *cjk_str = "饕餮 로 초성, 중성, 종성을 東京都と周辺7県で首都圏を構成\n" + "【システマ流】誰でも出来る「不眠.ストレス」に打ち勝つ呼吸法(東京都・埼玉県・千葉県・神奈川県)の総人口は約 千葉県・神奈川日本の民間研究所が年に発表した「世界の都市総合力ランキング」では、ロンド\n" + "ンとニューヨークに次ぐ世界3位と評価された年に首都圏整備法の施行に伴い廃止された。このように首都建設法の廃止により区部の東部には、隅田川、荒川、江戸川、中川などの河口部に沖積平野が広がっ日本国内におけ\n" + "る気候区分では23区〜多摩東部および伊豆諸島は太平洋側気候、多摩西部などは中央高地式気候に属する。小笠原諸島は南日本気候である。特徴としては、四季の変化が明瞭であり、天気が日によって変化しやすい。夏季は\n" + "高温・多雨となり、冬季は晴れて乾燥する東京都区部 - 気象庁露場のあった大手町付近の観測による最低気温が最も高くなることも珍しくなかった。しかし、夏場の最高気温自体はそれほど高くもない。一方、内陸寄りにあ\n" + "る練馬区のアメダス観測[注 7][22]地域では冬日は珍しくなく、新宿区や渋谷区などの都心部でも冬日の観測はよく見られる。また、気象観測所のある千代田区内におい足立区、荒川区、板橋区、江戸川区、大田区、葛飾区、\n" + "北区、江東区、品川区、渋谷区、新宿区、杉並区、墨田区、世田谷区、台東区、中央区、千代田区、豊島区、中野区、練馬区、文京区、港区、目黒区昭島市、あきる野市、稲城市、青梅市、清瀬市、国立市、小金井市、国分寺市、\n" + "小平市、狛江市、立川市、多摩市、調布市、西東京市、八王子市、羽村市、東久留米市、東村山市、東大和市、日野市、府中市、福生市、町田市、三鷹市、武蔵野市、武蔵村山市"; mgl_text cjk_text; mgl_text_init(&cjk_text, u->cjk_font, cjk_str, strlen(cjk_str)); @@ -66,12 +71,6 @@ static void draw(mgl_window *window, void *userdata) { mgl_text_draw(context, &cjk_text); mgl_text_deinit(&cjk_text); - mgl_vertex_buffer_set_position(u->vertex_buffer1, (mgl_vec2f){ window->cursor_position.x, window->cursor_position.y }); - mgl_vertex_buffer_draw(context, u->vertex_buffer1, &u->font->texture); - - mgl_vertex_buffer_set_position(u->vertex_buffer2, (mgl_vec2f){ window->cursor_position.x, window->cursor_position.y + 500 }); - mgl_vertex_buffer_draw(context, u->vertex_buffer2, &u->font->texture); - mgl_view prev_view; mgl_window_get_view(window, &prev_view); @@ -110,17 +109,91 @@ static void draw(mgl_window *window, void *userdata) { mgl_vertices_draw(context, vertices, 4, MGL_PRIMITIVE_QUADS); mgl_window_set_view(window, &prev_view); + + mgl_rectangle rect = { + .position = { window->cursor_position.x, window->cursor_position.y }, + .size = { u->cjk_font->texture.width, u->cjk_font->texture.height }, + .color = { 255, 255, 255, 255 }, + }; + mgl_rectangle_draw(context, &rect); + + mgl_vertex vertices1[4] = { + (mgl_vertex){ + .position = {0.0f, 0.0f}, + .texcoords = {0.0f, 0.0f}, + .color = {255, 0, 0, 100} + }, + (mgl_vertex){ + .position = {u->cjk_font->texture.width, 0.0f}, + .texcoords = {u->cjk_font->texture.width, 0.0f}, + .color = {0, 255, 0, 100}, + }, + (mgl_vertex){ + .position = {u->cjk_font->texture.width, u->cjk_font->texture.height}, + .texcoords = {u->cjk_font->texture.width, u->cjk_font->texture.height}, + .color = {0, 0, 255, 100}, + }, + (mgl_vertex){ + .position = {0.0f, u->cjk_font->texture.height}, + .texcoords = {0.0f, u->cjk_font->texture.height}, + .color = {255, 0, 255, 100} + } + }; + + mgl_vertex_buffer_update(u->vertex_buffer1, vertices1, 4, MGL_PRIMITIVE_QUADS, MGL_USAGE_STREAM); + mgl_vertex_buffer_set_position(u->vertex_buffer1, (mgl_vec2f){ window->cursor_position.x, window->cursor_position.y }); + mgl_vertex_buffer_draw(context, u->vertex_buffer1, &u->cjk_font->texture); +} + +static void test_hash_map_get_insert(mgl_font_char_map *char_map, uint32_t unicode, bool exists) { + mgl_font_glyph font_glyph; + font_glyph.advance = 5.0f; + if(exists) { + require_not_equals(mgl_font_char_map_get(char_map, unicode), NULL); + } else { + require_equals(mgl_font_char_map_get(char_map, unicode), NULL); + require_equals(mgl_font_char_map_insert(char_map, unicode, &font_glyph, NULL), 0); + } +} + +static void test_hash_map() { + mgl_font_char_map char_map; + mgl_font_char_map_init(&char_map); + + test_hash_map_get_insert(&char_map, 'h', false); + test_hash_map_get_insert(&char_map, 'e', false); + test_hash_map_get_insert(&char_map, 'l', false); + test_hash_map_get_insert(&char_map, 'l', true); + test_hash_map_get_insert(&char_map, 'o', false); + test_hash_map_get_insert(&char_map, ' ', false); + test_hash_map_get_insert(&char_map, 'f', false); + test_hash_map_get_insert(&char_map, 'p', false); + test_hash_map_get_insert(&char_map, 's', false); + + require_not_equals(mgl_font_char_map_get(&char_map, 'h'), NULL); + require_not_equals(mgl_font_char_map_get(&char_map, 'e'), NULL); + require_not_equals(mgl_font_char_map_get(&char_map, 'l'), NULL); + require_not_equals(mgl_font_char_map_get(&char_map, 'o'), NULL); + require_not_equals(mgl_font_char_map_get(&char_map, ' '), NULL); + require_not_equals(mgl_font_char_map_get(&char_map, 'f'), NULL); + require_not_equals(mgl_font_char_map_get(&char_map, 'p'), NULL); + require_not_equals(mgl_font_char_map_get(&char_map, 's'), NULL); + + mgl_font_char_map_deinit(&char_map); } int main(int argc, char **argv) { + test_hash_map(); + if(mgl_init() != 0) return 1; mgl_texture texture; + mgl_memory_mapped_file font_file; + mgl_memory_mapped_file cjk_font_file; mgl_font font; mgl_font cjk_font; mgl_vertex_buffer vertex_buffer1; - mgl_vertex_buffer vertex_buffer2; mgl_shader_program shader_program; Userdata userdata; @@ -128,7 +201,6 @@ int main(int argc, char **argv) { userdata.font = &font; userdata.cjk_font = &cjk_font; userdata.vertex_buffer1 = &vertex_buffer1; - userdata.vertex_buffer2 = &vertex_buffer2; userdata.shader_program = &shader_program; userdata.fps = 0; userdata.fps_counter = 0; @@ -138,80 +210,34 @@ int main(int argc, char **argv) { if(mgl_window_create(&window, "mgl", 1280, 720) != 0) return 1; - if(mgl_texture_load_from_file(&texture, "tests/X11.jpg", NULL) != 0) + if(mgl_texture_init(&texture) != 0) return 1; - if(mgl_font_load_from_file(&font, "/usr/share/fonts/noto/NotoSans-Regular.ttf", 32) != 0) + if(mgl_texture_load_from_file(&texture, "tests/X11.jpg", &(mgl_texture_load_options){ false, true }) != 0) return 1; - if(mgl_font_load_from_file(&cjk_font, "/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc", 32) != 0) + if(mgl_mapped_file_load("/usr/share/fonts/noto/NotoSans-Regular.ttf", &font_file, &(mgl_memory_mapped_file_load_options){ .readable = true, .writable = false }) != 0) return 1; - if(mgl_shader_program_init(&shader_program) != 0) + if(mgl_mapped_file_load("/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc", &cjk_font_file, &(mgl_memory_mapped_file_load_options){ .readable = true, .writable = false }) != 0) return 1; - if(mgl_shader_program_add_shader_from_file(&shader_program, "tests/circle_mask.glsl", MGL_SHADER_FRAGMENT) != 0) + if(mgl_font_load_from_file(&font, &font_file, 26) != 0) return 1; - if(mgl_shader_program_finalize(&shader_program) != 0) + if(mgl_font_load_from_file(&cjk_font, &cjk_font_file, 26) != 0) return 1; - mgl_vertex_buffer_init(&vertex_buffer1); - mgl_vertex_buffer_init(&vertex_buffer2); - - mgl_vertex vertices1[4] = { - (mgl_vertex){ - .position = {0.0f, 0.0f}, - .texcoords = {0.0f, 0.0f}, - .color = {255, 0, 0, 100} - }, - (mgl_vertex){ - .position = {font.texture.width, 0.0f}, - .texcoords = {1.0f, 0.0f}, - .color = {0, 255, 0, 100}, - }, - (mgl_vertex){ - .position = {font.texture.width, font.texture.height/2}, - .texcoords = {1.0f, 0.5f}, - .color = {0, 0, 255, 100}, - }, - (mgl_vertex){ - .position = {0.0f, font.texture.height/2}, - .texcoords = {0.0f, 0.5f}, - .color = {255, 0, 255, 100} - } - }; - - mgl_vertex vertices2[4] = { - (mgl_vertex){ - .position = {0.0f, 0.0f}, - .texcoords = {0.0f, 0.5f}, - .color = {255, 0, 0, 100} - }, - (mgl_vertex){ - .position = {font.texture.width, 0.0f}, - .texcoords = {1.0f, 0.5f}, - .color = {0, 255, 0, 100}, - }, - (mgl_vertex){ - .position = {font.texture.width, font.texture.height/2}, - .texcoords = {1.0f, 1.0f}, - .color = {0, 0, 255, 100}, - }, - (mgl_vertex){ - .position = {0.0f, font.texture.height/2}, - .texcoords = {0.0f, 1.0f}, - .color = {255, 0, 255, 100} - } - }; + if(mgl_shader_program_init(&shader_program) != 0) + return 1; - if(mgl_vertex_buffer_update(&vertex_buffer1, vertices1, 4, MGL_PRIMITIVE_QUADS, MGL_USAGE_STATIC) != 0) + if(mgl_shader_program_add_shader_from_file(&shader_program, "tests/circle_mask.glsl", MGL_SHADER_FRAGMENT) != 0) return 1; - if(mgl_vertex_buffer_update(&vertex_buffer2, vertices2, 4, MGL_PRIMITIVE_QUADS, MGL_USAGE_STATIC) != 0) + if(mgl_shader_program_finalize(&shader_program) != 0) return 1; - fprintf(stderr, "Font texture width: %d, texture height: %d\n", font.texture.width, font.texture.height); + mgl_vertex_buffer_init(&vertex_buffer1); mgl_event event; while(mgl_window_is_open(&window)) { @@ -232,16 +258,17 @@ int main(int argc, char **argv) { } } - mgl_window_clear(&window, (mgl_color){0, 0, 0, 255}); + mgl_window_clear(&window, (mgl_color){0, 0, 0, 0}); draw(&window, &userdata); mgl_window_display(&window); } - mgl_vertex_buffer_deinit(&vertex_buffer2); mgl_vertex_buffer_deinit(&vertex_buffer1); mgl_shader_program_deinit(&shader_program); mgl_font_unload(&cjk_font); mgl_font_unload(&font); + mgl_mapped_file_unload(&cjk_font_file); + mgl_mapped_file_unload(&font_file); mgl_texture_unload(&texture); mgl_window_deinit(&window); mgl_deinit(); -- cgit v1.2.3