diff --git a/src/pp/pp.c b/src/pp/pp.c index d9242ed8..a39a2d73 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -115,6 +115,9 @@ void PushGameUiStyle(void) 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); } @@ -359,12 +362,32 @@ void DrawDebugConsole(b32 minimized) UI_Box *console_box = 0; { 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); + UI_Push(Parent, console_box); + if (!minimized) + { + UI_BuildSpacer(UI_FILL(1, 0)); + } } - UI_Push(Parent, console_box); - UI_Push(Width, UI_TextSize(0)); - UI_Push(Height, UI_TextSize(0)); + // UI_Push(Width, UI_TXT(0)); + UI_Push(Width, UI_FIT(1)); + UI_Push(Height, UI_FIT(1)); UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1)); UI_Push(Rounding, 0); UI_Push(TextPadding, 6); @@ -420,8 +443,29 @@ void DrawDebugConsole(b32 minimized) u32 color = colors[log->level][log->color_index]; UI_SetNext(BackgroundColor, color); UI_SetNext(Tint, Alpha32F(0xFFFFFFFF, opacity)); - UI_Box *log_box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey); - UI_SetDisplayText(log_box, text); + UI_SetNext(LayoutAxis, Axis_X); + 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); @@ -2060,14 +2104,24 @@ void UpdateUser(void) GPU_Stats gpu_stats = GPU_QueryStats(); + /* Draw console */ + { + b32 console_minimized = !g->debug_console; + DrawDebugConsole(console_minimized); + } + /* Draw debug info */ if (g->debug_draw) { __profn("Draw debug info"); + UI_BuildSpacer(UI_FILL(1, 0)); + UI_SetNext(LayoutAxis, Axis_Y); UI_SetNext(BackgroundColor, 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_PushCheckpoint(); { @@ -2080,7 +2134,7 @@ void UpdateUser(void) 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_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("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("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; 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); 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)); @@ -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 (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("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_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 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 descriptors: %F", FmtUint(gpu_stats.driver_descriptors_allocated)); @@ -2132,7 +2186,7 @@ void UpdateUser(void) //UI_BuildLabelF(\n")); #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(\n")); #endif @@ -2140,12 +2194,6 @@ void UpdateUser(void) UI_PopCheckpoint(); } - /* Draw console */ - { - b32 console_minimized = !g->debug_console; - DrawDebugConsole(console_minimized); - } - ////////////////////////////// //- Render diff --git a/src/pp/pp_step.c b/src/pp/pp_step.c index d9fdc31c..48ea285e 100644 --- a/src/pp/pp_step.c +++ b/src/pp/pp_step.c @@ -1096,7 +1096,8 @@ void StepSim(SimStepCtx *ctx) } if (flags & ControlFlag_SpawnTest1) { - P_LogDebugF("Spawn test 1"); + // P_LogDebugF("Spawn test 1"); + P_LogDebugF("Spawn test 1 ****************************************************************************************************************************************************************"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) diff --git a/src/ui/ui_common.c b/src/ui/ui_common.c index f2c88369..b1509174 100644 --- a/src/ui/ui_common.c +++ b/src/ui/ui_common.c @@ -4,8 +4,8 @@ UI_Box *UI_BuildLabel(String text) { UI_Key key = UI_KeyFromString(0, text); - UI_SetNext(Width, UI_TextSize(0)); - UI_SetNext(Height, UI_TextSize(0)); + UI_SetNext(Width, UI_TXT(0)); + UI_SetNext(Height, UI_TXT(0)); UI_Box *box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey); UI_SetDisplayText(box, text); return box; @@ -32,9 +32,16 @@ UI_Box *UI_BuildLabelF_(char *fmt_cstr, ...) UI_Box *UI_BuildSpacer(UI_Size size) { UI_SetNext(Tint, 0); - /* FIXME: Only set size in parent layout direction */ - UI_SetNext(Width, size); - UI_SetNext(Height, size); + if (UI_PeekTop(Parent)->layout_axis == Axis_X) + { + 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); return box; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index c5f81734..7feb06d8 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -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_Parent]->style.Parent = g->root_box; - g->style_tops[UI_StyleKind_Width]->style.Width = UI_RatioSize(1, 0); - g->style_tops[UI_StyleKind_Height]->style.Height = 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_FILL(1, 0); 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_Tint]->style.Tint = 0xFFFFFFFF; @@ -388,7 +388,7 @@ i64 UI_EndBuild(GPU_Resource *render_target) { 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 */ f32 text_size = 0; @@ -420,14 +420,14 @@ i64 UI_EndBuild(GPU_Resource *render_target) for (Axis axis = 0; axis < Axis_CountXY; ++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; 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_Text) + if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_TextContents) { ancestor_size = ancestor->solved_dims[axis]; 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 */ 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); } - /* 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 @@ -515,59 +593,66 @@ i64 UI_EndBuild(GPU_Resource *render_target) for (u64 pre_index = 0; pre_index < boxes_count; ++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); - 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) + /* Push box rect */ { - rect->tex = GPU_Texture2DRidFromResource(box->background_texture); - rect->tex_uv0 = box->background_texture_uv0; - rect->tex_uv1 = box->background_texture_uv1; - } - } - /* Push text rects */ - 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); - - 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 * !!(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) { - 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 = GPU_Texture2DRidFromResource(box->background_texture); + rect->tex_uv0 = box->background_texture_uv0; + rect->tex_uv1 = box->background_texture_uv1; + } + } + /* Push text rects */ + 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; + } } } } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 7cb8501e..f7f765cb 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -14,10 +14,10 @@ Struct(UI_Key) Enum(UI_SizeKind) { - UI_SizeKind_Children, - UI_SizeKind_Ratio, + UI_SizeKind_Fit, + UI_SizeKind_Fill, UI_SizeKind_Pixel, - UI_SizeKind_Text, + UI_SizeKind_TextContents, }; Struct(UI_Size) @@ -226,10 +226,13 @@ UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use); //////////////////////////////////////////////////////////// //~ Size helpers -#define UI_ChildrenSize(_strictness) ((UI_Size) { .kind = UI_SizeKind_Children, .strictness = strictness_ }) -#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_TextSize(_strictness) ((UI_Size) { .kind = UI_SizeKind_Text, .strictness = _strictness }) +#define UI_SIZE(_kind, _v, _s) (UI_Size) { .kind = (_kind), .v = (_v), .strictness = (_s) } + +#define UI_PIX(_v, _s) UI_SIZE(UI_SizeKind_Pixel, (_v), (_s)) +#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