Skip to content

Commit aba5043

Browse files
authored
Add ImPlot (#352)
* basic implot setup * clean up implot context management, add some tests * more context cleanup * add unfortunate note about screenshot not fully working * add implot to demo
1 parent d7a2a04 commit aba5043

File tree

11 files changed

+121
-5
lines changed

11 files changed

+121
-5
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@
1212
[submodule "deps/glm"]
1313
path = deps/glm
1414
url = https://github.com/g-truc/glm.git
15+
[submodule "deps/imgui/implot"]
16+
path = deps/imgui/implot
17+
url = https://github.com/epezent/implot

deps/imgui/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,22 @@ endif()
1919

2020
if("${POLYSCOPE_BACKEND_OPENGL3_GLFW}")
2121

22-
set(SRCS imgui/imgui.cpp imgui/imgui_draw.cpp imgui/imgui_tables.cpp imgui/imgui_widgets.cpp imgui/imgui_demo.cpp imgui/backends/imgui_impl_glfw.cpp imgui/backends/imgui_impl_opengl3.cpp)
22+
# imgui sources
23+
list(APPEND SRCS imgui/imgui.cpp imgui/imgui_draw.cpp imgui/imgui_tables.cpp imgui/imgui_widgets.cpp imgui/imgui_demo.cpp imgui/backends/imgui_impl_glfw.cpp imgui/backends/imgui_impl_opengl3.cpp)
24+
25+
# implot sources
26+
list(APPEND SRCS
27+
implot/implot.cpp
28+
implot/implot_items.cpp
29+
)
2330

2431
add_library(
2532
imgui
2633
${SRCS}
2734
)
2835

2936
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/imgui/")
37+
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/implot/")
3038
target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../glfw/include/")
3139
target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../glad/include/")
3240

deps/imgui/implot

Submodule implot added at 3da8bd3

examples/demo-app/demo_app.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ void constructDemoCurveNetwork(std::string curveName, std::vector<glm::vec3> nod
9292
valYabs[iE] = std::fabs(midpointPos.y);
9393
}
9494
polyscope::getCurveNetwork(curveName)->addEdgeScalarQuantity("edge len", edgeLen, polyscope::DataType::MAGNITUDE);
95-
polyscope::getCurveNetwork(curveName)->addEdgeScalarQuantity("edge valYabs", valYabs, polyscope::DataType::MAGNITUDE);
95+
polyscope::getCurveNetwork(curveName)->addEdgeScalarQuantity("edge valYabs", valYabs,
96+
polyscope::DataType::MAGNITUDE);
9697
polyscope::getCurveNetwork(curveName)->addEdgeScalarQuantity("edge categorical", valEdgeCat,
9798
polyscope::DataType::CATEGORICAL);
9899
polyscope::getCurveNetwork(curveName)->addEdgeColorQuantity("eColor", randColor);
@@ -845,6 +846,9 @@ void callback() {
845846
}
846847
}
847848

849+
if (ImGui::Button("nested show")) {
850+
polyscope::show();
851+
}
848852

849853
if (ImGui::Button("drop camera view here")) {
850854
dropCameraView();
@@ -858,9 +862,28 @@ void callback() {
858862
addVolumeGrid();
859863
}
860864

865+
// ImPlot
866+
// dummy data
867+
if (ImGui::TreeNode("ImPlot")) {
868+
869+
std::vector<float> plotVals;
870+
for (float t = 0; t < 10.; t += 0.01) {
871+
plotVals.push_back(std::cosf(t + ImGui::GetTime()));
872+
}
873+
874+
// sample plot
875+
if (ImPlot::BeginPlot("test plot")) {
876+
ImPlot::PlotLine("sample_val", &plotVals.front(), plotVals.size());
877+
ImPlot::EndPlot();
878+
}
879+
880+
ImGui::TreePop();
881+
}
882+
861883
ImGui::PopItemWidth();
862884
}
863885

