Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions include/polyscope/render/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,9 +445,9 @@ class Engine {
virtual void shutdown() {};
virtual void checkError(bool fatal = false) = 0;
void buildEngineGui();

// 'headless' means there is no physical display to actually render to, e.g. when running on a remote server
virtual bool isHeadless() { return false; }
virtual bool isHeadless() { return false; }

virtual void clearDisplay();
virtual void bindDisplay();
Expand Down Expand Up @@ -519,6 +519,10 @@ class Engine {

void setImGuiStyle();
ImFontAtlas* getImGuiGlobalFontAtlas();

// Display an ImGui window showing a texture
// WARNING: you must ensure that the texture buffer pointer stays valid until after the ImGui frame is rendered, which
// is not until the end of a main loop iteration.
virtual void showTextureInImGuiWindow(std::string windowName, TextureBuffer* buffer);


Expand Down Expand Up @@ -630,6 +634,11 @@ class Engine {
ImFont* monoFont = nullptr;
FrameBuffer* currRenderFramebuffer = nullptr;

// Manage some resources that we need to preserve because ImGui will use them to render at the end of the frame
// This matters if we delete something mid-frame but have already passed a pointer to a texture for imgui to render,
// which happens at the end of the frame.
void preserveResourceUntilImguiFrameCompletes(std::shared_ptr<TextureBuffer> texture);

protected:
// TODO Manage a cache of compiled shaders?

Expand Down Expand Up @@ -664,6 +673,10 @@ class Engine {
std::vector<std::string> defaultRules_sceneObject{"GLSL_VERSION", "GLOBAL_FRAGMENT_FILTER"};
std::vector<std::string> defaultRules_pick{"GLSL_VERSION", "GLOBAL_FRAGMENT_FILTER", "SHADE_COLOR", "LIGHT_PASSTHRU"};
std::vector<std::string> defaultRules_process{"GLSL_VERSION"};

// Lists of points to support preserving resources until the end of an ImGUI frame (see note above)
void clearResourcesPreservedForImguiFrame();
std::vector<std::shared_ptr<TextureBuffer>> resourcesPreservedForImGuiFrame;
};


Expand Down
1 change: 1 addition & 0 deletions src/color_image_quantity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ void ColorImageQuantity::showInImGuiWindow() {
} else if (imageOrigin == ImageOrigin::UpperLeft) {
ImGui::Image(colors.getRenderTextureBuffer()->getNativeHandle(), ImVec2(w, h));
}
render::engine->preserveResourceUntilImguiFrameCompletes(colors.getRenderTextureBuffer());

ImGui::End();
}
Expand Down
1 change: 1 addition & 0 deletions src/histogram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ void Histogram::buildUI(float width) {

// Render image
ImGui::Image(texture->getNativeHandle(), ImVec2(w, h), ImVec2(0, 1), ImVec2(1, 0));
render::engine->preserveResourceUntilImguiFrameCompletes(texture);

// Helpful info for drawing annotations below
ImU32 annoColor = ImGui::ColorConvertFloat4ToU32(ImVec4(254 / 255., 221 / 255., 66 / 255., 1.0));
Expand Down
6 changes: 6 additions & 0 deletions src/render/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1183,5 +1183,11 @@ void Engine::showTextureInImGuiWindow(std::string windowName, TextureBuffer* buf

ImFontAtlas* Engine::getImGuiGlobalFontAtlas() { return globalFontAtlas; }

void Engine::preserveResourceUntilImguiFrameCompletes(std::shared_ptr<TextureBuffer> texture) {
resourcesPreservedForImGuiFrame.push_back(texture);
}

void Engine::clearResourcesPreservedForImguiFrame() { resourcesPreservedForImGuiFrame.clear(); }

} // namespace render
} // namespace polyscope
5 changes: 4 additions & 1 deletion src/render/mock_opengl/mock_gl_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1659,7 +1659,10 @@ void MockGLEngine::ImGuiNewFrame() {
ImGui::NewFrame();
}

void MockGLEngine::ImGuiRender() { ImGui::Render(); }
void MockGLEngine::ImGuiRender() {
ImGui::Render();
clearResourcesPreservedForImguiFrame();
}

void MockGLEngine::setDepthMode(DepthMode newMode) {}

Expand Down
5 changes: 4 additions & 1 deletion src/render/opengl/gl_engine_egl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,10 @@ void GLEngineEGL::ImGuiNewFrame() {
ImGui::NewFrame();
}

void GLEngineEGL::ImGuiRender() { ImGui::Render(); }
void GLEngineEGL::ImGuiRender() {
ImGui::Render();
clearResourcesPreservedForImguiFrame();
}


void GLEngineEGL::swapDisplayBuffers() {
Expand Down
1 change: 1 addition & 0 deletions src/render/opengl/gl_engine_glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ void GLEngineGLFW::ImGuiNewFrame() {
void GLEngineGLFW::ImGuiRender() {
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
clearResourcesPreservedForImguiFrame();
}


Expand Down
1 change: 1 addition & 0 deletions src/scalar_image_quantity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ void ScalarImageQuantity::showInImGuiWindow() {
// here we always use the same ImVec2 UV coords below, because the texture order is always openGL convention after the
// intermediate render pass
ImGui::Image(textureIntermediateRendered->getNativeHandle(), ImVec2(w, h), ImVec2(0, 1), ImVec2(1, 0));
render::engine->preserveResourceUntilImguiFrameCompletes(textureIntermediateRendered);


ImGui::End();
Expand Down
Loading