diff --git a/bindings/imgui_bundle/demos_cpp/sandbox/sandbox_immapp_manual_render.cpp b/bindings/imgui_bundle/demos_cpp/sandbox/sandbox_immapp_manual_render.cpp
new file mode 100644
index 00000000..235cf952
--- /dev/null
+++ b/bindings/imgui_bundle/demos_cpp/sandbox/sandbox_immapp_manual_render.cpp
@@ -0,0 +1,70 @@
+#include "immapp/immapp.h"
+#include "imgui_md_wrapper/imgui_md_wrapper.h"
+#include "hello_imgui/hello_imgui.h"
+#include "imgui.h"
+
+
+void Gui()
+{
+ ImGuiMd::RenderUnindented(R"(
+ # Sandbox
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit
+ )");
+ if (ImGui::Button("Save"))
+ {
+ // Save something
+ }
+ ImGui::SameLine();
+ if (ImGui::Button("Load"))
+ {
+ // Load something
+ }
+}
+
+int main(int, char **)
+{
+
+ //ImmApp::Run(runnerParams, addonsParams);
+
+ {
+ HelloImGui::RunnerParams runnerParams;
+ runnerParams.callbacks.ShowGui = Gui;
+ ImmApp::AddOnsParams addonsParams;
+ addonsParams.withMarkdown = true;
+
+ ImmApp::ManualRender::SetupFromRunnerParams(runnerParams, addonsParams);
+ while(!HelloImGui::GetRunnerParams()->appShallExit)
+ ImmApp::ManualRender::Render();
+ ImmApp::ManualRender::TearDown();
+ }
+
+ {
+ ImmApp::ManualRender::SetupFromGuiFunction(
+ Gui,
+ "Sandbox", // windowTitle
+ false, // windowSizeAuto
+ false, // windowRestorePreviousGeometry
+ ImmApp::DefaultWindowSize, // windowSize
+ 10.f, // fpsIdle
+ false, // withImplot
+ true, // withMarkdown
+ false // withNodeEditor
+ );
+ while(!HelloImGui::GetRunnerParams()->appShallExit)
+ ImmApp::ManualRender::Render();
+ ImmApp::ManualRender::TearDown();
+ }
+
+ {
+ HelloImGui::SimpleRunnerParams runnerParams;
+ runnerParams.guiFunction = Gui;
+ ImmApp::AddOnsParams addonsParams;
+ addonsParams.withMarkdown = true;
+ ImmApp::ManualRender::SetupFromSimpleRunnerParams(runnerParams, addonsParams);
+ while(!HelloImGui::GetRunnerParams()->appShallExit)
+ ImmApp::ManualRender::Render();
+ ImmApp::ManualRender::TearDown();
+ }
+
+}
\ No newline at end of file
diff --git a/bindings/imgui_bundle/demos_python/sandbox/sandbox_immapp_manual_render.py b/bindings/imgui_bundle/demos_python/sandbox/sandbox_immapp_manual_render.py
new file mode 100644
index 00000000..044f86da
--- /dev/null
+++ b/bindings/imgui_bundle/demos_python/sandbox/sandbox_immapp_manual_render.py
@@ -0,0 +1,29 @@
+from imgui_bundle import immapp, hello_imgui, imgui_md, imgui
+
+
+def gui():
+ imgui_md.render_unindented("""
+ # Sandbox
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit
+ """)
+ if imgui.button("Save"):
+ # Save something
+ pass
+ imgui.same_line()
+ if imgui.button("Load"):
+ # Load something
+ pass
+
+
+def main():
+ immapp.manual_render.setup_from_gui_function(gui)
+ while not hello_imgui.get_runner_params().app_shall_exit:
+ immapp.manual_render.render()
+ immapp.manual_render.tear_down()
+
+
+if __name__ == "__main__":
+ main()
+ main()
+ main()
diff --git a/bindings/imgui_bundle/immapp/__init__.py b/bindings/imgui_bundle/immapp/__init__.py
index 9a20bbbc..cef0398f 100644
--- a/bindings/imgui_bundle/immapp/__init__.py
+++ b/bindings/imgui_bundle/immapp/__init__.py
@@ -1,4 +1,5 @@
# Part of ImGui Bundle - MIT License - Copyright (c) 2022-2023 Pascal Thomet - https://github.com/pthom/imgui_bundle
+from imgui_bundle import _imgui_bundle as _native_bundle
from imgui_bundle._imgui_bundle import immapp_cpp as immapp_cpp # type: ignore
from imgui_bundle._imgui_bundle.immapp_cpp import ( # type: ignore
clock_seconds,
@@ -32,7 +33,7 @@
# runner_params.callbacks.default_icon_font = hello_imgui.DefaultIconFont.font_awesome6
from imgui_bundle.immapp import icons_fontawesome_4 as icons_fontawesome_4
from imgui_bundle.immapp import icons_fontawesome_6 as icons_fontawesome_6
-from imgui_bundle.immapp import icons_fontawesome_4 as icons_fontawesome # v4
+from imgui_bundle.immapp import icons_fontawesome_4 as icons_fontawesome # Icons font awesome v4
from imgui_bundle.immapp.immapp_utils import (
static as static,
@@ -46,6 +47,9 @@
SimpleRunnerParams as SimpleRunnerParams,
)
+
+manual_render = _native_bundle.immapp_cpp.manual_render
+
__all__ = [
"clock_seconds",
"default_node_editor_context",
@@ -69,6 +73,7 @@
"RunnerParams",
"SimpleRunnerParams",
"snippets",
+ "manual_render",
"begin_plot_in_node_editor",
"end_plot_in_node_editor",
"show_resizable_plot_in_node_editor",
diff --git a/bindings/imgui_bundle/immapp/__init__.pyi b/bindings/imgui_bundle/immapp/__init__.pyi
index d21848d5..0fbcf65b 100644
--- a/bindings/imgui_bundle/immapp/__init__.pyi
+++ b/bindings/imgui_bundle/immapp/__init__.pyi
@@ -10,6 +10,7 @@ from .immapp_cpp import (
run_with_markdown as run_with_markdown,
AddOnsParams as AddOnsParams,
snippets as snippets,
+ manual_render as manual_render,
begin_plot_in_node_editor as begin_plot_in_node_editor,
end_plot_in_node_editor as end_plot_in_node_editor,
show_resizable_plot_in_node_editor as show_resizable_plot_in_node_editor,
diff --git a/bindings/imgui_bundle/immapp/immapp_cpp.pyi b/bindings/imgui_bundle/immapp/immapp_cpp.pyi
index 66cb99d0..069b8b15 100644
--- a/bindings/imgui_bundle/immapp/immapp_cpp.pyi
+++ b/bindings/imgui_bundle/immapp/immapp_cpp.pyi
@@ -303,8 +303,87 @@ def delete_node_editor_settings(runner_params: HelloImGui.RunnerParams) -> None:
pass
# #endif
-# }
+#
+
+# =========================== HelloImGui::ManualRender ==================================
+# @@md#HelloImGui::ManualRender
+
+# @@md
+
+#
+class manual_render: # Proxy class that introduces typings for the *submodule* manual_render
+ pass # (This corresponds to a C++ namespace. All method are static!)
+ """ namespace ManualRender"""
+ # Immapp::ManualRender is a namespace that groups functions, allowing fine-grained control over the rendering process:
+ # - It is customizable like Immapp::Run: initialize it with `RunnerParams` and `AddOnsParams`.
+ # - `ManualRender::Render()` will render the application for one frame:
+ # - Ensure that `ManualRender::Render()` is triggered regularly (e.g., through a loop or other mechanism)
+ # to maintain responsiveness. This method must be called on the main thread.
+
+ @staticmethod
+ def setup_from_runner_params(
+ runner_params: HelloImGui.RunnerParams,
+ add_ons_params: Optional[AddOnsParams] = None,
+ ) -> None:
+ """Initializes the rendering with the full customizable `RunnerParams`.
+ This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
+ A distinct copy of `RunnerParams` is stored internally.
+ ---
+ Python bindings defaults:
+ If addOnsParams is None, then its default value will be: AddOnsParams()
+ """
+ pass
+
+ @staticmethod
+ def setup_from_simple_runner_params(
+ simple_params: HelloImGui.SimpleRunnerParams,
+ add_ons_params: Optional[AddOnsParams] = None,
+ ) -> None:
+ """Initializes the rendering with `SimpleRunnerParams`.
+ This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
+ ---
+ Python bindings defaults:
+ If addOnsParams is None, then its default value will be: AddOnsParams()
+ """
+ pass
+
+ @staticmethod
+ def setup_from_gui_function(
+ gui_function: VoidFunction,
+ window_title: str = "",
+ window_size_auto: bool = False,
+ window_restore_previous_geometry: bool = False,
+ window_size: Optional[ScreenSize] = None,
+ fps_idle: float = 10.0,
+ with_implot: bool = False,
+ with_markdown: bool = False,
+ with_node_editor: bool = False,
+ with_tex_inspect: bool = False,
+ with_node_editor_config: Optional[NodeEditorConfig] = None,
+ with_markdown_options: Optional[ImGuiMd.MarkdownOptions] = None,
+ ) -> None:
+ """Initializes the renderer with a simple GUI function and additional parameters.
+ This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
+ ---
+ Python bindings defaults:
+ If windowSize is None, then its default value will be: DefaultWindowSize
+ """
+ pass
+
+ @staticmethod
+ def render() -> None:
+ """Renders the current frame. Should be called regularly to maintain the application's responsiveness."""
+ pass
+
+ @staticmethod
+ def tear_down() -> None:
+ """Tears down the renderer and releases all associated resources.
+ This will release the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
+ After calling `TearDown()`, the InitFromXXX can be called with new parameters.
+ """
+ pass
+#
#################### ####################
#################### ####################
diff --git a/external/immapp/bindings/pybind_immapp_cpp.cpp b/external/immapp/bindings/pybind_immapp_cpp.cpp
index 814f499b..5acf5b28 100644
--- a/external/immapp/bindings/pybind_immapp_cpp.cpp
+++ b/external/immapp/bindings/pybind_immapp_cpp.cpp
@@ -284,7 +284,79 @@ void py_init_module_immapp_cpp(nb::module_& m)
nb::arg("runner_params"),
"DeleteNodeEditorSettings deletes the json file for the node editor settings.");
// #endif
- // }
+ //
+
+ { //
+ nb::module_ pyNsManualRender = m.def_submodule("manual_render", "namespace ManualRender");
+ pyNsManualRender.def("setup_from_runner_params",
+ [](const HelloImGui::RunnerParams & runnerParams, const std::optional & addOnsParams = std::nullopt)
+ {
+ auto SetupFromRunnerParams_adapt_mutable_param_with_default_value = [](const HelloImGui::RunnerParams & runnerParams, const std::optional & addOnsParams = std::nullopt)
+ {
+
+ const ImmApp::AddOnsParams& addOnsParams_or_default = [&]() -> const ImmApp::AddOnsParams {
+ if (addOnsParams.has_value())
+ return addOnsParams.value();
+ else
+ return ImmApp::AddOnsParams();
+ }();
+
+ ImmApp::ManualRender::SetupFromRunnerParams(runnerParams, addOnsParams_or_default);
+ };
+
+ SetupFromRunnerParams_adapt_mutable_param_with_default_value(runnerParams, addOnsParams);
+ },
+ nb::arg("runner_params"), nb::arg("add_ons_params") = nb::none(),
+ " Initializes the rendering with the full customizable `RunnerParams`.\n This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).\n A distinct copy of `RunnerParams` is stored internally.\n---\nPython bindings defaults:\n If addOnsParams is None, then its default value will be: AddOnsParams()");
+
+ pyNsManualRender.def("setup_from_simple_runner_params",
+ [](const HelloImGui::SimpleRunnerParams & simpleParams, const std::optional & addOnsParams = std::nullopt)
+ {
+ auto SetupFromSimpleRunnerParams_adapt_mutable_param_with_default_value = [](const HelloImGui::SimpleRunnerParams & simpleParams, const std::optional & addOnsParams = std::nullopt)
+ {
+
+ const ImmApp::AddOnsParams& addOnsParams_or_default = [&]() -> const ImmApp::AddOnsParams {
+ if (addOnsParams.has_value())
+ return addOnsParams.value();
+ else
+ return ImmApp::AddOnsParams();
+ }();
+
+ ImmApp::ManualRender::SetupFromSimpleRunnerParams(simpleParams, addOnsParams_or_default);
+ };
+
+ SetupFromSimpleRunnerParams_adapt_mutable_param_with_default_value(simpleParams, addOnsParams);
+ },
+ nb::arg("simple_params"), nb::arg("add_ons_params") = nb::none(),
+ " Initializes the rendering with `SimpleRunnerParams`.\n This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).\n---\nPython bindings defaults:\n If addOnsParams is None, then its default value will be: AddOnsParams()");
+
+ pyNsManualRender.def("setup_from_gui_function",
+ [](const VoidFunction & guiFunction, const std::string & windowTitle = "", bool windowSizeAuto = false, bool windowRestorePreviousGeometry = false, const std::optional & windowSize = std::nullopt, float fpsIdle = 10.f, bool withImplot = false, bool withMarkdown = false, bool withNodeEditor = false, bool withTexInspect = false, const std::optional & withNodeEditorConfig = std::nullopt, const std::optional & withMarkdownOptions = std::nullopt)
+ {
+ auto SetupFromGuiFunction_adapt_mutable_param_with_default_value = [](const VoidFunction & guiFunction, const std::string & windowTitle = "", bool windowSizeAuto = false, bool windowRestorePreviousGeometry = false, const std::optional & windowSize = std::nullopt, float fpsIdle = 10.f, bool withImplot = false, bool withMarkdown = false, bool withNodeEditor = false, bool withTexInspect = false, const std::optional & withNodeEditorConfig = std::nullopt, const std::optional & withMarkdownOptions = std::nullopt)
+ {
+
+ const ScreenSize& windowSize_or_default = [&]() -> const ScreenSize {
+ if (windowSize.has_value())
+ return windowSize.value();
+ else
+ return DefaultWindowSize;
+ }();
+
+ ImmApp::ManualRender::SetupFromGuiFunction(guiFunction, windowTitle, windowSizeAuto, windowRestorePreviousGeometry, windowSize_or_default, fpsIdle, withImplot, withMarkdown, withNodeEditor, withTexInspect, withNodeEditorConfig, withMarkdownOptions);
+ };
+
+ SetupFromGuiFunction_adapt_mutable_param_with_default_value(guiFunction, windowTitle, windowSizeAuto, windowRestorePreviousGeometry, windowSize, fpsIdle, withImplot, withMarkdown, withNodeEditor, withTexInspect, withNodeEditorConfig, withMarkdownOptions);
+ },
+ nb::arg("gui_function"), nb::arg("window_title") = "", nb::arg("window_size_auto") = false, nb::arg("window_restore_previous_geometry") = false, nb::arg("window_size") = nb::none(), nb::arg("fps_idle") = 10.f, nb::arg("with_implot") = false, nb::arg("with_markdown") = false, nb::arg("with_node_editor") = false, nb::arg("with_tex_inspect") = false, nb::arg("with_node_editor_config") = nb::none(), nb::arg("with_markdown_options") = nb::none(),
+ " Initializes the renderer with a simple GUI function and additional parameters.\n This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).\n---\nPython bindings defaults:\n If windowSize is None, then its default value will be: DefaultWindowSize");
+
+ pyNsManualRender.def("render",
+ ImmApp::ManualRender::Render, "Renders the current frame. Should be called regularly to maintain the application's responsiveness.");
+
+ pyNsManualRender.def("tear_down",
+ ImmApp::ManualRender::TearDown, " Tears down the renderer and releases all associated resources.\n This will release the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).\n After calling `TearDown()`, the InitFromXXX can be called with new parameters.");
+ } //
//////////////////// ////////////////////
diff --git a/external/immapp/immapp/runner.cpp b/external/immapp/immapp/runner.cpp
index af65f59f..b77c33a9 100644
--- a/external/immapp/immapp/runner.cpp
+++ b/external/immapp/immapp/runner.cpp
@@ -48,11 +48,8 @@ namespace ImmApp
ImmAppContext gImmAppContext;
-
- void Run(HelloImGui::RunnerParams& runnerParams, const AddOnsParams& addOnsParams_)
+ static void Priv_Setup(HelloImGui::RunnerParams& runnerParams, AddOnsParams& addOnsParams)
{
- AddOnsParams addOnsParams = addOnsParams_;
-
// create implot context if required
#ifdef IMGUI_BUNDLE_WITH_IMPLOT
if (addOnsParams.withImplot)
@@ -139,7 +136,7 @@ namespace ImmApp
runnerParams.callbacks.PostInit = HelloImGui::SequenceFunctions(
fn_ImGuiTextInspect_Init,
runnerParams.callbacks.PostInit
- );
+ );
}
// Modify before-exit: DeInit ImGuiTexInspect
@@ -155,7 +152,7 @@ namespace ImmApp
runnerParams.callbacks.BeforeExit = HelloImGui::SequenceFunctions(
fn_ImGuiTextInspect_DeInit,
runnerParams.callbacks.BeforeExit
- );
+ );
}
}
#endif
@@ -166,10 +163,10 @@ namespace ImmApp
runnerParams.callbacks.BeforeExit,
ImmVision::ClearTextureCache);
#endif
+ }
-
- HelloImGui::Run(runnerParams);
-
+ void Priv_Teardown(AddOnsParams& addOnsParams)
+ {
#ifdef IMGUI_BUNDLE_WITH_IMPLOT
if (addOnsParams.withImplot)
ImPlot::DestroyContext();
@@ -186,7 +183,14 @@ namespace ImmApp
if (addOnsParams.withMarkdown || addOnsParams.withMarkdownOptions.has_value())
ImGuiMd::DeInitializeMarkdown();
+ }
+ void Run(HelloImGui::RunnerParams& runnerParams, const AddOnsParams& addOnsParams_)
+ {
+ AddOnsParams addOnsParams = addOnsParams_;
+ Priv_Setup(runnerParams, addOnsParams);
+ HelloImGui::Run(runnerParams);
+ Priv_Teardown(addOnsParams);
}
void Run(const HelloImGui::SimpleRunnerParams& simpleParams, const AddOnsParams& addOnsParams)
@@ -354,4 +358,108 @@ namespace ImmApp
}
#endif
+
+
+// ========================= ManualRender ====================================================
+
+namespace ManualRender // namespace ImmApp::ManualRender
+{
+ // Enumeration to track the current state of the ManualRenderer
+ enum class RendererStatus
+ {
+ NotInitialized,
+ Initialized,
+ };
+ RendererStatus sCurrentStatus = RendererStatus::NotInitialized;
+
+ static AddOnsParams sAddOnsParams;
+
+ // Changes the current status to Initialized if it was NotInitialized,
+ // otherwise raises an error (assert or exception)
+ void TrySwitchToInitialized()
+ {
+ if (sCurrentStatus == RendererStatus::Initialized)
+ IM_ASSERT(false && "ImmApp::ManualRender::SetupFromXXX() cannot be called while already initialized. Call TearDown() first.");
+ sCurrentStatus = RendererStatus::Initialized;
+ }
+
+ // Changes the current status to NotInitialized if it was Initialized,
+ // otherwise raises an error (assert or exception)
+ void TrySwitchToNotInitialized()
+ {
+ if (sCurrentStatus == RendererStatus::NotInitialized)
+ IM_ASSERT(false && "ImmApp::ManualRender::TearDown() cannot be called while not initialized.");
+ sCurrentStatus = RendererStatus::NotInitialized;
+ }
+
+
+ void SetupFromRunnerParams(const HelloImGui::RunnerParams& runnerParams, const AddOnsParams& addOnsParams)
+ {
+ TrySwitchToInitialized();
+ sAddOnsParams = addOnsParams;
+ HelloImGui::RunnerParams runnerParamsCopy = runnerParams;
+ Priv_Setup(runnerParamsCopy, sAddOnsParams);
+ HelloImGui::ManualRender::SetupFromRunnerParams(runnerParamsCopy);
+ }
+
+ void SetupFromSimpleRunnerParams(const HelloImGui::SimpleRunnerParams& simpleParams, const AddOnsParams& addOnsParams)
+ {
+ HelloImGui::RunnerParams runnerParams = simpleParams.ToRunnerParams();
+ SetupFromRunnerParams(runnerParams, addOnsParams);
+ }
+
+ void SetupFromGuiFunction(
+ const VoidFunction& guiFunction,
+ const std::string& windowTitle,
+ bool windowSizeAuto,
+ bool windowRestorePreviousGeometry,
+ const ScreenSize& windowSize,
+ float fpsIdle,
+
+ // AddOnsParams below:
+ bool withImplot,
+ bool withMarkdown,
+ bool withNodeEditor,
+ bool withTexInspect,
+#ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR
+ const std::optional& withNodeEditorConfig,
+#endif
+ const std::optional & withMarkdownOptions
+ )
+ {
+ HelloImGui::SimpleRunnerParams simpleRunnerParams;
+ simpleRunnerParams.guiFunction = guiFunction;
+ simpleRunnerParams.windowTitle = windowTitle;
+ simpleRunnerParams.windowSizeAuto = windowSizeAuto;
+ simpleRunnerParams.windowRestorePreviousGeometry = windowRestorePreviousGeometry;
+ simpleRunnerParams.windowSize = windowSize;
+ simpleRunnerParams.fpsIdle = fpsIdle;
+
+ AddOnsParams addOnsParams;
+ addOnsParams.withImplot = withImplot;
+ addOnsParams.withMarkdown = true;
+ addOnsParams.withNodeEditor = withNodeEditor;
+ addOnsParams.withTexInspect = withTexInspect;
+#ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR
+ addOnsParams.withNodeEditorConfig = withNodeEditorConfig;
+#endif
+ addOnsParams.withMarkdownOptions = withMarkdownOptions;
+
+ SetupFromSimpleRunnerParams(simpleRunnerParams, addOnsParams);
+ }
+
+ void Render()
+ {
+ HelloImGui::ManualRender::Render();
+ }
+
+ void TearDown()
+ {
+ TrySwitchToNotInitialized();
+ HelloImGui::ManualRender::TearDown();
+ Priv_Teardown(sAddOnsParams);
+ sAddOnsParams = AddOnsParams();
+ }
+} // namespace ManualRender
+
} // namespace ImmApp
diff --git a/external/immapp/immapp/runner.h b/external/immapp/immapp/runner.h
index 5260aed5..1b913fdc 100644
--- a/external/immapp/immapp/runner.h
+++ b/external/immapp/immapp/runner.h
@@ -174,4 +174,58 @@ namespace ImmApp
void DeleteNodeEditorSettings(const HelloImGui::RunnerParams& runnerParams);
#endif
+
+
+// =========================== HelloImGui::ManualRender ==================================
+// @@md#HelloImGui::ManualRender
+
+ namespace ManualRender
+ {
+ // Immapp::ManualRender is a namespace that groups functions, allowing fine-grained control over the rendering process:
+ // - It is customizable like Immapp::Run: initialize it with `RunnerParams` and `AddOnsParams`.
+ // - `ManualRender::Render()` will render the application for one frame:
+ // - Ensure that `ManualRender::Render()` is triggered regularly (e.g., through a loop or other mechanism)
+ // to maintain responsiveness. This method must be called on the main thread.
+
+ // Initializes the rendering with the full customizable `RunnerParams`.
+ // This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
+ // A distinct copy of `RunnerParams` is stored internally.
+ void SetupFromRunnerParams(const HelloImGui::RunnerParams& runnerParams, const AddOnsParams& addOnsParams = AddOnsParams());
+
+ // Initializes the rendering with `SimpleRunnerParams`.
+ // This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
+ void SetupFromSimpleRunnerParams(const HelloImGui::SimpleRunnerParams& simpleParams, const AddOnsParams& addOnsParams = AddOnsParams());
+
+ // Initializes the renderer with a simple GUI function and additional parameters.
+ // This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
+ void SetupFromGuiFunction(
+ const VoidFunction& guiFunction,
+ const std::string& windowTitle = "",
+ bool windowSizeAuto = false,
+ bool windowRestorePreviousGeometry = false,
+ const ScreenSize& windowSize = DefaultWindowSize,
+ float fpsIdle = 10.f,
+
+ // AddOnsParams below:
+ bool withImplot = false,
+ bool withMarkdown = false,
+ bool withNodeEditor = false,
+ bool withTexInspect = false,
+#ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR
+ const std::optional& withNodeEditorConfig = std::nullopt,
+#endif
+ const std::optional & withMarkdownOptions = std::nullopt
+ );
+
+ // Renders the current frame. Should be called regularly to maintain the application's responsiveness.
+ void Render();
+
+ // Tears down the renderer and releases all associated resources.
+ // This will release the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.).
+ // After calling `TearDown()`, the InitFromXXX can be called with new parameters.
+ void TearDown();
+ } // namespace ManualRender
+
+// @@md
+
} // namespace ImmApp