mirror of
https://github.com/orange-cpp/omath.git
synced 2026-04-18 19:03:28 +00:00
@@ -2,6 +2,7 @@ add_subdirectory(example_barycentric)
|
|||||||
add_subdirectory(example_glfw3)
|
add_subdirectory(example_glfw3)
|
||||||
add_subdirectory(example_proj_mat_builder)
|
add_subdirectory(example_proj_mat_builder)
|
||||||
add_subdirectory(example_signature_scan)
|
add_subdirectory(example_signature_scan)
|
||||||
|
add_subdirectory(example_hud)
|
||||||
|
|
||||||
if(OMATH_ENABLE_VALGRIND)
|
if(OMATH_ENABLE_VALGRIND)
|
||||||
omath_setup_valgrind(example_projection_matrix_builder)
|
omath_setup_valgrind(example_projection_matrix_builder)
|
||||||
|
|||||||
16
examples/example_hud/CMakeLists.txt
Normal file
16
examples/example_hud/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
project(example_hud)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} main.cpp gui/main_window.cpp gui/main_window.hpp)
|
||||||
|
|
||||||
|
set_target_properties(
|
||||||
|
${PROJECT_NAME}
|
||||||
|
PROPERTIES CXX_STANDARD 23
|
||||||
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}"
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}")
|
||||||
|
|
||||||
|
find_package(OpenGL)
|
||||||
|
find_package(GLEW REQUIRED)
|
||||||
|
find_package(glfw3 CONFIG REQUIRED)
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE glfw imgui::imgui omath::omath OpenGL::GL)
|
||||||
110
examples/example_hud/gui/main_window.cpp
Normal file
110
examples/example_hud/gui/main_window.cpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
//
|
||||||
|
// Created by Orange on 11/11/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "main_window.hpp"
|
||||||
|
#include "omath/hud/renderer_realizations/imgui_renderer.hpp"
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_impl_glfw.h>
|
||||||
|
#include <imgui_impl_opengl3.h>
|
||||||
|
#include <omath/hud/entity_overlay.hpp>
|
||||||
|
|
||||||
|
namespace imgui_desktop::gui
|
||||||
|
{
|
||||||
|
bool MainWindow::m_canMoveWindow = false;
|
||||||
|
|
||||||
|
MainWindow::MainWindow(const std::string_view& caption, int width, int height)
|
||||||
|
{
|
||||||
|
if (!glfwInit())
|
||||||
|
std::exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, true);
|
||||||
|
m_window = glfwCreateWindow(width, height, caption.data(), nullptr, nullptr);
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(m_window);
|
||||||
|
|
||||||
|
ImGui::CreateContext();
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
|
ImGui::GetStyle().Colors[ImGuiCol_WindowBg] = {0.f, 0.f, 0.f, 0.f};
|
||||||
|
|
||||||
|
ImGui::GetStyle().AntiAliasedLines = false;
|
||||||
|
ImGui::GetStyle().AntiAliasedFill = false;
|
||||||
|
|
||||||
|
ImGui_ImplGlfw_InitForOpenGL(m_window, true);
|
||||||
|
ImGui_ImplOpenGL3_Init("#version 130");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::Run()
|
||||||
|
{
|
||||||
|
omath::Color box_color = {0.f, 0.f, 0.f, 1.f};
|
||||||
|
omath::Color box_fill = {0.f, 0.f, 0.f, 0.f};
|
||||||
|
omath::Color bar_color = {0.f, 1.f, 0.f, 1.f};
|
||||||
|
omath::Color bar_bg_color = {0.f, 0.f, 0.f, 0.0f};
|
||||||
|
omath::Color bar_outline_color = {0.f, 0.f, 0.f, 1.f};
|
||||||
|
float bar_width = 3.f;
|
||||||
|
float bar_value = 1.f;
|
||||||
|
|
||||||
|
while (!glfwWindowShouldClose(m_window) && m_opened)
|
||||||
|
{
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
|
ImGui_ImplGlfw_NewFrame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
ImGui::GetBackgroundDrawList()->AddRectFilled({}, ImGui::GetMainViewport()->Size, ImColor(40, 40, 40, 200));
|
||||||
|
|
||||||
|
ImGui::Begin("OHUD Showcase", &m_opened,
|
||||||
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDecoration);
|
||||||
|
{
|
||||||
|
ImGui::SetWindowPos({});
|
||||||
|
ImGui::SetWindowSize(ImGui::GetMainViewport()->Size);
|
||||||
|
|
||||||
|
ImGui::ColorEdit4("Box", reinterpret_cast<float*>(&box_color), ImGuiColorEditFlags_NoInputs);
|
||||||
|
ImGui::ColorEdit4("Box fill", reinterpret_cast<float*>(&box_fill), ImGuiColorEditFlags_NoInputs);
|
||||||
|
ImGui::ColorEdit4("Bar", reinterpret_cast<float*>(&bar_color), ImGuiColorEditFlags_NoInputs);
|
||||||
|
ImGui::ColorEdit4("Bar Background", reinterpret_cast<float*>(&bar_bg_color),
|
||||||
|
ImGuiColorEditFlags_NoInputs);
|
||||||
|
ImGui::ColorEdit4("Bar Outline", reinterpret_cast<float*>(&bar_outline_color),
|
||||||
|
ImGuiColorEditFlags_NoInputs);
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(100.f);
|
||||||
|
ImGui::SliderFloat("Bar Width", &bar_width, 1.f, 20.f);
|
||||||
|
ImGui::SliderFloat("Bar Value", &bar_value, 0.f, 1.f);
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
omath::hud::EntityOverlay ent({400.f, 100.f}, {400.f, 400.f}, std::make_shared<omath::hud::ImguiHudRenderer>());
|
||||||
|
|
||||||
|
ent.add_2d_box(box_color, box_fill, 1.f);
|
||||||
|
ent.add_cornered_2d_box(omath::Color::from_rgba(255, 0, 255, 255), box_fill);
|
||||||
|
ent.add_right_bar(bar_color, bar_outline_color, bar_bg_color, bar_width, bar_value);
|
||||||
|
ent.add_left_bar(bar_color, bar_outline_color, bar_bg_color, bar_width, bar_value);
|
||||||
|
ent.add_top_bar(bar_color, bar_outline_color, bar_bg_color, bar_width, bar_value);
|
||||||
|
ent.add_right_label({0.f, 1.f, 0.f, 1.f}, 3, true, "Health: {}/100", 100);
|
||||||
|
ent.add_right_label({1.f, 0.f, 0.f, 1.f}, 3, true, "Shield: {}/125", 125);
|
||||||
|
ent.add_right_label({1.f, 0.f, 1.f, 1.f}, 3, true, "*LOCKED*");
|
||||||
|
|
||||||
|
ent.add_top_label(omath::Color::from_rgba(255, 255, 0, 255), 3, true, "*SCOPED*");
|
||||||
|
ent.add_top_label(omath::Color::from_rgba(255, 0, 0, 255), 3, true, "*BLEEDING*");
|
||||||
|
ent.add_snap_line(omath::Vector2<float>{400, 600}, omath::Color::from_rgba(255, 0, 0, 255), 2.f);
|
||||||
|
ImGui::Render();
|
||||||
|
|
||||||
|
int display_w, display_h;
|
||||||
|
|
||||||
|
glfwGetFramebufferSize(m_window, &display_w, &display_h);
|
||||||
|
glViewport(0, 0, display_w, display_h);
|
||||||
|
|
||||||
|
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
glfwSwapBuffers(m_window);
|
||||||
|
}
|
||||||
|
glfwDestroyWindow(m_window);
|
||||||
|
}
|
||||||
|
} // namespace imgui_desktop::gui
|
||||||
|
// imgui_desktop
|
||||||
28
examples/example_hud/gui/main_window.hpp
Normal file
28
examples/example_hud/gui/main_window.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Created by Vlad on 6/17/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Created by Orange on 11/11/2024.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
struct GLFWwindow;
|
||||||
|
|
||||||
|
namespace imgui_desktop::gui
|
||||||
|
{
|
||||||
|
class MainWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MainWindow(const std::string_view &caption, int width, int height);
|
||||||
|
|
||||||
|
void Run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLFWwindow* m_window;
|
||||||
|
static bool m_canMoveWindow;
|
||||||
|
bool m_opened = true;
|
||||||
|
};
|
||||||
|
} // gui
|
||||||
|
// imgui_desktop
|
||||||
8
examples/example_hud/main.cpp
Normal file
8
examples/example_hud/main.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
//
|
||||||
|
// Created by orange on 13.03.2026.
|
||||||
|
//
|
||||||
|
#include "gui/main_window.hpp"
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
imgui_desktop::gui::MainWindow("omath::hud", 800, 600).Run();
|
||||||
|
}
|
||||||
23
include/omath/hud/canvas_box.hpp
Normal file
23
include/omath/hud/canvas_box.hpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Created by orange on 13.03.2026.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include "omath/linear_algebra/vector2.hpp"
|
||||||
|
#include <array>
|
||||||
|
namespace omath::hud
|
||||||
|
{
|
||||||
|
class CanvasBox final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CanvasBox(Vector2<float> top, Vector2<float> bottom, float ratio = 4.f);
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
std::array<Vector2<float>, 4> as_array() const;
|
||||||
|
|
||||||
|
Vector2<float> top_left_corner;
|
||||||
|
Vector2<float> top_right_corner;
|
||||||
|
|
||||||
|
Vector2<float> bottom_left_corner;
|
||||||
|
Vector2<float> bottom_right_corner;
|
||||||
|
};
|
||||||
|
} // namespace omath::hud
|
||||||
66
include/omath/hud/entity_overlay.hpp
Normal file
66
include/omath/hud/entity_overlay.hpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// Created by orange on 13.03.2026.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include "canvas_box.hpp"
|
||||||
|
#include "hud_renderer_interface.hpp"
|
||||||
|
#include "omath/linear_algebra/vector2.hpp"
|
||||||
|
#include "omath/utility/color.hpp"
|
||||||
|
#include <memory>
|
||||||
|
#include <string_view>
|
||||||
|
namespace omath::hud
|
||||||
|
{
|
||||||
|
class EntityOverlay final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EntityOverlay(const Vector2<float>& top, const Vector2<float>& bottom,
|
||||||
|
const std::shared_ptr<HudRendererInterface>& renderer);
|
||||||
|
|
||||||
|
void 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;
|
||||||
|
|
||||||
|
void add_cornered_2d_box(const Color& box_color, const Color& fill_color = Color{0.f, 0.f, 0.f, 0.f},
|
||||||
|
float corner_ratio_len = 0.2f, float thickness = 1.f) const;
|
||||||
|
|
||||||
|
void add_right_bar(const Color& color, const Color& outline_color, const Color& bg_color, float width,
|
||||||
|
float ratio, float offset = 5.f);
|
||||||
|
|
||||||
|
void add_left_bar(const Color& color, const Color& outline_color, const Color& bg_color, float width,
|
||||||
|
float ratio, float offset = 5.f) const;
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void add_right_label(const Color& color, const float offset, const bool outlined,
|
||||||
|
std::format_string<Args...> fmt, Args&&... args)
|
||||||
|
{
|
||||||
|
const std::string label = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||||
|
|
||||||
|
add_right_label(color, offset, outlined, std::string_view{label});
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_right_label(const Color& color, float offset, bool outlined, const std::string_view& text);
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void add_top_label(const Color& color, const float offset, const bool outlined, std::format_string<Args...> fmt,
|
||||||
|
Args&&... args)
|
||||||
|
{
|
||||||
|
const std::string label = std::vformat(fmt.get(), std::make_format_args(args...));
|
||||||
|
|
||||||
|
add_top_label(color, offset, outlined, std::string_view{label});
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_top_label(const Color& color, float offset, bool outlined, std::string_view text);
|
||||||
|
|
||||||
|
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 Vector2<float>& start_pos, const Color& color, float width);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void draw_outlined_text(const Vector2<float>& position, const Color& color,
|
||||||
|
const std::string_view& text);
|
||||||
|
CanvasBox m_canvas;
|
||||||
|
Vector2<float> m_text_cursor_right;
|
||||||
|
Vector2<float> m_text_cursor_top;
|
||||||
|
std::shared_ptr<HudRendererInterface> m_renderer;
|
||||||
|
};
|
||||||
|
} // namespace omath::hud
|
||||||
28
include/omath/hud/hud_renderer_interface.hpp
Normal file
28
include/omath/hud/hud_renderer_interface.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Created by orange on 13.03.2026.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include "omath/linear_algebra/vector2.hpp"
|
||||||
|
#include "omath/utility/color.hpp"
|
||||||
|
#include <span>
|
||||||
|
|
||||||
|
namespace omath::hud
|
||||||
|
{
|
||||||
|
class HudRendererInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~HudRendererInterface() = default;
|
||||||
|
virtual void add_line(const Vector2<float>& line_start, const Vector2<float>& line_end, const Color& color,
|
||||||
|
float thickness) = 0;
|
||||||
|
|
||||||
|
virtual void add_polyline(const std::span<const Vector2<float>>& vertexes, const Color& color, float thickness) = 0;
|
||||||
|
|
||||||
|
virtual void add_filled_polyline(const std::span<const Vector2<float>>& vertexes, const Color& color, float thickness) = 0;
|
||||||
|
|
||||||
|
virtual void add_rectangle(const Vector2<float>& min, const Vector2<float>& max, const Color& color) = 0;
|
||||||
|
|
||||||
|
virtual void add_filled_rectangle(const Vector2<float>& min, const Vector2<float>& max, const Color& color) = 0;
|
||||||
|
|
||||||
|
virtual void add_text(const Vector2<float>& position, const Color& color, const std::string_view& text) = 0;
|
||||||
|
};
|
||||||
|
} // namespace omath::hud
|
||||||
20
include/omath/hud/renderer_realizations/imgui_renderer.hpp
Normal file
20
include/omath/hud/renderer_realizations/imgui_renderer.hpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Created by orange on 13.03.2026.
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
#include <omath/hud/hud_renderer_interface.hpp>
|
||||||
|
namespace omath::hud
|
||||||
|
{
|
||||||
|
class ImguiHudRenderer final : public HudRendererInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~ImguiHudRenderer() override;
|
||||||
|
void add_line(const Vector2<float>& line_start, const Vector2<float>& line_end, const Color& color,
|
||||||
|
float thickness) override;
|
||||||
|
void add_polyline(const std::span<const Vector2<float>>& vertexes, const Color& color, float thickness) override;
|
||||||
|
void add_filled_polyline(const std::span<const Vector2<float>>& vertexes, const Color& color, float thickness) override;
|
||||||
|
void add_rectangle(const Vector2<float>& min, const Vector2<float>& max, const Color& color) override;
|
||||||
|
void add_filled_rectangle(const Vector2<float>& min, const Vector2<float>& max, const Color& color) override;
|
||||||
|
void add_text(const Vector2<float>& position, const Color& color, const std::string_view& text) override;
|
||||||
|
};
|
||||||
|
}
|
||||||
27
source/hud/canvas_box.cpp
Normal file
27
source/hud/canvas_box.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// Created by orange on 13.03.2026.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by Vlad on 6/17/2025.
|
||||||
|
//
|
||||||
|
#include "omath/hud/canvas_box.hpp"
|
||||||
|
|
||||||
|
namespace omath::hud
|
||||||
|
{
|
||||||
|
|
||||||
|
CanvasBox::CanvasBox(const Vector2<float> top, Vector2<float> bottom, const float ratio)
|
||||||
|
{
|
||||||
|
bottom.x = top.x;
|
||||||
|
const auto height = std::abs(top.y - bottom.y);
|
||||||
|
|
||||||
|
top_left_corner = top - Vector2<float>{height / ratio, 0};
|
||||||
|
top_right_corner = top + Vector2<float>{height / ratio, 0};
|
||||||
|
|
||||||
|
bottom_left_corner = bottom - Vector2<float>{height / ratio, 0};
|
||||||
|
bottom_right_corner = bottom + Vector2<float>{height / ratio, 0};
|
||||||
|
}
|
||||||
|
std::array<Vector2<float>, 4> CanvasBox::as_array() const
|
||||||
|
{
|
||||||
|
return {top_left_corner, top_right_corner, bottom_right_corner, bottom_left_corner};
|
||||||
|
}
|
||||||
|
} // namespace ohud
|
||||||
138
source/hud/entity_overlay.cpp
Normal file
138
source/hud/entity_overlay.cpp
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
//
|
||||||
|
// Created by orange on 13.03.2026.
|
||||||
|
//
|
||||||
|
#include "omath/hud/entity_overlay.hpp"
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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<float>{corner_line_length, 0.f}, box_color, thickness);
|
||||||
|
|
||||||
|
m_renderer->add_line(m_canvas.top_left_corner,
|
||||||
|
m_canvas.top_left_corner + Vector2<float>{0.f, corner_line_length}, box_color, thickness);
|
||||||
|
|
||||||
|
m_renderer->add_line(m_canvas.bottom_left_corner,
|
||||||
|
m_canvas.bottom_left_corner - Vector2<float>{0.f, corner_line_length}, box_color,
|
||||||
|
thickness);
|
||||||
|
|
||||||
|
m_renderer->add_line(m_canvas.bottom_left_corner,
|
||||||
|
m_canvas.bottom_left_corner + Vector2<float>{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<float>{corner_line_length, 0.f}, box_color, thickness);
|
||||||
|
|
||||||
|
m_renderer->add_line(m_canvas.top_right_corner,
|
||||||
|
m_canvas.top_right_corner + Vector2<float>{0.f, corner_line_length}, box_color, thickness);
|
||||||
|
|
||||||
|
m_renderer->add_line(m_canvas.bottom_right_corner,
|
||||||
|
m_canvas.bottom_right_corner - Vector2<float>{0.f, corner_line_length}, box_color,
|
||||||
|
thickness);
|
||||||
|
|
||||||
|
m_renderer->add_line(m_canvas.bottom_right_corner,
|
||||||
|
m_canvas.bottom_right_corner - Vector2<float>{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<float>{offset, 0.f};
|
||||||
|
m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2<float>(width, -max_bar_height), bg_color);
|
||||||
|
|
||||||
|
m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2<float>(width, -max_bar_height * ratio), color);
|
||||||
|
m_renderer->add_rectangle(bar_start - Vector2<float>(1.f, 0.f),
|
||||||
|
bar_start + Vector2<float>(width, -max_bar_height), outline_color);
|
||||||
|
|
||||||
|
m_text_cursor_right.x += offset + width;
|
||||||
|
}
|
||||||
|
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<float>{-(offset + width), 0.f};
|
||||||
|
m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2<float>(width, -max_bar_height), bg_color);
|
||||||
|
|
||||||
|
m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2<float>(width, -max_bar_height * ratio), color);
|
||||||
|
m_renderer->add_rectangle(bar_start - Vector2<float>(1.f, 0.f),
|
||||||
|
bar_start + Vector2<float>(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<float>{offset, 0.f}, color, text);
|
||||||
|
else
|
||||||
|
m_renderer->add_text(m_text_cursor_right + Vector2<float>{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<float>{0.f, -offset}, color, text);
|
||||||
|
else
|
||||||
|
m_renderer->add_text(m_text_cursor_top + Vector2<float>{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<float>{0.f, offset};
|
||||||
|
m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2<float>(max_bar_width, -height), bg_color);
|
||||||
|
|
||||||
|
m_renderer->add_filled_rectangle(bar_start, bar_start + Vector2<float>(max_bar_width * ratio, -height), color);
|
||||||
|
m_renderer->add_rectangle(bar_start, bar_start + Vector2<float>(max_bar_width, -height), outline_color);
|
||||||
|
|
||||||
|
m_text_cursor_top.y -= offset + height;
|
||||||
|
}
|
||||||
|
void EntityOverlay::add_snap_line(const Vector2<float>& start_pos, const Color& color, const float width)
|
||||||
|
{
|
||||||
|
const Vector2<float> line_end =
|
||||||
|
m_canvas.bottom_left_corner
|
||||||
|
+ Vector2<float>{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<float>& position, const Color& color,
|
||||||
|
const std::string_view& text)
|
||||||
|
{
|
||||||
|
static constexpr std::array outline_offsets = {
|
||||||
|
Vector2<float>{-1, -1}, Vector2<float>{-1, 0}, Vector2<float>{-1, 1}, Vector2<float>{0, -1},
|
||||||
|
Vector2<float>{0, 1}, Vector2<float>{1, -1}, Vector2<float>{1, 0}, Vector2<float>{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<float>& top, const Vector2<float>& bottom,
|
||||||
|
const std::shared_ptr<HudRendererInterface>& 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
|
||||||
53
source/hud/renderer_realizations/imgui_renderer.cpp
Normal file
53
source/hud/renderer_realizations/imgui_renderer.cpp
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// Created by orange on 13.03.2026.
|
||||||
|
//
|
||||||
|
#include "omath/hud/renderer_realizations/imgui_renderer.hpp"
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace omath::hud
|
||||||
|
{
|
||||||
|
ImguiHudRenderer::~ImguiHudRenderer() = default;
|
||||||
|
|
||||||
|
void ImguiHudRenderer::add_line(const Vector2<float>& line_start, const Vector2<float>& 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<const Vector2<float>>& vertexes, const Color& color,
|
||||||
|
const float thickness)
|
||||||
|
{
|
||||||
|
ImGui::GetBackgroundDrawList()->AddPolyline(
|
||||||
|
reinterpret_cast<const ImVec2*>(vertexes.data()),
|
||||||
|
static_cast<int>(vertexes.size()),
|
||||||
|
color.to_im_color(), ImDrawFlags_None, thickness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImguiHudRenderer::add_filled_polyline(const std::span<const Vector2<float>>& vertexes, const Color& color,
|
||||||
|
const float thickness)
|
||||||
|
{
|
||||||
|
ImGui::GetBackgroundDrawList()->AddPolyline(
|
||||||
|
reinterpret_cast<const ImVec2*>(vertexes.data()),
|
||||||
|
static_cast<int>(vertexes.size()),
|
||||||
|
color.to_im_color(), ImDrawFlags_Closed, thickness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImguiHudRenderer::add_rectangle(const Vector2<float>& min, const Vector2<float>& 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<float>& min, const Vector2<float>& 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<float>& 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
|
||||||
@@ -31,7 +31,11 @@
|
|||||||
"dependencies": [
|
"dependencies": [
|
||||||
"glfw3",
|
"glfw3",
|
||||||
"glew",
|
"glew",
|
||||||
"opengl"
|
"opengl",
|
||||||
|
{
|
||||||
|
"name": "imgui",
|
||||||
|
"features": ["glfw-binding", "opengl3-binding"]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"imgui": {
|
"imgui": {
|
||||||
|
|||||||
Reference in New Issue
Block a user