From 43328be60dfb00e800ef259aeecce90ca0bc46e4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 19 May 2021 19:26:25 +0200 Subject: [PATCH] Shadows: Fix for latest, reuse ImDrawList, remove ImDrawShadowFlags. --- imgui.cpp | 2 +- imgui.h | 21 +++++++-------------- imgui_demo.cpp | 12 ++++++------ imgui_draw.cpp | 20 ++++++++++---------- 4 files changed, 24 insertions(+), 31 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4348774c..a5662598 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6336,7 +6336,7 @@ void ImGui::RenderWindowShadow(ImGuiWindow* window) float shadow_size = style.WindowShadowSize; ImU32 shadow_col = GetColorU32(ImGuiCol_WindowShadow); ImVec2 shadow_offset = ImVec2(ImCos(style.WindowShadowOffsetAngle), ImSin(style.WindowShadowOffsetAngle)) * style.WindowShadowOffsetDist; - window->DrawList->AddShadowRect(window->Pos, window->Pos + window->Size, shadow_col, shadow_size, shadow_offset, ImDrawShadowFlags_CutOutShapeBackground, window->WindowRounding); + window->DrawList->AddShadowRect(window->Pos, window->Pos + window->Size, shadow_col, shadow_size, shadow_offset, ImDrawFlags_ShadowCutOutShapeBackground, window->WindowRounding); } // Render title text, collapse button, close button diff --git a/imgui.h b/imgui.h index d9cb7507..8235d825 100644 --- a/imgui.h +++ b/imgui.h @@ -211,7 +211,6 @@ typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A // - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments. typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance -typedef int ImDrawShadowFlags; // -> enum ImDrawShadowFlags_ // Flags: for ImDrawList::AddShadowRect(), AddShadowCircle() etc. typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for InvisibleButton() @@ -2753,13 +2752,7 @@ enum ImDrawFlags_ ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified. ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone, -}; - -// Flags for ImDrawList::AddShadowRect(), AddShadowCircle() etc. -enum ImDrawShadowFlags_ -{ - ImDrawShadowFlags_None = 0, - ImDrawShadowFlags_CutOutShapeBackground = 1 << 0 // Do not render the shadow shape under the objects to be shadowed to save on fill-rate or facilitate blending. Slower on CPU. + ImDrawFlags_ShadowCutOutShapeBackground = 1 << 9, // Do not render the shadow shape under the objects to be shadowed to save on fill-rate or facilitate blending. Slower on CPU. }; // Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly. @@ -2861,17 +2854,17 @@ struct ImDrawList // - Add shadow for a object, with min/max or center/radius describing the object extents, and offset shifting the shadow. // - Rounding parameters refer to the object itself, not the shadow! // - By default, the area under the object is filled, because this is simpler to process. - // Using the ImDrawShadowFlags_CutOutShapeBackground flag makes the function not render this area and leave a hole under the object. + // Using the ImDrawFlags_ShadowCutOutShapeBackground flag makes the function not render this area and leave a hole under the object. // - Shadows w/ fill under the object: a bit faster for CPU, more pixels rendered, visible/darkening if used behind a transparent shape. // Typically used by: small, frequent objects, opaque objects, transparent objects if shadow darkening isn't an issue. // - Shadows w/ hole under the object: a bit slower for CPU, less pixels rendered, no difference if used behind a transparent shape. // Typically used by: large, infrequent objects, transparent objects if exact blending/color matter. - // - FIXME-SHADOWS: 'offset' + ImDrawShadowFlags_CutOutBackground are not currently supported together with AddShadowCircle(), AddShadowConvexPoly(), AddShadowNGon(). + // - FIXME-SHADOWS: 'offset' + ImDrawFlags_ShadowCutOutShapeBackground are not currently supported together with AddShadowCircle(), AddShadowConvexPoly(), AddShadowNGon(). #define IMGUI_HAS_SHADOWS 1 - IMGUI_API void AddShadowRect(const ImVec2& obj_min, const ImVec2& obj_max, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawShadowFlags shadow_flags = 0, float obj_rounding = 0.0f, ImDrawCornerFlags obj_rounding_corners = ImDrawCornerFlags_All); - IMGUI_API void AddShadowCircle(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawShadowFlags shadow_flags = 0, int obj_num_segments = 12); - IMGUI_API void AddShadowConvexPoly(const ImVec2* points, int points_count, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawShadowFlags shadow_flags = 0); - IMGUI_API void AddShadowNGon(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawShadowFlags shadow_flags, int obj_num_segments); + IMGUI_API void AddShadowRect(const ImVec2& obj_min, const ImVec2& obj_max, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags = 0, float obj_rounding = 0.0f); + IMGUI_API void AddShadowCircle(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags = 0, int obj_num_segments = 12); + IMGUI_API void AddShadowConvexPoly(const ImVec2* points, int points_count, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags = 0); + IMGUI_API void AddShadowNGon(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags, int obj_num_segments); // Stateful path API, add points then finish with PathFillConvex() or PathStroke() // - Important: filled shapes must always use clockwise winding order! The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0e84822b..f9b888cc 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -8431,8 +8431,8 @@ static void ShowExampleAppCustomRendering(bool* p_open) ImVec2 r1(p.x + 50.0f, p.y + 50.0f); ImVec2 r2(p.x + 150.0f, p.y + 150.0f); - ImDrawShadowFlags shadow_flags = shadow_filled ? ImDrawShadowFlags_None : ImDrawShadowFlags_CutOutShapeBackground; - draw_list->AddShadowRect(r1, r2, ImGui::GetColorU32(shadow_color), shadow_thickness, shadow_offset, shadow_flags, shape_rounding); + ImDrawFlags draw_flags = shadow_filled ? ImDrawFlags_None : ImDrawFlags_ShadowCutOutShapeBackground; + draw_list->AddShadowRect(r1, r2, ImGui::GetColorU32(shadow_color), shadow_thickness, shadow_offset, draw_flags, shape_rounding); if (wireframe) draw_list->AddRect(r1, r2, ImGui::GetColorU32(shape_color), shape_rounding); @@ -8452,8 +8452,8 @@ static void ShowExampleAppCustomRendering(bool* p_open) ImVec2 r1(p.x + 50.0f + off, p.y + 50.0f + off); ImVec2 r2(p.x + 150.0f - off, p.y + 150.0f - off); ImVec2 center(p.x + 100.0f, p.y + 100.0f); - ImDrawShadowFlags shadow_flags = shadow_filled ? ImDrawShadowFlags_None : ImDrawShadowFlags_CutOutShapeBackground; - draw_list->AddShadowCircle(center, 50.0f, ImGui::GetColorU32(shadow_color), shadow_thickness, shadow_filled ? shadow_offset : ImVec2(0.0f, 0.0f), shadow_flags, 0); + ImDrawFlags draw_flags = shadow_filled ? ImDrawFlags_None : ImDrawFlags_ShadowCutOutShapeBackground; + draw_list->AddShadowCircle(center, 50.0f, ImGui::GetColorU32(shadow_color), shadow_thickness, shadow_filled ? shadow_offset : ImVec2(0.0f, 0.0f), draw_flags, 0); if (wireframe) draw_list->AddCircle(center, 50.0f, ImGui::GetColorU32(shape_color), 0); @@ -8528,8 +8528,8 @@ static void ShowExampleAppCustomRendering(bool* p_open) } // FIXME-SHADOWS: Offset forced to zero when shadow is not filled because it isn't supported - ImDrawShadowFlags shadow_flags = shadow_filled ? ImDrawShadowFlags_None : ImDrawShadowFlags_CutOutShapeBackground; - draw_list->AddShadowConvexPoly(poly_points, poly_points_count, ImGui::GetColorU32(shadow_color), shadow_thickness, shadow_filled ? shadow_offset : ImVec2(0.0f, 0.0f), shadow_flags); + ImDrawFlags draw_flags = shadow_filled ? ImDrawFlags_None : ImDrawFlags_ShadowCutOutShapeBackground; + draw_list->AddShadowConvexPoly(poly_points, poly_points_count, ImGui::GetColorU32(shadow_color), shadow_thickness, shadow_filled ? shadow_offset : ImVec2(0.0f, 0.0f), draw_flags); if (wireframe) draw_list->AddPolyline(poly_points, poly_points_count, ImGui::GetColorU32(shape_color), true, 1.0f); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c82566a1..860144c1 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2439,7 +2439,7 @@ static void AddSubtractedRect(ImDrawList* draw_list, const ImVec2& a_min, const } } -void ImDrawList::AddShadowRect(const ImVec2& obj_min, const ImVec2& obj_max, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawShadowFlags shadow_flags, float obj_rounding, ImDrawCornerFlags obj_rounding_corners) +void ImDrawList::AddShadowRect(const ImVec2& obj_min, const ImVec2& obj_max, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags, float obj_rounding) { if ((shadow_col & IM_COL32_A_MASK) == 0) return; @@ -2448,12 +2448,12 @@ void ImDrawList::AddShadowRect(const ImVec2& obj_min, const ImVec2& obj_max, ImU int inner_rect_points_count = 0; // Generate a path describing the inner rectangle and copy it to our buffer - const bool is_filled = (shadow_flags & ImDrawShadowFlags_CutOutShapeBackground) == 0; - const bool is_rounded = (obj_rounding > 0.0f) && (obj_rounding_corners != ImDrawCornerFlags_None); // Do we have rounded corners? + const bool is_filled = (flags & ImDrawFlags_ShadowCutOutShapeBackground) == 0; + const bool is_rounded = (obj_rounding > 0.0f) && ((flags & ImDrawFlags_RoundCornersMask_) != ImDrawFlags_RoundCornersNone); // Do we have rounded corners? if (is_rounded && !is_filled) { IM_ASSERT(_Path.Size == 0); - PathRect(obj_min, obj_max, obj_rounding, obj_rounding_corners); + PathRect(obj_min, obj_max, obj_rounding, flags); inner_rect_points_count = _Path.Size; inner_rect_points = (ImVec2*)alloca(inner_rect_points_count * sizeof(ImVec2)); //-V630 memcpy(inner_rect_points, _Path.Data, inner_rect_points_count * sizeof(ImVec2)); @@ -2499,9 +2499,9 @@ void ImDrawList::AddShadowRect(const ImVec2& obj_min, const ImVec2& obj_max, ImU } // Add a shadow for a convex shape described by points and num_points -void ImDrawList::AddShadowConvexPoly(const ImVec2* points, int points_count, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawShadowFlags shadow_flags) +void ImDrawList::AddShadowConvexPoly(const ImVec2* points, int points_count, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags) { - const bool is_filled = (shadow_flags & ImDrawShadowFlags_CutOutShapeBackground) == 0; + const bool is_filled = (flags & ImDrawFlags_ShadowCutOutShapeBackground) == 0; IM_ASSERT((is_filled || (ImLengthSqr(shadow_offset) < 0.00001f)) && "Drawing circle/convex shape shadows with no center fill and an offset is not currently supported"); IM_ASSERT(points_count >= 3); @@ -2724,7 +2724,7 @@ void ImDrawList::AddShadowConvexPoly(const ImVec2* points, int points_count, ImU // Draw a shadow for a circular object // Uses the draw path and so wipes any existing data there -void ImDrawList::AddShadowCircle(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawShadowFlags shadow_flags, int num_segments) +void ImDrawList::AddShadowCircle(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags, int num_segments) { // Obtain segment count if (num_segments <= 0) @@ -2751,14 +2751,14 @@ void ImDrawList::AddShadowCircle(const ImVec2& obj_center, float obj_radius, ImU PathArcTo(obj_center, obj_radius, 0.0f, a_max, num_segments - 1); // Draw the shadow using the convex shape code - AddShadowConvexPoly(_Path.Data, _Path.Size, shadow_col, shadow_thickness, shadow_offset, shadow_flags); + AddShadowConvexPoly(_Path.Data, _Path.Size, shadow_col, shadow_thickness, shadow_offset, flags); _Path.Size = 0; } -void ImDrawList::AddShadowNGon(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawShadowFlags shadow_flags, int num_segments) +void ImDrawList::AddShadowNGon(const ImVec2& obj_center, float obj_radius, ImU32 shadow_col, float shadow_thickness, const ImVec2& shadow_offset, ImDrawFlags flags, int num_segments) { IM_ASSERT(num_segments != 0); - AddShadowCircle(obj_center, obj_radius, shadow_col, shadow_thickness, shadow_offset, shadow_flags, num_segments); + AddShadowCircle(obj_center, obj_radius, shadow_col, shadow_thickness, shadow_offset, flags, num_segments); } //-----------------------------------------------------------------------------