886+
864887
int main(int argc, char** argv) {
865888
// Configure the argument parser
866889
args::ArgumentParser parser("A simple demo of Polyscope.\nBy "

include/polyscope/polyscope.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <unordered_set>
1010

1111
#include "imgui.h"
12+
#include "implot.h"
1213

1314
#include "polyscope/context.h"
1415
#include "polyscope/group.h"

src/polyscope.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <thread>
99

1010
#include "imgui.h"
11+
#include "implot.h"
1112

1213
#include "polyscope/options.h"
1314
#include "polyscope/pick.h"
@@ -33,6 +34,7 @@ namespace {
3334
// initialization.
3435
struct ContextEntry {
3536
ImGuiContext* context;
37+
ImPlotContext* plotContext;
3638
std ::function<void()> callback;
3739
bool drawDefaultUI;
3840
};
@@ -183,7 +185,7 @@ void init(std::string backend) {
183185

184186
// Create an initial context based context. Note that calling show() never actually uses this context, because it
185187
// pushes a new one each time. But using frameTick() may use this context.
186-
contextStack.push_back(ContextEntry{ImGui::GetCurrentContext(), nullptr, true});
188+
contextStack.push_back(ContextEntry{ImGui::GetCurrentContext(), ImPlot::GetCurrentContext(), nullptr, true});
187189

188190
view::invalidateView();
189191

@@ -205,11 +207,13 @@ void pushContext(std::function<void()> callbackFunction, bool drawDefaultUI) {
205207

206208
// Create a new context and push it on to the stack
207209
ImGuiContext* newContext = ImGui::CreateContext();
210+
ImPlotContext* newPlotContext = ImPlot::CreateContext();
208211
ImGuiIO& oldIO = ImGui::GetIO(); // used to GLFW + OpenGL data to the new IO object
209212
#ifdef IMGUI_HAS_DOCK
210213
ImGuiPlatformIO& oldPlatformIO = ImGui::GetPlatformIO();
211214
#endif
212215
ImGui::SetCurrentContext(newContext);
216+
ImPlot::SetCurrentContext(newPlotContext);
213217
#ifdef IMGUI_HAS_DOCK
214218
// Propagate GLFW window handle to new context
215219
ImGui::GetMainViewport()->PlatformHandle = oldPlatformIO.Viewports[0]->PlatformHandle;
@@ -219,7 +223,8 @@ void pushContext(std::function<void()> callbackFunction, bool drawDefaultUI) {
219223

220224
render::engine->configureImGui();
221225

222-
contextStack.push_back(ContextEntry{newContext, callbackFunction, drawDefaultUI});
226+
227+
contextStack.push_back(ContextEntry{newContext, newPlotContext, callbackFunction, drawDefaultUI});
223228

224229
if (contextStack.size() > 50) {
225230
// Catch bugs with nested show()
@@ -259,14 +264,17 @@ void pushContext(std::function<void()> callbackFunction, bool drawDefaultUI) {
259264
// Workaround overzealous ImGui assertion before destroying any inner context
260265
// https://github.com/ocornut/imgui/pull/7175
261266
ImGui::SetCurrentContext(newContext);
267+
ImPlot::SetCurrentContext(newPlotContext);
262268
ImGui::GetIO().BackendPlatformUserData = nullptr;
263269
ImGui::GetIO().BackendRendererUserData = nullptr;
264270

271+
ImPlot::DestroyContext(newPlotContext);
265272
ImGui::DestroyContext(newContext);
266273

267274
// Restore the previous context, if there was one
268275
if (!contextStack.empty()) {
269276
ImGui::SetCurrentContext(contextStack.back().context);
277+
ImPlot::SetCurrentContext(contextStack.back().plotContext);
270278
}
271279
}
272280

src/render/mock_opengl/mock_gl_engine.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,7 @@ void MockGLEngine::initialize() {
15761576

15771577
void MockGLEngine::initializeImGui() {
15781578
ImGui::CreateContext(); // must call once at start
1579+
ImPlot::CreateContext();
15791580
configureImGui();
15801581
}
15811582

@@ -1597,7 +1598,10 @@ void MockGLEngine::shutdown() {
15971598
shutdownImGui();
15981599
}
15991600

1600-
void MockGLEngine::shutdownImGui() { ImGui::DestroyContext(); }
1601+
void MockGLEngine::shutdownImGui() {
1602+
ImPlot::DestroyContext();
1603+
ImGui::DestroyContext();
1604+
}
16011605

16021606
void MockGLEngine::swapDisplayBuffers() {}
16031607

src/render/opengl/gl_engine_egl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ void GLEngineEGL::initializeImGui() {
437437
// functions
438438

439439
ImGui::CreateContext();
440+
ImPlot::CreateContext();
440441
configureImGui();
441442
}
442443

src/render/opengl/gl_engine_glfw.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ void GLEngineGLFW::initializeImGui() {
148148
bindDisplay();
149149

150150
ImGui::CreateContext(); // must call once at start
151+
ImPlot::CreateContext();
151152

152153
// Set up ImGUI glfw bindings
153154
ImGui_ImplGlfw_InitForOpenGL(mainWindow, true);
@@ -197,6 +198,7 @@ void GLEngineGLFW::shutdownImGui() {
197198
// ImGui shutdown things
198199
ImGui_ImplOpenGL3_Shutdown();
199200
ImGui_ImplGlfw_Shutdown();
201+
ImPlot::DestroyContext();
200202
ImGui::DestroyContext();
201203
}
202204

src/screenshot.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,29 @@ std::vector<unsigned char> getRenderInBuffer(const ScreenshotOptions& options =
4747
bool requestedAlready = redrawRequested();
4848
requestRedraw();
4949

50+
// There's a ton of junk needed here to handle the includeUI case...
5051
// Create a new context and push it on to the stack
52+
// FIXME this solution doesn't really work, it forgets UI state like which nodes were open, scrolled setting, etc.
53+
// I'm not sure if it's possible to do this like we want in ImGui. The alternate solution would be to save the render
54+
// from the previous render pass, but I think that comes with other problems on the Polyscope side. I'm not sure what
55+
// the answer is.
5156
ImGuiContext* oldContext;
5257
ImGuiContext* newContext;
58+
ImPlotContext* oldPlotContext;
59+
ImPlotContext* newPlotContext;
5360
if (options.includeUI) {
5461
// WARNING: code duplicated here and in pushContext()
5562
oldContext = ImGui::GetCurrentContext();
5663
newContext = ImGui::CreateContext();
64+
oldPlotContext = ImPlot::GetCurrentContext();
65+
newPlotContext = ImPlot::CreateContext();
5766
ImGuiIO& oldIO = ImGui::GetIO(); // used to GLFW + OpenGL data to the new IO object
5867
#ifdef IMGUI_HAS_DOCK
5968
ImGuiPlatformIO& oldPlatformIO = ImGui::GetPlatformIO();
6069
#endif
6170
ImGui::SetCurrentContext(newContext);
71+
ImPlot::SetCurrentContext(newPlotContext);
72+
6273
#ifdef IMGUI_HAS_DOCK
6374
// Propagate GLFW window handle to new context
6475
ImGui::GetMainViewport()->PlatformHandle = oldPlatformIO.Viewports[0]->PlatformHandle;
@@ -81,11 +92,15 @@ std::vector<unsigned char> getRenderInBuffer(const ScreenshotOptions& options =
8192
// Workaround overzealous ImGui assertion before destroying any inner context
8293
// https://github.com/ocornut/imgui/pull/7175
8394
ImGui::SetCurrentContext(newContext);
95+
ImPlot::SetCurrentContext(newPlotContext);
8496
ImGui::GetIO().BackendPlatformUserData = nullptr;
8597
ImGui::GetIO().BackendRendererUserData = nullptr;
8698

99+
ImPlot::DestroyContext(newPlotContext);
87100
ImGui::DestroyContext(newContext);
101+
88102
ImGui::SetCurrentContext(oldContext);
103+
ImPlot::SetCurrentContext(oldPlotContext);
89104
}
90105

91106

0 commit comments

Comments
 (0)