From 5dada770c5cfb8f1eba9ba2b3c0d1f8dec4c85ba Mon Sep 17 00:00:00 2001 From: Breno Cunha Queiroz Date: Sat, 4 Apr 2026 07:49:50 +0200 Subject: [PATCH 01/11] feat: add per-index color/size fields to ImPlot3DSpec --- example/CMakeLists.txt | 2 +- implot3d.h | 87 +++++++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 7bcb2e8..f3615ca 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -47,7 +47,7 @@ target_link_libraries(imgui PUBLIC glfw OpenGL::GL) FetchContent_Declare( implot GIT_REPOSITORY "https://github.com/epezent/implot" - GIT_TAG "v0.17" + GIT_TAG "feat/spec-colors" GIT_PROGRESS TRUE ) FetchContent_MakeAvailable(implot) diff --git a/implot3d.h b/implot3d.h index a529f8e..14b3cf9 100644 --- a/implot3d.h +++ b/implot3d.h @@ -103,17 +103,22 @@ typedef ImTextureID ImTextureRef; // Plotting properties. These provide syntactic sugar for creating ImPlot3DSpec from (ImPlot3DProp,value) pairs enum ImPlot3DProp_ { - ImPlot3DProp_LineColor, // Line color; IMPLOT3D_AUTO_COL will use next Colormap color - ImPlot3DProp_LineWeight, // Line weight in pixels - ImPlot3DProp_FillColor, // Fill color (applies to shaded regions); IMPLOT3D_AUTO_COL will use next Colormap color - ImPlot3DProp_FillAlpha, // Alpha multiplier (applies to FillColor and MarkerFillColor) - ImPlot3DProp_Marker, // Marker type - ImPlot3DProp_MarkerSize, // Size of markers (radius) *in pixels* - ImPlot3DProp_MarkerLineColor, // Marker outline color; IMPLOT3D_AUTO_COL will use next LineColor - ImPlot3DProp_MarkerFillColor, // Marker fill color; IMPLOT3D_AUTO_COL will use LineColor - ImPlot3DProp_Offset, // Data index offset - ImPlot3DProp_Stride, // Data stride in bytes; IMPLOT3D_AUTO will result in sizeof(T) where T is the type passed to PlotX - ImPlot3DProp_Flags // Optional item flags; can be composed from common ImPlot3DItemFlags and/or specialized ImPlot3DXFlags + ImPlot3DProp_LineColor, // Line color; IMPLOT3D_AUTO_COL will use next Colormap color + ImPlot3DProp_LineColors, // Array of line colors (ImU32*); if nullptr, use LineColor for all + ImPlot3DProp_LineWeight, // Line weight in pixels + ImPlot3DProp_FillColor, // Fill color (applies to shaded regions); IMPLOT3D_AUTO_COL will use next Colormap color + ImPlot3DProp_FillColors, // Array of fill colors (ImU32*); if nullptr, use FillColor for all + ImPlot3DProp_FillAlpha, // Alpha multiplier (applies to FillColor, FillColors, MarkerFillColor, and MarkerFillColors) + ImPlot3DProp_Marker, // Marker type + ImPlot3DProp_MarkerSize, // Size of markers (radius) *in pixels* + ImPlot3DProp_MarkerSizes, // Array of marker sizes (float*); if nullptr, use MarkerSize for all + ImPlot3DProp_MarkerLineColor, // Marker outline color; IMPLOT3D_AUTO_COL will use next LineColor + ImPlot3DProp_MarkerLineColors, // Array of marker outline colors (ImU32*); if nullptr, use MarkerLineColor for all + ImPlot3DProp_MarkerFillColor, // Marker fill color; IMPLOT3D_AUTO_COL will use LineColor + ImPlot3DProp_MarkerFillColors, // Array of marker fill colors (ImU32*); if nullptr, use MarkerFillColor for all + ImPlot3DProp_Offset, // Data index offset + ImPlot3DProp_Stride, // Data stride in bytes; IMPLOT3D_AUTO will result in sizeof(T) where T is the type passed to PlotX + ImPlot3DProp_Flags // Optional item flags; can be composed from common ImPlot3DItemFlags and/or specialized ImPlot3DXFlags }; // Flags for ImPlot3D::BeginPlot() @@ -374,16 +379,21 @@ enum ImPlot3DColormap_ { // ImPlot3DProp_Flags, ImPlot3DItemFlags_NoLegend | ImPlot3DLineFlags_Segments // }); struct ImPlot3DSpec { - ImVec4 LineColor = IMPLOT3D_AUTO_COL; // Line color; IMPLOT3D_AUTO_COL will use next Colormap color - float LineWeight = 1.0f; // Line weight in pixels - ImVec4 FillColor = IMPLOT3D_AUTO_COL; // Fill color (applies to shaded regions); IMPLOT3D_AUTO_COL will use next Colormap color - float FillAlpha = IMPLOT3D_AUTO; // Alpha multiplier (applies to FillColor and MarkerFillColor) - ImPlot3DMarker Marker = ImPlot3DMarker_Auto; // Marker type - float MarkerSize = IMPLOT3D_AUTO; // Size of markers (radius) *in pixels* - ImVec4 MarkerLineColor = IMPLOT3D_AUTO_COL; // Marker outline color; IMPLOT3D_AUTO_COL will use LineColor - ImVec4 MarkerFillColor = IMPLOT3D_AUTO_COL; // Marker fill color; IMPLOT3D_AUTO_COL will use LineColor - int Offset = 0; // Data index offset - int Stride = IMPLOT3D_AUTO; // Data stride in bytes; IMPLOT3D_AUTO will result in sizeof(T) where T is the type passed to PlotX + ImVec4 LineColor = IMPLOT3D_AUTO_COL; // Line color; IMPLOT3D_AUTO_COL will use next Colormap color + ImU32* LineColors = nullptr; // Per-index line colors; if nullptr, use LineColor for all + float LineWeight = 1.0f; // Line weight in pixels + ImVec4 FillColor = IMPLOT3D_AUTO_COL; // Fill color (applies to shaded regions); IMPLOT3D_AUTO_COL will use next Colormap color + ImU32* FillColors = nullptr; // Per-index fill colors; if nullptr, use FillColor for all + float FillAlpha = IMPLOT3D_AUTO; // Alpha multiplier (applies to FillColor, FillColors, MarkerFillColor, and MarkerFillColors) + ImPlot3DMarker Marker = ImPlot3DMarker_Auto; // Marker type + float MarkerSize = IMPLOT3D_AUTO; // Size of markers (radius) *in pixels* + float* MarkerSizes = nullptr; // Per-index marker sizes; if nullptr, use MarkerSize for all + ImVec4 MarkerLineColor = IMPLOT3D_AUTO_COL; // Marker outline color; IMPLOT3D_AUTO_COL will use LineColor + ImU32* MarkerLineColors = nullptr; // Per-index marker outline colors; if nullptr, use MarkerLineColor for all + ImVec4 MarkerFillColor = IMPLOT3D_AUTO_COL; // Marker fill color; IMPLOT3D_AUTO_COL will use LineColor + ImU32* MarkerFillColors = nullptr; // Per-index marker fill colors; if nullptr, use MarkerFillColor for all + int Offset = 0; // Data index offset + int Stride = IMPLOT3D_AUTO; // Data stride in bytes; IMPLOT3D_AUTO will result in sizeof(T) where T is the type passed to PlotX ImPlot3DItemFlags Flags = ImPlot3DItemFlags_None; // Optional item flags; can be composed from common ImPlot3DItemFlags and/or specialized ImPlot3DXFlags @@ -423,6 +433,27 @@ struct ImPlot3DSpec { IM_ASSERT(0 && "User provided an ImPlot3DProp which cannot be set from scalar value!"); } + // Set a property from an ImU32* array (per-index colors). + void SetProp(ImPlot3DProp prop, ImU32* v) { + switch (prop) { + case ImPlot3DProp_LineColors: LineColors = v; return; + case ImPlot3DProp_FillColors: FillColors = v; return; + case ImPlot3DProp_MarkerLineColors: MarkerLineColors = v; return; + case ImPlot3DProp_MarkerFillColors: MarkerFillColors = v; return; + default: break; + } + IM_ASSERT(0 && "User provided an ImPlot3DProp which cannot be set from ImU32* value!"); + } + + // Set a property from a float* array (per-index sizes). + void SetProp(ImPlot3DProp prop, float* v) { + switch (prop) { + case ImPlot3DProp_MarkerSizes: MarkerSizes = v; return; + default: break; + } + IM_ASSERT(0 && "User provided an ImPlot3DProp which cannot be set from float* value!"); + } + // Set a property from an ImVec4 value. void SetProp(ImPlot3DProp prop, const ImVec4& v) { switch (prop) { @@ -1008,8 +1039,7 @@ struct ImPlot3DStyle { // Constructor IMPLOT3D_API ImPlot3DStyle(); ImPlot3DStyle(const ImPlot3DStyle& other) = default; - ImPlot3DStyle& operator=(const ImPlot3DStyle& other) = - default; + ImPlot3DStyle& operator=(const ImPlot3DStyle& other) = default; }; //----------------------------------------------------------------------------- @@ -1066,11 +1096,16 @@ extern unsigned int duck_idx[DUCK_IDX_COUNT]; // Duck indices namespace ImPlot3D { // OBSOLETED in v0.4 (from February 2026) -// IMPLOT_API void SetNextLineStyle(const ImVec4& col = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO); // OBSOLETED IN v0.4 // Set ImPlotSpec.LineColor/LineWeight or construct ImPlotSpec with { ImPlotSpec_LineColor, color, ImPlotSpec_LineWeight, weight }. +// IMPLOT_API void SetNextLineStyle(const ImVec4& col = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO); // OBSOLETED IN v0.4 // Set +// ImPlotSpec.LineColor/LineWeight or construct ImPlotSpec with { ImPlotSpec_LineColor, color, ImPlotSpec_LineWeight, weight }. -// IMPLOT_API void SetNextFillStyle(const ImVec4& col = IMPLOT_AUTO_COL, float alpha_mod = IMPLOT_AUTO);// OBSOLETED IN v0.4 // Set ImPlotSpec.FillColor/FillAlpha or construct ImPlotSpec with { ImPlotSpec_FillColor, color, ImPlotSpec_FillAlpha, alpha }. +// IMPLOT_API void SetNextFillStyle(const ImVec4& col = IMPLOT_AUTO_COL, float alpha_mod = IMPLOT_AUTO);// OBSOLETED IN v0.4 // Set +// ImPlotSpec.FillColor/FillAlpha or construct ImPlotSpec with { ImPlotSpec_FillColor, color, ImPlotSpec_FillAlpha, alpha }. -// IMPLOT_API void SetNextMarkerStyle(ImPlotMarker marker = IMPLOT_AUTO, float size = IMPLOT_AUTO, const ImVec4& fill = IMPLOT_AUTO_COL, float weight = IMPLOT_AUTO, const ImVec4& outline = IMPLOT_AUTO_COL); // OBSOLETED IN v0.4 // Set ImPlotSpec.Marker/MarkerSize/MarkerFillColor/LineWeight/MarkerLineColor or construct ImPlotSpec with { ImPlotSpec_Marker, marker, ImPlotSpec_MarkerSize, size, ImPlotSpec_MarkerFillColor, fill_color, ImPlotSpec_LineWeight, weight, ImPlotSpec_MarkerLineColor, outline }. +// IMPLOT_API void SetNextMarkerStyle(ImPlotMarker marker = IMPLOT_AUTO, float size = IMPLOT_AUTO, const ImVec4& fill = IMPLOT_AUTO_COL, float weight +// = IMPLOT_AUTO, const ImVec4& outline = IMPLOT_AUTO_COL); // OBSOLETED IN v0.4 // Set +// ImPlotSpec.Marker/MarkerSize/MarkerFillColor/LineWeight/MarkerLineColor or construct ImPlotSpec with { ImPlotSpec_Marker, marker, +// ImPlotSpec_MarkerSize, size, ImPlotSpec_MarkerFillColor, fill_color, ImPlotSpec_LineWeight, weight, ImPlotSpec_MarkerLineColor, outline }. // OBSOLETED in v0.3 -> PLANNED REMOVAL in v1.0 IMPLOT3D_DEPRECATED(IMPLOT3D_API ImVec2 GetPlotPos()); // Renamed to GetPlotRectPos() From 0dc8b8dfedcd2b612d62e32f74c8e6dc3e556142 Mon Sep 17 00:00:00 2001 From: Breno Cunha Queiroz Date: Sat, 4 Apr 2026 08:16:51 +0200 Subject: [PATCH 02/11] refactor: render plots using GetterConstColor --- implot3d_items.cpp | 238 ++++++++++++++++++++++++++++----------------- 1 file changed, 151 insertions(+), 87 deletions(-) diff --git a/implot3d_items.cpp b/implot3d_items.cpp index 373e909..bcae9fb 100644 --- a/implot3d_items.cpp +++ b/implot3d_items.cpp @@ -344,9 +344,9 @@ struct RendererBase { const unsigned int VtxConsumed; // Number of vertices consumed per primitive }; -template struct RendererMarkersFill : RendererBase { - RendererMarkersFill(const _Getter& getter, const ImVec2* marker, int count, float size, ImU32 col) - : RendererBase(getter.Count, (count - 2) * 3, count), Getter(getter), Marker(marker), Count(count), Size(size), Col(col) {} +template struct RendererMarkersFill : RendererBase { + RendererMarkersFill(const _Getter& getter, const _GetterColor& col_getter, const _GetterSize& size_getter, const ImVec2* marker, int count) + : RendererBase(getter.Count, (count - 2) * 3, count), Getter(getter), ColGetter(col_getter), SizeGetter(size_getter), Marker(marker), Count(count) {} void Init(ImDrawList3D& draw_list_3d) const { UV = draw_list_3d._SharedData->TexUvWhitePixel; } @@ -355,12 +355,14 @@ template struct RendererMarkersFill : RendererBase { if (!cull_box.Contains(p_plot)) return false; ImVec2 p = PlotToPixels(p_plot); + ImU32 col = ColGetter(prim); + float size = SizeGetter(prim); // 3 vertices per triangle for (int i = 0; i < Count; i++) { - draw_list_3d._VtxWritePtr[0].pos.x = p.x + Marker[i].x * Size; - draw_list_3d._VtxWritePtr[0].pos.y = p.y + Marker[i].y * Size; + draw_list_3d._VtxWritePtr[0].pos.x = p.x + Marker[i].x * size; + draw_list_3d._VtxWritePtr[0].pos.y = p.y + Marker[i].y * size; draw_list_3d._VtxWritePtr[0].uv = UV; - draw_list_3d._VtxWritePtr[0].col = Col; + draw_list_3d._VtxWritePtr[0].col = col; draw_list_3d._VtxWritePtr++; } // 3 indices per triangle @@ -379,17 +381,17 @@ template struct RendererMarkersFill : RendererBase { return true; } const _Getter& Getter; + const _GetterColor ColGetter; + const _GetterSize SizeGetter; const ImVec2* Marker; const int Count; - const float Size; - const ImU32 Col; mutable ImVec2 UV; }; -template struct RendererMarkersLine : RendererBase { - RendererMarkersLine(const _Getter& getter, const ImVec2* marker, int count, float size, float weight, ImU32 col) - : RendererBase(getter.Count, count / 2 * 6, count / 2 * 4), Getter(getter), Marker(marker), Count(count), - HalfWeight(ImMax(1.0f, weight) * 0.5f), Size(size), Col(col) {} +template struct RendererMarkersLine : RendererBase { + RendererMarkersLine(const _Getter& getter, const _GetterColor& col_getter, const _GetterSize& size_getter, const ImVec2* marker, int count, float weight) + : RendererBase(getter.Count, count / 2 * 6, count / 2 * 4), Getter(getter), ColGetter(col_getter), SizeGetter(size_getter), + Marker(marker), Count(count), HalfWeight(ImMax(1.0f, weight) * 0.5f) {} void Init(ImDrawList3D& draw_list_3d) const { GetLineRenderProps(draw_list_3d, HalfWeight, UV0, UV1); } @@ -398,27 +400,29 @@ template struct RendererMarkersLine : RendererBase { if (!cull_box.Contains(p_plot)) return false; ImVec2 p = PlotToPixels(p_plot); + ImU32 col = ColGetter(prim); + float size = SizeGetter(prim); for (int i = 0; i < Count; i = i + 2) { - ImVec2 p1(p.x + Marker[i].x * Size, p.y + Marker[i].y * Size); - ImVec2 p2(p.x + Marker[i + 1].x * Size, p.y + Marker[i + 1].y * Size); - PrimLine(draw_list_3d, p1, p2, HalfWeight, Col, UV0, UV1, GetPointDepth(p_plot)); + ImVec2 p1(p.x + Marker[i].x * size, p.y + Marker[i].y * size); + ImVec2 p2(p.x + Marker[i + 1].x * size, p.y + Marker[i + 1].y * size); + PrimLine(draw_list_3d, p1, p2, HalfWeight, col, UV0, UV1, GetPointDepth(p_plot)); } return true; } const _Getter& Getter; + const _GetterColor ColGetter; + const _GetterSize SizeGetter; const ImVec2* Marker; const int Count; mutable float HalfWeight; - const float Size; - const ImU32 Col; mutable ImVec2 UV0; mutable ImVec2 UV1; }; -template struct RendererLineStrip : RendererBase { - RendererLineStrip(const _Getter& getter, ImU32 col, float weight) - : RendererBase(getter.Count - 1, 6, 4), Getter(getter), Col(col), HalfWeight(ImMax(1.0f, weight) * 0.5f) { +template struct RendererLineStrip : RendererBase { + RendererLineStrip(const _Getter& getter, const _GetterColor& col_getter, float weight) + : RendererBase(getter.Count - 1, 6, 4), Getter(getter), ColGetter(col_getter), HalfWeight(ImMax(1.0f, weight) * 0.5f) { // Initialize the first point in plot coordinates P1_plot = Getter(0); } @@ -437,7 +441,7 @@ template struct RendererLineStrip : RendererBase { ImVec2 P1_screen = PlotToPixels(P1_clipped); ImVec2 P2_screen = PlotToPixels(P2_clipped); // Render the line segment - PrimLine(draw_list_3d, P1_screen, P2_screen, HalfWeight, Col, UV0, UV1, GetPointDepth((P1_plot + P2_plot) * 0.5)); + PrimLine(draw_list_3d, P1_screen, P2_screen, HalfWeight, ColGetter(prim), UV0, UV1, GetPointDepth((P1_plot + P2_plot) * 0.5)); } // Update for next segment @@ -447,16 +451,16 @@ template struct RendererLineStrip : RendererBase { } const _Getter& Getter; - const ImU32 Col; + const _GetterColor ColGetter; mutable float HalfWeight; mutable ImPlot3DPoint P1_plot; mutable ImVec2 UV0; mutable ImVec2 UV1; }; -template struct RendererLineStripSkip : RendererBase { - RendererLineStripSkip(const _Getter& getter, ImU32 col, float weight) - : RendererBase(getter.Count - 1, 6, 4), Getter(getter), Col(col), HalfWeight(ImMax(1.0f, weight) * 0.5f) { +template struct RendererLineStripSkip : RendererBase { + RendererLineStripSkip(const _Getter& getter, const _GetterColor& col_getter, float weight) + : RendererBase(getter.Count - 1, 6, 4), Getter(getter), ColGetter(col_getter), HalfWeight(ImMax(1.0f, weight) * 0.5f) { // Initialize the first point in plot coordinates P1_plot = Getter(0); } @@ -480,7 +484,7 @@ template struct RendererLineStripSkip : RendererBase { ImVec2 P1_screen = PlotToPixels(P1_clipped); ImVec2 P2_screen = PlotToPixels(P2_clipped); // Render the line segment - PrimLine(draw_list_3d, P1_screen, P2_screen, HalfWeight, Col, UV0, UV1, GetPointDepth((P1_plot + P2_plot) * 0.5)); + PrimLine(draw_list_3d, P1_screen, P2_screen, HalfWeight, ColGetter(prim), UV0, UV1, GetPointDepth((P1_plot + P2_plot) * 0.5)); } } @@ -492,16 +496,16 @@ template struct RendererLineStripSkip : RendererBase { } const _Getter& Getter; - const ImU32 Col; + const _GetterColor ColGetter; mutable float HalfWeight; mutable ImPlot3DPoint P1_plot; mutable ImVec2 UV0; mutable ImVec2 UV1; }; -template struct RendererLineSegments : RendererBase { - RendererLineSegments(const _Getter& getter, ImU32 col, float weight) - : RendererBase(getter.Count / 2, 6, 4), Getter(getter), Col(col), HalfWeight(ImMax(1.0f, weight) * 0.5f) {} +template struct RendererLineSegments : RendererBase { + RendererLineSegments(const _Getter& getter, const _GetterColor& col_getter, float weight) + : RendererBase(getter.Count / 2, 6, 4), Getter(getter), ColGetter(col_getter), HalfWeight(ImMax(1.0f, weight) * 0.5f) {} void Init(ImDrawList3D& draw_list_3d) const { GetLineRenderProps(draw_list_3d, HalfWeight, UV0, UV1); } @@ -522,7 +526,7 @@ template struct RendererLineSegments : RendererBase { ImVec2 P1_screen = PlotToPixels(P1_clipped); ImVec2 P2_screen = PlotToPixels(P2_clipped); // Render the line segment - PrimLine(draw_list_3d, P1_screen, P2_screen, HalfWeight, Col, UV0, UV1, GetPointDepth((P1_plot + P2_plot) * 0.5)); + PrimLine(draw_list_3d, P1_screen, P2_screen, HalfWeight, ColGetter(prim), UV0, UV1, GetPointDepth((P1_plot + P2_plot) * 0.5)); } return visible; } @@ -531,14 +535,14 @@ template struct RendererLineSegments : RendererBase { } const _Getter& Getter; - const ImU32 Col; + const _GetterColor ColGetter; mutable float HalfWeight; mutable ImVec2 UV0; mutable ImVec2 UV1; }; -template struct RendererTriangleFill : RendererBase { - RendererTriangleFill(const _Getter& getter, ImU32 col) : RendererBase(getter.Count / 3, 3, 3), Getter(getter), Col(col) {} +template struct RendererTriangleFill : RendererBase { + RendererTriangleFill(const _Getter& getter, const _GetterColor& col_getter) : RendererBase(getter.Count / 3, 3, 3), Getter(getter), ColGetter(col_getter) {} void Init(ImDrawList3D& draw_list_3d) const { UV = draw_list_3d._SharedData->TexUvWhitePixel; } @@ -558,19 +562,21 @@ template struct RendererTriangleFill : RendererBase { p[1] = PlotToPixels(p_plot[1]); p[2] = PlotToPixels(p_plot[2]); + ImU32 col = ColGetter(prim); + // 3 vertices per triangle draw_list_3d._VtxWritePtr[0].pos.x = p[0].x; draw_list_3d._VtxWritePtr[0].pos.y = p[0].y; draw_list_3d._VtxWritePtr[0].uv = UV; - draw_list_3d._VtxWritePtr[0].col = Col; + draw_list_3d._VtxWritePtr[0].col = col; draw_list_3d._VtxWritePtr[1].pos.x = p[1].x; draw_list_3d._VtxWritePtr[1].pos.y = p[1].y; draw_list_3d._VtxWritePtr[1].uv = UV; - draw_list_3d._VtxWritePtr[1].col = Col; + draw_list_3d._VtxWritePtr[1].col = col; draw_list_3d._VtxWritePtr[2].pos.x = p[2].x; draw_list_3d._VtxWritePtr[2].pos.y = p[2].y; draw_list_3d._VtxWritePtr[2].uv = UV; - draw_list_3d._VtxWritePtr[2].col = Col; + draw_list_3d._VtxWritePtr[2].col = col; draw_list_3d._VtxWritePtr += 3; // 3 indices per triangle @@ -589,12 +595,12 @@ template struct RendererTriangleFill : RendererBase { } const _Getter& Getter; + const _GetterColor ColGetter; mutable ImVec2 UV; - const ImU32 Col; }; -template struct RendererQuadFill : RendererBase { - RendererQuadFill(const _Getter& getter, ImU32 col) : RendererBase(getter.Count / 4, 6, 4), Getter(getter), Col(col) {} +template struct RendererQuadFill : RendererBase { + RendererQuadFill(const _Getter& getter, const _GetterColor& col_getter) : RendererBase(getter.Count / 4, 6, 4), Getter(getter), ColGetter(col_getter) {} void Init(ImDrawList3D& draw_list_3d) const { UV = draw_list_3d._SharedData->TexUvWhitePixel; } @@ -616,26 +622,28 @@ template struct RendererQuadFill : RendererBase { p[2] = PlotToPixels(p_plot[2]); p[3] = PlotToPixels(p_plot[3]); + ImU32 col = ColGetter(prim); + // Add vertices for two triangles draw_list_3d._VtxWritePtr[0].pos.x = p[0].x; draw_list_3d._VtxWritePtr[0].pos.y = p[0].y; draw_list_3d._VtxWritePtr[0].uv = UV; - draw_list_3d._VtxWritePtr[0].col = Col; + draw_list_3d._VtxWritePtr[0].col = col; draw_list_3d._VtxWritePtr[1].pos.x = p[1].x; draw_list_3d._VtxWritePtr[1].pos.y = p[1].y; draw_list_3d._VtxWritePtr[1].uv = UV; - draw_list_3d._VtxWritePtr[1].col = Col; + draw_list_3d._VtxWritePtr[1].col = col; draw_list_3d._VtxWritePtr[2].pos.x = p[2].x; draw_list_3d._VtxWritePtr[2].pos.y = p[2].y; draw_list_3d._VtxWritePtr[2].uv = UV; - draw_list_3d._VtxWritePtr[2].col = Col; + draw_list_3d._VtxWritePtr[2].col = col; draw_list_3d._VtxWritePtr[3].pos.x = p[3].x; draw_list_3d._VtxWritePtr[3].pos.y = p[3].y; draw_list_3d._VtxWritePtr[3].uv = UV; - draw_list_3d._VtxWritePtr[3].col = Col; + draw_list_3d._VtxWritePtr[3].col = col; draw_list_3d._VtxWritePtr += 4; @@ -663,8 +671,8 @@ template struct RendererQuadFill : RendererBase { } const _Getter& Getter; + const _GetterColor ColGetter; mutable ImVec2 UV; - const ImU32 Col; }; template struct RendererQuadImage : RendererBase { @@ -999,13 +1007,51 @@ struct GetterMeshTriangles { int Count; }; +//----------------------------------------------------------------------------- +// [SECTION] Color and Size Getters +//----------------------------------------------------------------------------- + +struct GetterConstColor { + GetterConstColor(ImU32 col) : Col(col) {} + IMPLOT3D_INLINE ImU32 operator()(int) const { return Col; } + ImU32 Col; +}; + +struct GetterIdxColor { + GetterIdxColor(const ImU32* data, int count, float alpha = 1.0f) : Data(data), Count(count), Alpha(alpha) {} + IMPLOT3D_INLINE ImU32 operator()(int idx) const { + ImU32 col = Data[idx]; + if (Alpha < 1.0f) { + ImVec4 c = ImGui::ColorConvertU32ToFloat4(col); + c.w *= Alpha; + col = ImGui::ColorConvertFloat4ToU32(c); + } + return col; + } + const ImU32* Data; + const int Count; + const float Alpha; +}; + +struct GetterConstSize { + GetterConstSize(float size) : Size(size) {} + IMPLOT3D_INLINE float operator()(int) const { return Size; } + float Size; +}; + +struct GetterIdxSize { + GetterIdxSize(const float* data, int count) : Data(data), Count(count) {} + IMPLOT3D_INLINE float operator()(int idx) const { return Data[idx]; } + const float* Data; + const int Count; +}; + //----------------------------------------------------------------------------- // [SECTION] RenderPrimitives //----------------------------------------------------------------------------- -/// Renders primitive shapes -template