From 90b04eda01347d29ea10e554a928bacc17d1ad9e Mon Sep 17 00:00:00 2001 From: G-glop Date: Sun, 13 May 2018 21:37:44 +0200 Subject: [PATCH 1/4] remove buffer from AddConvexPolyFilled --- imgui_draw.cpp | 74 +++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 7bd85ab397cd..84b1a02aede9 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -842,6 +842,10 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun const ImVec2 uv = _Data->TexUvWhitePixel; + if (points_count < 2) { + return; + } + if (Flags & ImDrawListFlags_AntiAliasedFill) { // Anti-aliased Fill @@ -851,32 +855,29 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun 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; - } + const ImDrawIdx common_idx = (ImDrawIdx)_VtxCurrentIdx; - // Compute normals - ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); - for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) + for (int i0 = points_count-2, i1 = i0+1, i2 = 0; i2 < points_count; i0 = i1, i1=i2++) { 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; - } + const ImVec2& p2 = points[i2]; + + ImVec2 n0 = p1 - p0; + ImVec2 n1 = p2 - p1; + { + float n0l = ImInvLength(n0, 1); + float n1l = ImInvLength(n1, 1); + float temp0 = n0.x; + n0.x = n0.y; + n0.y = -temp0; + float temp1 = n1.x; + n1.x = n1.y; + n1.y = -temp1; + n0 *= n0l; + n1 *= n1l; + } - for (int i0 = points_count-1, i1 = 0; 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) @@ -887,17 +888,34 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun } dm *= AA_SIZE * 0.5f; - // Add vertices - _VtxWritePtr[0].pos = (points[i1] - dm); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner - _VtxWritePtr[1].pos = (points[i1] + dm); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer + // 2 vertices + _VtxWritePtr[0].pos = p1 - dm; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner + _VtxWritePtr[1].pos = p1 + dm; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer _VtxWritePtr += 2; - // 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)); + // 2 triangles for border + // Order: + // [0] +0 [1] +1 [2] +2 + // [3] +1 [4] +2 [5] +3 + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx + 0); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + 1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + 2); + _IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx + 1); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx + 2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx + 3); _IdxWritePtr += 6; + + // Maybe 1 triangle for fill + if (i2 >= 2) + { + _IdxWritePtr[0] = common_idx; _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx-2); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx); + _IdxWritePtr += 3; + } + + _VtxCurrentIdx += 2; } - _VtxCurrentIdx += (ImDrawIdx)vtx_count; + + // Patch last indices to point to 1st iteration vertices + int offset = points_count < 3 ? 6 : 9; // If there is a fill triangle at the end of the buffer + _IdxWritePtr[2-offset] = common_idx; + _IdxWritePtr[4-offset] = common_idx; + _IdxWritePtr[5-offset] = common_idx + 1; } else { From 85fcab0811b0a0d662e17f16d42256e7acd437c2 Mon Sep 17 00:00:00 2001 From: G-glop Date: Wed, 30 May 2018 08:35:43 +0200 Subject: [PATCH 2/4] use the vertex output as a buffer --- imgui_draw.cpp | 69 ++++++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 84b1a02aede9..b0f1bac52c6f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -855,30 +855,34 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun const int vtx_count = (points_count*2); PrimReserve(idx_count, vtx_count); - const ImDrawIdx common_idx = (ImDrawIdx)_VtxCurrentIdx; + // 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; + } - for (int i0 = points_count-2, i1 = i0+1, i2 = 0; i2 < points_count; i0 = i1, i1=i2++) + // Compute normals + for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) { const ImVec2& p0 = points[i0]; const ImVec2& p1 = points[i1]; - const ImVec2& p2 = points[i2]; + ImVec2 diff = p1 - p0; + diff *= ImInvLength(diff, 1.0f); + _VtxWritePtr[i0 << 1].pos.x = diff.y; + _VtxWritePtr[i0 << 1].pos.y = -diff.x; + } - ImVec2 n0 = p1 - p0; - ImVec2 n1 = p2 - p1; - { - float n0l = ImInvLength(n0, 1); - float n1l = ImInvLength(n1, 1); - float temp0 = n0.x; - n0.x = n0.y; - n0.y = -temp0; - float temp1 = n1.x; - n1.x = n1.y; - n1.y = -temp1; - n0 *= n0l; - n1 *= n1l; - } + ImVec2 n0 = _VtxWritePtr[(points_count-1) << 1].pos; + for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) + { + // Average normals + const ImVec2& n1 = _VtxWritePtr[0].pos; ImVec2 dm = (n0 + n1) * 0.5f; + n0 = n1; float dmr2 = dm.x*dm.x + dm.y*dm.y; if (dmr2 > 0.000001f) { @@ -888,34 +892,17 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun } dm *= AA_SIZE * 0.5f; - // 2 vertices - _VtxWritePtr[0].pos = p1 - dm; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner - _VtxWritePtr[1].pos = p1 + dm; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer + // Add vertices + _VtxWritePtr[0].pos = (points[i1] - dm); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner + _VtxWritePtr[1].pos = (points[i1] + dm); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer _VtxWritePtr += 2; - // 2 triangles for border - // Order: - // [0] +0 [1] +1 [2] +2 - // [3] +1 [4] +2 [5] +3 - _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx + 0); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + 1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + 2); - _IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx + 1); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx + 2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx + 3); + // 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; - - // Maybe 1 triangle for fill - if (i2 >= 2) - { - _IdxWritePtr[0] = common_idx; _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx-2); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx); - _IdxWritePtr += 3; - } - - _VtxCurrentIdx += 2; } - - // Patch last indices to point to 1st iteration vertices - int offset = points_count < 3 ? 6 : 9; // If there is a fill triangle at the end of the buffer - _IdxWritePtr[2-offset] = common_idx; - _IdxWritePtr[4-offset] = common_idx; - _IdxWritePtr[5-offset] = common_idx + 1; + _VtxCurrentIdx += (ImDrawIdx)vtx_count; } else { From 939d53b3710f021d2d510fb3ec4c8c29ecd53937 Mon Sep 17 00:00:00 2001 From: G-glop Date: Mon, 31 Dec 2018 10:40:52 +0100 Subject: [PATCH 3/4] update to newest --- imgui_draw.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b0f1bac52c6f..7eb7b89f151e 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -842,17 +842,13 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun const ImVec2 uv = _Data->TexUvWhitePixel; - if (points_count < 2) { - return; - } - if (Flags & ImDrawListFlags_AntiAliasedFill) { // Anti-aliased Fill const float AA_SIZE = 1.0f; const ImU32 col_trans = col & ~IM_COL32_A_MASK; - const int idx_count = (points_count-2)*3 + points_count*6; - const int vtx_count = (points_count*2); + 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 @@ -865,24 +861,23 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun } // 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); - _VtxWritePtr[i0 << 1].pos.x = diff.y; - _VtxWritePtr[i0 << 1].pos.y = -diff.x; + temp_normals[i0].x = diff.y; + temp_normals[i0].y = -diff.x; } - ImVec2 n0 = _VtxWritePtr[(points_count-1) << 1].pos; - for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) { // Average normals - const ImVec2& n1 = _VtxWritePtr[0].pos; + const ImVec2& n0 = temp_normals[i0]; + const ImVec2& n1 = temp_normals[i1]; ImVec2 dm = (n0 + n1) * 0.5f; - n0 = n1; float dmr2 = dm.x*dm.x + dm.y*dm.y; if (dmr2 > 0.000001f) { @@ -907,7 +902,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun else { // Non Anti-aliased Fill - const int idx_count = (points_count-2)*3; + 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++) @@ -917,7 +912,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun } for (int i = 2; i < points_count; i++) { - _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+i-1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+i); + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + i - 1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + i); _IdxWritePtr += 3; } _VtxCurrentIdx += (ImDrawIdx)vtx_count; From f38dd953941ec40e2b009c35d3aed5073981f93e Mon Sep 17 00:00:00 2001 From: G-glop Date: Mon, 31 Dec 2018 10:41:41 +0100 Subject: [PATCH 4/4] alias end of the vertex buffer as a tempoary array --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 7eb7b89f151e..4db39f8bf567 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -861,7 +861,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun } // Compute normals - ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); + ImVec2* temp_normals = (ImVec2*)((size_t)(_VtxWritePtr + vtx_count) & ~(alignof(ImVec2) - 1)) - points_count; for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) { const ImVec2& p0 = points[i0];