ui violation pass

This commit is contained in:
jacob 2025-11-02 11:08:22 -06:00
parent 6a5f65d291
commit 5d87cc2a0e
5 changed files with 273 additions and 129 deletions

View File

@ -115,6 +115,9 @@ void PushGameUiStyle(void)
UI_Push(BorderColor, Rgba32F(0.6, 0.6, 0.6, 1)); UI_Push(BorderColor, Rgba32F(0.6, 0.6, 0.6, 1));
UI_Push(Width, UI_FILL(1, 0));
UI_Push(Height, UI_FILL(1, 0));
UI_Push(LayoutAxis, Axis_Y); UI_Push(LayoutAxis, Axis_Y);
} }
@ -359,12 +362,32 @@ void DrawDebugConsole(b32 minimized)
UI_Box *console_box = 0; UI_Box *console_box = 0;
{ {
UI_SetNext(LayoutAxis, Axis_Y); UI_SetNext(LayoutAxis, Axis_Y);
UI_SetNext(Tint, 0); // UI_SetNext(Tint, 0);
// UI_SetNext(BorderColor, Rgba32F(1, 1, 1, 0.25));
UI_SetNext(Border, 0);
// UI_SetNext(Width, UI_FIT(1));
if (minimized)
{
UI_SetNext(BackgroundColor, 0);
UI_SetNext(Width, UI_PIX(500, 1));
UI_SetNext(Height, UI_FIT(1));
}
else
{
UI_SetNext(BackgroundColor, Rgba32F(1, 1, 1, 0.02));
UI_SetNext(Width, UI_FILL(1, 0));
UI_SetNext(Height, UI_FILL(0.33, 1));
}
console_box = UI_BuildBox(0, UI_NilKey); console_box = UI_BuildBox(0, UI_NilKey);
UI_Push(Parent, console_box);
if (!minimized)
{
UI_BuildSpacer(UI_FILL(1, 0));
}
} }
UI_Push(Parent, console_box); // UI_Push(Width, UI_TXT(0));
UI_Push(Width, UI_TextSize(0)); UI_Push(Width, UI_FIT(1));
UI_Push(Height, UI_TextSize(0)); UI_Push(Height, UI_FIT(1));
UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1)); UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1));
UI_Push(Rounding, 0); UI_Push(Rounding, 0);
UI_Push(TextPadding, 6); UI_Push(TextPadding, 6);
@ -420,8 +443,29 @@ void DrawDebugConsole(b32 minimized)
u32 color = colors[log->level][log->color_index]; u32 color = colors[log->level][log->color_index];
UI_SetNext(BackgroundColor, color); UI_SetNext(BackgroundColor, color);
UI_SetNext(Tint, Alpha32F(0xFFFFFFFF, opacity)); UI_SetNext(Tint, Alpha32F(0xFFFFFFFF, opacity));
UI_Box *log_box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey); UI_SetNext(LayoutAxis, Axis_X);
UI_SetDisplayText(log_box, text); UI_Box *log_box = UI_BuildBox(UI_BoxFlag_None, UI_NilKey);
UI_PushCheckpoint();
{
UI_Push(Parent, log_box);
UI_Push(BackgroundColor, 0);
UI_Push(Border, 0);
f32 spacer = 50;
{
// UI_BuildSpacer(UI_PIX(spacer, 0));
}
{
UI_SetNext(Width, UI_FILL(1, 1));
UI_SetNext(Height, UI_TXT(1));
UI_Box *log_textbox = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey);
UI_SetDisplayText(log_textbox, text);
}
// {
// UI_BuildSpacer(UI_PIX(spacer, 0));
// }
UI_Pop(Parent, log_box);
}
UI_PopCheckpoint();
} }
} }
Unlock(&lock); Unlock(&lock);
@ -2060,14 +2104,24 @@ void UpdateUser(void)
GPU_Stats gpu_stats = GPU_QueryStats(); GPU_Stats gpu_stats = GPU_QueryStats();
/* Draw console */
{
b32 console_minimized = !g->debug_console;
DrawDebugConsole(console_minimized);
}
/* Draw debug info */ /* Draw debug info */
if (g->debug_draw) if (g->debug_draw)
{ {
__profn("Draw debug info"); __profn("Draw debug info");
UI_BuildSpacer(UI_FILL(1, 0));
UI_SetNext(LayoutAxis, Axis_Y); UI_SetNext(LayoutAxis, Axis_Y);
UI_SetNext(BackgroundColor, 0); UI_SetNext(BackgroundColor, 0);
UI_SetNext(BorderColor, 0); UI_SetNext(BorderColor, 0);
UI_SetNext(Width, UI_FIT(1));
UI_SetNext(Height, UI_FIT(1));
UI_Box *dbg_box = UI_BuildBox(0, UI_NilKey); UI_Box *dbg_box = UI_BuildBox(0, UI_NilKey);
UI_PushCheckpoint(); UI_PushCheckpoint();
{ {
@ -2080,7 +2134,7 @@ void UpdateUser(void)
UI_BuildLabelF("blended world tick: %F", FmtUint(g->ss_blended->tick)); UI_BuildLabelF("blended world tick: %F", FmtUint(g->ss_blended->tick));
UI_BuildLabelF("blended world time: %F", FmtFloat(SecondsFromNs(g->ss_blended->sim_time_ns))); UI_BuildLabelF("blended world time: %F", FmtFloat(SecondsFromNs(g->ss_blended->sim_time_ns)));
UI_BuildSpacer(UI_PixelSize(20, 0)); UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("average local sim publish dt: %F", FmtFloat(SecondsFromNs(g->average_local_to_user_snapshot_publish_dt_ns))); UI_BuildLabelF("average local sim publish dt: %F", FmtFloat(SecondsFromNs(g->average_local_to_user_snapshot_publish_dt_ns)));
UI_BuildLabelF("local sim last known tick: %F", FmtUint(g->local_sim_last_known_tick)); UI_BuildLabelF("local sim last known tick: %F", FmtUint(g->local_sim_last_known_tick));
@ -2091,7 +2145,7 @@ void UpdateUser(void)
UI_BuildLabelF("render time: %F", FmtFloat(SecondsFromNs(g->render_time_ns))); UI_BuildLabelF("render time: %F", FmtFloat(SecondsFromNs(g->render_time_ns)));
UI_BuildLabelF("local player: [%F]", FmtUid(local_player->id.uid)); UI_BuildLabelF("local player: [%F]", FmtUid(local_player->id.uid));
UI_BuildSpacer(UI_PixelSize(20, 0)); UI_BuildSpacer(UI_PIX(20, 0));
Vec2 world_cursor = g->world_cursor; Vec2 world_cursor = g->world_cursor;
UI_BuildLabelF("cursor world: %F, %F", FmtFloat(world_cursor.x), FmtFloat(world_cursor.y)); UI_BuildLabelF("cursor world: %F, %F", FmtFloat(world_cursor.x), FmtFloat(world_cursor.y));
@ -2104,7 +2158,7 @@ void UpdateUser(void)
Vec2I32 tile_chunk_cursor = TileChunkIndexFromWorldTileIndex(world_tile_cursor); Vec2I32 tile_chunk_cursor = TileChunkIndexFromWorldTileIndex(world_tile_cursor);
UI_BuildLabelF("cursor tile chunk: %F, %F", FmtSint(tile_chunk_cursor.x), FmtSint(tile_chunk_cursor.y)); UI_BuildLabelF("cursor tile chunk: %F, %F", FmtSint(tile_chunk_cursor.x), FmtSint(tile_chunk_cursor.y));
UI_BuildSpacer(UI_PixelSize(20, 0)); UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("Network read: %F mbit/s", FmtFloat((f64)g->net_bytes_read.last_second * 8 / 1000 / 1000)); UI_BuildLabelF("Network read: %F mbit/s", FmtFloat((f64)g->net_bytes_read.last_second * 8 / 1000 / 1000));
@ -2113,18 +2167,18 @@ void UpdateUser(void)
UI_BuildLabelF("Ping (real): %F ms", FmtFloat(SecondsFromNs(local_player->player_last_rtt_ns) * 1000)); UI_BuildLabelF("Ping (real): %F ms", FmtFloat(SecondsFromNs(local_player->player_last_rtt_ns) * 1000));
UI_BuildLabelF("Ping (average): %F ms", FmtFloat(local_player->player_average_rtt_seconds * 1000)); UI_BuildLabelF("Ping (average): %F ms", FmtFloat(local_player->player_average_rtt_seconds * 1000));
UI_BuildSpacer(UI_PixelSize(20, 0)); UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("Memory committed: %F MiB", FmtFloat((f64)GetGstat(GSTAT_MEMORY_COMMITTED) / 1024 / 1024)); UI_BuildLabelF("Memory committed: %F MiB", FmtFloat((f64)GetGstat(GSTAT_MEMORY_COMMITTED) / 1024 / 1024));
UI_BuildLabelF("Virtual memory reserved: %F TiB", FmtFloat((f64)GetGstat(GSTAT_MEMORY_RESERVED) / 1024 / 1024 / 1024 / 1024)); UI_BuildLabelF("Virtual memory reserved: %F TiB", FmtFloat((f64)GetGstat(GSTAT_MEMORY_RESERVED) / 1024 / 1024 / 1024 / 1024));
UI_BuildLabelF("Arenas allocated: %F", FmtUint(GetGstat(GSTAT_NUM_ARENAS))); UI_BuildLabelF("Arenas allocated: %F", FmtUint(GetGstat(GSTAT_NUM_ARENAS)));
UI_BuildSpacer(UI_PixelSize(20, 0)); UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("GPU dedicated memory usage: %F MiB", FmtFloat((f64)gpu_stats.local_committed / 1024 / 1024)); UI_BuildLabelF("GPU dedicated memory usage: %F MiB", FmtFloat((f64)gpu_stats.local_committed / 1024 / 1024));
UI_BuildLabelF("GPU shared memory usage: %F MiB", FmtFloat((f64)gpu_stats.non_local_committed / 1024 / 1024)); UI_BuildLabelF("GPU shared memory usage: %F MiB", FmtFloat((f64)gpu_stats.non_local_committed / 1024 / 1024));
UI_BuildSpacer(UI_PixelSize(20, 0)); UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("GPU resources: %F", FmtUint(gpu_stats.driver_resources_allocated)); UI_BuildLabelF("GPU resources: %F", FmtUint(gpu_stats.driver_resources_allocated));
UI_BuildLabelF("GPU descriptors: %F", FmtUint(gpu_stats.driver_descriptors_allocated)); UI_BuildLabelF("GPU descriptors: %F", FmtUint(gpu_stats.driver_descriptors_allocated));
@ -2132,7 +2186,7 @@ void UpdateUser(void)
//UI_BuildLabelF(\n")); //UI_BuildLabelF(\n"));
#if RtcIsEnabled #if RtcIsEnabled
UI_BuildSpacer(UI_PixelSize(20, 0)); UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("Debug steps: %F", FmtUint(GetGstat(GSTAT_DEBUG_STEPS))); UI_BuildLabelF("Debug steps: %F", FmtUint(GetGstat(GSTAT_DEBUG_STEPS)));
//UI_BuildLabelF(\n")); //UI_BuildLabelF(\n"));
#endif #endif
@ -2140,12 +2194,6 @@ void UpdateUser(void)
UI_PopCheckpoint(); UI_PopCheckpoint();
} }
/* Draw console */
{
b32 console_minimized = !g->debug_console;
DrawDebugConsole(console_minimized);
}
////////////////////////////// //////////////////////////////
//- Render //- Render

View File

@ -1096,7 +1096,8 @@ void StepSim(SimStepCtx *ctx)
} }
if (flags & ControlFlag_SpawnTest1) if (flags & ControlFlag_SpawnTest1)
{ {
P_LogDebugF("Spawn test 1"); // P_LogDebugF("Spawn test 1");
P_LogDebugF("Spawn test 1 ****************************************************************************************************************************************************************");
u32 count = 1; u32 count = 1;
f32 spread = 0; f32 spread = 0;
for (u32 j = 0; j < count; ++j) for (u32 j = 0; j < count; ++j)

View File

@ -4,8 +4,8 @@
UI_Box *UI_BuildLabel(String text) UI_Box *UI_BuildLabel(String text)
{ {
UI_Key key = UI_KeyFromString(0, text); UI_Key key = UI_KeyFromString(0, text);
UI_SetNext(Width, UI_TextSize(0)); UI_SetNext(Width, UI_TXT(0));
UI_SetNext(Height, UI_TextSize(0)); UI_SetNext(Height, UI_TXT(0));
UI_Box *box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey); UI_Box *box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey);
UI_SetDisplayText(box, text); UI_SetDisplayText(box, text);
return box; return box;
@ -32,9 +32,16 @@ UI_Box *UI_BuildLabelF_(char *fmt_cstr, ...)
UI_Box *UI_BuildSpacer(UI_Size size) UI_Box *UI_BuildSpacer(UI_Size size)
{ {
UI_SetNext(Tint, 0); UI_SetNext(Tint, 0);
/* FIXME: Only set size in parent layout direction */ if (UI_PeekTop(Parent)->layout_axis == Axis_X)
UI_SetNext(Width, size); {
UI_SetNext(Height, size); UI_SetNext(Width, size);
UI_SetNext(Height, UI_FILL(1, 0));
}
else
{
UI_SetNext(Width, UI_FILL(1, 0));
UI_SetNext(Height, size);
}
UI_Box *box = UI_BuildBox(0, UI_NilKey); UI_Box *box = UI_BuildBox(0, UI_NilKey);
return box; return box;
} }

View File

@ -289,8 +289,8 @@ void UI_BeginBuild(void)
} }
g->style_tops[UI_StyleKind_Tag]->style.Tag = HashFnv64(Fnv64Basis, Lit("root")); g->style_tops[UI_StyleKind_Tag]->style.Tag = HashFnv64(Fnv64Basis, Lit("root"));
g->style_tops[UI_StyleKind_Parent]->style.Parent = g->root_box; g->style_tops[UI_StyleKind_Parent]->style.Parent = g->root_box;
g->style_tops[UI_StyleKind_Width]->style.Width = UI_RatioSize(1, 0); g->style_tops[UI_StyleKind_Width]->style.Width = UI_FILL(1, 0);
g->style_tops[UI_StyleKind_Height]->style.Height = UI_RatioSize(1, 0); g->style_tops[UI_StyleKind_Height]->style.Height = UI_FILL(1, 0);
g->style_tops[UI_StyleKind_Font]->style.Font = UI_GetDefaultFontResource(); g->style_tops[UI_StyleKind_Font]->style.Font = UI_GetDefaultFontResource();
g->style_tops[UI_StyleKind_FontSize]->style.FontSize = 12.0f; g->style_tops[UI_StyleKind_FontSize]->style.FontSize = 12.0f;
g->style_tops[UI_StyleKind_Tint]->style.Tint = 0xFFFFFFFF; g->style_tops[UI_StyleKind_Tint]->style.Tint = 0xFFFFFFFF;
@ -388,7 +388,7 @@ i64 UI_EndBuild(GPU_Resource *render_target)
{ {
box->solved_dims[axis] = pref_size.v; box->solved_dims[axis] = pref_size.v;
} }
else if (pref_size.kind == UI_SizeKind_Text) else if (pref_size.kind == UI_SizeKind_TextContents)
{ {
/* TODO: Distinguish between baseline alignment & visual alignment */ /* TODO: Distinguish between baseline alignment & visual alignment */
f32 text_size = 0; f32 text_size = 0;
@ -420,14 +420,14 @@ i64 UI_EndBuild(GPU_Resource *render_target)
for (Axis axis = 0; axis < Axis_CountXY; ++axis) for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{ {
UI_Size pref_size = box->pref_size[axis]; UI_Size pref_size = box->pref_size[axis];
if (pref_size.kind == UI_SizeKind_Ratio) if (pref_size.kind == UI_SizeKind_Fill)
{ {
UI_Box *ancestor = box->parent; UI_Box *ancestor = box->parent;
f32 ancestor_size = 0; f32 ancestor_size = 0;
for (; ancestor; ancestor = ancestor->parent) for (; ancestor; ancestor = ancestor->parent)
{ {
UI_Size tmp = ancestor->pref_size[axis]; UI_Size tmp = ancestor->pref_size[axis];
if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_Text) if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_TextContents)
{ {
ancestor_size = ancestor->solved_dims[axis]; ancestor_size = ancestor->solved_dims[axis];
break; break;
@ -438,6 +438,127 @@ i64 UI_EndBuild(GPU_Resource *render_target)
} }
} }
/* Calculate downwards-dependent sizes */
for (u64 post_index = 0; post_index < boxes_count; ++post_index)
{
UI_Box *box = boxes_post[post_index];
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{
UI_Size pref_size = box->pref_size[axis];
if (pref_size.kind == UI_SizeKind_Fit)
{
f32 accum = 0;
for (UI_Box *child = box->first; child; child = child->next)
{
if (axis == box->layout_axis)
{
accum += child->solved_dims[axis];
}
else
{
accum = MaxF32(child->solved_dims[axis], accum);
}
}
box->solved_dims[axis] = accum;
}
}
}
/* TODO: Remove this */
#if 0
/* Calculate upwards-dependent sizes */
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{
UI_Size pref_size = box->pref_size[axis];
if (pref_size.kind == UI_SizeKind_Fill)
{
UI_Box *ancestor = box->parent;
f32 ancestor_size = 0;
for (; ancestor; ancestor = ancestor->parent)
{
UI_Size tmp = ancestor->pref_size[axis];
if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_TextContents)
{
ancestor_size = ancestor->solved_dims[axis];
break;
}
}
box->solved_dims[axis] = pref_size.v * ancestor_size;
}
}
}
/* Calculate downwards-dependent sizes */
for (u64 post_index = 0; post_index < boxes_count; ++post_index)
{
UI_Box *box = boxes_post[post_index];
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{
UI_Size pref_size = box->pref_size[axis];
if (pref_size.kind == UI_SizeKind_Fit)
{
f32 accum = 0;
for (UI_Box *child = box->first; child; child = child->next)
{
if (axis == box->layout_axis)
{
accum += child->solved_dims[axis];
}
else
{
accum = MaxF32(child->solved_dims[axis], accum);
}
}
box->solved_dims[axis] = accum;
}
}
}
#endif
/* Solve violations */
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{
f32 size_accum = 0;
f32 flex_accum = 0;
for (UI_Box *child = box->first; child; child = child->next)
{
f32 size = child->solved_dims[axis];
f32 strictness = child->pref_size[axis].strictness;
f32 flex = size * (1.0 - strictness);
if (axis == box->layout_axis)
{
size_accum += size;
flex_accum += flex;
}
else
{
size_accum = MaxF32(size_accum, size);
flex_accum = MaxF32(flex_accum, flex);
}
}
f32 violation = size_accum - box->solved_dims[axis];
if (violation > 0 && flex_accum > 0)
{
for (UI_Box *child = box->first; child; child = child->next)
{
f32 size = child->solved_dims[axis];
f32 strictness = child->pref_size[axis].strictness;
f32 flex = size * (1.0 - strictness);
f32 chopoff = MinF32(flex, violation * (flex / flex_accum));
f32 new_size = size - chopoff;
child->solved_dims[axis] = new_size;
}
}
}
}
/* Calculate final positions */ /* Calculate final positions */
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index) for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{ {
@ -455,49 +576,6 @@ i64 UI_EndBuild(GPU_Resource *render_target)
box->p1 = AddVec2(box->p0, final_size); box->p1 = AddVec2(box->p0, final_size);
} }
/* TODO: Remove this */
#if 0
{
Struct(BoxNode) { BoxNode *next; UI_Box *box; };
BoxNode *first_dfs = 0;
BoxNode *first_dfs_reverse = 0;
/* Constrain layout downwards */
UI_Box *box = g->root_box;
while (box)
{
/* Push to reverse stack */
{
BoxNode *n = PushStruct(scratch.arena, BoxNode);
n->box = box;
StackPush(first_dfs_reverse, n);
}
{
}
/* Push children to dfs stack (in reverse) */
for (UI_Box *child = box->last; child; child = child->prev)
{
BoxNode *n = PushStruct(scratch.arena, BoxNode);
n->box = child;
StackPush(first_dfs, n);
}
/* Pop dfs stack */
if (first_dfs)
{
box = first_dfs->box;
StackPop(first_dfs);
}
else
{
box = 0;
}
}
}
#endif
////////////////////////////// //////////////////////////////
//- Build render data //- Build render data
@ -515,59 +593,66 @@ i64 UI_EndBuild(GPU_Resource *render_target)
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index) for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{ {
UI_Box *box = boxes_pre[pre_index]; UI_Box *box = boxes_pre[pre_index];
/* Push box rect */ b32 is_visible = 1;
is_visible = is_visible && ((box->tint & 0xFF000000) != 0);
is_visible = is_visible && (box->p1.x > box->p0.x);
is_visible = is_visible && (box->p1.y > box->p0.y);
if (is_visible)
{ {
UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance); /* Push box rect */
rect->flags |= UI_RectFlag_DrawTexture * !!(box->background_texture != 0);
rect->p0 = box->p0;
rect->p1 = box->p1;
rect->tex_uv0 = VEC2(0, 0);
rect->tex_uv1 = VEC2(1, 1);
rect->background_srgb = box->background_color;
rect->border_srgb = box->border_color;
rect->tint_srgb = box->tint;
rect->border = box->border;
rect->rounding = box->rounding;
if (box->background_texture != 0)
{ {
rect->tex = GPU_Texture2DRidFromResource(box->background_texture); UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance);
rect->tex_uv0 = box->background_texture_uv0; rect->flags |= UI_RectFlag_DrawTexture * !!(box->background_texture != 0);
rect->tex_uv1 = box->background_texture_uv1; rect->p0 = box->p0;
} rect->p1 = box->p1;
} rect->tex_uv0 = VEC2(0, 0);
/* Push text rects */ rect->tex_uv1 = VEC2(1, 1);
if ((box->flags & UI_BoxFlag_DrawText) && box->glyph_run.count > 0 && box->font) rect->background_srgb = box->background_color;
{ rect->border_srgb = box->border_color;
Texture2DRid tex_rid = GPU_Texture2DRidFromResource(box->font->texture); rect->tint_srgb = box->tint;
Vec2 inv_font_image_size = VEC2(1.0f / (f32)box->font->image_width, 1.0f / (f32)box->font->image_height); rect->border = box->border;
rect->rounding = box->rounding;
String text = box->display_text; if (box->background_texture != 0)
F_Run run = box->glyph_run;
f32 ascent = box->font->ascent;
f32 descent = box->font->descent;
f32 padding = box->text_padding;
Vec2 baseline = box->p0;
baseline = AddVec2(baseline, VEC2(padding, padding + ascent));
for (u64 i = 0; i < run.count; ++i)
{
F_RunRect rr = run.rects[i];
Vec2 atlas_p0 = Vec2FromFields(rr.atlas_p0);
Vec2 atlas_p1 = Vec2FromFields(rr.atlas_p1);
Vec2 glyph_size = SubVec2(atlas_p1, atlas_p0);
if (glyph_size.x != 0 || glyph_size.y != 0)
{ {
UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance); rect->tex = GPU_Texture2DRidFromResource(box->background_texture);
rect->flags |= UI_RectFlag_DrawTexture; rect->tex_uv0 = box->background_texture_uv0;
rect->p0 = AddVec2(baseline, rr.baseline_start_offset); rect->tex_uv1 = box->background_texture_uv1;
rect->p1 = AddVec2(rect->p0, glyph_size); }
rect->tint_srgb = box->tint; }
rect->tex_uv0 = MulVec2Vec2(atlas_p0, inv_font_image_size); /* Push text rects */
rect->tex_uv1 = MulVec2Vec2(atlas_p1, inv_font_image_size); if ((box->flags & UI_BoxFlag_DrawText) && box->glyph_run.count > 0 && box->font)
{
Texture2DRid tex_rid = GPU_Texture2DRidFromResource(box->font->texture);
Vec2 inv_font_image_size = VEC2(1.0f / (f32)box->font->image_width, 1.0f / (f32)box->font->image_height);
rect->tex = tex_rid; String text = box->display_text;
F_Run run = box->glyph_run;
f32 ascent = box->font->ascent;
f32 descent = box->font->descent;
f32 padding = box->text_padding;
Vec2 baseline = box->p0;
baseline = AddVec2(baseline, VEC2(padding, padding + ascent));
for (u64 i = 0; i < run.count; ++i)
{
F_RunRect rr = run.rects[i];
Vec2 atlas_p0 = Vec2FromFields(rr.atlas_p0);
Vec2 atlas_p1 = Vec2FromFields(rr.atlas_p1);
Vec2 glyph_size = SubVec2(atlas_p1, atlas_p0);
if (glyph_size.x != 0 || glyph_size.y != 0)
{
UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance);
rect->flags |= UI_RectFlag_DrawTexture;
rect->p0 = AddVec2(baseline, rr.baseline_start_offset);
rect->p1 = AddVec2(rect->p0, glyph_size);
rect->tint_srgb = box->tint;
rect->tex_uv0 = MulVec2Vec2(atlas_p0, inv_font_image_size);
rect->tex_uv1 = MulVec2Vec2(atlas_p1, inv_font_image_size);
rect->tex = tex_rid;
}
} }
} }
} }

