mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-01 02:37:24 +01:00
AddCircle, AddCircleFilled: Add auto-calculation of circle segment counts (amends)
Tweak default max error value, Changelog, comments, path-fast for 12 segments circles, made LUT store ImU8
This commit is contained in:
parent
051ce0765e
commit
5363af7f47
@ -55,6 +55,7 @@ Breaking Changes:
|
|||||||
documented (can only unreserve from the last reserve call). If you suspect you ever
|
documented (can only unreserve from the last reserve call). If you suspect you ever
|
||||||
used that feature before, #define IMGUI_DEBUG_PARANOID in imconfig.h to catch existing
|
used that feature before, #define IMGUI_DEBUG_PARANOID in imconfig.h to catch existing
|
||||||
calls. [@ShironekoBen]
|
calls. [@ShironekoBen]
|
||||||
|
- ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius.
|
||||||
- Limiting Columns()/BeginColumns() api to 64 columns with an assert. While the current code
|
- Limiting Columns()/BeginColumns() api to 64 columns with an assert. While the current code
|
||||||
technically supports it, future code may not so we're putting the restriction ahead.
|
technically supports it, future code may not so we're putting the restriction ahead.
|
||||||
- imgui_internal.h: changed ImRect() default constructor initializes all fields to 0.0f instead
|
- imgui_internal.h: changed ImRect() default constructor initializes all fields to 0.0f instead
|
||||||
@ -70,6 +71,8 @@ Other Changes:
|
|||||||
those improvements in 1.73 makes them unnecessary. (#2722, #2770). [@rokups]
|
those improvements in 1.73 makes them unnecessary. (#2722, #2770). [@rokups]
|
||||||
- ColorEdit: "Copy As" context-menu tool shows hex values with a '#' prefix instead of '0x'.
|
- ColorEdit: "Copy As" context-menu tool shows hex values with a '#' prefix instead of '0x'.
|
||||||
- ColorEdit: "Copy As" content-menu tool shows hex values both with/without alpha when available.
|
- ColorEdit: "Copy As" content-menu tool shows hex values both with/without alpha when available.
|
||||||
|
- ImDrawList: AddCircle(), AddCircleFilled() API can now auto-tessellate when provided a segment
|
||||||
|
count of zero. Alter tessellation quality with 'style.CircleSegmentMaxError'. [@ShironekoBen]
|
||||||
- ImDrawList: Add AddNgon(), AddNgonFilled() API with a guarantee on the explicit segment count.
|
- ImDrawList: Add AddNgon(), AddNgonFilled() API with a guarantee on the explicit segment count.
|
||||||
In the current branch they are essentially the same as AddCircle(), AddCircleFilled() but as
|
In the current branch they are essentially the same as AddCircle(), AddCircleFilled() but as
|
||||||
we will rework the circle rendering functions to use textures and automatic segment count
|
we will rework the circle rendering functions to use textures and automatic segment count
|
||||||
|
@ -362,6 +362,7 @@ CODE
|
|||||||
When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
||||||
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||||
|
|
||||||
|
- 2020/01/22 (1.75) - ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius any more.
|
||||||
- 2019/12/17 (1.75) - made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead.
|
- 2019/12/17 (1.75) - made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead.
|
||||||
- 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value.
|
- 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value.
|
||||||
- 2019/12/08 (1.75) - removed redirecting functions/enums that were marked obsolete in 1.53 (December 2017):
|
- 2019/12/08 (1.75) - removed redirecting functions/enums that were marked obsolete in 1.53 (December 2017):
|
||||||
@ -988,7 +989,7 @@ ImGuiStyle::ImGuiStyle()
|
|||||||
AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU.
|
AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU.
|
||||||
AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
|
AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
|
||||||
CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
||||||
CircleSegmentMaxError = 0.75f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
|
CircleSegmentMaxError = 1.60f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
|
||||||
|
|
||||||
// Default theme
|
// Default theme
|
||||||
ImGui::StyleColorsDark(this);
|
ImGui::StyleColorsDark(this);
|
||||||
@ -3624,7 +3625,7 @@ void ImGui::NewFrame()
|
|||||||
IM_ASSERT(g.Font->IsLoaded());
|
IM_ASSERT(g.Font->IsLoaded());
|
||||||
g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y);
|
g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y);
|
||||||
g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol;
|
g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol;
|
||||||
g.DrawListSharedData.CircleSegmentMaxError = g.Style.CircleSegmentMaxError;
|
g.DrawListSharedData.SetCircleSegmentMaxError(g.Style.CircleSegmentMaxError);
|
||||||
g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
|
g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
|
||||||
if (g.Style.AntiAliasedLines)
|
if (g.Style.AntiAliasedLines)
|
||||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
|
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
|
||||||
@ -3633,10 +3634,6 @@ void ImGui::NewFrame()
|
|||||||
if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
|
if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
|
||||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset;
|
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset;
|
||||||
|
|
||||||
// Recalculate circle segment counts if the segment error has changed
|
|
||||||
if (g.DrawListSharedData.CircleSegmentMaxError != g.DrawListSharedData.CircleSegmentCountsMaxCircleSegmentError)
|
|
||||||
g.DrawListSharedData.RecalculateCircleSegmentCounts();
|
|
||||||
|
|
||||||
g.BackgroundDrawList.Clear();
|
g.BackgroundDrawList.Clear();
|
||||||
g.BackgroundDrawList.PushTextureID(g.IO.Fonts->TexID);
|
g.BackgroundDrawList.PushTextureID(g.IO.Fonts->TexID);
|
||||||
g.BackgroundDrawList.PushClipRectFullScreen();
|
g.BackgroundDrawList.PushClipRectFullScreen();
|
||||||
|
11
imgui.h
11
imgui.h
@ -1941,6 +1941,9 @@ struct ImDrawList
|
|||||||
|
|
||||||
// Primitives
|
// Primitives
|
||||||
// - For rectangular primitives, "p_min" and "p_max" represent the upper-left and lower-right corners.
|
// - For rectangular primitives, "p_min" and "p_max" represent the upper-left and lower-right corners.
|
||||||
|
// - For circle primitives, use "num_segments == 0" to automatically calculate tessellation (preferred).
|
||||||
|
// In future versions we will use textures to provide cheaper and higher-quality circles.
|
||||||
|
// Use AddNgon() and AddNgonFilled() functions if you need to guaranteed a specific number of sides.
|
||||||
IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f);
|
IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f);
|
||||||
IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size), rounding_corners_flags: 4 bits corresponding to which corner to round
|
IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size), rounding_corners_flags: 4 bits corresponding to which corner to round
|
||||||
IMGUI_API void AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All); // a: upper-left, b: lower-right (== upper-left + size)
|
IMGUI_API void AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All); // a: upper-left, b: lower-right (== upper-left + size)
|
||||||
@ -1949,10 +1952,10 @@ struct ImDrawList
|
|||||||
IMGUI_API void AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col);
|
IMGUI_API void AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col);
|
||||||
IMGUI_API void AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness = 1.0f);
|
IMGUI_API void AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness = 1.0f);
|
||||||
IMGUI_API void AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col);
|
IMGUI_API void AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col);
|
||||||
IMGUI_API void AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f); // Draw a circle - use num_segments <= 0 to automatically calculate tessellation (preferred). Use AddNgon() instead if you need a specific segment count.
|
IMGUI_API void AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f);
|
||||||
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 12); // Draw a filled circle - use num_segments <= 0 to automatically calculate tessellation (preferred). Use AddNgonFilled() instead if you need a specific segment count.
|
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 12);
|
||||||
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f); // Draw an n-gon with a specific number of sides. Use AddCircle() instead if you want an actual circle and don't care about the exact side count.
|
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);
|
||||||
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments); // Draw a filled n-gon with a specific number of sides. Use AddCircleFilled() instead if you want an actual circle and don't care about the exact side count.
|
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
|
||||||
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
||||||
IMGUI_API void 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);
|
IMGUI_API void 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);
|
||||||
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness);
|
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness);
|
||||||
|
@ -3500,9 +3500,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
|||||||
ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.");
|
ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.");
|
||||||
ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
|
ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
|
||||||
ImGui::PushItemWidth(100);
|
ImGui::PushItemWidth(100);
|
||||||
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, "%.2f", 2.0f);
|
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f");
|
||||||
if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f;
|
if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f;
|
||||||
ImGui::DragFloat("Max circle segment error", &style.CircleSegmentMaxError, 0.01f, 0.1f, 10.0f, "%.2f", 1.0f);
|
ImGui::DragFloat("Circle segment Max Error", &style.CircleSegmentMaxError, 0.01f, 0.10f, 10.0f, "%.2f");
|
||||||
ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
|
ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
@ -4455,24 +4455,33 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
|||||||
static float sz = 36.0f;
|
static float sz = 36.0f;
|
||||||
static float thickness = 3.0f;
|
static float thickness = 3.0f;
|
||||||
static int ngon_sides = 6;
|
static int ngon_sides = 6;
|
||||||
|
static bool circle_segments_override = false;
|
||||||
|
static int circle_segments_override_v = 12;
|
||||||
static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
|
static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
|
||||||
|
ImGui::PushItemWidth(-ImGui::GetFontSize() * 10);
|
||||||
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
|
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
|
||||||
ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
|
ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
|
||||||
ImGui::SliderInt("n-gon sides", &ngon_sides, 3, 12);
|
ImGui::SliderInt("N-gon sides", &ngon_sides, 3, 12);
|
||||||
|
ImGui::Checkbox("##circlesegmentoverride", &circle_segments_override);
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
if (ImGui::SliderInt("Circle segments", &circle_segments_override_v, 3, 40))
|
||||||
|
circle_segments_override = true;
|
||||||
ImGui::ColorEdit4("Color", &colf.x);
|
ImGui::ColorEdit4("Color", &colf.x);
|
||||||
|
ImGui::PopItemWidth();
|
||||||
const ImVec2 p = ImGui::GetCursorScreenPos();
|
const ImVec2 p = ImGui::GetCursorScreenPos();
|
||||||
const ImU32 col = ImColor(colf);
|
const ImU32 col = ImColor(colf);
|
||||||
|
const float spacing = 10.0f;
|
||||||
|
const ImDrawCornerFlags corners_none = 0;
|
||||||
|
const ImDrawCornerFlags corners_all = ImDrawCornerFlags_All;
|
||||||
|
const ImDrawCornerFlags corners_tl_br = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight;
|
||||||
|
const int circle_segments = circle_segments_override ? circle_segments_override_v : 0;
|
||||||
float x = p.x + 4.0f, y = p.y + 4.0f;
|
float x = p.x + 4.0f, y = p.y + 4.0f;
|
||||||
float spacing = 10.0f;
|
|
||||||
ImDrawCornerFlags corners_none = 0;
|
|
||||||
ImDrawCornerFlags corners_all = ImDrawCornerFlags_All;
|
|
||||||
ImDrawCornerFlags corners_tl_br = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight;
|
|
||||||
for (int n = 0; n < 2; n++)
|
for (int n = 0; n < 2; n++)
|
||||||
{
|
{
|
||||||
// First line uses a thickness of 1.0f, second line uses the configurable thickness
|
// First line uses a thickness of 1.0f, second line uses the configurable thickness
|
||||||
float th = (n == 0) ? 1.0f : thickness;
|
float th = (n == 0) ? 1.0f : thickness;
|
||||||
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // n-gon
|
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
|
||||||
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, 0, th); x += sz + spacing; // Circle
|
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
|
||||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, corners_none, th); x += sz + spacing; // Square
|
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, corners_none, th); x += sz + spacing; // Square
|
||||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th); x += sz + spacing; // Square with all rounded corners
|
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th); x += sz + spacing; // Square with all rounded corners
|
||||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
|
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners
|
||||||
@ -4485,8 +4494,8 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
|||||||
x = p.x + 4;
|
x = p.x + 4;
|
||||||
y += sz + spacing;
|
y += sz + spacing;
|
||||||
}
|
}
|
||||||
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // n-gon
|
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // N-gon
|
||||||
draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, 0); x += sz + spacing; // Circle
|
draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments);x += sz + spacing; // Circle
|
||||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square
|
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square
|
||||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
|
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
|
||||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
|
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
|
||||||
|
@ -349,16 +349,29 @@ ImDrawListSharedData::ImDrawListSharedData()
|
|||||||
FontSize = 0.0f;
|
FontSize = 0.0f;
|
||||||
CurveTessellationTol = 0.0f;
|
CurveTessellationTol = 0.0f;
|
||||||
CircleSegmentMaxError = 0.0f;
|
CircleSegmentMaxError = 0.0f;
|
||||||
CircleSegmentCountsMaxCircleSegmentError = -FLT_MIN; // Impossible value to force recalculation
|
|
||||||
ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f);
|
ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f);
|
||||||
InitialFlags = ImDrawListFlags_None;
|
InitialFlags = ImDrawListFlags_None;
|
||||||
|
|
||||||
// Const data
|
// Lookup tables
|
||||||
for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++)
|
for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++)
|
||||||
{
|
{
|
||||||
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(CircleVtx12);
|
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(CircleVtx12);
|
||||||
CircleVtx12[i] = ImVec2(ImCos(a), ImSin(a));
|
CircleVtx12[i] = ImVec2(ImCos(a), ImSin(a));
|
||||||
}
|
}
|
||||||
|
memset(CircleSegmentCounts, 0, sizeof(CircleSegmentCounts)); // This will be set by
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error)
|
||||||
|
{
|
||||||
|
if (CircleSegmentMaxError == max_error)
|
||||||
|
return;
|
||||||
|
CircleSegmentMaxError = max_error;
|
||||||
|
for (int i = 0; i < IM_ARRAYSIZE(CircleSegmentCounts); i++)
|
||||||
|
{
|
||||||
|
const float radius = i + 1.0f;
|
||||||
|
const int segment_count = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError);
|
||||||
|
CircleSegmentCounts[i] = (ImU8)ImMin(segment_count, 255);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::Clear()
|
void ImDrawList::Clear()
|
||||||
@ -1085,59 +1098,62 @@ void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImV
|
|||||||
PathFillConvex(col);
|
PathFillConvex(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawListSharedData::RecalculateCircleSegmentCounts()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NumCircleSegmentCounts; i++)
|
|
||||||
{
|
|
||||||
const float radius = i + 1.0f;
|
|
||||||
CircleSegmentCounts[i] = ImClamp((int)((IM_PI * 2.0f) / ImAcos((radius - CircleSegmentMaxError) / radius)), 3, 10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
CircleSegmentCountsMaxCircleSegmentError = CircleSegmentMaxError;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness)
|
void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness)
|
||||||
{
|
{
|
||||||
if ((col & IM_COL32_A_MASK) == 0 || (radius <= 0.0f))
|
if ((col & IM_COL32_A_MASK) == 0 || radius <= 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Calculate number of segments if required
|
// Obtain segment count
|
||||||
if (num_segments <= 0)
|
if (num_segments <= 0)
|
||||||
{
|
{
|
||||||
int radius_int = (int)radius;
|
// Automatic segment count
|
||||||
if (radius_int <= ImDrawListSharedData::NumCircleSegmentCounts)
|
const int radius_idx = (int)radius - 1;
|
||||||
num_segments = _Data->CircleSegmentCounts[radius_int - 1]; // Use cached value
|
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
|
||||||
|
num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value
|
||||||
else
|
else
|
||||||
num_segments = ImClamp((int)((IM_PI * 2.0f) / ImAcos((radius - _Data->CircleSegmentMaxError) / radius)), 3, 10000);
|
num_segments = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
num_segments = ImClamp(num_segments, 3, 10000); // Clamp to avoid drawing insanely tessellated shapes
|
{
|
||||||
|
// Explicit segment count (still clamp to avoid drawing insanely tessellated shapes)
|
||||||
|
num_segments = ImClamp(num_segments, 3, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||||
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||||
|
if (num_segments == 12)
|
||||||
|
PathArcToFast(center, radius - 0.5f, 0, 12);
|
||||||
|
else
|
||||||
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
|
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
|
||||||
PathStroke(col, true, thickness);
|
PathStroke(col, true, thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments)
|
void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments)
|
||||||
{
|
{
|
||||||
if ((col & IM_COL32_A_MASK) == 0 || (radius <= 0.0f))
|
if ((col & IM_COL32_A_MASK) == 0 || radius <= 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Calculate number of segments if required
|
// Obtain segment count
|
||||||
if (num_segments <= 0)
|
if (num_segments <= 0)
|
||||||
{
|
{
|
||||||
int radius_int = (int)radius;
|
// Automatic segment count
|
||||||
if (radius_int <= ImDrawListSharedData::NumCircleSegmentCounts)
|
const int radius_idx = (int)radius - 1;
|
||||||
num_segments = _Data->CircleSegmentCounts[radius_int - 1]; // Use cached value
|
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
|
||||||
|
num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value
|
||||||
else
|
else
|
||||||
num_segments = ImClamp((int)((IM_PI * 2.0f) / ImAcos((radius - _Data->CircleSegmentMaxError) / radius)), 3, 10000);
|
num_segments = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
num_segments = ImClamp(num_segments, 3, 10000); // Clamp to avoid drawing insanely tessellated shapes
|
{
|
||||||
|
// Explicit segment count (still clamp to avoid drawing insanely tessellated shapes)
|
||||||
|
num_segments = ImClamp(num_segments, 3, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||||
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||||
|
if (num_segments == 12)
|
||||||
|
PathArcToFast(center, radius, 0, 12);
|
||||||
|
else
|
||||||
PathArcTo(center, radius, 0.0f, a_max, num_segments - 1);
|
PathArcTo(center, radius, 0.0f, a_max, num_segments - 1);
|
||||||
PathFillConvex(col);
|
PathFillConvex(col);
|
||||||
}
|
}
|
||||||
|
@ -848,7 +848,13 @@ struct ImGuiColumns
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper function to calculate a circle's segment count given its radius and a "maximum error" value.
|
||||||
|
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 12
|
||||||
|
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512
|
||||||
|
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp((int)((IM_PI * 2.0f) / ImAcos((_RAD - _MAXERROR) / _RAD)), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX)
|
||||||
|
|
||||||
// Data shared between all ImDrawList instances
|
// Data shared between all ImDrawList instances
|
||||||
|
// You may want to create your own instance of this if you want to use ImDrawList completely without ImGui. In that case, watch out for future changes to this structure.
|
||||||
struct IMGUI_API ImDrawListSharedData
|
struct IMGUI_API ImDrawListSharedData
|
||||||
{
|
{
|
||||||
ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas
|
ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas
|
||||||
@ -859,18 +865,12 @@ struct IMGUI_API ImDrawListSharedData
|
|||||||
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
|
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
|
||||||
ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)
|
ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)
|
||||||
|
|
||||||
// Const data
|
// [Internal] Lookup tables
|
||||||
// FIXME: Bake rounded corners fill/borders in atlas
|
ImVec2 CircleVtx12[12]; // FIXME: Bake rounded corners fill/borders in atlas
|
||||||
ImVec2 CircleVtx12[12];
|
ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius (array index + 1) before we calculate it dynamically (to avoid calculation overhead)
|
||||||
|
|
||||||
// Cached circle segment counts for the first <n> radii (to avoid calculation overhead)
|
|
||||||
static const int NumCircleSegmentCounts = 64;// Number of circle segment counts to cache (i.e. the maximum radius before we calculate dynamically)
|
|
||||||
int CircleSegmentCounts[NumCircleSegmentCounts]; // The segment count for radius (array index + 1)
|
|
||||||
float CircleSegmentCountsMaxCircleSegmentError; // The MaxCircleSegmentError used to calculate these counts
|
|
||||||
|
|
||||||
void RecalculateCircleSegmentCounts(); // Recalculate circle segment counts based on the current MaxCircleSegmentError
|
|
||||||
|
|
||||||
ImDrawListSharedData();
|
ImDrawListSharedData();
|
||||||
|
void SetCircleSegmentMaxError(float max_error);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImDrawDataBuilder
|
struct ImDrawDataBuilder
|
||||||
|
Loading…
Reference in New Issue
Block a user