From e6003e3029fee821eb3a576ee5e3cc5406dae42a Mon Sep 17 00:00:00 2001 From: SergeyN Date: Wed, 13 May 2020 07:32:10 +0200 Subject: [PATCH 1/2] obvious optimization: call getter, transformer and cull test once per point instead of twice --- implot.cpp | 53 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/implot.cpp b/implot.cpp index 98cb7e8..5a6cd8b 100644 --- a/implot.cpp +++ b/implot.cpp @@ -2081,34 +2081,43 @@ inline void RenderLineAA(ImDrawList& DrawList, const ImVec2& p1, const ImVec2& p } template -inline void RenderLines(Transformer transformer, ImDrawList& DrawList, Getter getter, int count, int offset, float line_weight, ImU32 col_line, bool cull) { +inline void RenderLineStrip(Transformer transformer, ImDrawList& DrawList, Getter getter, int count, int offset, float line_weight, ImU32 col_line, bool cull) { // render line segments + offset %= count; + if (offset < 0) offset += count; // shift negative offset to positive range + int i_start = offset + 1; + if (i_start >= count ) i_start -= count; + int i_end = offset + count; + if (i_end >= count) i_end -= count; + const int segments = count - 1; - int i1 = offset; - ImVec2 p1, p2; + ImVec2 p1 = transformer(getter(offset)); + bool test1 = !cull || gp.BB_Grid.Contains(p1); if (HasFlag(gp.CurrentPlot->Flags, ImPlotFlags_AntiAliased)) { - for (int s = 0; s < segments; ++s) { - const int i2 = (i1 + 1) % count; - p1 = transformer(getter(i1)); - p2 = transformer(getter(i2)); - i1 = i2; - if (!cull || gp.BB_Grid.Contains(p1) || gp.BB_Grid.Contains(p2)) + for (int i1 = i_start; i1 != i_end; i1 = i1 + 1 < count ? i1 + 1 : i1 + 1 - count) + { + ImVec2 p2 = transformer(getter(i1)); + bool test2 = !cull || gp.BB_Grid.Contains(p2); + if (test1 | test2) RenderLineAA(DrawList, p1, p2, line_weight, col_line); + p1 = p2; + test1 = test2; } } else { const ImVec2 uv = DrawList._Data->TexUvWhitePixel; DrawList.PrimReserve(segments * 6, segments * 4); int segments_culled = 0; - for (int s = 0; s < segments; ++s) { - const int i2 = (i1 + 1) % count; - p1 = transformer(getter(i1)); - p2 = transformer(getter(i2)); - i1 = i2; - if (!cull || gp.BB_Grid.Contains(p1) || gp.BB_Grid.Contains(p2)) - RenderLine(DrawList, p1, p2, line_weight, col_line, uv); - else - segments_culled++; + for (int i1 = i_start; i1 != i_end; i1 = i1 + 1 < count ? i1 + 1 : i1 + 1 - count) + { + ImVec2 p2 = transformer(getter(i1)); + bool test2 = !cull || gp.BB_Grid.Contains(p2); + if (test1 | test2) + RenderLine(DrawList, p1, p2, line_weight, col_line, uv); + else + segments_culled++; + p1 = p2; + test1 = test2; } if (segments_culled > 0) DrawList.PrimUnreserve(segments_culled * 6, segments_culled * 4); @@ -2204,13 +2213,13 @@ inline void PlotEx(const char* label_id, Getter getter, int count, int offset) PushPlotClipRect(); if (count > 1 && rend_line) { if (HasFlag(plot->XAxis.Flags, ImAxisFlags_LogScale) && HasFlag(plot->YAxis[y_axis].Flags, ImAxisFlags_LogScale)) - RenderLines(Plt2PixLogLog(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); + RenderLineStrip(Plt2PixLogLog(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); else if (HasFlag(plot->XAxis.Flags, ImAxisFlags_LogScale)) - RenderLines(Plt2PixLogLin(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); + RenderLineStrip(Plt2PixLogLin(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); else if (HasFlag(plot->YAxis[y_axis].Flags, ImAxisFlags_LogScale)) - RenderLines(Plt2PixLinLog(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); + RenderLineStrip(Plt2PixLinLog(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); else - RenderLines(Plt2PixLinLin(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); + RenderLineStrip(Plt2PixLinLin(y_axis), DrawList, getter, count, offset, line_weight, col_line, cull); } // render markers if (gp.Style.Marker != ImMarker_None) { From b11fb62f55ee8a815d88f90ed583be155352bead Mon Sep 17 00:00:00 2001 From: Evan Pezent Date: Wed, 13 May 2020 08:43:33 -0500 Subject: [PATCH 2/2] test negative offset, add to demo --- implot_demo.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/implot_demo.cpp b/implot_demo.cpp index 62d3504..45bd878 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -706,6 +706,20 @@ void ShowDemoWindow(bool* p_open) { } } //------------------------------------------------------------------------- + if (ImGui::CollapsingHeader("Offset Data")) { + float xs[50], ys[50]; + for (int i = 0; i < 50; ++i) { + xs[i] = 0.5 + 0.4 * cos(i/50.f * 6.28); + ys[i] = 0.5 + 0.4 * sin(i/50.f * 6.28); + } + static int offset = 0; + ImGui::SliderInt("Offset", &offset, -100, 100); + if (ImPlot::BeginPlot("##offset")) { + ImPlot::Plot("circle", xs, ys, 50, offset); + ImPlot::EndPlot(); + } + } + //------------------------------------------------------------------------- if (ImGui::CollapsingHeader("Custom Styles")) { static ImVec4 my_palette[3] = { {0.000f, 0.980f, 0.604f, 1.0f},