From 8292034f447779e0c31f1e49faab5e8349b7d6d0 Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Thu, 11 Dec 2025 18:32:45 -0800 Subject: [PATCH 1/4] restore callback pointers on shutdown (fix unrelated bug) --- src/polyscope.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/polyscope.cpp b/src/polyscope.cpp index fb589916..b10dab50 100644 --- a/src/polyscope.cpp +++ b/src/polyscope.cpp @@ -10,6 +10,7 @@ #include "imgui.h" #include "implot.h" +#include "polyscope/imgui_config.h" #include "polyscope/options.h" #include "polyscope/pick.h" #include "polyscope/render/engine.h" @@ -1175,8 +1176,8 @@ void shutdown(bool allowMidFrameShutdown) { removeAllSlicePlanes(); clearMessages(); state::userCallback = nullptr; - options::configureImGuiStyleCallback = nullptr; - options::prepareImGuiFontsCallback = nullptr; + options::configureImGuiStyleCallback = configureImGuiStyle; // restore defaults + options::prepareImGuiFontsCallback = prepareImGuiFonts; options::filesDroppedCallback = nullptr; // Shut down the render engine From 44af44e30f0de0917881fa34211d22c05d98ae62 Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Thu, 11 Dec 2025 18:34:13 -0800 Subject: [PATCH 2/4] add failing test to repro renderimage slice bug --- test/src/floating_test.cpp | 70 ++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/test/src/floating_test.cpp b/test/src/floating_test.cpp index c1578be6..bee1f692 100644 --- a/test/src/floating_test.cpp +++ b/test/src/floating_test.cpp @@ -104,6 +104,12 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) { im->setEnabled(true); polyscope::show(3); polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + + // add a slice plane + polyscope::addSceneSlicePlane(); + polyscope::show(3); + polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + polyscope::removeLastSceneSlicePlane(); } { // with no normals polyscope::DepthRenderImageQuantity* im = polyscope::addDepthRenderImageQuantity( @@ -112,6 +118,12 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) { im->setEnabled(true); polyscope::show(3); polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + + // add a slice plane + polyscope::addSceneSlicePlane(); + polyscope::show(3); + polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + polyscope::removeLastSceneSlicePlane(); } { // ColorImageQuantity @@ -121,6 +133,12 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) { im->setEnabled(true); polyscope::show(3); polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + + // add a slice plane + polyscope::addSceneSlicePlane(); + polyscope::show(3); + polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + polyscope::removeLastSceneSlicePlane(); } { // with no normals polyscope::ColorRenderImageQuantity* im = polyscope::addColorRenderImageQuantity( @@ -129,6 +147,12 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) { im->setEnabled(true); polyscope::show(3); polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + + // add a slice plane + polyscope::addSceneSlicePlane(); + polyscope::show(3); + polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + polyscope::removeLastSceneSlicePlane(); } { // ScalarRenderImageQuantity @@ -138,6 +162,12 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) { im->setEnabled(true); polyscope::show(3); polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + + // add a slice plane + polyscope::addSceneSlicePlane(); + polyscope::show(3); + polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + polyscope::removeLastSceneSlicePlane(); } { // with no normals polyscope::ScalarRenderImageQuantity* im = polyscope::addScalarRenderImageQuantity( @@ -146,7 +176,14 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) { im->setEnabled(true); polyscope::show(3); polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + + // add a slice plane + polyscope::addSceneSlicePlane(); + polyscope::show(3); + polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + polyscope::removeLastSceneSlicePlane(); } + { // categorical polyscope::ScalarRenderImageQuantity* im = polyscope::addScalarRenderImageQuantity("render im scalar", dimX, dimY, depthVals, normalVals, scalarVals, @@ -155,6 +192,12 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) { im->setEnabled(true); polyscope::show(3); polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + + // add a slice plane + polyscope::addSceneSlicePlane(); + polyscope::show(3); + polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + polyscope::removeLastSceneSlicePlane(); } { // RawColorImageQuantity @@ -164,6 +207,12 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) { im->setEnabled(true); polyscope::show(3); polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + + // add a slice plane + polyscope::addSceneSlicePlane(); + polyscope::show(3); + polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); + polyscope::removeLastSceneSlicePlane(); } { // RawColorAlphaImageQuantity @@ -175,16 +224,23 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) { im->setIsPremultiplied(true); polyscope::show(3); polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); - } - // make sure it doesn't blow up with transparancy - polyscope::options::transparencyMode = polyscope::TransparencyMode::Simple; - polyscope::show(3); + // add a slice plane + polyscope::addSceneSlicePlane(); + polyscope::show(3); + polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8)); - polyscope::options::transparencyMode = polyscope::TransparencyMode::Pretty; - polyscope::show(3); + // make sure it doesn't blow up with transparancy + polyscope::options::transparencyMode = polyscope::TransparencyMode::Simple; + polyscope::show(3); - polyscope::options::transparencyMode = polyscope::TransparencyMode::None; + polyscope::options::transparencyMode = polyscope::TransparencyMode::Pretty; + polyscope::show(3); + + polyscope::options::transparencyMode = polyscope::TransparencyMode::None; + + polyscope::removeLastSceneSlicePlane(); + } // make sure removing works polyscope::removeFloatingQuantity("render im depth", true); From 1d11508f64b32e4a3b1eef218a2c4c8fc81dad0b Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Thu, 11 Dec 2025 19:15:44 -0800 Subject: [PATCH 3/4] make RenderImages support slice planes --- include/polyscope/render/engine.h | 4 ++++ src/color_render_image_quantity.cpp | 11 ++++++----- src/depth_render_image_quantity.cpp | 11 +++++++---- src/raw_color_alpha_render_image_quantity.cpp | 15 ++++++++++----- src/raw_color_render_image_quantity.cpp | 14 +++++++++----- src/render/engine.cpp | 9 +++++++++ .../opengl/shaders/texture_draw_shaders.cpp | 11 +++++------ src/render_image_quantity_base.cpp | 10 +++++++--- src/scalar_render_image_quantity.cpp | 9 +++++---- 9 files changed, 62 insertions(+), 32 deletions(-) diff --git a/include/polyscope/render/engine.h b/include/polyscope/render/engine.h index 5272b4f4..6f69090a 100644 --- a/include/polyscope/render/engine.h +++ b/include/polyscope/render/engine.h @@ -698,4 +698,8 @@ inline std::string getRenderEngineBackendName() { return engineBackendName; } } // namespace render + +// === Small free helpers +std::vector removeRule(std::vector initRules, std::string ruleName); + } // namespace polyscope diff --git a/src/color_render_image_quantity.cpp b/src/color_render_image_quantity.cpp index ed2013eb..9a6b39fc 100644 --- a/src/color_render_image_quantity.cpp +++ b/src/color_render_image_quantity.cpp @@ -59,16 +59,17 @@ void ColorRenderImageQuantity::prepare() { // Create the sourceProgram // clang-format off - program = render::engine->requestShader("TEXTURE_DRAW_RENDERIMAGE_PLAIN", - render::engine->addMaterialRules(material.get(), + + std::vector rules = render::engine->addMaterialRules(material.get(), parent.addStructureRules({ getImageOriginRule(imageOrigin), hasNormals ? "SHADE_NORMAL_FROM_TEXTURE" : "SHADE_NORMAL_FROM_VIEWPOS_VAR", "TEXTURE_SHADE_COLOR" }) - ), - render::ShaderReplacementDefaults::SceneObjectNoSlice); - // clang-format on + ); + rules = removeRule(rules, "GENERATE_VIEW_POS"); + + program = render::engine->requestShader("TEXTURE_DRAW_RENDERIMAGE_PLAIN", rules); program->setAttribute("a_position", render::engine->screenTrianglesCoords()); program->setTextureFromBuffer("t_depth", depths.getRenderTextureBuffer().get()); diff --git a/src/depth_render_image_quantity.cpp b/src/depth_render_image_quantity.cpp index f6bdf1f0..b6d0d947 100644 --- a/src/depth_render_image_quantity.cpp +++ b/src/depth_render_image_quantity.cpp @@ -64,15 +64,18 @@ void DepthRenderImageQuantity::prepare() { // Create the sourceProgram // clang-format off - program = render::engine->requestShader("TEXTURE_DRAW_RENDERIMAGE_PLAIN", - render::engine->addMaterialRules(material.get(), + + std::vector rules = render::engine->addMaterialRules(material.get(), parent.addStructureRules({ getImageOriginRule(imageOrigin), hasNormals ? "SHADE_NORMAL_FROM_TEXTURE" : "SHADE_NORMAL_FROM_VIEWPOS_VAR", "SHADE_BASECOLOR", }) - ), - render::ShaderReplacementDefaults::SceneObjectNoSlice); + ); + rules = removeRule(rules, "GENERATE_VIEW_POS"); + + program = render::engine->requestShader("TEXTURE_DRAW_RENDERIMAGE_PLAIN", rules); + // clang-format on program->setAttribute("a_position", render::engine->screenTrianglesCoords()); diff --git a/src/raw_color_alpha_render_image_quantity.cpp b/src/raw_color_alpha_render_image_quantity.cpp index 184dd6f9..89190ab6 100644 --- a/src/raw_color_alpha_render_image_quantity.cpp +++ b/src/raw_color_alpha_render_image_quantity.cpp @@ -63,11 +63,16 @@ void RawColorAlphaRenderImageQuantity::prepare() { // applied after compositing. // Create the sourceProgram - program = render::engine->requestShader( - "TEXTURE_DRAW_RAW_RENDERIMAGE_PLAIN", - parent.addStructureRules({getImageOriginRule(imageOrigin), "TEXTURE_SHADE_COLORALPHA", "INVERSE_TONEMAP", - getIsPremultiplied() ? "" : "TEXTURE_PREMULTIPLY_OUT"}), - render::ShaderReplacementDefaults::SceneObjectNoSlice); + // clang-format off + std::vector rules = parent.addStructureRules({ + getImageOriginRule(imageOrigin), + "TEXTURE_SHADE_COLORALPHA", "INVERSE_TONEMAP", + getIsPremultiplied() ? "" : "TEXTURE_PREMULTIPLY_OUT" + }); + rules = removeRule(rules, "GENERATE_VIEW_POS"); + + program = render::engine->requestShader("TEXTURE_DRAW_RAW_RENDERIMAGE_PLAIN", rules); + // clang-format on program->setAttribute("a_position", render::engine->screenTrianglesCoords()); program->setTextureFromBuffer("t_depth", depths.getRenderTextureBuffer().get()); diff --git a/src/raw_color_render_image_quantity.cpp b/src/raw_color_render_image_quantity.cpp index 91425577..a3b32b0b 100644 --- a/src/raw_color_render_image_quantity.cpp +++ b/src/raw_color_render_image_quantity.cpp @@ -58,11 +58,15 @@ void RawColorRenderImageQuantity::refresh() { void RawColorRenderImageQuantity::prepare() { // Create the sourceProgram - program = - render::engine->requestShader("TEXTURE_DRAW_RAW_RENDERIMAGE_PLAIN", - parent.addStructureRules({getImageOriginRule(imageOrigin), "TEXTURE_SHADE_COLOR", - "INVERSE_TONEMAP", "PREMULTIPLY_LIT_COLOR"}), - render::ShaderReplacementDefaults::SceneObjectNoSlice); + // clang-format off + std::vector rules = parent.addStructureRules({ + getImageOriginRule(imageOrigin), + "TEXTURE_SHADE_COLOR", "INVERSE_TONEMAP", "PREMULTIPLY_LIT_COLOR"} + ); + rules = removeRule(rules, "GENERATE_VIEW_POS"); + + program = render::engine->requestShader("TEXTURE_DRAW_RAW_RENDERIMAGE_PLAIN", rules); + // clang-format on program->setAttribute("a_position", render::engine->screenTrianglesCoords()); program->setTextureFromBuffer("t_depth", depths.getRenderTextureBuffer().get()); diff --git a/src/render/engine.cpp b/src/render/engine.cpp index 1c82db01..23ec8005 100644 --- a/src/render/engine.cpp +++ b/src/render/engine.cpp @@ -1200,5 +1200,14 @@ void Engine::preserveResourceUntilImguiFrameCompletes(std::shared_ptr removeRule(std::vector initRules, std::string ruleName) { + initRules.erase(std::remove(initRules.begin(), initRules.end(), ruleName), initRules.end()); + return initRules; +} + } // namespace polyscope diff --git a/src/render/opengl/shaders/texture_draw_shaders.cpp b/src/render/opengl/shaders/texture_draw_shaders.cpp index 322532d5..7a5b66cb 100644 --- a/src/render/opengl/shaders/texture_draw_shaders.cpp +++ b/src/render/opengl/shaders/texture_draw_shaders.cpp @@ -167,14 +167,10 @@ R"( // Fetch values from texture float depth = texture(t_depth, tCoord).r; - - ${ GLOBAL_FRAGMENT_FILTER_PREP }$ - ${ GLOBAL_FRAGMENT_FILTER }$ - if(depth > LARGE_FLOAT()) { discard; } - + // Set the depth of the fragment from the stored texture data // TODO: this a wasteful way to convert ray depth to gl_FragDepth, I am sure it can be done with much less arithmetic... figure it out // WARNING this code is duplicated in other shaders @@ -185,6 +181,8 @@ R"( float fragdepth = fragDepthFromView(u_projMatrix, depthRange, viewPos); gl_FragDepth = fragdepth; + ${ GLOBAL_FRAGMENT_FILTER_PREP }$ + ${ GLOBAL_FRAGMENT_FILTER }$ // Shading vec3 shadeNormal = vec3(0.f, 0.f, 0.f); @@ -252,7 +250,6 @@ R"( // Fetch values from texture float depth = texture(t_depth, tCoord).r; - if(depth > LARGE_FLOAT()) { discard; } @@ -267,6 +264,8 @@ R"( float fragdepth = fragDepthFromView(u_projMatrix, depthRange, viewPos); gl_FragDepth = fragdepth; + ${ GLOBAL_FRAGMENT_FILTER_PREP }$ + ${ GLOBAL_FRAGMENT_FILTER }$ // Shading ${ GENERATE_SHADE_VALUE }$ diff --git a/src/render_image_quantity_base.cpp b/src/render_image_quantity_base.cpp index 461a7355..b5e257a6 100644 --- a/src/render_image_quantity_base.cpp +++ b/src/render_image_quantity_base.cpp @@ -89,6 +89,7 @@ void RenderImageQuantityBase::drawPickDelayed() { if (!pickProgram) preparePick(); // set uniforms + parent.setStructureUniforms(*pickProgram); glm::mat4 P = view::getCameraPerspectiveMatrix(); glm::mat4 Pinv = glm::inverse(P); @@ -111,11 +112,14 @@ void RenderImageQuantityBase::preparePick() { // Create the sourceProgram // clang-format off - pickProgram = render::engine->requestShader("TEXTURE_DRAW_RENDERIMAGE_PLAIN", - parent.addStructureRules({ + std::vector rules = parent.addStructureRules({ getImageOriginRule(imageOrigin), "SHADECOLOR_FROM_UNIFORM", - }), + }); + rules = removeRule(rules, "GENERATE_VIEW_POS"); + + pickProgram = render::engine->requestShader("TEXTURE_DRAW_RENDERIMAGE_PLAIN", + rules, render::ShaderReplacementDefaults::Pick ); // clang-format on diff --git a/src/scalar_render_image_quantity.cpp b/src/scalar_render_image_quantity.cpp index 05da3c1e..2ed82796 100644 --- a/src/scalar_render_image_quantity.cpp +++ b/src/scalar_render_image_quantity.cpp @@ -72,8 +72,7 @@ void ScalarRenderImageQuantity::prepare() { // Create the sourceProgram // clang-format off - program = render::engine->requestShader("TEXTURE_DRAW_RENDERIMAGE_PLAIN", - render::engine->addMaterialRules(material.get(), + std::vector rules = render::engine->addMaterialRules(material.get(), addScalarRules( parent.addStructureRules({ getImageOriginRule(imageOrigin), @@ -81,8 +80,10 @@ void ScalarRenderImageQuantity::prepare() { "TEXTURE_PROPAGATE_VALUE", }) ) - ), - render::ShaderReplacementDefaults::SceneObjectNoSlice); + ); + rules = removeRule(rules, "GENERATE_VIEW_POS"); + + program = render::engine->requestShader("TEXTURE_DRAW_RENDERIMAGE_PLAIN", rules); // clang-format on program->setAttribute("a_position", render::engine->screenTrianglesCoords()); From b51d3400cf304f00171258007b99107439063a6f Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Thu, 11 Dec 2025 19:15:54 -0800 Subject: [PATCH 4/4] minor build fix --- examples/demo-app/demo_app.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/demo-app/demo_app.cpp b/examples/demo-app/demo_app.cpp index c358f0f4..eaed4407 100644 --- a/examples/demo-app/demo_app.cpp +++ b/examples/demo-app/demo_app.cpp @@ -870,7 +870,7 @@ void callback() { std::vector plotVals; for (float t = 0; t < 10.; t += 0.01) { - plotVals.push_back(std::cosf(t + ImGui::GetTime())); + plotVals.push_back(std::cos(t + ImGui::GetTime())); } // sample plot