Гайд Работаем с DrawList в mimgui

chapo

🫡 В армии с 17.10.2023. В ЛС НЕ ОТВЕЧАЮ
Автор темы
Друг
8,763
11,198
Привет, в этой теме покажу как рисовать примитивы через DrawList в mimgui.

С помощью DrawList вы сможете выводить на экран такие штуки как:
  • круг
  • заполненный круг
  • квадрат
  • заполненный квадрат
  • квадрат заполненный градиентом
  • линии и т.д.
1644749108296.png


Начало работы
Для начала работы с DrawList нам необходимо вызвать следующую функцию:
Lua:
local dl = imgui.GetWindowDrawList()
Теперь нам нужно перевести координаты "курсора" ImGui окна в экранные и записать их в переменную (в моем случае переменная "p"), для этого используем:
Lua:
local p = imgui.GetCursorScreenPos()
(!) Если вы хотите изменить положение элемента, то функцию SetCursorPos нужно вызывать до GetCursorScreenPos, например:
Lua:
imgui.SetCursorPos(imgui.ImVec2(5, 35))
local p = imgui.GetCursorScreenPos()

Примеры:
Lua:
dl:AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f);
dl:AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ~0, float thickness = 1.0f);   // a: upper-left, b: lower-right, rounding_corners_flags: 4-bits corresponding to which corner to round
dl:AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ~0);                     // a: upper-left, b: lower-right
dl:AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left);
dl:AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f);
dl:AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col);
dl:AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness = 1.0f);
dl:AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col);
dl:AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f);
dl:AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
dl:AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
dl:AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
dl:AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF);
dl:AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF);
dl:AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased);
dl:AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased);
dl:AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0);
Пример отрисовки квадратов:
Lua:
--==[ БЕЗ ЗАЛИВКИ ]==--
imgui.SetCursorPos(imgui.ImVec2(5, 85))
local p = imgui.GetCursorScreenPos()
--[[
    AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ~0, float thickness = 1.0f)
    Параметры:
    const ImVec2& a - левый верхний угол
    const ImVec2& b - правый нижний угол
    ImU32 col, - цвет в формате U32 (0xAABBGGRR)
    float rounding - радиус закругления
    int rounding_corners_flags - закругляемые углы
    float thickness - толщина
]]
dl:AddRect(p, imgui.ImVec2(p.x + 30, p.y + 30), 0xFF0000ff)

--==[ C ЗАЛИВКОЙ ]==--
imgui.SetCursorPos(imgui.ImVec2(5 + 35, 85))
local p = imgui.GetCursorScreenPos()
dl:AddRectFilled(p, imgui.ImVec2(p.x + 30, p.y + 30), 0xFF0000ff) -- функция принимает такие же аргументы как и AddRect (выше)

Результат:
1644750066784.png
Lua:
--[[
    AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f);
    Параметры:
    const ImVec2& centre -- положение (центр)
    float radius - радиус
    ImU32 col - цвет в формате U32
    int num_segments, - кол-во полигонов (углов у круга (че блять))
    float thickness - толщина обводки
]]

--==[ БЕЗ ЗАЛИВКИ ]==--
imgui.SetCursorPos(imgui.ImVec2(20, 50))
local p = imgui.GetCursorScreenPos()
dl:AddCircle(p, 15, 0xFF0000ff)

--==[ С ЗАЛИВКОЙ ]==--
imgui.SetCursorPos(imgui.ImVec2(20 + 35, 50))
local p = imgui.GetCursorScreenPos()
dl:AddCircleFilled(p, 15, 0xFF0000ff) -- от AddCircle отличается только отсутствием 5 аргумента (толщины)

Результат:
1644750319302.png

Отрисовка элементов вне окна:
так же в mimgui можно рисовать вне окна, для этого заменяем imgui.GetWindowDrawList() на imgui.GetBackgroundDrawList()
Пример:
Lua:
local backgroundDraw = imgui.OnFrame(
    function() return true end,
    function(self)
        self.HideCursor = true
        local dl = imgui.GetBackgroundDrawList()
        dl:AddRectFilled(imgui.ImVec2(800, 500), imgui.ImVec2(1000, 600), 0xFF0000ff, 20, 1 + 8)
        --[[
            в качестве положения в переменной Vec2 нужно использовать координаты экрана, вот более простой пример:
                local pos = imgui.ImVec2(800, 500) -- 800 - положение по X, 500 - положение по Y
                local size = imgui.ImVec2(200, 100) -- 200 - размер по X, 100 - размер по Y
                dl:AddRectFilled(pos, imgui.ImVec2(pos.x + size.x, pos.y + size.y), 0xFF0000ff, 20, 1 + 8)
        ]]
    end
)

Результат:
1644750628835.png


(!) Что бы получить цвет формата U32 из Vec4 можно использовать следующие функции:
  • ImGui - imgui.GetColorU32(vec_color) -- вернет 0xFF0000FF
  • MImGui - imgui.GetColorU32Vec4(vec_color) -- вернет 0xFF0000FF
  • Пример:
    Lua:
    local vec_color = imgui.ImVec4(1, 0, 0, 1)
    print(imgui.GetColorU32Vec4(vec_color))
    -->> 0xFF0000FF
 

Hatiko

Известный
Проверенный
1,472
611
Так был уже гайд, при чем недавно был создан. Что этот, что тот урезанный, особо толку нету инфы, кроме как круг с квадратом нарисовать.
 

Hatiko

Известный
Проверенный
1,472
611
drawlist в мимгуе разве как-то отличается от дравлиста в обычном имгуе?
В основном одинаково. давно ещё ковырялся, вроде бы как новые методы есть несколько штук , но они не совсем для "примитивов" нужны,