View File

@ -14,10 +14,10 @@ Struct(UI_Key)
Enum(UI_SizeKind) Enum(UI_SizeKind)
{ {
UI_SizeKind_Children, UI_SizeKind_Fit,
UI_SizeKind_Ratio, UI_SizeKind_Fill,
UI_SizeKind_Pixel, UI_SizeKind_Pixel,
UI_SizeKind_Text, UI_SizeKind_TextContents,
}; };
Struct(UI_Size) Struct(UI_Size)
@ -226,10 +226,13 @@ UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Size helpers //~ Size helpers
#define UI_ChildrenSize(_strictness) ((UI_Size) { .kind = UI_SizeKind_Children, .strictness = strictness_ }) #define UI_SIZE(_kind, _v, _s) (UI_Size) { .kind = (_kind), .v = (_v), .strictness = (_s) }
#define UI_RatioSize(_ratio, _strictness) ((UI_Size) { .kind = UI_SizeKind_Ratio, .v = _ratio, .strictness = _strictness })
#define UI_PixelSize(_pixels, _strictness) ((UI_Size) { .kind = UI_SizeKind_Pixel, .v = _pixels, .strictness = _strictness }) #define UI_PIX(_v, _s) UI_SIZE(UI_SizeKind_Pixel, (_v), (_s))
#define UI_TextSize(_strictness) ((UI_Size) { .kind = UI_SizeKind_Text, .strictness = _strictness }) #define UI_FIT(_s) UI_SIZE(UI_SizeKind_Fit, 0, (_s))
#define UI_FILL(_v, _s) UI_SIZE(UI_SizeKind_Fill, (_v), (_s))
#define UI_TXT(_s) UI_SIZE(UI_SizeKind_TextContents, 0, (_s))
#define UI_EM(_v, _s) UI_SIZE(UI_SizeKind_Pixel, (f32)UI_PeekTop(FontSize) * (_v), (_s))
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Box //~ Box