From 449eceea63bef9411de73262708a62d75f636a1b Mon Sep 17 00:00:00 2001 From: Cameron Reikes Date: Sat, 11 Feb 2023 16:42:58 -0800 Subject: [PATCH] Text rendering and lower number of rendering funcs --- assets/white square.png | Bin 520 -> 4761 bytes main.c | 158 +++++++++++++++++++++++++++------------- 2 files changed, 107 insertions(+), 51 deletions(-) diff --git a/assets/white square.png b/assets/white square.png index 9054853051cec9a5cff66bf163c4db82cf0e66fe..d58e9f7fe033df6915c3e3027e76d9cbd0ba9285 100644 GIT binary patch literal 4761 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 0.0); + HMM_Vec2 points[4] = { + HMM_AddV2(upper_left, HMM_V2(0.0f, 0.0f)), + HMM_AddV2(upper_left, HMM_V2(size.X, 0.0f)), + HMM_AddV2(upper_left, HMM_V2(size.X, -size.Y)), + HMM_AddV2(upper_left, HMM_V2(0.0f, -size.Y)), + }; + draw_quad(world_space, points, image_white_square, full_region(image_white_square), color); } -// full region in pixels -AABB full_region(sg_image img) { - return (AABB) { - .upper_left = HMM_V2(0.0f, 0.0f), - .lower_right = img_size(img), - }; +// returns bounds. To measure text you can set dry run to true and get the bounds + +AABB draw_text(bool world_space, bool dry_run, const char *text, size_t length, HMM_Vec2 pos, Color color) { + size_t text_len = strlen(text); + AABB bounds = {0}; + float y = 0.0; + float x = 0.0; + for(int i = 0; i < text_len; i++) { + stbtt_aligned_quad q; + float old_y = y; + stbtt_GetBakedQuad(cdata, 512, 512, text[i]-32, &x, &y, &q, 1); + float difference = y - old_y; + y = old_y + difference; + + HMM_Vec2 size = HMM_V2(q.x1 - q.x0, q.y1 - q.y0); + if(size.Y > 0.0 && size.X > 0.0) { // spaces (and maybe other characters) produce quads of size 0 + HMM_Vec2 points[4] = { + HMM_AddV2(HMM_V2(q.x0, -q.y0), HMM_V2(0.0f, 0.0f)), + HMM_AddV2(HMM_V2(q.x0, -q.y0), HMM_V2(size.X, 0.0f)), + HMM_AddV2(HMM_V2(q.x0, -q.y0), HMM_V2(size.X, -size.Y)), + HMM_AddV2(HMM_V2(q.x0, -q.y0), HMM_V2(0.0f, -size.Y)), + }; + + AABB font_atlas_region = (AABB) { + .upper_left = HMM_V2(q.s0, q.t0), + .lower_right = HMM_V2(q.s1, q.t1), + }; + font_atlas_region.upper_left.X *= img_size(image_font).X; + font_atlas_region.lower_right.X *= img_size(image_font).X; + font_atlas_region.upper_left.Y *= img_size(image_font).Y; + font_atlas_region.lower_right.Y *= img_size(image_font).Y; + + for(int i = 0; i < 4; i++) { + bounds.upper_left.X = min(bounds.upper_left.X, points[i].X); + bounds.upper_left.Y = max(bounds.upper_left.Y, points[i].Y); + bounds.lower_right.X = max(bounds.lower_right.X, points[i].X); + bounds.lower_right.Y = min(bounds.lower_right.Y, points[i].Y); + } + + for(int i = 0; i < 4; i++) { + points[i] = HMM_AddV2(points[i], pos); + } + + if(!dry_run) { + draw_quad(world_space, points, image_font, font_atlas_region, color); + } + } + } + + return bounds; } double time = 0.0; @@ -376,6 +442,7 @@ void frame(void) { double dt_double = 0.0; { dt_double = stm_sec(stm_diff(stm_now(), last_frame_time)); + dt_double = min(dt_double, 5.0 / 60.0); // clamp dt at maximum 5 frames, avoid super huge dt time += dt_double; last_frame_time = stm_now(); } @@ -413,7 +480,7 @@ void frame(void) { } } if(info == NULL) info = &mystery_tile; - draw_quad_world_all(points, *info->img, info->regions[0], WHITE); + draw_quad(true, points, *info->img, info->regions[0], WHITE); } } } @@ -423,40 +490,29 @@ void frame(void) { { HMM_Vec2 points[4] = {0}; quad_points_centered_size(points, HMM_V2(0.0, 0.0), HMM_V2(250.0, 250.0)); - draw_quad_world_all(points, image_font,full_region(image_font), BLACK); + draw_quad(true, points, image_font,full_region(image_font), BLACK); } + +#ifdef DEVTOOLS + // statistics + { + // background panel + colorbox(false, HMM_V2(0.0, 0.0), HMM_V2(200.0, -200.0), (Color){1.0, 1.0, 1.0, 0.5}); + char frametime[128] = {0}; + snprintf(frametime, 128, "Frametime: %.1f ms", dt*1000.0); + draw_text(false, false, frametime, strlen(frametime), HMM_V2(0.0, 0.0), BLACK); + } +#endif + const char *text = "great idea"; + // measure text + { + AABB bounds = draw_text(true, true, text, strlen(text), HMM_V2(0.0, 0.0), BLACK); + colorbox(true, bounds.upper_left, bounds.lower_right, (Color){1.0,0.0,0.0,0.5}); + } // draw text - const char *text = "Hello, can anybody hear me?"; { - float x = 0.0; - float y = 0.0; - for(int i = 0; i < strlen(text); i++) { - stbtt_aligned_quad q; - float old_y = y; - stbtt_GetBakedQuad(cdata, 512, 512, text[i]-32, &x, &y, &q, 1); - float difference = y - old_y; - y = old_y + difference; - - HMM_Vec2 size = HMM_V2(q.x1 - q.x0, q.y1 - q.y0); - HMM_Vec2 points[4] = { - HMM_AddV2(HMM_V2(q.x0, -q.y0), HMM_V2(0.0f, 0.0f)), - HMM_AddV2(HMM_V2(q.x0, -q.y0), HMM_V2(size.X, 0.0f)), - HMM_AddV2(HMM_V2(q.x0, -q.y0), HMM_V2(size.X, -size.Y)), - HMM_AddV2(HMM_V2(q.x0, -q.y0), HMM_V2(0.0f, -size.Y)), - }; - - AABB region = (AABB){ - .upper_left = HMM_V2(q.s0, q.t0), - .lower_right = HMM_V2(q.s1, q.t1), - }; - region.upper_left.X *= img_size(image_font).X; - region.lower_right.X *= img_size(image_font).X; - region.upper_left.Y *= img_size(image_font).Y; - region.lower_right.Y *= img_size(image_font).Y; - - draw_quad_world_all(points, image_font, region, BLACK); - } + draw_text(true, false, text, strlen(text), HMM_V2(0.0, 0.0), BLACK); } // merchant @@ -471,7 +527,7 @@ void frame(void) { region.upper_left = HMM_V2( (float)((index % ((int)img_size(image_merchant).X/cell_size)) * cell_size), 0.0); region.lower_right = HMM_V2(region.upper_left.X + (float)cell_size, (float)cell_size); - draw_quad_world_all(points, image_merchant, region, WHITE); + draw_quad(true, points, image_merchant, region, WHITE); sg_end_pass(); sg_commit();