From 8b2d449b165f2214a088f8d0cd8a20b684e99787 Mon Sep 17 00:00:00 2001 From: thedmd Date: Sun, 19 Nov 2017 21:00:38 +0100 Subject: [PATCH 1/2] Add ShadeVertsLinearUV() --- imgui_draw.cpp | 24 ++++++++++++++++++++++++ imgui_internal.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 8718e978..5d8cc5d9 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1226,6 +1226,30 @@ void ImGui::ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_sta } } +// Distribute UV over (a, b) rectangle +void ImGui::ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp) +{ + const ImVec2 size = b - a; + const ImVec2 uv_size = uv_b - uv_a; + const ImVec2 scale = ImVec2( + size.x ? (uv_size.x / size.x) : 0.0f, + size.y ? (uv_size.y / size.y) : 0.0f); + + if (clamp) + { + const ImVec2 min = ImMin(uv_a, uv_b); + const ImVec2 max = ImMax(uv_a, uv_b); + + for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) + vertex->uv = ImClamp(uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale), min, max); + } + else + { + for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) + vertex->uv = uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale); + } +} + //----------------------------------------------------------------------------- // ImFontConfig //----------------------------------------------------------------------------- diff --git a/imgui_internal.h b/imgui_internal.h index 6a5c24aa..f9c9a7d4 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -155,6 +155,7 @@ static inline ImVec2 ImFloor(const ImVec2& v) static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } +static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. // Defining a custom placement new() with a dummy parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. @@ -873,6 +874,7 @@ namespace ImGui // Shade functions IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); IMGUI_API void ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_start, ImDrawVert* vert_end, float gradient_p0_x, float gradient_p1_x); + IMGUI_API void ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); } // namespace ImGui From 79f07f6ff040f6bfbf6b86320bf417f1d495966b Mon Sep 17 00:00:00 2001 From: thedmd Date: Sun, 19 Nov 2017 21:48:13 +0100 Subject: [PATCH 2/2] Add AddImageRounded() to ImDrawList --- imgui.h | 2 ++ imgui_draw.cpp | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/imgui.h b/imgui.h index 98e016bf..b1bba790 100644 --- a/imgui.h +++ b/imgui.h @@ -1308,6 +1308,7 @@ struct ImDrawList 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 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); IMGUI_API void 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); + IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, float rounding, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF, int rounding_corners = ~0); IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased); IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased); IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); @@ -1347,6 +1348,7 @@ struct ImDrawList inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } IMGUI_API void UpdateClipRect(); IMGUI_API void UpdateTextureID(); + IMGUI_API void PrimDistributeUV(ImDrawVert* start, ImDrawVert* end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); }; // All draw data to render an ImGui frame diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 5d8cc5d9..e3098f77 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1152,6 +1152,41 @@ void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, cons PopTextureID(); } +void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, float rounding, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, int rounding_corners) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + if (rounding <= 0.0f) + { + AddImage(user_texture_id, a, b, uv_a, uv_b, col); + return; + } + + // FIXME-OPT: This is wasting draw calls. + const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); + if (push_texture_id) + PushTextureID(user_texture_id); + + if (rounding > 0.0f && rounding_corners != 0) + { + size_t startIndex = VtxBuffer.size(); + PathRect(a, b, rounding, rounding_corners); + PathFillConvex(col); + size_t endIndex = VtxBuffer.size(); + + ImGui::ShadeVertsLinearUV(VtxBuffer.Data + startIndex, VtxBuffer.Data + endIndex, a, b, uv_a, uv_b, true); + } + else + { + PrimReserve(6, 4); + PrimRectUV(a, b, uv_a, uv_b, col); + } + + if (push_texture_id) + PopTextureID(); +} + //----------------------------------------------------------------------------- // ImDrawData //-----------------------------------------------------------------------------