diff --git a/examples/example_hud/gui/main_window.cpp b/examples/example_hud/gui/main_window.cpp index 7b12ffb..9a4646e 100644 --- a/examples/example_hud/gui/main_window.cpp +++ b/examples/example_hud/gui/main_window.cpp @@ -82,6 +82,7 @@ namespace imgui_desktop::gui ImGui::Checkbox("Dashed", &m_show_dashed_box); ImGui::ColorEdit4("Color##box", reinterpret_cast(&m_box_color), ImGuiColorEditFlags_NoInputs); ImGui::ColorEdit4("Fill##box", reinterpret_cast(&m_box_fill), ImGuiColorEditFlags_NoInputs); + ImGui::ColorEdit4("Outline##box", reinterpret_cast(&m_box_outline), ImGuiColorEditFlags_NoInputs); ImGui::SliderFloat("Thickness", &m_box_thickness, 0.5f, 5.f); ImGui::SliderFloat("Corner ratio", &m_corner_ratio, 0.05f, 0.5f); ImGui::Separator(); @@ -199,9 +200,9 @@ namespace imgui_desktop::gui std::make_shared()) .contents( // ── Boxes ──────────────────────────────────────────────────── - when(m_show_box, Box{m_box_color, m_box_fill, m_box_thickness}), + when(m_show_box, Box{m_box_color, m_box_fill, m_box_outline, m_box_thickness}), when(m_show_cornered_box, CorneredBox{omath::Color::from_rgba(255, 0, 255, 255), m_box_fill, - m_corner_ratio, m_box_thickness}), + m_box_outline, m_corner_ratio, m_box_thickness}), when(m_show_dashed_box, DashedBox{m_dash_color, m_dash_len, m_dash_gap, m_dash_thickness}), RightSide{ when(m_show_right_bar, bar), diff --git a/examples/example_hud/gui/main_window.hpp b/examples/example_hud/gui/main_window.hpp index cef9ee0..ad28b28 100644 --- a/examples/example_hud/gui/main_window.hpp +++ b/examples/example_hud/gui/main_window.hpp @@ -31,6 +31,7 @@ namespace imgui_desktop::gui // Box omath::Color m_box_color{1.f, 1.f, 1.f, 1.f}; omath::Color m_box_fill{0.f, 0.f, 0.f, 0.f}; + omath::Color m_box_outline{0.f, 0.f, 0.f, 0.f}; float m_box_thickness = 1.f, m_corner_ratio = 0.2f; bool m_show_box = true, m_show_cornered_box = true, m_show_dashed_box = false; diff --git a/include/omath/hud/entity_overlay.hpp b/include/omath/hud/entity_overlay.hpp index 4aa2e96..a203a9f 100644 --- a/include/omath/hud/entity_overlay.hpp +++ b/include/omath/hud/entity_overlay.hpp @@ -20,9 +20,10 @@ namespace omath::hud // ── Boxes ──────────────────────────────────────────────────────── EntityOverlay& add_2d_box(const Color& box_color, const Color& fill_color = Color{0.f, 0.f, 0.f, 0.f}, - float thickness = 1.f); + const Color& outline_color = Color{0.f, 0.f, 0.f, 0.f}, float thickness = 1.f); EntityOverlay& add_cornered_2d_box(const Color& box_color, const Color& fill_color = Color{0.f, 0.f, 0.f, 0.f}, + const Color& outline_color = Color{0.f, 0.f, 0.f, 0.f}, float corner_ratio_len = 0.2f, float thickness = 1.f); EntityOverlay& add_dashed_box(const Color& color, float dash_len = 8.f, float gap_len = 5.f, diff --git a/include/omath/hud/entity_overlay_widgets.hpp b/include/omath/hud/entity_overlay_widgets.hpp index a895494..69c66b2 100644 --- a/include/omath/hud/entity_overlay_widgets.hpp +++ b/include/omath/hud/entity_overlay_widgets.hpp @@ -26,6 +26,7 @@ namespace omath::hud::widget { Color color; Color fill{0.f, 0.f, 0.f, 0.f}; + Color outline{0.f, 0.f, 0.f, 0.f}; float thickness = 1.f; }; @@ -33,6 +34,7 @@ namespace omath::hud::widget { Color color; Color fill{0.f, 0.f, 0.f, 0.f}; + Color outline{0.f, 0.f, 0.f, 0.f}; float corner_ratio = 0.2f; float thickness = 1.f; }; diff --git a/source/hud/entity_overlay.cpp b/source/hud/entity_overlay.cpp index 66eb872..4833979 100644 --- a/source/hud/entity_overlay.cpp +++ b/source/hud/entity_overlay.cpp @@ -5,10 +5,14 @@ namespace omath::hud { - EntityOverlay& EntityOverlay::add_2d_box(const Color& box_color, const Color& fill_color, const float thickness) + EntityOverlay& EntityOverlay::add_2d_box(const Color& box_color, const Color& fill_color, + const Color& outline_color, const float thickness) { const auto points = m_canvas.as_array(); + if (outline_color.value().w > 0.f) + m_renderer->add_polyline({points.data(), points.size()}, outline_color, thickness + 2.f); + m_renderer->add_polyline({points.data(), points.size()}, box_color, thickness); if (fill_color.value().w > 0.f) @@ -17,41 +21,46 @@ namespace omath::hud return *this; } EntityOverlay& EntityOverlay::add_cornered_2d_box(const Color& box_color, const Color& fill_color, - const float corner_ratio_len, const float thickness) + const Color& outline_color, const float corner_ratio_len, + const float thickness) { const auto corner_line_length = std::abs((m_canvas.top_left_corner - m_canvas.top_right_corner).x * corner_ratio_len); if (fill_color.value().w > 0.f) add_2d_box(fill_color, fill_color); + + const auto draw_corner_line = [&](const Vector2& a, const Vector2& b) + { + if (outline_color.value().w > 0.f) + m_renderer->add_line(a, b, outline_color, thickness + 2.f); + m_renderer->add_line(a, b, box_color, thickness); + }; + // Left Side - m_renderer->add_line(m_canvas.top_left_corner, - m_canvas.top_left_corner + Vector2{corner_line_length, 0.f}, box_color, thickness); + draw_corner_line(m_canvas.top_left_corner, + m_canvas.top_left_corner + Vector2{corner_line_length, 0.f}); - m_renderer->add_line(m_canvas.top_left_corner, - m_canvas.top_left_corner + Vector2{0.f, corner_line_length}, box_color, thickness); + draw_corner_line(m_canvas.top_left_corner, + m_canvas.top_left_corner + Vector2{0.f, corner_line_length}); - m_renderer->add_line(m_canvas.bottom_left_corner, - m_canvas.bottom_left_corner - Vector2{0.f, corner_line_length}, box_color, - thickness); + draw_corner_line(m_canvas.bottom_left_corner, + m_canvas.bottom_left_corner - Vector2{0.f, corner_line_length}); - m_renderer->add_line(m_canvas.bottom_left_corner, - m_canvas.bottom_left_corner + Vector2{corner_line_length, 0.f}, box_color, - thickness); + draw_corner_line(m_canvas.bottom_left_corner, + m_canvas.bottom_left_corner + Vector2{corner_line_length, 0.f}); // Right Side - m_renderer->add_line(m_canvas.top_right_corner, - m_canvas.top_right_corner - Vector2{corner_line_length, 0.f}, box_color, thickness); + draw_corner_line(m_canvas.top_right_corner, + m_canvas.top_right_corner - Vector2{corner_line_length, 0.f}); - m_renderer->add_line(m_canvas.top_right_corner, - m_canvas.top_right_corner + Vector2{0.f, corner_line_length}, box_color, thickness); + draw_corner_line(m_canvas.top_right_corner, + m_canvas.top_right_corner + Vector2{0.f, corner_line_length}); - m_renderer->add_line(m_canvas.bottom_right_corner, - m_canvas.bottom_right_corner - Vector2{0.f, corner_line_length}, box_color, - thickness); + draw_corner_line(m_canvas.bottom_right_corner, + m_canvas.bottom_right_corner - Vector2{0.f, corner_line_length}); - m_renderer->add_line(m_canvas.bottom_right_corner, - m_canvas.bottom_right_corner - Vector2{corner_line_length, 0.f}, box_color, - thickness); + draw_corner_line(m_canvas.bottom_right_corner, + m_canvas.bottom_right_corner - Vector2{corner_line_length, 0.f}); return *this; } @@ -591,12 +600,13 @@ namespace omath::hud // ── widget dispatch ─────────────────────────────────────────────────────── void EntityOverlay::dispatch(const widget::Box& box) { - add_2d_box(box.color, box.fill, box.thickness); + add_2d_box(box.color, box.fill, box.outline, box.thickness); } void EntityOverlay::dispatch(const widget::CorneredBox& cornered_box) { - add_cornered_2d_box(cornered_box.color, cornered_box.fill, cornered_box.corner_ratio, cornered_box.thickness); + add_cornered_2d_box(cornered_box.color, cornered_box.fill, cornered_box.outline, cornered_box.corner_ratio, + cornered_box.thickness); } void EntityOverlay::dispatch(const widget::DashedBox& dashed_box) diff --git a/source/lua/lua_hud.cpp b/source/lua/lua_hud.cpp index 3a79024..9dd2420 100644 --- a/source/lua/lua_hud.cpp +++ b/source/lua/lua_hud.cpp @@ -285,17 +285,20 @@ namespace omath::lua "add_2d_box", [](omath::hud::EntityOverlay& overlay, const omath::Color& box_color, - sol::optional fill_color, sol::optional thickness) -> omath::hud::EntityOverlay& + sol::optional fill_color, sol::optional outline_color, + sol::optional thickness) -> omath::hud::EntityOverlay& { return overlay.add_2d_box(box_color, fill_color.value_or(transparent_black()), - thickness.value_or(1.f)); + outline_color.value_or(transparent_black()), thickness.value_or(1.f)); }, "add_cornered_2d_box", [](omath::hud::EntityOverlay& overlay, const omath::Color& box_color, - sol::optional fill_color, sol::optional corner_ratio_len, + sol::optional fill_color, sol::optional outline_color, + sol::optional corner_ratio_len, sol::optional thickness) -> omath::hud::EntityOverlay& { return overlay.add_cornered_2d_box(box_color, fill_color.value_or(transparent_black()), + outline_color.value_or(transparent_black()), corner_ratio_len.value_or(0.2f), thickness.value_or(1.f)); }, "add_dashed_box", diff --git a/tests/lua/hud_tests.lua b/tests/lua/hud_tests.lua index d3f10fb..2023fd7 100644 --- a/tests/lua/hud_tests.lua +++ b/tests/lua/hud_tests.lua @@ -110,17 +110,21 @@ end function Hud_EntityOverlay_add_2d_box() local commands = {} - overlay(commands):add_2d_box(color(), fill(), 2) - assert(#commands == 2) - assert(commands[1].kind == "polyline" and #commands[1].points == 4) - assert(commands[2].kind == "filled_polyline") + overlay(commands):add_2d_box(color(), fill(), outline(), 2) + assert(#commands == 3) + assert(commands[1].kind == "polyline" and approx(commands[1].thickness, 4)) + assert(commands[2].kind == "polyline" and approx(commands[2].thickness, 2) and #commands[2].points == 4) + assert(commands[3].kind == "filled_polyline") end function Hud_EntityOverlay_add_cornered_2d_box() local commands = {} - overlay(commands):add_cornered_2d_box(color(), fill(), 0.25, 2) - assert(#commands == 10) - assert(commands[1].kind == "polyline" and commands[10].kind == "line") + overlay(commands):add_cornered_2d_box(color(), fill(), outline(), 0.25, 2) + assert(#commands == 18) + assert(commands[1].kind == "polyline" and commands[2].kind == "filled_polyline") + assert(commands[3].kind == "line" and approx(commands[3].thickness, 4)) + assert(commands[4].kind == "line" and approx(commands[4].thickness, 2)) + assert(commands[18].kind == "line") end function Hud_EntityOverlay_add_dashed_box()