diff --git a/include/omath/hud/entity_overlay.hpp b/include/omath/hud/entity_overlay.hpp index fd120e1..c64e523 100644 --- a/include/omath/hud/entity_overlay.hpp +++ b/include/omath/hud/entity_overlay.hpp @@ -10,13 +10,7 @@ #include namespace omath::hud { - enum class SnapLineStartPosition - { - SCREEN_BOTTOM, - SCREEN_TOP, - SCREEN_CENTER, - }; - class EntityOverlay + class EntityOverlay final { public: EntityOverlay(const Vector2& top, const Vector2& bottom, @@ -59,14 +53,14 @@ namespace omath::hud void add_top_bar(const Color& color, const Color& outline_color, const Color& bg_color, float height, float ratio, float offset = 5.f); - void add_snap_line(const SnapLineStartPosition& start_pos, const Color& color, float width); + void add_snap_line(const Vector3& start_pos, const Color& color, float width); private: - static void draw_outlined_text(const Vector2& position, const Color& color, + void draw_outlined_text(const Vector2& position, const Color& color, const std::string_view& text); CanvasBox m_canvas; Vector2 m_text_cursor_right; Vector2 m_text_cursor_top; - std::shared_ptr renderer; + std::shared_ptr m_renderer; }; } // namespace omath::hud \ No newline at end of file diff --git a/include/omath/hud/hud_renderer_interface.hpp b/include/omath/hud/hud_renderer_interface.hpp index 4891e1e..c563154 100644 --- a/include/omath/hud/hud_renderer_interface.hpp +++ b/include/omath/hud/hud_renderer_interface.hpp @@ -14,9 +14,9 @@ namespace omath::hud virtual void add_line(const Vector2& line_start, const Vector2& line_end, const Color& color, float thickness) = 0; - virtual void add_polyline(const std::span>& vertexes, float thickness) = 0; + virtual void add_polyline(const std::span>& vertexes, const Color& color, float thickness) = 0; - virtual void add_filled_polyline(const std::span>& vertexes, float thickness) = 0; + virtual void add_filled_polyline(const std::span>& vertexes, const Color& color, float thickness) = 0; virtual void add_rectangle(const Vector2& min, const Vector2& max, const Color& color) = 0; diff --git a/include/omath/hud/renderer_realizations/imgui_renderer.hpp b/include/omath/hud/renderer_realizations/imgui_renderer.hpp index 3e0d608..be7f637 100644 --- a/include/omath/hud/renderer_realizations/imgui_renderer.hpp +++ b/include/omath/hud/renderer_realizations/imgui_renderer.hpp @@ -11,8 +11,8 @@ namespace omath::hud ~ImguiHudRenderer() override; void add_line(const Vector2& line_start, const Vector2& line_end, const Color& color, float thickness) override; - void add_polyline(const std::span>& vertexes, float thickness) override; - void add_filled_polyline(const std::span>& vertexes, float thickness) override; + void add_polyline(const std::span>& vertexes, const Color& color, float thickness) override; + void add_filled_polyline(const std::span>& vertexes, const Color& color, float thickness) override; void add_rectangle(const Vector2& min, const Vector2& max, const Color& color) override; void add_filled_rectangle(const Vector2& min, const Vector2& max, const Color& color) override; void add_text(const Vector2& position, const Color& color, const std::string_view& text) override; diff --git a/source/hud/entity_overlay.cpp b/source/hud/entity_overlay.cpp index 11f6c95..d342364 100644 --- a/source/hud/entity_overlay.cpp +++ b/source/hud/entity_overlay.cpp @@ -5,5 +5,136 @@ namespace omath::hud { + void EntityOverlay::add_2d_box(const Color& box_color, const Color& fill_color, const float thickness) const + { + const auto points = m_canvas.as_array(); -} \ No newline at end of file + m_renderer->add_polyline({points.data(), points.size()}, box_color, thickness); + m_renderer->add_filled_polyline({points.data(), points.size()}, fill_color, thickness); + } + void EntityOverlay::add_cornered_2d_box(const Color& box_color, const Color& fill_color, + const float corner_ratio_len, const float thickness) const + { + 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); + // 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); + + m_renderer->add_line(m_canvas.top_left_corner, + m_canvas.top_left_corner + Vector2{0.f, corner_line_length}, box_color, thickness); + + m_renderer->add_line(m_canvas.bottom_left_corner, + m_canvas.bottom_left_corner - Vector2{0.f, corner_line_length}, box_color, + thickness); + + m_renderer->add_line(m_canvas.bottom_left_corner, + m_canvas.bottom_left_corner + Vector2{corner_line_length, 0.f}, box_color, + thickness); + // 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); + + m_renderer->add_line(m_canvas.top_right_corner, + m_canvas.top_right_corner + Vector2{0.f, corner_line_length}, box_color, thickness); + + m_renderer->add_line(m_canvas.bottom_right_corner, + m_canvas.bottom_right_corner - Vector2{0.f, corner_line_length}, box_color, + thickness); + + m_renderer->add_line(m_canvas.bottom_right_corner, + m_canvas.bottom_right_corner - Vector2{corner_line_length, 0.f}, box_color, + thickness); + } + void EntityOverlay::add_right_bar(const Color& color, const Color& outline_color, const Color& bg_color, + const float width, float ratio, const float offset) + { + ratio = std::clamp(ratio, 0.f, 1.f); + const auto max_bar_height = std::abs(m_canvas.top_right_corner.y - m_canvas.bottom_right_corner.y); + + const auto bar_start = m_canvas.bottom_right_corner + Vector2{offset, 0.f}; + m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2(width, -max_bar_height), bg_color); + + m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2(width, -max_bar_height * ratio), color); + m_renderer->add_rectangle(bar_start - Vector2(1.f, 0.f), + bar_start + Vector2(width, -max_bar_height), outline_color); + + // NOTE: Move text 1 pixel horizontali due to imgui logic of rendering rectangle + m_text_cursor_right.x += offset + width + 1.f; + } + void EntityOverlay::add_left_bar(const Color& color, const Color& outline_color, const Color& bg_color, + const float width, float ratio, const float offset) const + { + ratio = std::clamp(ratio, 0.f, 1.f); + const auto max_bar_height = std::abs(m_canvas.top_left_corner.y - m_canvas.bottom_right_corner.y); + + const auto bar_start = m_canvas.bottom_left_corner + Vector2{-(offset + width), 0.f}; + m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2(width, -max_bar_height), bg_color); + + m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2(width, -max_bar_height * ratio), color); + m_renderer->add_rectangle(bar_start - Vector2(1.f, 0.f), + bar_start + Vector2(width, -max_bar_height), outline_color); + } + void EntityOverlay::add_right_label(const Color& color, const float offset, const bool outlined, + const std::string_view& text) + { + if (outlined) + draw_outlined_text(m_text_cursor_right + Vector2{offset, 0.f}, color, text); + else + m_renderer->add_text(m_text_cursor_right + Vector2{offset, 0.f}, color, text.data()); + + m_text_cursor_right.y += ImGui::CalcTextSize(text.data()).y; + } + void EntityOverlay::add_top_label(const Color& color, const float offset, const bool outlined, + const std::string_view text) + { + + m_text_cursor_top.y -= ImGui::CalcTextSize(text.data()).y; + + if (outlined) + draw_outlined_text(m_text_cursor_top + Vector2{0.f, -offset}, color, text); + else + m_renderer->add_text(m_text_cursor_top + Vector2{0.f, -offset}, color, text.data()); + } + void EntityOverlay::add_top_bar(const Color& color, const Color& outline_color, const Color& bg_color, + const float height, float ratio, const float offset) + { + ratio = std::clamp(ratio, 0.f, 1.f); + const auto max_bar_width = std::abs(m_canvas.top_left_corner.x - m_canvas.bottom_right_corner.x); + + const auto bar_start = m_canvas.top_left_corner - Vector2{0.f, offset}; + m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2(max_bar_width, -height), bg_color); + + m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2(max_bar_width * ratio, -height), color); + m_renderer->add_rectangle(bar_start, bar_start + Vector2(max_bar_width, -height), outline_color); + + m_text_cursor_top.y -= offset + height; + } + void EntityOverlay::add_snap_line(const Vector3& start_pos, const Color& color, const float width) + { + const Vector2 line_end = + m_canvas.bottom_left_corner + + Vector2{m_canvas.bottom_right_corner.x - m_canvas.bottom_left_corner.x, 0.f} / 2; + m_renderer->add_line(start_pos, line_end, color, width); + } + void EntityOverlay::draw_outlined_text(const Vector2& position, const Color& color, + const std::string_view& text) + { + static constexpr std::array outline_offsets = { + Vector2{-1, -1}, Vector2{-1, 0}, Vector2{-1, 1}, Vector2{0, -1}, + Vector2{0, 1}, Vector2{1, -1}, Vector2{1, 0}, Vector2{1, 1}}; + + for (const auto& outline_offset : outline_offsets) + m_renderer->add_text(position + outline_offset, Color{0.f, 0.f, 0.f, 1.f}, text.data()); + m_renderer->add_text(position, color, text.data()); + } + EntityOverlay::EntityOverlay(const Vector2& top, const Vector2& bottom, + const std::shared_ptr& renderer) + : m_canvas(top, bottom), m_text_cursor_right(m_canvas.top_right_corner), + m_text_cursor_top(m_canvas.top_left_corner), m_renderer(renderer) + { + } +} // namespace omath::hud \ No newline at end of file diff --git a/source/hud/renderer_realizations/imgui_renderer.cpp b/source/hud/renderer_realizations/imgui_renderer.cpp index 525a014..0f61f62 100644 --- a/source/hud/renderer_realizations/imgui_renderer.cpp +++ b/source/hud/renderer_realizations/imgui_renderer.cpp @@ -2,8 +2,52 @@ // Created by orange on 13.03.2026. // #include "omath/hud/renderer_realizations/imgui_renderer.hpp" +#include namespace omath::hud { + ImguiHudRenderer::~ImguiHudRenderer() = default; -} \ No newline at end of file + void ImguiHudRenderer::add_line(const Vector2& line_start, const Vector2& line_end, + const Color& color, const float thickness) + { + ImGui::GetBackgroundDrawList()->AddLine(line_start.to_im_vec2(), line_end.to_im_vec2(), + color.to_im_color(), thickness); + } + + void ImguiHudRenderer::add_polyline(const std::span>& vertexes, const Color& color, + const float thickness) + { + ImGui::GetBackgroundDrawList()->AddPolyline( + reinterpret_cast(vertexes.data()), + static_cast(vertexes.size()), + color.to_im_color(), ImDrawFlags_None, thickness); + } + + void ImguiHudRenderer::add_filled_polyline(const std::span>& vertexes, const Color& color, + const float thickness) + { + ImGui::GetBackgroundDrawList()->AddPolyline( + reinterpret_cast(vertexes.data()), + static_cast(vertexes.size()), + color.to_im_color(), ImDrawFlags_Closed, thickness); + } + + void ImguiHudRenderer::add_rectangle(const Vector2& min, const Vector2& max, const Color& color) + { + ImGui::GetBackgroundDrawList()->AddRect(min.to_im_vec2(), max.to_im_vec2(), color.to_im_color()); + } + + void ImguiHudRenderer::add_filled_rectangle(const Vector2& min, const Vector2& max, + const Color& color) + { + ImGui::GetBackgroundDrawList()->AddRectFilled(min.to_im_vec2(), max.to_im_vec2(), color.to_im_color()); + } + + void ImguiHudRenderer::add_text(const Vector2& position, const Color& color, + const std::string_view& text) + { + ImGui::GetBackgroundDrawList()->AddText(position.to_im_vec2(), color.to_im_color(), text.data(), + text.data() + text.size()); + } +} // namespace omath::hud