///
-
Автор темы
- #1
Привет ЛЮДЯМ И Мастерам искуссно-пастерской деятельносьти! Автор - XVII a.k.a _dev0x
Сегодня поведаю как сделать:
- Круглое меню для вашей очередной пасточки!
___________________________________________________________________________________________________________________
Нам понадобится:
- Мозг
- Руки
- Visual Studio
- Знание C++ (хотя бы Базовое)
- Мой гайд :3
- ImGui (Скачать можно тут:
Пожалуйста, авторизуйтесь для просмотра ссылки.
- НЕ РЕКЛАМА)
И так приступим
Думаю как создавать проект, объяснять не нужно) Если нужно пишите в ВК помогу)
1. Создаём проект, далее в нём файлик где это будет хранится
Код:
]static float RADIUS_MIN = 0.f;
static float RADIUS_MAX = 0.f;
static float RADIUS_INTERACT_MIN = 30.0f;
int PiePopupSelectMenu(const ImVec2& center, const char* popup_id, const char** items, int items_count, int* p_selected)
{
int ret = -1;
ImGui::SetNextWindowPos({ -100, -100 });
static bool p_open = true;
if (ImGui::Begin(popup_id), &p_open)
{
const ImVec2 drag_delta = ImVec2(ImGui::GetIO().MousePos.x - center.x, ImGui::GetIO().MousePos.y - center.y);
const float drag_dist2 = drag_delta.x*drag_delta.x + drag_delta.y*drag_delta.y;
const ImGuiStyle& style = ImGui::GetStyle();
const int ITEMS_MIN = 5;
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->PushClipRectFullScreen();
draw_list->PathArcTo(center, (RADIUS_MIN + RADIUS_MAX)*0.45f, 0.f, IM_PI*2.0f*0.99f, 32);
draw_list->PathStroke(ImColor(0.f, 0.f, 0.f), true, RADIUS_MAX - RADIUS_MIN);
const float item_arc_span = 2 * IM_PI / ImMax(ITEMS_MIN, items_count);
float drag_angle = atan2f(drag_delta.y, drag_delta.x);
if (drag_angle < -0.5f * item_arc_span)
drag_angle += 2.0f * IM_PI;
int item_hovered = -1;
for (int item_n = 0; item_n < items_count; item_n++)
{
const char* item_label = items[item_n];
const float item_ang_min = item_arc_span * (item_n + 0.02f) - item_arc_span * 0.50f;
const float item_ang_max = item_arc_span * (item_n + 0.98f) - item_arc_span * 0.50f;
bool hovered = false;
if (drag_dist2 >= RADIUS_INTERACT_MIN * RADIUS_INTERACT_MIN && drag_dist2 < RADIUS_MAX*RADIUS_MAX)
{
if (drag_angle >= item_ang_min && drag_angle < item_ang_max)
hovered = true;
}
bool selected = p_selected && (*p_selected == item_n);
int arc_segments = (int)(32 * item_arc_span / (2 * IM_PI));
draw_list->PathArcTo(center, RADIUS_MAX - style.ItemInnerSpacing.x /*- 1.0f*/ , item_ang_min, item_ang_max, arc_segments);
draw_list->PathArcTo(center, RADIUS_MIN /*- 7.f*/+ style.ItemInnerSpacing.x , item_ang_max, item_ang_min, arc_segments);
draw_list->PathFill(
hovered ? ImColor((ImGui::GetColorU32(ImGuiCol_FirstTabColorHovered))) : selected ? ImColor((ImGui::GetColorU32(ImGuiCol_FirstTabColorActive))) : ImColor((ImGui::GetColorU32(ImGuiCol_FirstTabColor))),
hovered ? ImColor((ImGui::GetColorU32(ImGuiCol_SecondTabColorHovered))) : selected ? ImColor((ImGui::GetColorU32(ImGuiCol_SecondTabColorActive))) : ImColor((ImGui::GetColorU32(ImGuiCol_SecondTabColor))));
ImVec2 text_size = ImGui::GetWindowFont()->CalcTextSizeA(ImGui::GetWindowFontSize(), FLT_MAX, 0.0f, item_label);
ImVec2 text_pos = ImVec2(
center.x + cosf((item_ang_min + item_ang_max) * 0.5f) * (RADIUS_MIN + RADIUS_MAX) * 0.5f - text_size.x * 0.5f,
center.y + sinf((item_ang_min + item_ang_max) * 0.5f) * (RADIUS_MIN + RADIUS_MAX) * 0.5f - text_size.y * 0.5f);
draw_list->AddText(text_pos, ImColor(255, 255, 255), item_label);
if (hovered)
item_hovered = item_n;
}
draw_list->PopClipRect();
if (drag_dist2 >= RADIUS_INTERACT_MIN * RADIUS_INTERACT_MIN && drag_dist2 < RADIUS_MAX*RADIUS_MAX)
{
if (ImGui::IsMouseReleased(0))
{
ImGui::CloseCurrentPopup();
ret = item_hovered;
if (p_selected)
*p_selected = item_hovered;
}
}
ImGui::End();
}
return ret;
}
2. Далее, в EndScene или где вы меню будете рисовать пишем это:
Код:
if (RADIUS_MAX < 120.f)
RADIUS_MAX += 7.f;
if (RADIUS_MAX == 120.f && RADIUS_MIN < 35.f)
RADIUS_MIN += 5.f;
static const char* test_data = "Menu";
const char* items[] = { u8"Rage", u8"Trigger", u8"Visual", u8"Misc", u8"Skins",u8"Legit" };
int items_count = sizeof(items) / sizeof(*items);
static int selected = -1;
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
PiePopupSelectMenu(ImVec2(200, 200), "##piepopup", items, items_count, &selected);
ImGui::PopStyleColor();
if (selected > -1)
{
ImGui::Begin(charenc("##open_"), &MenuSettings.Menu.Opened, ImVec2(597, 340), 0.9f, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoFocusOnAppearing);
{
ImVec2 lPos = ImGui::GetCursorPos();
ImGuiContext* io = ImGui::GetCurrentContext();
ImGuiStyle& style = ImGui::GetStyle();
ImGui::BeginChild(charenc("##Menu-Child"), ImVec2(0, 0), false);
{
if (selected == 0)
RageTab();
if (selected == 1)
TrigTab();
if (selected == 2)
VisTab();
if (selected == 3)
MiscTab();
if (selected == 4)
SkinTab();
if (selected == 5)
LegitTab();
}
ImGui::EndChild();
}
ImGui::End(); //End main window
}
}
else
{
RADIUS_MIN = 0.f;
RADIUS_MAX = 0.f;
}
3. Дальше используем ImGui, самое веселое настало - это градиент. Мучаемся с ImGui)
Идём в imgui_draw.cpp и заменяем этим кодом:
Идём в imgui_draw.cpp и заменяем этим кодом:
Код:
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased,ImU32 col2)
{
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
const ImVec2 uv2 = GImGui->FontTexUvWhitePixel;
anti_aliased &= GImGui->Style.AntiAliasedShapes;
if (anti_aliased)
{
// Anti-aliased Fill
const float AA_SIZE = 1.0f;
const ImU32 col_trans = /*ImU32(ImGui::GetColorU32(ImGuiCol_FirstTabColor)) */col & IM_COL32(255, 255, 255, 0);
const ImU32 col_trans2 =/* ImU32(ImGui::GetColorU32(ImGuiCol_SecondTabColor))*/ col2 & IM_COL32(255, 255, 255, 0);
const int idx_count = (points_count-2)*3 + points_count*6;
const int vtx_count = (points_count*2);
PrimReserve(idx_count, vtx_count);
// Add indexes for fill
unsigned int vtx_inner_idx = _VtxCurrentIdx;
unsigned int vtx_outer_idx = _VtxCurrentIdx+1;
for (int i = 2; i < points_count; i++)
{
_IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx+((i-1)<<1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx+(i<<1));
_IdxWritePtr += 3;
}
// Compute normals
ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2));
for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++)
{
const ImVec2& p0 = points[i0];
const ImVec2& p1 = points[i1];
ImVec2 diff = p1 - p0;
diff *= ImInvLength(diff, 1.0f);
temp_normals[i0].x = diff.y;
temp_normals[i0].y = -diff.x;
}
for (int i0 = (points_count / 2) - 1, i1 = 0; i1 < points_count / 2; i0 = i1++)
{
// Average normals
const ImVec2& n0 = temp_normals[i0];
const ImVec2& n1 = temp_normals[i1];
ImVec2 dm = (n0 + n1) * 0.5f;
float dmr2 = dm.x*dm.x + dm.y*dm.y;
if (dmr2 > 0.000001f)
{
float scale = 1.0f / dmr2;
if (scale > 100.0f) scale = 100.0f;
dm *= scale;
}
dm *= AA_SIZE * 0.5f;
// Add indexes for fringes
_IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1));
_IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1));
_IdxWritePtr += 6;
_VtxWritePtr[0].pos = (points[i1] - dm);
_VtxWritePtr[0].uv = uv;
_VtxWritePtr[0].col = col;
_VtxWritePtr[1].pos = (points[i1] + dm);
_VtxWritePtr[1].uv = uv;
_VtxWritePtr[1].col = col_trans;
_VtxWritePtr += 2;
}
for (int i0 = points_count - 1, i1 = (points_count / 2); i1 < points_count; i0 = i1++)
{
// Average normals
const ImVec2& n0 = temp_normals[i0];
const ImVec2& n1 = temp_normals[i1];
ImVec2 dm = (n0 + n1) * 0.5f;
float dmr2 = dm.x*dm.x + dm.y*dm.y;
if (dmr2 > 0.000001f)
{
float scale = 1.0f / dmr2;
if (scale > 100.0f) scale = 100.0f;
dm *= scale;
}
dm *= AA_SIZE * 0.5f;
// Add indexes for fringes
_IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1));
_IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1));
_IdxWritePtr += 6;
_VtxWritePtr[0].pos = (points[i1] - dm);
_VtxWritePtr[0].uv = uv2;
_VtxWritePtr[0].col = col2;
_VtxWritePtr[1].pos = (points[i1] - dm);
_VtxWritePtr[1].uv = uv2;
_VtxWritePtr[1].col = col_trans2;
_VtxWritePtr += 2;
}
_VtxCurrentIdx += (ImDrawIdx)vtx_count;
}
else
{
// Non Anti-aliased Fill
const int idx_count = (points_count-2)*3;
const int vtx_count = points_count;
PrimReserve(idx_count, vtx_count);
for (int i = 0; i < vtx_count; i++)
{
_VtxWritePtr[0].pos = points[i];
_VtxWritePtr[0].uv = uv;
_VtxWritePtr[0].col = col;
_VtxWritePtr++;
}
for (int i = 2; i < points_count; i++)
{
_IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+i-1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+i);
_IdxWritePtr += 3;
}
_VtxCurrentIdx += (ImDrawIdx)vtx_count;
}
}
4. Идём в файлик imgui.h и заменяем вот на эту строчку:
Код:
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased,ImU32 col2 = 0xFFFFFFFF);
Это тоже:
Код:
inline void PathClear() { _Path.resize(0); }
inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); }
inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); }
inline void PathFill(ImU32 col,ImU32 col2 = 0xFFFFFFFF) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true , col2); PathClear(); }
inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); }
IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10);
IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0);
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners_flags = ~0); // rounding_corners_flags: 4-bits corresponding to which corner to round
5. Дальше, добавляем цвета. Для этого заменим:
Код:
enum ImGuiCol_
{
ImGuiCol_Text,
ImGuiCol_TextDisabled,
ImGuiCol_WindowBg, // Background of normal windows
ImGuiCol_ChildWindowBg, // Background of child windows
ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows
ImGuiCol_Border,
ImGuiCol_BorderShadow,
ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input
ImGuiCol_FrameBgHovered,
ImGuiCol_FrameBgActive,
ImGuiCol_TitleBg,
ImGuiCol_TitleBgCollapsed,
ImGuiCol_TitleBgActive,
ImGuiCol_MenuBarBg,
ImGuiCol_ScrollbarBg,
ImGuiCol_ScrollbarGrab,
ImGuiCol_ScrollbarGrabHovered,
ImGuiCol_ScrollbarGrabActive,
ImGuiCol_ComboBg,
ImGuiCol_CheckMark,
ImGuiCol_SliderGrab,
ImGuiCol_SliderGrabActive,
ImGuiCol_Button,
ImGuiCol_ButtonHovered,
ImGuiCol_ButtonActive,
ImGuiCol_Tab,
ImGuiCol_TabHovered,
ImGuiCol_TabActive,
ImGuiCol_TabText,
ImGuiCol_TabTextActive,
ImGuiCol_TabSelected,
ImGuiCol_SelectedLine,
ImGuiCol_Header,
ImGuiCol_HeaderHovered,
ImGuiCol_HeaderActive,
ImGuiCol_HeaderSelected,
ImGuiCol_Column,
ImGuiCol_ColumnHovered,
ImGuiCol_ColumnActive,
ImGuiCol_ResizeGrip,
ImGuiCol_ResizeGripHovered,
ImGuiCol_ResizeGripActive,
ImGuiCol_CloseButton,
ImGuiCol_CloseButtonHovered,
ImGuiCol_CloseButtonActive,
ImGuiCol_PlotLines,
ImGuiCol_PlotLinesHovered,
ImGuiCol_PlotHistogram,
ImGuiCol_PlotHistogramHovered,
ImGuiCol_TextSelectedBg,
ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active
ImGuiCol_FirstTabColor,
ImGuiCol_SecondTabColor,
ImGuiCol_FirstTabColorHovered,
ImGuiCol_SecondTabColorHovered,
ImGuiCol_FirstTabColorActive,
ImGuiCol_SecondTabColorActive,
ImGuiCol_COUNT
};
6. И пропишем им цвет в инициализации:
Код:
style.Colors[ImGuiCol_FirstTabColor] = ImVec4(0.16f, 0.18f, 0.20f, 1.00f);
style.Colors[ImGuiCol_SecondTabColor] = ImVec4(0.14f, 0.15f, 0.18f, 1.00f);
style.Colors[ImGuiCol_FirstTabColorHovered] = ImVec4(0.75f, 0.22f, 0.22f, 1.00f);
style.Colors[ImGuiCol_SecondTabColorHovered] = ImVec4(0.73f, 0.20f, 0.22f, 0.71f);
style.Colors[ImGuiCol_FirstTabColorActive] = ImVec4(1.00f, 0.49f, 0.51f, 1.00f);
style.Colors[ImGuiCol_SecondTabColorActive] = ImVec4(0.85f, 0.27f, 0.29f, 1.00f);
Если вы всё сделали правильно, то у вас должно получиться
примерно это:
примерно это:
P.S. Если я где-то ошибся, или оформил так как не надо или нельзя, поправьте поже)
Адменам чайку с печеньками)
Последнее редактирование: