C++ Гайд Делаем свое собственное меню на ImGui. Урок 2. Учимся работать с DrawList.

Олдфаг
Статус
Оффлайн
Регистрация
4 Янв 2020
Сообщения
2,995
Реакции[?]
1,275
Поинты[?]
5K
В прошлом уроке, который вышел уже очень давно я пообещал, что мы создадим свое собственное меню, но так как в тех уроках мы не разобрали огромное количество материала, то я предлагаю вам немного подождать и изучить имгуи более углубленно, так что в этом уроке мы поговорим о DrawList'e, рисовании фигур, немного напишем своих собственных функций. Так как нормальных уроков с объяснением дравлиста я не нашел, то постараюсь пояснить понятным языком.
Начнем с самого популярного вопроса, как отрисовать шейпы? На самом деле вопрос максимально глупый, ибо в интернете есть информация, причем в самой верхней строчке поиска по запросу ImGui Rect, но так как вы путей сложных не ищете и вникать в работу библиотеки не собираетесь, мы с вами разберем это здесь и сейчас, ибо в дальнейшем это вам очень пригодится.
Чтобы отрисовать рект используется Drawlist, чтобы задействовать дравлист, есть два способа, это создать указатель на ImGuiWindow, затем через него указывать на дравлист и уже через него рендерить вас шейп, либо использовать функцию:
C++:
ImGui::GetWindowDrawList()->AddRectFilled();
На первый взгляд может показаться, что разницы никакой, но это далеко не так. Если вы будете рендерить шейпы вот таким образом, то когда перенесите меню в чит заметите, что все ваши ректы и другие шейпы при движении меню исчезают, ибо не привязаны к вашему окну. Чтобы рендерить нормальные шейпы через дравлист, как я и сказал создаем указатель на ImGuiWindow и задаем ему значение ImGui::GetCurrentWIndow();
Создаем ImGui::Begin:
C++:
 ImGui::Begin("LamantineSDK", &opened, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar);
//сюда будем вставлять код
 ImGui::End();
Создаем наш указатель на структуру ImGuiWindow:
C++:
 ImGuiWindow* window = ImGui::GetCurrentWindow();
Будьте внимательны, создавайте указатель на окно только внутри тела ImGui::Begin, иначе произойдет, что у вас создастся окно с надписью Debug и вы ничего с ним не сделаете.
Теперь отрисуем рект через дравлист, записываем нашу переменную и указываем на drawlist:
C++:
window->DrawList->AddRectFilled();
Наполним нашу функцию аргументами, у функции адд рект есть максимум 6 аргументов, минимально можно задействовать три из них. Разберем каждый возможный аргумент:
Первые три аргумента самые важные, это позиция нашего ректа и его размер, для примера зададим нулевую позицию и размер 670x50, также укажем цвет, использовать будем ImColor, так как он конвертирует все в RGB:
C++:
window->DrawList->AddRectFilled(ImVec2(), ImVec2(670, 50), ImColor(56, 56, 56));
Вот что у нас получилось:

Поменяем цвет нашего фона, он находится в наших колорстайлах, и добавим логотип, чтобы смотрелось презентабельно.
Надеюсь вы еще помните как это делается. Вот, что у нас уже получается:

Теперь через наш дравлист отрендерим линию, она будет разделять наш логотип и табы к примеру.
Пора бы нам уже разобрать логику позиции при рендере шейпов, чтобы все корректно работало и вы не гадали почему ваш рект или что угодно рисуется где попало, позиция и размер указываются вот так:
C++:
window->DrawList->AddLine(ImVec2(175, 10), ImVec2(175, 10 + 30), ImColor(75, 75, 75), 1.5f);
Аргументы функции вы сами можете посмотреть наведя на нее:
1623906880844.png
Думаю вы поняли логику, чтобы указать позицию и размер нужно указать позицию в первом аргументе, а затем указать размер прибавив к нему позицию, это касается всех элементов кроме круга к примеру. В случае с ректом мы этого не делали так как рисовали от нулевой позиции, т.е ImVec2(тут бы ничего не указывали, значит взяли 0 по x и по y).
Надеюсь суть вы уловили, вот что у нас получилось.

Чтобы отрисовать любую другую фигуру также используйте дравлист, во втором аргументе во всех фигурах кроме круга плюсуйте позицию к размеру, я сам очень долго с этим парился, пока не понял, как это работает.
Чтобы посмотреть какие есть фигуры просто напишите window->Drawlist->"тут визуалка сама подскажет возможные фигуры для отрисовки".
Надеюсь, что я вам помог.
Сразу предвижу глупые вопросы и отвечу на них:
Чтобы скруглить рект поставьте запятую после аргумента с цветом, он третий по счету и запишите туда float, пример:
window->DrawList->AddRectFilled(ImVec2(), ImVec2(670, 50), ImColor(56, 56, 56), 2.5f);
Наше скругление будет 2.5. Чтобы скруглить окно и не делать что-то подобное:
1623907362037.png
Нужно использовать DrawCornerFlags -

Вот что вышло -

Если будут вопросы - задавайте, постараюсь ответить.
 
Последнее редактирование:
Сверху Снизу