From 7c4e3b2eee96785f2bcd8b6d3a9c6accf8afa25e Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Tue, 9 Apr 2024 21:39:20 +0200 Subject: [PATCH 01/57] Work on adding support for netImgui --- CMakeLists.txt | 6 + CMakePresets.json | 10 +- external/.gitignore | 1 + hello_imgui_cmake/hello_imgui_build_lib.cmake | 45 +++++- src/CMakeLists.txt | 3 + src/hello_imgui/impl/hello_imgui.cpp | 6 + .../backend_impls/abstract_runner.cpp | 106 +++++++++++++ .../internal/backend_impls/abstract_runner.h | 3 + .../internal/backend_impls/runner_factory.cpp | 10 ++ src/hello_imgui/runner_params.h | 32 ++++ src/netimgui_remote_display/CMakeLists.txt | 18 +++ .../NetImguiServer_HAL_Glfw.cpp | 113 +++++++++++++ .../netimgui_remote_display.cpp | 150 ++++++++++++++++++ 13 files changed, 497 insertions(+), 6 deletions(-) create mode 100644 src/netimgui_remote_display/CMakeLists.txt create mode 100644 src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp create mode 100644 src/netimgui_remote_display/netimgui_remote_display.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 803c30de..87b0f04e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,12 @@ option(HELLOIMGUI_HAS_NULL "Null rendering backend" OFF) # for testing and remo option(HELLOIMGUI_NULL_BACKEND "Use Null rendering/platform backend" OFF) # # do not remove this line (used by the script that generates the documentation) +#------------------------------------------------------------------------------ +# Options / Remoting +#------------------------------------------------------------------------------ +# Using https://github.com/sammyfreg/netImgui, you can use HelloImGui with remote rendering +# (this is useful for example to render ImGui on a remote device, or to render ImGui in a web browser) +option(HELLOIMGUI_WITH_NETIMGUI "Use netImgui for remote rendering" OFF) #------------------------------------------------------------------------------ # Options / Freetype diff --git a/CMakePresets.json b/CMakePresets.json index f96aafca..fdaaa20c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -29,14 +29,16 @@ "HELLOIMGUI_HAS_VULKAN": "ON", "HELLOIMGUI_HAS_DIRECTX11": "ON", "HELLOIMGUI_HAS_DIRECTX12": "ON", - "HELLOIMGUI_HAS_NULL": "ON" + "HELLOIMGUI_HAS_NULL": "ON", + "HELLOIMGUI_WITH_NETIMGUI": "ON" } }, { - "name": "build_null_backend", - "description": "Build with null backend.", + "name": "build_netimgui", + "description": "Build with netImgui.", "cacheVariables": { - "HELLOIMGUI_NULL_BACKEND": "ON" + "HELLOIMGUI_NULL_BACKEND": "ON", + "HELLOIMGUI_WITH_NETIMGUI": "ON" } }, { diff --git a/external/.gitignore b/external/.gitignore index fea25349..972ae40c 100644 --- a/external/.gitignore +++ b/external/.gitignore @@ -1,3 +1,4 @@ SDL SDL2-*/ qtimgui/ +netImgui/ diff --git a/hello_imgui_cmake/hello_imgui_build_lib.cmake b/hello_imgui_cmake/hello_imgui_build_lib.cmake index f53da250..eac7c56a 100644 --- a/hello_imgui_cmake/hello_imgui_build_lib.cmake +++ b/hello_imgui_cmake/hello_imgui_build_lib.cmake @@ -1031,6 +1031,42 @@ function(_him_fetch_glfw_if_needed) endfunction() +################################################################################################### +# Remoting with https://github.com/sammyfreg/netImgui: API = him_with_netimgui +################################################################################################### +function(him_with_netimgui) + target_compile_definitions(${HELLOIMGUI_TARGET} PUBLIC HELLOIMGUI_WITH_NETIMGUI) + +# message(STATUS "HelloImGui: downloading and building netImgui") +# include(FetchContent) +# # Set(FETCHCONTENT_QUIET FALSE) +# FetchContent_Declare(net_imgui +# GIT_REPOSITORY https://github.com/pthom/netImgui.git +# GIT_TAG cmake_multiplatform +# GIT_PROGRESS TRUE +# ) +# FetchContent_MakeAvailable(net_imgui) + + + # Add netImgui to the project + set(NETIMGUI_DIR ${HELLOIMGUI_BASEPATH}/external/netImgui CACHE STRING "" FORCE) + set(NETIMGUI_BUILD_IMGUI OFF CACHE BOOL "" FORCE) + set(NETIMGUI_BUILD_CLIENT ON CACHE BOOL "" FORCE) + set(NETIMGUI_BUILD_SERVER_LIB ON CACHE BOOL "" FORCE) + + #set(NETIMGUI_BUILD_SERVER_APP_SOKOL ON CACHE BOOL "" FORCE) + set(NETIMGUI_BUILD_SERVER_APP_SOKOL OFF CACHE BOOL "" FORCE) + set(NETIMGUI_SERVER_APP_BACKEND_GLFW_GL3 ON CACHE BOOL "" FORCE) + + set(NETIMGUI_BUILD_SAMPLES OFF CACHE BOOL "" FORCE) + add_subdirectory(${NETIMGUI_DIR} netimgui) + + target_link_libraries(${HELLOIMGUI_TARGET} PUBLIC net_imgui_client) + him_add_installable_dependency(net_imgui_client) +endfunction() + + + ################################################################################################### # Miscellaneous: API = him_add_misc_options ################################################################################################### @@ -1083,8 +1119,9 @@ function(him_log_configuration) =========================================================================== Hello ImGui build options: =========================================================================== - Platform Backend(s): ${active_platform_backends} - Rendering Backend(s): ${active_rendering_backends} + Platform Backend(s): ${active_platform_backends} + Rendering Backend(s): ${active_rendering_backends} + Use netImGui: ${HELLOIMGUI_WITH_NETIMGUI} --------------------------------------------------------------------------- Options: HELLOIMGUI_USE_FREETYPE: ${HELLOIMGUI_USE_FREETYPE} (${HELLOIMGUI_FREETYPE_SELECTED_INFO}) @@ -1185,6 +1222,10 @@ function(him_main_add_hello_imgui_library) target_compile_definitions(${HELLOIMGUI_TARGET} PUBLIC HELLOIMGUI_HAS_NULL) endif() + if (HELLOIMGUI_WITH_NETIMGUI) + him_with_netimgui() + endif() + him_add_apple_options() him_add_linux_options() him_add_windows_options() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e57ac50e..57c198ec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,3 +6,6 @@ endif() if(HELLOIMGUI_BUILD_TESTS) add_subdirectory(hello_imgui_tests) endif() +if(HELLOIMGUI_WITH_NETIMGUI AND HELLOIMGUI_HAS_OPENGL3 AND HELLOIMGUI_USE_GLFW3) + add_subdirectory(netimgui_remote_display) +endif() diff --git a/src/hello_imgui/impl/hello_imgui.cpp b/src/hello_imgui/impl/hello_imgui.cpp index aec1a945..b43194af 100644 --- a/src/hello_imgui/impl/hello_imgui.cpp +++ b/src/hello_imgui/impl/hello_imgui.cpp @@ -197,6 +197,8 @@ std::string PlatformBackendTypeToString(PlatformBackendType platformBackendType) return "Glfw"; else if (platformBackendType == PlatformBackendType::Sdl) return "Sdl"; + else if (platformBackendType == PlatformBackendType::Null) + return "Null"; else return "Unknown platform backend"; } @@ -213,6 +215,8 @@ std::string RendererBackendTypeToString(RendererBackendType rendererBackendType) return "DirectX11"; else if (rendererBackendType == RendererBackendType::DirectX12) return "DirectX12"; + else if (rendererBackendType == RendererBackendType::Null) + return "Null"; else return "Unknown renderer backend"; } @@ -220,6 +224,8 @@ std::string RendererBackendTypeToString(RendererBackendType rendererBackendType) std::string GetBackendDescription() { const auto& params = GetRunnerParams(); + if (params->remoteParams.enableRemoting) + return "Remote"; std::string platformBackend = PlatformBackendTypeToString(params->platformBackendType); std::string rendererBackend = RendererBackendTypeToString(params->rendererBackendType); return platformBackend + " - " + rendererBackend; diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index cef532b6..600e9537 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -21,11 +21,16 @@ #define SCOPED_RELEASE_GIL_ON_MAIN_THREAD #endif +#ifdef HELLOIMGUI_WITH_NETIMGUI +#include "NetImgui_Api.h" +#endif + #include #include #include #include #include +#include #if __APPLE__ #include @@ -680,8 +685,97 @@ void AbstractRunner::Setup() style.Colors[ImGuiCol_TitleBgCollapsed].w = 1.f; } params.callbacks.SetupImGuiStyle(); + +#ifdef HELLOIMGUI_WITH_NETIMGUI + if (params.remoteParams.enableRemoting) + { + if (!NetImGui_Connect()) + { + IM_ASSERT(false && "NetImGui_Connect() failed! Please launch the server/display app before!"); + exit(1); + } + } +#endif +} + + +void AbstractRunner::NetImGui_LogConnectionStatusOnce() +{ + if (! params.remoteParams.enableRemoting) + return; +#ifdef HELLOIMGUI_WITH_NETIMGUI + // Log connection status and return + if (NetImgui::IsConnectionPending()) + { + static bool wasMessageShown = false; + if (!wasMessageShown) + { + wasMessageShown = true; + printf("Waiting for NetImgui connection...\n"); + } + } + else if (NetImgui::IsConnected()) + { + static bool wasMessageShown = false; + if (!wasMessageShown) + { + wasMessageShown = true; + printf("Connected to NetImgui server\n"); + } + } +#endif } + +bool AbstractRunner::NetImGui_Connect() +{ +#ifdef HELLOIMGUI_WITH_NETIMGUI + // 0. Startup NetImgui + NetImgui::Startup(); + // 1. Connect to NetImgui server + std::string clientName = params.remoteParams.clientName; + if (clientName.empty()) + clientName = params.appWindowParams.windowTitle; + if (clientName.empty()) + clientName = "HelloImGui"; + bool clientActiveImmediately = NetImgui::ConnectToApp(clientName.c_str(), params.remoteParams.serverHost.c_str(), params.remoteParams.serverPort); + + // 2. Wait a bit for the connection to be established (this is optional, just to display the messages after) + if (!clientActiveImmediately) + { + printf("Sleeping 0.1s to wait for NetImgui connection...\n"); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + // 3. Log connection status (this is optional also, since this is called also inside CreateFramesAndRender) + NetImGui_LogConnectionStatusOnce(); + if (!NetImgui::IsConnected() && !NetImgui::IsConnectionPending()) + { + printf("Connection to NetImgui server failed!\n"); + return false; + } + + // 4. Send Font texture to NetImgui server + const ImFontAtlas* pFonts = ImGui::GetIO().Fonts; + if( pFonts->TexPixelsAlpha8) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) + { + uint8_t* pPixelData(nullptr); int width(0), height(0); + ImGui::GetIO().Fonts->GetTexDataAsAlpha8(&pPixelData, &width, &height); + NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtA8); + } + if( pFonts->TexPixelsRGBA32) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) + { + uint8_t* pPixelData(nullptr); int width(0), height(0); + ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pPixelData, &width, &height); + NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtRGBA8); + } + return true; +#else + return false; +#endif +} + + void AbstractRunner::SetLayoutResetIfNeeded() { if (params.imGuiWindowParams.defaultImGuiWindowType == DefaultImGuiWindowType::ProvideFullScreenDockSpace) @@ -775,6 +869,11 @@ void AbstractRunner::CreateFramesAndRender() // (it is here only to make the code more readable, and to enable to collapse blocks of code) constexpr bool foldable_region = true; +#ifdef HELLOIMGUI_WITH_NETIMGUI + if (params.remoteParams.enableRemoting) + NetImGui_LogConnectionStatusOnce(); +#endif + if (foldable_region) // Update frame rate stats { _UpdateFrameRateStats(); @@ -1141,6 +1240,13 @@ void AbstractRunner::TearDown(bool gotException) if (params.useImGuiTestEngine) TestEngineCallbacks::TearDown_ImGuiContextDestroyed(); #endif + +#ifdef HELLOIMGUI_WITH_NETIMGUI + if (params.remoteParams.enableRemoting) + { + NetImgui::Shutdown(); + } +#endif } diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.h b/src/hello_imgui/internal/backend_impls/abstract_runner.h index cf6bef1b..d4881b3b 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.h +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.h @@ -98,6 +98,9 @@ class AbstractRunner void LayoutSettings_Load(); void LayoutSettings_Save(); + bool NetImGui_Connect(); + void NetImGui_LogConnectionStatusOnce(); + public: BackendApi::WindowPointer mWindow = nullptr; protected: diff --git a/src/hello_imgui/internal/backend_impls/runner_factory.cpp b/src/hello_imgui/internal/backend_impls/runner_factory.cpp index 1ce35969..b80c52fa 100644 --- a/src/hello_imgui/internal/backend_impls/runner_factory.cpp +++ b/src/hello_imgui/internal/backend_impls/runner_factory.cpp @@ -39,10 +39,20 @@ void ChooseBackendTypesIfSelectedAsFirstAvailable(RunnerParams* runnerParams) } } +void ChooseNullBackendsIfUsingRemote(RunnerParams* runnerParams) +{ + if (runnerParams->remoteParams.enableRemoting) + { + runnerParams->platformBackendType = PlatformBackendType::Null; + runnerParams->rendererBackendType = RendererBackendType::Null; + } +} + std::unique_ptr FactorRunner(RunnerParams& params) { ChooseBackendTypesIfSelectedAsFirstAvailable(¶ms); + ChooseNullBackendsIfUsingRemote(¶ms); if (params.platformBackendType == PlatformBackendType::Glfw) { #ifdef HELLOIMGUI_USE_GLFW3 diff --git a/src/hello_imgui/runner_params.h b/src/hello_imgui/runner_params.h index a7ea9c99..af4498fd 100644 --- a/src/hello_imgui/runner_params.h +++ b/src/hello_imgui/runner_params.h @@ -133,6 +133,36 @@ struct FpsIdling // -------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- + +// @@md#NetImGuiParams + +// NetImGuiParams is a struct that contains the settings for displaying the application on a remote device. +// using https://github.com/sammyfreg/netImgui +// (This will only work if the application is compiled with the option -DHELLOIMGUI_WITH_NETIMGUI=ON) +struct NetImGuiParams +{ + bool enableRemoting = false; + + // Name of the client (if empty, will use params.appWindowParams.windowTitle) + // (The client is the app that contains the application logic) + std::string clientName = ""; + + // The server host (if empty, will use "localhost") + // The server is the app that simply displays the application on a remote device + std::string serverHost = "localhost"; + // The server port (default is 8888) + uint32_t serverPort = 8888; + + // The client port (default is 8889) + // This is unused since it is the client (i.e. the app logic) that connects to the server, + // using NetImgui::ConnectToApp + uint32_t clientPort = 8889; +}; + +// @@md + +// -------------------------------------------------------------------------------------------------------------------- // @@md#RunnerParams @@ -195,6 +225,8 @@ struct RunnerParams // Only useful when multiple rendering backend are compiled and available. RendererBackendType rendererBackendType = RendererBackendType::FirstAvailable; + // --------------- RemoteParams ------------------- + NetImGuiParams remoteParams; // --------------- Settings ------------------- diff --git a/src/netimgui_remote_display/CMakeLists.txt b/src/netimgui_remote_display/CMakeLists.txt new file mode 100644 index 00000000..5059d715 --- /dev/null +++ b/src/netimgui_remote_display/CMakeLists.txt @@ -0,0 +1,18 @@ +if (NOT HELLOIMGUI_WITH_NETIMGUI) + message(FATAL_ERROR "HELLOIMGUI_WITH_NETIMGUI is not enabled") +endif() +if (NOT HELLOIMGUI_HAS_OPENGL3) + message(FATAL_ERROR "HELLOIMGUI_HAS_OPENGL3 is not enabled, and required for hello_imgui_remote_display") +endif() +if (NOT HELLOIMGUI_USE_GLFW3) + message(FATAL_ERROR "HELLOIMGUI_USE_GLFW3 is not enabled, and required for hello_imgui_remote_display") +endif() + + +set(hal_gl3_cpp_file ${NETIMGUI_DIR}/Code/ServerApp/Source/GlfwGL3/NetImguiServer_HAL_GL3.cpp) +set(sources ${hal_gl3_cpp_file} netimgui_remote_display.cpp NetImguiServer_HAL_Glfw.cpp) +hello_imgui_add_app(netimgui_remote_display ${sources}) +target_compile_definitions(net_imgui_server_lib PUBLIC NETIMGUI_SERVER_APP_BACKEND_GLFW_GL3=1) +target_link_libraries(netimgui_remote_display PRIVATE net_imgui_server_lib) +find_package(OpenGL REQUIRED) +target_link_libraries(netimgui_remote_display PRIVATE OpenGL::GL) diff --git a/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp b/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp new file mode 100644 index 00000000..b198b713 --- /dev/null +++ b/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp @@ -0,0 +1,113 @@ +#include "NetImguiServer_App.h" + +#if HAL_API_PLATFORM_GLFW_GL3 + +#include +#include "hello_imgui/hello_imgui.h" +#include + + +namespace NetImguiServer { namespace App +{ + +//================================================================================================= +// HAL STARTUP +// Additional initialisation that are platform specific +//================================================================================================= +bool HAL_Startup(const char* CmdLine) +{ + IM_UNUSED(CmdLine); + return true; +} + +//================================================================================================= +// HAL SHUTDOWN +// Prepare for shutdown of application, with platform specific code +//================================================================================================= +void HAL_Shutdown() +{ +} + +//================================================================================================= +// HAL GET SOCKET INFO +// Take a platform specific socket (based on the NetImguiNetworkXXX.cpp implementation) and +// fetch informations about the client IP connected +//================================================================================================= +bool HAL_GetSocketInfo(NetImgui::Internal::Network::SocketInfo* pClientSocket, char* pOutHostname, size_t HostNameLen, int& outPort) +{ +#ifdef _WIN32 + sockaddr socketAdr; + int sizeSocket(sizeof(sockaddr)); + SOCKET* pClientSocketWin = reinterpret_cast(pClientSocket); + if( getsockname(*pClientSocketWin, &socketAdr, &sizeSocket) == 0 ) + { + char zPortBuffer[32]; + if( getnameinfo(&socketAdr, sizeSocket, pOutHostname, static_cast(HostNameLen), zPortBuffer, sizeof(zPortBuffer), NI_NUMERICSERV) == 0 ) + { + outPort = atoi(zPortBuffer); + return true; + } + } +#endif + return false; +} + +//================================================================================================= +// HAL GET USER SETTING FOLDER +// Request the directory where to the 'shared config' clients should be saved +// Return 'nullptr' to disable this feature +//================================================================================================= +const char* HAL_GetUserSettingFolder() +{ + static std::string result = HelloImGui::IniFolderLocation(HelloImGui::IniFolderType::AppUserConfigFolder); + return result.c_str(); +} + +//================================================================================================= +// HAL GET CLIPBOARD UPDATED +// Detect when clipboard had a content change and we should refetch it on the Server and +// forward it to the Clients +//================================================================================================= +bool HAL_GetClipboardUpdated() +{ + auto updateClipboardEverySecond = []() -> bool + { + static std::chrono::steady_clock::time_point sLastCheck = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); + if( (now - sLastCheck) > std::chrono::seconds(1) ) + { + sLastCheck = now; + return true; + } + else + { + return false; + } + }; + +#ifdef HELLOIMGUI_USE_GLFW3 + GLFWwindow* mainWindow = (GLFWwindow*)HelloImGui::GetRunnerParams()->backendPointers.glfwWindow; + if (! mainWindow) + return updateClipboardEverySecond(); + else + { + static std::string lastClipboardContent; + const char* clipboardContent = glfwGetClipboardString(mainWindow); + if (clipboardContent && lastClipboardContent != clipboardContent) + { + lastClipboardContent = clipboardContent; + return true; + } + else + { + return false; + } + } +#else + return updateClipboardEverySecond(); +#endif +} + +}} // namespace NetImguiServer { namespace App + +#endif // HAL_API_PLATFORM_WIN32DX11 \ No newline at end of file diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp new file mode 100644 index 00000000..03b75020 --- /dev/null +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -0,0 +1,150 @@ +#include "NetImguiServer_App.h" + + + +// @SAMPLE_EDIT +// Note: The 'imgui_impl_opengl3_loader.h' included by Dear Imgui Backend has been replaced +// with our own version without stripped symbol. The server App needs a few extra +// function that are not shipped with Dear ImGui. +// The unstripped version comes from : https://github.com/dearimgui/gl3w_stripped/releases + +#include +#include "NetImguiServer_UI.h" +#include "hello_imgui/hello_imgui.h" +//#include "backends/imgui_impl_opengl3.cpp" +//#include "backends/imgui_impl_glfw.cpp" +////================================================================================================= + +// +//#include "imgui.h" +//#include "imgui_impl_glfw.h" +//#include "imgui_impl_opengl3.h" +//#include +//#if defined(IMGUI_IMPL_OPENGL_ES2) +//#include +//#endif +//#include // Will drag system OpenGL headers + +int main(int argc, char **argv) +{ + auto init_net_imgui_server = [&]() + { + // Start the NetImgui server + std::string cmdArgs; + for (size_t i = 0; i < size_t(argc); ++i) + cmdArgs += std::string(argv[i]) + " "; + if (!cmdArgs.empty()) + cmdArgs.pop_back(); + if (! NetImguiServer::App::Startup(cmdArgs.c_str())) + return 1; + }; + + auto handle_dpi_awareness = []() + { + // @SAMPLE_EDIT (DPI Awareness) + + // float scaleX, scaleY; + // ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + // glfwGetWindowContentScale(bd->Window, &scaleX, &scaleY); + // + // float maxScale = scaleX > scaleY ? scaleX : scaleY; + // float windowDPI = (float)(NetImguiServer::UI::kWindowDPIDefault) * maxScale; // = kWindowDPIDefault=96 + // NetImguiServer::UI::SetWindowDPI((int)windowDPI); + // ImGui::GetIO().FontGlobalScale = NetImguiServer::UI::GetFontDPIScale(); + + + // HelloImGui::GetRunnerParams()->dpiAwareParams.fontRenderingScale; + // HelloImGui::GetRunnerParams()->dpiAwareParams.dpiWindowSizeFactor; + // HelloImGui::GetRunnerParams()->dpiAwareParams.DpiFontLoadingFactor(); + float windowDPI = HelloImGui::GetRunnerParams()->dpiAwareParams.fontRenderingScale + * (float)(NetImguiServer::UI::kWindowDPIDefault); // 96 + NetImguiServer::UI::SetWindowDPI((int)windowDPI); + + }; + + + // Runner Params + HelloImGui::RunnerParams runnerParams; + + runnerParams.callbacks.PostInit = [&init_net_imgui_server]() { + init_net_imgui_server(); + //ImGui::GetIO().ConfigFlags = ImGui::GetIO().ConfigFlags | ImGuiConfigFlags_DockingEnable; + }; + + runnerParams.callbacks.PreNewFrame = [&handle_dpi_awareness]() { + // Request each client to update their drawing content + NetImguiServer::App::UpdateRemoteContent(); + handle_dpi_awareness(); + }; + + runnerParams.callbacks.BeforeImGuiRender = []() { + ImVec4 clear_color = NetImguiServer::UI::DrawImguiContent(); + HelloImGui::GetRunnerParams()->imGuiWindowParams.backgroundColor = clear_color; + }; + + + runnerParams.callbacks.BeforeExit = []() { + NetImguiServer::App::Shutdown(); + }; + + runnerParams.imGuiWindowParams.defaultImGuiWindowType = HelloImGui::DefaultImGuiWindowType::NoDefaultWindow; + +// runnerParams.dpiAwareParams.dpiWindowSizeFactor = 1.0f; +// runnerParams.dpiAwareParams.fontRenderingScale = 1.0f; + + // Start the HelloImGui runner + HelloImGui::Run(runnerParams); +} + +/* +int main(int argc, char **argv) +{ + + while (ok && !glfwWindowShouldClose(window)) + //========================================================================================= + { + glfwPollEvents(); + + + //========================================================================================= + // @SAMPLE_EDIT (Invoke our own Imgui content drawing, instead of the sample code) + clear_color = NetImguiServer::UI::DrawImguiContent(); + IM_UNUSED(show_demo_window); + IM_UNUSED(show_another_window); + //========================================================================================= + + // Rendering + ImGui::Render(); + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + // Update and Render additional Platform Windows + // (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere. + // For this specific demo app we could also call glfwMakeContextCurrent(window) directly) + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + GLFWwindow* backup_current_context = glfwGetCurrentContext(); + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + glfwMakeContextCurrent(backup_current_context); + } + + glfwSwapBuffers(window); + } + + // Cleanup + NetImguiServer::App::Shutdown(); // @SAMPLE_EDIT (Deallocate resources) + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(window); + glfwTerminate(); + + return 0; +} +*/ From e61894bd4e09138f24b47a58218d1884cacf6e38 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 10 Apr 2024 07:28:37 +0200 Subject: [PATCH 02/57] AbstractRunner: exit when NetImgui disconnected --- .../internal/backend_impls/abstract_runner.cpp | 10 +++++++++- .../netimgui_remote_display.cpp | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 600e9537..650d486f 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -870,8 +870,16 @@ void AbstractRunner::CreateFramesAndRender() constexpr bool foldable_region = true; #ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) + if (params.remoteParams.enableRemoting) // Hande NetImGui connection + { NetImGui_LogConnectionStatusOnce(); + if (!NetImgui::IsConnected()) + { + // Maybe we should wait for a few frames before we exit. + printf("NetImGui: Not connected anymore, exiting app\n"); + params.appShallExit = true; + } + } #endif if (foldable_region) // Update frame rate stats diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 03b75020..01089355 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -77,7 +77,7 @@ int main(int argc, char **argv) handle_dpi_awareness(); }; - runnerParams.callbacks.BeforeImGuiRender = []() { + runnerParams.callbacks.ShowGui = []() { ImVec4 clear_color = NetImguiServer::UI::DrawImguiContent(); HelloImGui::GetRunnerParams()->imGuiWindowParams.backgroundColor = clear_color; }; From a67e9f3b932915ae5c350e32662b93b321979de5 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 10 Apr 2024 14:46:22 +0200 Subject: [PATCH 03/57] NetImGui: gracefully handle connection / reconnection --- .../backend_impls/abstract_runner.cpp | 252 +++++++++++------- .../internal/backend_impls/abstract_runner.h | 3 - src/hello_imgui/runner_params.h | 3 + 3 files changed, 163 insertions(+), 95 deletions(-) diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 650d486f..376b4418 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -74,6 +74,162 @@ namespace HelloImGui void setFinalAppWindowScreenshotRgbBuffer(const ImageBuffer& b); +// ===================================================================================================================== +// +// ===================================================================================================================== +#ifdef HELLOIMGUI_WITH_NETIMGUI +struct NetImGuiRaii { + NetImGuiRaii() { NetImgui::Startup(); } + ~NetImGuiRaii() { NetImgui::Shutdown(); } +}; + + +class NetImGuiWrapper +{ +public: + NetImGuiWrapper() = default; + ~NetImGuiWrapper() = default; + + void HeartBeat() + { + if (mNetImguiRaii == nullptr) + { + InitiateConnection(); + return; + } + + int nbConnectionsPending = mNbConnectionsTentatives - mNbConnectionsSuccess - mNbConnectionsFailures; + IM_ASSERT(nbConnectionsPending == 0 || nbConnectionsPending == 1); + + if (nbConnectionsPending == 1) + { + if (NetImgui::IsConnected()) + { + LogStatus("Connection success...\n"); + ++ mNbConnectionsSuccess; + mLastConnectionSuccess = true; + } + else if (NetImgui::IsConnectionPending()) + { + LogStatus("Connection pending...\n"); + } + else + { + LogStatus("Connection failure...\n"); + ++ mNbConnectionsFailures; + mLastConnectionSuccess = false; + } + } + else // nbConnectionsPending == 0 + { + if (mLastConnectionSuccess) + { + if (!NetImgui::IsConnected()) + { + if (remoteParams().exitWhenServerDisconnected) + { + LogStatus("Connection lost... Exiting\n"); + runnerParams().appShallExit = true; + } + else + { + mTimePointConnectionEnded = HelloImGui::Internal::ClockSeconds(); + LogStatus("Connection lost... Reconnecting\n"); + InitiateConnection(); + } + } + } + else // Last connection was a failure + { + LogStatus("Last connection was a failure... Reconnecting\n"); + InitiateConnection(); + } + } + + // Exit if failure since too long + { + bool isDisconnected = !mLastConnectionSuccess; + if (isDisconnected) + { + double disconnectionTime = HelloImGui::Internal::ClockSeconds() - mTimePointConnectionEnded; + std::string msg = "Disconnected since " + std::to_string(disconnectionTime) + "s"; + LogStatus(msg); + bool isTooLong = disconnectionTime > remoteParams().durationMaxDisconnected; + if (isTooLong) + { + LogStatus("Too long disconnected... Exiting\n"); + runnerParams().appShallExit = true; + } + } + } + } + +private: + void InitiateConnection() + { + printf("NetImGuiWrapper: InitiateConnection\n"); + mNetImguiRaii.release(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + mNetImguiRaii = std::make_unique(); + NetImgui::ConnectToApp(clientName().c_str(), remoteParams().serverHost.c_str(), remoteParams().serverPort); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + ++ mNbConnectionsTentatives; + sendFonts(); + } + + std::string clientName() + { + std::string clientName = remoteParams().clientName; + if (clientName.empty()) + clientName = runnerParams().appWindowParams.windowTitle; + if (clientName.empty()) + clientName = "HelloImGui"; + clientName += "##" + std::to_string(ImGui::GetTime()); + return clientName; + } + + HelloImGui::NetImGuiParams& remoteParams() { return HelloImGui::GetRunnerParams()->remoteParams; } + HelloImGui::RunnerParams& runnerParams() { return *HelloImGui::GetRunnerParams(); } + + void sendFonts() + { + printf("NetImGuiWrapper: sendFonts\n"); + const ImFontAtlas* pFonts = ImGui::GetIO().Fonts; + if( pFonts->TexPixelsAlpha8) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) + { + uint8_t* pPixelData(nullptr); int width(0), height(0); + ImGui::GetIO().Fonts->GetTexDataAsAlpha8(&pPixelData, &width, &height); + NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtA8); + } + if( pFonts->TexPixelsRGBA32) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) + { + uint8_t* pPixelData(nullptr); int width(0), height(0); + ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pPixelData, &width, &height); + NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtRGBA8); + } + } + + void LogStatus(const std::string& msg) + { + printf("NetImGuiWrapper: %s\n", msg.c_str()); + } + +private: // Members + std::unique_ptr mNetImguiRaii; + int mNbConnectionsTentatives = 0; + int mNbConnectionsSuccess = 0; + int mNbConnectionsFailures = 0; + bool mLastConnectionSuccess = false; + double mTimePointConnectionEnded = 0.0; +}; + +std::unique_ptr gNetImGuiWrapper; +#endif +// ===================================================================================================================== +// +// ===================================================================================================================== + + AbstractRunner::AbstractRunner(RunnerParams ¶ms_) : params(params_) {} @@ -688,90 +844,7 @@ void AbstractRunner::Setup() #ifdef HELLOIMGUI_WITH_NETIMGUI if (params.remoteParams.enableRemoting) - { - if (!NetImGui_Connect()) - { - IM_ASSERT(false && "NetImGui_Connect() failed! Please launch the server/display app before!"); - exit(1); - } - } -#endif -} - - -void AbstractRunner::NetImGui_LogConnectionStatusOnce() -{ - if (! params.remoteParams.enableRemoting) - return; -#ifdef HELLOIMGUI_WITH_NETIMGUI - // Log connection status and return - if (NetImgui::IsConnectionPending()) - { - static bool wasMessageShown = false; - if (!wasMessageShown) - { - wasMessageShown = true; - printf("Waiting for NetImgui connection...\n"); - } - } - else if (NetImgui::IsConnected()) - { - static bool wasMessageShown = false; - if (!wasMessageShown) - { - wasMessageShown = true; - printf("Connected to NetImgui server\n"); - } - } -#endif -} - - -bool AbstractRunner::NetImGui_Connect() -{ -#ifdef HELLOIMGUI_WITH_NETIMGUI - // 0. Startup NetImgui - NetImgui::Startup(); - // 1. Connect to NetImgui server - std::string clientName = params.remoteParams.clientName; - if (clientName.empty()) - clientName = params.appWindowParams.windowTitle; - if (clientName.empty()) - clientName = "HelloImGui"; - bool clientActiveImmediately = NetImgui::ConnectToApp(clientName.c_str(), params.remoteParams.serverHost.c_str(), params.remoteParams.serverPort); - - // 2. Wait a bit for the connection to be established (this is optional, just to display the messages after) - if (!clientActiveImmediately) - { - printf("Sleeping 0.1s to wait for NetImgui connection...\n"); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - - // 3. Log connection status (this is optional also, since this is called also inside CreateFramesAndRender) - NetImGui_LogConnectionStatusOnce(); - if (!NetImgui::IsConnected() && !NetImgui::IsConnectionPending()) - { - printf("Connection to NetImgui server failed!\n"); - return false; - } - - // 4. Send Font texture to NetImgui server - const ImFontAtlas* pFonts = ImGui::GetIO().Fonts; - if( pFonts->TexPixelsAlpha8) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) - { - uint8_t* pPixelData(nullptr); int width(0), height(0); - ImGui::GetIO().Fonts->GetTexDataAsAlpha8(&pPixelData, &width, &height); - NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtA8); - } - if( pFonts->TexPixelsRGBA32) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) - { - uint8_t* pPixelData(nullptr); int width(0), height(0); - ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pPixelData, &width, &height); - NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtRGBA8); - } - return true; -#else - return false; + gNetImGuiWrapper = std::make_unique(); #endif } @@ -872,13 +945,7 @@ void AbstractRunner::CreateFramesAndRender() #ifdef HELLOIMGUI_WITH_NETIMGUI if (params.remoteParams.enableRemoting) // Hande NetImGui connection { - NetImGui_LogConnectionStatusOnce(); - if (!NetImgui::IsConnected()) - { - // Maybe we should wait for a few frames before we exit. - printf("NetImGui: Not connected anymore, exiting app\n"); - params.appShallExit = true; - } + gNetImGuiWrapper->HeartBeat(); } #endif @@ -1252,7 +1319,8 @@ void AbstractRunner::TearDown(bool gotException) #ifdef HELLOIMGUI_WITH_NETIMGUI if (params.remoteParams.enableRemoting) { - NetImgui::Shutdown(); + IM_ASSERT(gNetImGuiWrapper != nullptr); + gNetImGuiWrapper.release(); } #endif } diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.h b/src/hello_imgui/internal/backend_impls/abstract_runner.h index d4881b3b..cf6bef1b 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.h +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.h @@ -98,9 +98,6 @@ class AbstractRunner void LayoutSettings_Load(); void LayoutSettings_Save(); - bool NetImGui_Connect(); - void NetImGui_LogConnectionStatusOnce(); - public: BackendApi::WindowPointer mWindow = nullptr; protected: diff --git a/src/hello_imgui/runner_params.h b/src/hello_imgui/runner_params.h index af4498fd..567aa572 100644 --- a/src/hello_imgui/runner_params.h +++ b/src/hello_imgui/runner_params.h @@ -144,6 +144,9 @@ struct NetImGuiParams { bool enableRemoting = false; + bool exitWhenServerDisconnected = false; + double durationMaxDisconnected = 30.0; + // Name of the client (if empty, will use params.appWindowParams.windowTitle) // (The client is the app that contains the application logic) std::string clientName = ""; From 72d8c68298ae975aff8314751a686a8aeca6ba91 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 10 Apr 2024 17:10:03 +0200 Subject: [PATCH 04/57] Rename BackendWindowHelper::GetDisplayFramebufferScale --- src/hello_imgui/dpi_aware.h | 5 ++++- src/hello_imgui/internal/backend_impls/abstract_runner.cpp | 2 +- .../backend_window_helper/backend_window_helper.h | 2 +- .../backend_window_helper/glfw_window_helper.cpp | 4 ++-- .../backend_impls/backend_window_helper/glfw_window_helper.h | 2 +- .../backend_impls/backend_window_helper/null_window_helper.h | 2 +- .../backend_window_helper/sdl_window_helper.cpp | 2 +- .../backend_impls/backend_window_helper/sdl_window_helper.h | 2 +- src/hello_imgui/internal/backend_impls/null_config.h | 4 +++- 9 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/hello_imgui/dpi_aware.h b/src/hello_imgui/dpi_aware.h index cd48d60a..5a730bd7 100644 --- a/src/hello_imgui/dpi_aware.h +++ b/src/hello_imgui/dpi_aware.h @@ -64,7 +64,10 @@ struct DpiAwareParams // factor by which font size should be multiplied at loading time to get a similar // visible size on different OSes. // The size will be equivalent to a size given for a 96 PPI screen - float DpiFontLoadingFactor() { return dpiWindowSizeFactor / fontRenderingScale;}; + float DpiFontLoadingFactor() { + float r = dpiWindowSizeFactor / fontRenderingScale; + return r; + }; }; // ---------------------------------------------------------------------------- diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 376b4418..196541c0 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -478,7 +478,7 @@ void AbstractRunner::SetupDpiAwareParams() } ImGui::GetIO().FontGlobalScale = params.dpiAwareParams.fontRenderingScale; - ImGui::GetIO().DisplayFramebufferScale = mBackendWindowHelper->GetWindowScaleFactor(mWindow); + ImGui::GetIO().DisplayFramebufferScale = mBackendWindowHelper->GetDisplayFramebufferScale(mWindow); } diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/backend_window_helper.h b/src/hello_imgui/internal/backend_impls/backend_window_helper/backend_window_helper.h index 4d6d8c3f..e447470c 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/backend_window_helper.h +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/backend_window_helper.h @@ -62,7 +62,7 @@ namespace HelloImGui { namespace BackendApi virtual void WaitForEventTimeout(double timeout_seconds) = 0; // Return the ratio FrameBufferSize / WindowSize - virtual ImVec2 GetWindowScaleFactor(WindowPointer window) = 0; + virtual ImVec2 GetDisplayFramebufferScale(WindowPointer window) = 0; // Return the ratio by which the window size should be scaled to account for HighDPI // (i.e. the same size given at creation create the same physical size in mm on the screen) diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp index 71f4d4d2..9f066400 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp @@ -189,7 +189,7 @@ namespace HelloImGui { namespace BackendApi glfwWaitEventsTimeout(timeout_seconds); } - ImVec2 GlfwWindowHelper::GetWindowScaleFactor(HelloImGui::BackendApi::WindowPointer window) + ImVec2 GlfwWindowHelper::GetDisplayFramebufferScale(HelloImGui::BackendApi::WindowPointer window) { float x_scale, y_scale; glfwGetWindowContentScale((GLFWwindow *) window, &x_scale, &y_scale); @@ -201,7 +201,7 @@ namespace HelloImGui { namespace BackendApi #ifdef __APPLE__ return 1.f; #else - ImVec2 scale = GetWindowScaleFactor(window); + ImVec2 scale = GetDisplayFramebufferScale(window); return scale.x; #endif } diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.h b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.h index a659386d..4d1f65b8 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.h +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.h @@ -29,7 +29,7 @@ namespace HelloImGui { namespace BackendApi void WaitForEventTimeout(double timeout_seconds) override; - ImVec2 GetWindowScaleFactor(WindowPointer window) override; + ImVec2 GetDisplayFramebufferScale(WindowPointer window) override; float GetWindowSizeDpiScaleFactor(WindowPointer window) override; void HideWindow(WindowPointer window) override; diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h b/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h index fac9bc92..9138d171 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h @@ -35,7 +35,7 @@ namespace HelloImGui { namespace BackendApi std::this_thread::sleep_for(std::chrono::milliseconds((int)(timeout_seconds * 1000))); } - ImVec2 GetWindowScaleFactor(WindowPointer window) override { return NullConfig::GetWindowScaleFactor(); } + ImVec2 GetDisplayFramebufferScale(WindowPointer window) override { return NullConfig::GetDisplayFramebufferScale(); } float GetWindowSizeDpiScaleFactor(WindowPointer window) override { return NullConfig::GetWindowSizeDpiScaleFactor(); } void HideWindow(WindowPointer window) override {} diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.cpp b/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.cpp index 3bb13942..df8bc5af 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.cpp +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.cpp @@ -200,7 +200,7 @@ namespace HelloImGui { namespace BackendApi SDL_WaitEventTimeout(NULL, timeout_ms); } - ImVec2 SdlWindowHelper::GetWindowScaleFactor(WindowPointer window) + ImVec2 SdlWindowHelper::GetDisplayFramebufferScale(WindowPointer window) { int win_w, win_h, fb_w, fb_h; SDL_GetWindowSize((SDL_Window *) window, &win_w, &win_h); diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.h b/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.h index 0546bd84..1381ba79 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.h +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.h @@ -38,7 +38,7 @@ namespace HelloImGui { namespace BackendApi void WaitForEventTimeout(double timeout_seconds) override; - ImVec2 GetWindowScaleFactor(WindowPointer window) override; + ImVec2 GetDisplayFramebufferScale(WindowPointer window) override; float GetWindowSizeDpiScaleFactor(WindowPointer window) override; void HideWindow(WindowPointer window) override; diff --git a/src/hello_imgui/internal/backend_impls/null_config.h b/src/hello_imgui/internal/backend_impls/null_config.h index ff5bf905..1d91b4b5 100644 --- a/src/hello_imgui/internal/backend_impls/null_config.h +++ b/src/hello_imgui/internal/backend_impls/null_config.h @@ -21,7 +21,9 @@ namespace NullConfig return {GetScreenBounds()}; } - ImVec2 GetWindowScaleFactor() { return {1.f, 1.f}; } + ImVec2 GetDisplayFramebufferScale() { + return {1.f, 1.f}; + } float GetWindowSizeDpiScaleFactor() { return 1.f; } } From f8131ec7056081dbc4bfca1295f37a65e2f54256 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 10 Apr 2024 17:13:17 +0200 Subject: [PATCH 05/57] netimgui_remote_display (server): disable call to SetWindowDPI --- src/netimgui_remote_display/netimgui_remote_display.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 01089355..93625919 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -58,7 +58,12 @@ int main(int argc, char **argv) // HelloImGui::GetRunnerParams()->dpiAwareParams.DpiFontLoadingFactor(); float windowDPI = HelloImGui::GetRunnerParams()->dpiAwareParams.fontRenderingScale * (float)(NetImguiServer::UI::kWindowDPIDefault); // 96 - NetImguiServer::UI::SetWindowDPI((int)windowDPI); + //windowDPI = 48.f; + //printf("windowDPI: %f\n", windowDPI); + //NetImguiServer::UI::SetWindowDPI((int)windowDPI); + + // See void FontCreationCallback(float PreviousDPIScale, float NewDPIScale) + // in SampleFontDPI.cpp ?? }; From 5a07c12b731169ab41e2b629752f71840375ad40 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 10 Apr 2024 17:13:48 +0200 Subject: [PATCH 06/57] demodocking / hack: all dpi settings to one --- .../hello_imgui_demodocking/hello_imgui_demodocking.main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp index f2422984..06e0ddf8 100644 --- a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp +++ b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp @@ -790,6 +790,10 @@ int main(int, char**) //runnerParams.platformBackendType = HelloImGui::PlatformBackendType::Sdl; //runnerParams.rendererBackendType = HelloImGui::RendererBackendType::Vulkan; + //runnerParams.remoteParams.enableRemoting = true; + runnerParams.dpiAwareParams.dpiWindowSizeFactor = 1.0f; + runnerParams.dpiAwareParams.fontRenderingScale = 1.0f; + HelloImGui::Run(runnerParams); // Note: with ImGuiBundle, it is also possible to use ImmApp::Run(...) return 0; From 2dc44c8836d4b08cc6b794ccda4af5e0ad0f6038 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 10 Apr 2024 17:29:45 +0200 Subject: [PATCH 07/57] unignore netimgui --- external/.gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/external/.gitignore b/external/.gitignore index 972ae40c..fea25349 100644 --- a/external/.gitignore +++ b/external/.gitignore @@ -1,4 +1,3 @@ SDL SDL2-*/ qtimgui/ -netImgui/ From daa91f9620477892fe3d426cc6ceab502fcb7bdf Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 10 Apr 2024 17:31:53 +0200 Subject: [PATCH 08/57] Add submodule netimgui --- .gitmodules | 3 +++ external/netImgui | 1 + 2 files changed, 4 insertions(+) create mode 160000 external/netImgui diff --git a/.gitmodules b/.gitmodules index 55bacb4e..1733de0e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "_example_integration"] path = _example_integration url = https://github.com/pthom/hello_imgui_template.git +[submodule "external/netImgui"] + path = external/netImgui + url = https://github.com/pthom/netImgui.git diff --git a/external/netImgui b/external/netImgui new file mode 160000 index 00000000..cf7b8fc9 --- /dev/null +++ b/external/netImgui @@ -0,0 +1 @@ +Subproject commit cf7b8fc9df10d1010a9fc88bc1c07af33d8a953d From a1250d3945ff3bebc7e3db4e1153c355e76c3495 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 10 Apr 2024 17:44:52 +0200 Subject: [PATCH 09/57] Small fixes (linux) --- src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp | 2 +- src/netimgui_remote_display/netimgui_remote_display.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp b/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp index b198b713..32167ccd 100644 --- a/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp +++ b/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp @@ -4,7 +4,7 @@ #include #include "hello_imgui/hello_imgui.h" -#include +#include namespace NetImguiServer { namespace App diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 93625919..e741bd25 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -36,7 +36,7 @@ int main(int argc, char **argv) if (!cmdArgs.empty()) cmdArgs.pop_back(); if (! NetImguiServer::App::Startup(cmdArgs.c_str())) - return 1; + exit(1); }; auto handle_dpi_awareness = []() From 465c0b31663ea2765c5f5b8b867363eae7ac9408 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 11 Apr 2024 09:14:28 +0200 Subject: [PATCH 10/57] netimgui: work on framebufferdisplayScale (linux) --- external/netImgui | 2 +- .../hello_imgui_demodocking.main.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/external/netImgui b/external/netImgui index cf7b8fc9..bd90f5f0 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit cf7b8fc9df10d1010a9fc88bc1c07af33d8a953d +Subproject commit bd90f5f066b62cd67ac37cfb192989a09e9e8832 diff --git a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp index 06e0ddf8..31d5e4a2 100644 --- a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp +++ b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp @@ -790,9 +790,9 @@ int main(int, char**) //runnerParams.platformBackendType = HelloImGui::PlatformBackendType::Sdl; //runnerParams.rendererBackendType = HelloImGui::RendererBackendType::Vulkan; - //runnerParams.remoteParams.enableRemoting = true; - runnerParams.dpiAwareParams.dpiWindowSizeFactor = 1.0f; - runnerParams.dpiAwareParams.fontRenderingScale = 1.0f; + runnerParams.remoteParams.enableRemoting = true; + //runnerParams.dpiAwareParams.dpiWindowSizeFactor = 1.0f; + //runnerParams.dpiAwareParams.fontRenderingScale = 1.0f; HelloImGui::Run(runnerParams); // Note: with ImGuiBundle, it is also possible to use ImmApp::Run(...) From 36c454483a87076bfe696d8b5eed6c17e4086dbd Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 11 Apr 2024 09:14:46 +0200 Subject: [PATCH 11/57] Debug info / GlfwWindowHelper::GetWindowSizeDpiScaleFactor --- .../backend_impls/backend_window_helper/glfw_window_helper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp index 9f066400..7729d196 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp @@ -202,6 +202,7 @@ namespace HelloImGui { namespace BackendApi return 1.f; #else ImVec2 scale = GetDisplayFramebufferScale(window); + printf("GlfwWindowHelper::GetWindowSizeDpiScaleFactor: %f, %f\n", scale.x, scale.y); return scale.x; #endif } From 76e0c57a93548dad9173dc7afca5bb54d7c302e9 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 11 Apr 2024 09:15:38 +0200 Subject: [PATCH 12/57] dpi_aware: add doc --- src/hello_imgui/dpi_aware.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hello_imgui/dpi_aware.h b/src/hello_imgui/dpi_aware.h index 5a730bd7..b517e3be 100644 --- a/src/hello_imgui/dpi_aware.h +++ b/src/hello_imgui/dpi_aware.h @@ -54,10 +54,13 @@ struct DpiAwareParams float dpiWindowSizeFactor = 0.0f; // `fontRenderingScale` - // factor (that is either 1 or < 1.) by which fonts glyphs should be - // scaled at rendering time. - // On macOS retina screens, it will be 0.5, since macOS APIs hide - // the real resolution of the screen. + // factor (that is either 1 or < 1.) by which fonts glyphs should be scaled at rendering time. + // On macOS retina screens, it will be 0.5, since macOS APIs hide the real resolution of the screen. + // Changing this value will *not* change the visible font size on the screen, however it will + // affect the size of the loaded glyphs. + // For example, if fontRenderingScale=0.5 (which is the default on a macOS retina screen), + // a font size of 16 will be loaded as if it was 32, and will be rendered at half size. + // This leads to a better rendering quality on some platforms. float fontRenderingScale = 0.0f; // `dpiFontLoadingFactor` From 5c39c3b8ff16bb7033bc27c24c9044a28788fa64 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 11 Apr 2024 09:15:58 +0200 Subject: [PATCH 13/57] update netimgui (fix cmake) --- external/netImgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/netImgui b/external/netImgui index bd90f5f0..f50cff46 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit bd90f5f066b62cd67ac37cfb192989a09e9e8832 +Subproject commit f50cff468fd7fce3aa96c4f0d338aa607d4180c5 From 3659b634f569acfd7890dafec7d570f146d3c45f Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 11 Apr 2024 09:19:54 +0200 Subject: [PATCH 14/57] Debug Info / GlfwWindowHelper::GetWindowSizeDpiScaleFactor --- .../backend_impls/backend_window_helper/glfw_window_helper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp index 7729d196..b04d7893 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp @@ -193,6 +193,7 @@ namespace HelloImGui { namespace BackendApi { float x_scale, y_scale; glfwGetWindowContentScale((GLFWwindow *) window, &x_scale, &y_scale); + printf("GlfwWindowHelper::GetDisplayFramebufferScale: %f, %f\n", x_scale, y_scale); return ImVec2(x_scale, y_scale); } @@ -202,7 +203,6 @@ namespace HelloImGui { namespace BackendApi return 1.f; #else ImVec2 scale = GetDisplayFramebufferScale(window); - printf("GlfwWindowHelper::GetWindowSizeDpiScaleFactor: %f, %f\n", scale.x, scale.y); return scale.x; #endif } From dda70979bc7f296499fa2444cd4bb76a6fde3368 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 11 Apr 2024 10:54:21 +0200 Subject: [PATCH 15/57] add process_md_docs link --- docs_src/{generate_book.sh => _generate_book_impl.sh} | 0 docs_src/process_md_docs.py | 1 + tools/doc/process_md_docs.py | 2 +- 3 files changed, 2 insertions(+), 1 deletion(-) rename docs_src/{generate_book.sh => _generate_book_impl.sh} (100%) create mode 120000 docs_src/process_md_docs.py diff --git a/docs_src/generate_book.sh b/docs_src/_generate_book_impl.sh similarity index 100% rename from docs_src/generate_book.sh rename to docs_src/_generate_book_impl.sh diff --git a/docs_src/process_md_docs.py b/docs_src/process_md_docs.py new file mode 120000 index 00000000..1a883ac4 --- /dev/null +++ b/docs_src/process_md_docs.py @@ -0,0 +1 @@ +../tools/doc/process_md_docs.py \ No newline at end of file diff --git a/tools/doc/process_md_docs.py b/tools/doc/process_md_docs.py index 9fd5f0cb..7366b421 100755 --- a/tools/doc/process_md_docs.py +++ b/tools/doc/process_md_docs.py @@ -134,5 +134,5 @@ def process_main_readme(repo_dir: str): process_md_file(hello_imgui_dir + "doc_params.src.md", hello_imgui_dir + "doc_params.md") process_md_file(hello_imgui_dir + "doc_api.src.md", hello_imgui_dir + "doc_api.md") - generate_book_script = repo_dir + "docs_src/generate_book.sh" + generate_book_script = repo_dir + "docs_src/_generate_book_impl.sh" os.system(generate_book_script) From 48dfbfb3048811e1e3fda62b6efa346c423069af Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 11 Apr 2024 10:55:33 +0200 Subject: [PATCH 16/57] dpi_aware: add roDisplayFramebufferScale --- src/hello_imgui/dpi_aware.h | 19 +++++++++++++++++-- .../backend_impls/abstract_runner.cpp | 15 +++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/hello_imgui/dpi_aware.h b/src/hello_imgui/dpi_aware.h index b517e3be..22e9be7e 100644 --- a/src/hello_imgui/dpi_aware.h +++ b/src/hello_imgui/dpi_aware.h @@ -38,8 +38,9 @@ namespace HelloImGui struct DpiAwareParams { // `dpiWindowSizeFactor` - // factor by which window size should be multiplied to get a similar - // visible size on different OSes. + // factor by which window size should be multiplied to get a similar + // visible size on different OSes. This affects the size of the window, + // but *not* the size of widgets and text. // In a standard environment (i.e. outside of Hello ImGui), an application with a size of 960x480 pixels, // may have a physical size (in mm or inches) that varies depending on the screen DPI, and the OS. // @@ -71,6 +72,20 @@ struct DpiAwareParams float r = dpiWindowSizeFactor / fontRenderingScale; return r; }; + + // `roDisplayFramebufferScale` + // When rendering, the internal frame buffer size might be bigger than the + // size (in "virtual screen coordinate" pixels) of the window. + // For example: + // - on macOS retina screens, the frame buffer size will be twice the window size + // (and roDisplayFramebufferScale will be 2, 2) + // - on Windows, the frame buffer size will be the same as the window size. + // (since virtual screen coordinate pixels are the same as physical screen pixels on Windows) + // + // This is an output-only value: it will be set by the platform backend + // after it was initialized (any change you make to it at startup will not be used) + // It mirrors the value inside ImGui::GetIO().DisplayFramebufferScale. + ImVec2 roDisplayFramebufferScale = ImVec2(0.f, 0.f); }; // ---------------------------------------------------------------------------- diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 196541c0..168fc0b9 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -476,9 +476,19 @@ void AbstractRunner::SetupDpiAwareParams() params.dpiAwareParams.fontRenderingScale = 1.0f / fontSizeIncreaseFactor; } - ImGui::GetIO().FontGlobalScale = params.dpiAwareParams.fontRenderingScale; - ImGui::GetIO().DisplayFramebufferScale = mBackendWindowHelper->GetDisplayFramebufferScale(mWindow); + + // + // DisplayFramebufferScale + // + ImVec2 displayFramebufferScale = mBackendWindowHelper->GetDisplayFramebufferScale(mWindow); + // Note: ImGui_ImplGlfw_NewFrame, ImGui_ImplSDL2_NewFrame, ... will also set ImGui::GetIO().DisplayFramebufferScale + // (using their own backend abstraction). + // There is a slight chance of discrepancy here, However, GetDisplayFramebufferScale() and DearImGui + // do get the same results for SDL and GLFW under Windows Linux macOS, Android, iOS. + ImGui::GetIO().DisplayFramebufferScale = params.dpiAwareParams.roDisplayFramebufferScale; + // dpiAwareParams.roDisplayFramebufferScale is an output-only value (for information only) + params.dpiAwareParams.roDisplayFramebufferScale = displayFramebufferScale; } @@ -1101,6 +1111,7 @@ void AbstractRunner::CreateFramesAndRender() mRenderingBackendCallbacks->Impl_NewFrame_3D(); Impl_NewFrame_PlatformBackend(); + { // Workaround against SDL clock that sometimes leads to io.DeltaTime=0.f on emscripten // (which fails to an `IM_ASSERT(io.DeltaTime) > 0` in ImGui::NewFrame()) From b8c8702be8a6910ace5f9b8076331451df01014f Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 11 Apr 2024 12:08:11 +0200 Subject: [PATCH 17/57] Improve doc / Dpi Params --- docs_src/_toc.yml | 2 +- src/hello_imgui/doc_api.md | 105 ++++++++++++++++++++++------- src/hello_imgui/doc_api.src.md | 40 +---------- src/hello_imgui/doc_params.md | 68 ++++++++++++++++--- src/hello_imgui/doc_params.src.md | 9 ++- src/hello_imgui/dpi_aware.h | 108 ++++++++++++++++++++++++++++++ 6 files changed, 258 insertions(+), 74 deletions(-) diff --git a/docs_src/_toc.yml b/docs_src/_toc.yml index 8d260ba6..fce2e527 100644 --- a/docs_src/_toc.yml +++ b/docs_src/_toc.yml @@ -6,7 +6,7 @@ root: intro chapters: - file: get_started - - file: doc_api - file: doc_params + - file: doc_api - file: build diff --git a/src/hello_imgui/doc_api.md b/src/hello_imgui/doc_api.md index da526d15..c48080e6 100644 --- a/src/hello_imgui/doc_api.md +++ b/src/hello_imgui/doc_api.md @@ -408,42 +408,101 @@ void ShowAppMenu(RunnerParams & runnerParams); # Handling screens with high DPI -_Note: This part is relevant only for more advanced usages. If you use `HelloImGui::LoadFont()`, and always use `HelloImGui::EmToVec2()` to place widgets, you do not need to worry about DPI handling_ -## Details on DPI handling on different OS +_Note: This part is relevant only for more advanced usages. If you use `HelloImGui::LoadFont()`, + and always use `HelloImGui::EmToVec2()` to place widgets, you do not need to worry about DPI handling_ -Let's consider screen whose physical pixel resolution is 3600x2000, but which will displayed with a scaling factor of 200%, so that widgets do not look too small on it. +## OS specificities -The way it is handled depends on the OS: -- On MacOS, the screen will be seen as having a resolution of 1800x1000, and the OS handles the resizing by itself. -- On Linux, and on Windows if the application is DPI aware, the screen will be seen as having a resolution of 3600x2000. -- On Windows if the application is not DPI aware, the screen will be seen as having a resolution of 1800x1000 +There are several important things to know about high-DPI handling within Hello ImGui and Dear ImGui: -By default, if using the glfw backend, applications will be Dpi aware under windows. -Sdl applications are normally not Dpi aware. However HelloImGui makes them Dpi aware when using the sdl backend. +1. (virtual) screen coordinates vs (physical) pixels +2. DisplayFramebufferScale: Frame buffer size vs window size +3. FontGlobalScale: display-time font scaling factor +4. How to load fonts with the correct size +5. How to get similar window sizes on different OSes/DPI -## Dpi aware Font scaling +## Screen coordinates -`HelloImGui::LoadFont()` will load fonts with the correct size, taking into account the DPI scaling. +Screen coordinates are the coordinates you use to place and size windows on the screen. -If you prefer to use `ImGui::GetIO().Fonts->AddFontFromFileTTF()`, there are two things to know: +**Screen coordinates do not always correspond to physical pixels** -1. You should adjust `ImGui::GetIO().FontGlobalScale`: +- On macOS/iOS retina screens, a screen coordinate corresponds typically + to 2x2 physical pixels (but this may vary if you change the display scaling) +- On most Linux distributions, whenever there is a high DPI screen + you can set the display scale. For example if you set the scale to 300%, + then a screen coordinate will correspond to 3x3 physical pixels +- On Windows, there are two possible situations: + - If the application is DPI aware, a screen coordinate corresponds to 1x1 physical pixel, + and you can use the full extent of your screen resolution. + - If the application is not DPI aware, a screen coordinate may correspond to 2x2 physical pixels + (if the display scaling is set to 200% for example). However, the rendering of your application + will be blurry and will not use the full extent of your screen resolution. + - Notes: + - Applications created with HelloImGui are DPI aware by default (when using glfw and sdl backends). + - SDL applications are normally not DPI aware. However, HelloImGui makes them DPI aware. -Under windows and linux, it should be is 1: no rescaling should be done by ImGui. -Under macOS and emscripten, it may need to bet set to 0.5 (for example it will be 0.5 if the dpi scaling is 200% -on a macOS retina screen) -`HelloImGui::ImGuiDefaultFontGlobalScale()` returns the default value that should be stored inside `ImGui::GetIO().FontGlobalScale`. +## DisplayFramebufferScale +`DisplayFramebufferScale` is the ratio between the frame buffer size and the window size. +The frame buffer size is the size of the internal buffer used by the rendering backend. +It might be bigger than the actual window size. +`ImVec2 ImGui::GetIO().DisplayFramebufferScale` is a factor by which the frame buffer size is bigger than the window size. +It is set by the platform backend after it was initialized, and typically reflects the scaling ratio between +physical pixels and screen coordinates. -2. You should adjust the font size when loading a font: +Under windows, it will always be (1,1). Under macOS / linux, it will reflect the current display scaling. +It will typically be (2,2) on a macOS retina screen. -`HelloImGui::DpiFontLoadingFactor()` returns a factor by which you shall multiply your font sizes when loading them. +Notes: +- As a convenience, `ImGui::GetIO().DisplayFramebufferScale` is mirrored in `HelloImGui::DpiAwareParams::roDisplayFramebufferScale`. +- You cannot change DisplayFramebufferScale manually, it will be reset at each new frame, by asking the platform backend. -`HelloImGui::DpiFontLoadingFactor()` corresponds to: -`DpiWindowSizeFactor() * 1.f / ImGui::GetIO().FontGlobalScale` -where DpiWindowSizeFactor() is equal to `CurrentScreenPixelPerInch / 96` -under windows and linux, 1 under macOS +## FontGlobalScale + +`ImGui::GetIO().FontGlobalScale` is a factor by which fonts glyphs should be scaled at rendering time. +It is typically 1 on windows, and 0.5 on macOS retina screens. + + +## How to load fonts with the correct size + +### Using HelloImGui::LoadFont + +[`HelloImGui::LoadFont()`](https://pthom.github.io/hello_imgui/book/doc_api.html#load-fonts) will load fonts + with the correct size, taking into account the DPI scaling. + +### Using Dear ImGui's AddFontFromFileTTF(): +`ImGui::GetIO().Fonts->AddFontFromFileTTF()` loads a font with a given size, in *physical pixels*. + +If for example, DisplayFramebufferScale is (2,2), and you load a font with a size of 16, it will by default be rendered + with size of 16 *virtual screen coordinate pixels* (i.e. 32 physical pixels). This will lead to blurry text. +To solve this, you should load your font with a size of 16 *virtual screen coordinate pixels* (i.e. 32 physical pixels), +and set `ImGui::GetIO().FontGlobalScale` to 0.5. + +Helpers if using `ImGui::GetIO().Fonts->AddFontFromFileTTF()`: +- `HelloImGui::ImGuiDefaultFontGlobalScale()` returns the default value that should be stored inside `ImGui::GetIO().FontGlobalScale`. +- `HelloImGui::DpiFontLoadingFactor()` returns a factor by which you shall multiply your font sizes when loading them. + + +## Reproducible physical window sizes (in mm or inches) + +### Using HelloImGui +Simply specify a window size that corresponds to theoretical 96 PPI screen (inside `RunnerParams.appWindowParams.windowGeometry.size`) + +### Using your own code to create the backend window +If you prefer to create the window by yourself, its physical size in millimeters may vary widely, +depending on the OS and the current screen DPI setting. +Typically under Windows, your window may appear to be very small if your screen is high DPI. + +To get a similar window size on different OSes/DPI, you should multiply the window size by `HelloImGui::DpiWindowSizeFactor()`. + +Note: DpiWindowSizeFactor() is equal to `CurrentScreenPixelPerInch / 96` under windows and linux, and always 1 under macOS. + +## Fine tune DPI Handling + +See [`HelloImGui::DpiAwareParams`](https://pthom.github.io/hello_imgui/book/doc_params.html#dpi-aware-params) +for more information on how to fine tune DPI handling when using Hello ImGui. diff --git a/src/hello_imgui/doc_api.src.md b/src/hello_imgui/doc_api.src.md index 15db606d..df8fd9ba 100644 --- a/src/hello_imgui/doc_api.src.md +++ b/src/hello_imgui/doc_api.src.md @@ -100,42 +100,4 @@ See [hello_imgui.h](https://github.com/pthom/hello_imgui/blob/master/src/hello_i # Handling screens with high DPI -_Note: This part is relevant only for more advanced usages. If you use `HelloImGui::LoadFont()`, and always use `HelloImGui::EmToVec2()` to place widgets, you do not need to worry about DPI handling_ - -## Details on DPI handling on different OS - -Let's consider screen whose physical pixel resolution is 3600x2000, but which will displayed with a scaling factor of 200%, so that widgets do not look too small on it. - -The way it is handled depends on the OS: -- On MacOS, the screen will be seen as having a resolution of 1800x1000, and the OS handles the resizing by itself. -- On Linux, and on Windows if the application is DPI aware, the screen will be seen as having a resolution of 3600x2000. -- On Windows if the application is not DPI aware, the screen will be seen as having a resolution of 1800x1000 - -By default, if using the glfw backend, applications will be Dpi aware under windows. -Sdl applications are normally not Dpi aware. However HelloImGui makes them Dpi aware when using the sdl backend. - - -## Dpi aware Font scaling - -`HelloImGui::LoadFont()` will load fonts with the correct size, taking into account the DPI scaling. - -If you prefer to use `ImGui::GetIO().Fonts->AddFontFromFileTTF()`, there are two things to know: - -1. You should adjust `ImGui::GetIO().FontGlobalScale`: - -Under windows and linux, it should be is 1: no rescaling should be done by ImGui. -Under macOS and emscripten, it may need to bet set to 0.5 (for example it will be 0.5 if the dpi scaling is 200% -on a macOS retina screen) - -`HelloImGui::ImGuiDefaultFontGlobalScale()` returns the default value that should be stored inside `ImGui::GetIO().FontGlobalScale`. - - -2. You should adjust the font size when loading a font: - -`HelloImGui::DpiFontLoadingFactor()` returns a factor by which you shall multiply your font sizes when loading them. - -`HelloImGui::DpiFontLoadingFactor()` corresponds to: -`DpiWindowSizeFactor() * 1.f / ImGui::GetIO().FontGlobalScale` - -where DpiWindowSizeFactor() is equal to `CurrentScreenPixelPerInch / 96` -under windows and linux, 1 under macOS +@import "dpi_aware.h" {md_id=HandlingScreenHighDPI} diff --git a/src/hello_imgui/doc_params.md b/src/hello_imgui/doc_params.md index c6490bbe..e92d870c 100644 --- a/src/hello_imgui/doc_params.md +++ b/src/hello_imgui/doc_params.md @@ -1,6 +1,27 @@ # Application parameters -_RunnerParams_ contains all the settings and callbacks in order to run an application. + +__HelloImGui::Run()__ will run an application with a single call. + +Three signatures are provided: + +* `HelloImGui::Run(RunnerParams &)`: full signature, the most customizable version. + Runs an application whose params and Gui are provided by runnerParams. + +* `HelloImGui::Run(const SimpleRunnerParams&)`: + Runs an application, using simpler params. + +* `HelloImGui::Run(guiFunction, windowTitle, windowSize, windowSizeAuto=false, restoreLastWindowGeometry=false, fpsIdle=10)` + Runs an application, by providing the Gui function, the window title, etc. + +Although the API is extremely simple, it is highly customizable, and you can set many options by filling +the elements in the `RunnerParams` struct, or in the simpler `SimpleRunnerParams`. + +__HelloImGui::GetRunnerParams()__ will return the runnerParams of the current application. + + +# Diagram + The diagram below summarize all the possible settings and callbacks (which are explained in detail later in this document). [![diagram](https://raw.githubusercontent.com/pthom/hello_imgui/master/src/hello_imgui/doc_src/hello_imgui_diagram.jpg)](https://raw.githubusercontent.com/pthom/hello_imgui/master/src/hello_imgui/doc_src/hello_imgui_diagram.jpg) @@ -130,6 +151,8 @@ struct RunnerParams // Only useful when multiple rendering backend are compiled and available. RendererBackendType rendererBackendType = RendererBackendType::FirstAvailable; + // --------------- RemoteParams ------------------- + NetImGuiParams remoteParams; // --------------- Settings ------------------- @@ -212,6 +235,7 @@ enum class PlatformBackendType FirstAvailable, Glfw, Sdl, + Null }; // Rendering backend type (OpenGL3, Metal, Vulkan, DirectX11, DirectX12) @@ -224,6 +248,7 @@ enum class RendererBackendType Vulkan, DirectX11, DirectX12, + Null }; ``` @@ -820,8 +845,9 @@ struct FpsIdling # Dpi Aware Params -See [dpi_aware.h](https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/dpi_aware.h) +Optionally, DPI parameters can be fine-tuned. For detailed info, see [handling screens with high dpi](https://pthom.github.io/hello_imgui/book/doc_api.html#handling-screens-with-high-dpi) +Source: [dpi_aware.h](https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/dpi_aware.h) ```cpp // @@ -854,11 +880,14 @@ See [dpi_aware.h](https://github.com/pthom/hello_imgui/blob/master/src/hello_img // dpiWindowSizeFactor=2 // fontRenderingScale=0.5 // +// For more information, see the documentation on DPI handling, here: https://pthom.github.io/hello_imgui/book/doc_api.html#handling-screens-with-high-dpi +// struct DpiAwareParams { // `dpiWindowSizeFactor` - // factor by which window size should be multiplied to get a similar - // visible size on different OSes. + // factor by which window size should be multiplied to get a similar + // visible size on different OSes. This affects the size of the window, + // but *not* the size of widgets and text. // In a standard environment (i.e. outside of Hello ImGui), an application with a size of 960x480 pixels, // may have a physical size (in mm or inches) that varies depending on the screen DPI, and the OS. // @@ -873,23 +902,44 @@ struct DpiAwareParams float dpiWindowSizeFactor = 0.0f; // `fontRenderingScale` - // factor (that is either 1 or < 1.) by which fonts glyphs should be - // scaled at rendering time. - // On macOS retina screens, it will be 0.5, since macOS APIs hide - // the real resolution of the screen. + // factor (that is either 1 or < 1.) by which fonts glyphs should be scaled at rendering time. + // On macOS retina screens, it will be 0.5, since macOS APIs hide the real resolution of the screen. + // Changing this value will *not* change the visible font size on the screen, however it will + // affect the size of the loaded glyphs. + // For example, if fontRenderingScale=0.5 (which is the default on a macOS retina screen), + // a font size of 16 will be loaded as if it was 32, and will be rendered at half size. + // This leads to a better rendering quality on some platforms. float fontRenderingScale = 0.0f; // `dpiFontLoadingFactor` // factor by which font size should be multiplied at loading time to get a similar // visible size on different OSes. // The size will be equivalent to a size given for a 96 PPI screen - float DpiFontLoadingFactor() { return dpiWindowSizeFactor / fontRenderingScale;}; + float DpiFontLoadingFactor() { + float r = dpiWindowSizeFactor / fontRenderingScale; + return r; + }; + + // `roDisplayFramebufferScale` + // When rendering, the internal frame buffer size might be bigger than the + // size (in "virtual screen coordinate" pixels) of the window. + // For example: + // - on macOS retina screens, the frame buffer size will be twice the window size + // (and roDisplayFramebufferScale will be 2, 2) + // - on Windows, the frame buffer size will be the same as the window size. + // (since virtual screen coordinate pixels are the same as physical screen pixels on Windows) + // + // This is an output-only value: it will be set by the platform backend + // after it was initialized (any change you make to it at startup will not be used) + // It mirrors the value inside ImGui::GetIO().DisplayFramebufferScale. + ImVec2 roDisplayFramebufferScale = ImVec2(0.f, 0.f); }; // ---------------------------------------------------------------------------- ``` + ---- # Docking diff --git a/src/hello_imgui/doc_params.src.md b/src/hello_imgui/doc_params.src.md index cc273de7..383a059e 100644 --- a/src/hello_imgui/doc_params.src.md +++ b/src/hello_imgui/doc_params.src.md @@ -1,6 +1,9 @@ # Application parameters -_RunnerParams_ contains all the settings and callbacks in order to run an application. +@import "hello_imgui.h" {md_id=HelloImGui::Run} + +# Diagram + The diagram below summarize all the possible settings and callbacks (which are explained in detail later in this document). [![diagram](https://raw.githubusercontent.com/pthom/hello_imgui/master/src/hello_imgui/doc_src/hello_imgui_diagram.jpg)](https://raw.githubusercontent.com/pthom/hello_imgui/master/src/hello_imgui/doc_src/hello_imgui_diagram.jpg) @@ -120,12 +123,14 @@ See [runner_params.h](https://github.com/pthom/hello_imgui/blob/master/src/hello # Dpi Aware Params -See [dpi_aware.h](https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/dpi_aware.h) +Optionally, DPI parameters can be fine-tuned. For detailed info, see [handling screens with high dpi](https://pthom.github.io/hello_imgui/book/doc_api.html#handling-screens-with-high-dpi) +Source: [dpi_aware.h](https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/dpi_aware.h) ```cpp @import "dpi_aware.h" {md_id=DpiAwareParams} ``` + ---- # Docking diff --git a/src/hello_imgui/dpi_aware.h b/src/hello_imgui/dpi_aware.h index 22e9be7e..9af21452 100644 --- a/src/hello_imgui/dpi_aware.h +++ b/src/hello_imgui/dpi_aware.h @@ -35,6 +35,8 @@ namespace HelloImGui // dpiWindowSizeFactor=2 // fontRenderingScale=0.5 // +// For more information, see the documentation on DPI handling, here: https://pthom.github.io/hello_imgui/book/doc_api.html#handling-screens-with-high-dpi +// struct DpiAwareParams { // `dpiWindowSizeFactor` @@ -143,3 +145,109 @@ float DpiWindowSizeFactor(); float ImGuiDefaultFontGlobalScale(); } // namespace HelloImGui + +// ---------------------------------------------------------------------------- +// Handling screens with high DPI +// ---------------------------------------------------------------------------- +/* +@@md#HandlingScreenHighDPI + +_Note: This part is relevant only for more advanced usages. If you use `HelloImGui::LoadFont()`, + and always use `HelloImGui::EmToVec2()` to place widgets, you do not need to worry about DPI handling_ + +## OS specificities + +There are several important things to know about high-DPI handling within Hello ImGui and Dear ImGui: + +1. (virtual) screen coordinates vs (physical) pixels +2. DisplayFramebufferScale: Frame buffer size vs window size +3. FontGlobalScale: display-time font scaling factor +4. How to load fonts with the correct size +5. How to get similar window sizes on different OSes/DPI + + +## Screen coordinates + +Screen coordinates are the coordinates you use to place and size windows on the screen. + +**Screen coordinates do not always correspond to physical pixels** + +- On macOS/iOS retina screens, a screen coordinate corresponds typically + to 2x2 physical pixels (but this may vary if you change the display scaling) +- On most Linux distributions, whenever there is a high DPI screen + you can set the display scale. For example if you set the scale to 300%, + then a screen coordinate will correspond to 3x3 physical pixels +- On Windows, there are two possible situations: + - If the application is DPI aware, a screen coordinate corresponds to 1x1 physical pixel, + and you can use the full extent of your screen resolution. + - If the application is not DPI aware, a screen coordinate may correspond to 2x2 physical pixels + (if the display scaling is set to 200% for example). However, the rendering of your application + will be blurry and will not use the full extent of your screen resolution. + - Notes: + - Applications created with HelloImGui are DPI aware by default (when using glfw and sdl backends). + - SDL applications are normally not DPI aware. However, HelloImGui makes them DPI aware. + + +## DisplayFramebufferScale +`DisplayFramebufferScale` is the ratio between the frame buffer size and the window size. + +The frame buffer size is the size of the internal buffer used by the rendering backend. +It might be bigger than the actual window size. +`ImVec2 ImGui::GetIO().DisplayFramebufferScale` is a factor by which the frame buffer size is bigger than the window size. +It is set by the platform backend after it was initialized, and typically reflects the scaling ratio between +physical pixels and screen coordinates. + +Under windows, it will always be (1,1). Under macOS / linux, it will reflect the current display scaling. +It will typically be (2,2) on a macOS retina screen. + +Notes: +- As a convenience, `ImGui::GetIO().DisplayFramebufferScale` is mirrored in `HelloImGui::DpiAwareParams::roDisplayFramebufferScale`. +- You cannot change DisplayFramebufferScale manually, it will be reset at each new frame, by asking the platform backend. + + +## FontGlobalScale + +`ImGui::GetIO().FontGlobalScale` is a factor by which fonts glyphs should be scaled at rendering time. +It is typically 1 on windows, and 0.5 on macOS retina screens. + + +## How to load fonts with the correct size + +### Using HelloImGui::LoadFont + +[`HelloImGui::LoadFont()`](https://pthom.github.io/hello_imgui/book/doc_api.html#load-fonts) will load fonts + with the correct size, taking into account the DPI scaling. + +### Using Dear ImGui's AddFontFromFileTTF(): +`ImGui::GetIO().Fonts->AddFontFromFileTTF()` loads a font with a given size, in *physical pixels*. + +If for example, DisplayFramebufferScale is (2,2), and you load a font with a size of 16, it will by default be rendered + with size of 16 *virtual screen coordinate pixels* (i.e. 32 physical pixels). This will lead to blurry text. +To solve this, you should load your font with a size of 16 *virtual screen coordinate pixels* (i.e. 32 physical pixels), +and set `ImGui::GetIO().FontGlobalScale` to 0.5. + +Helpers if using `ImGui::GetIO().Fonts->AddFontFromFileTTF()`: +- `HelloImGui::ImGuiDefaultFontGlobalScale()` returns the default value that should be stored inside `ImGui::GetIO().FontGlobalScale`. +- `HelloImGui::DpiFontLoadingFactor()` returns a factor by which you shall multiply your font sizes when loading them. + + +## Reproducible physical window sizes (in mm or inches) + +### Using HelloImGui +Simply specify a window size that corresponds to theoretical 96 PPI screen (inside `RunnerParams.appWindowParams.windowGeometry.size`) + +### Using your own code to create the backend window +If you prefer to create the window by yourself, its physical size in millimeters may vary widely, +depending on the OS and the current screen DPI setting. +Typically under Windows, your window may appear to be very small if your screen is high DPI. + +To get a similar window size on different OSes/DPI, you should multiply the window size by `HelloImGui::DpiWindowSizeFactor()`. + +Note: DpiWindowSizeFactor() is equal to `CurrentScreenPixelPerInch / 96` under windows and linux, and always 1 under macOS. + +## Fine tune DPI Handling + +See [`HelloImGui::DpiAwareParams`](https://pthom.github.io/hello_imgui/book/doc_params.html#dpi-aware-params) +for more information on how to fine tune DPI handling when using Hello ImGui. +@@md +*/ From e5ab0b4f32f3bdb8ee9df74da57d485207fc8394 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 11:08:55 +0200 Subject: [PATCH 18/57] AbstractRunner: add _CheckDpiAwareParamsChanges / _DefaultOsFontRenderingScale --- src/hello_imgui/dpi_aware.h | 46 +++++----- .../backend_impls/abstract_runner.cpp | 88 ++++++++++++++----- 2 files changed, 90 insertions(+), 44 deletions(-) diff --git a/src/hello_imgui/dpi_aware.h b/src/hello_imgui/dpi_aware.h index 9af21452..fccf5038 100644 --- a/src/hello_imgui/dpi_aware.h +++ b/src/hello_imgui/dpi_aware.h @@ -41,8 +41,9 @@ struct DpiAwareParams { // `dpiWindowSizeFactor` // factor by which window size should be multiplied to get a similar - // visible size on different OSes. This affects the size of the window, - // but *not* the size of widgets and text. + // physical size on different OSes (as if they were all displayed on a 96 PPI screen). + // This affects the size of native app windows, + // but *not* imgui Windows, and *not* the size of widgets and text. // In a standard environment (i.e. outside of Hello ImGui), an application with a size of 960x480 pixels, // may have a physical size (in mm or inches) that varies depending on the screen DPI, and the OS. // @@ -58,35 +59,36 @@ struct DpiAwareParams // `fontRenderingScale` // factor (that is either 1 or < 1.) by which fonts glyphs should be scaled at rendering time. - // On macOS retina screens, it will be 0.5, since macOS APIs hide the real resolution of the screen. - // Changing this value will *not* change the visible font size on the screen, however it will - // affect the size of the loaded glyphs. - // For example, if fontRenderingScale=0.5 (which is the default on a macOS retina screen), - // a font size of 16 will be loaded as if it was 32, and will be rendered at half size. - // This leads to a better rendering quality on some platforms. + // On macOS retina screens, it will be 0.5, since macOS APIs hide the real resolution of the screen. + // Changing this value will *not* change the visible font size on the screen, however it will + // affect the size of the loaded glyphs. + // For example, if fontRenderingScale=0.5 (which is the default on a macOS retina screen), + // a font size of 16 will be loaded as if it was 32, and will be rendered at half size. + // This leads to a better rendering quality on some platforms. + // (This parameter will be used to set ImGui::GetIO().FontGlobalScale at startup) float fontRenderingScale = 0.0f; // `dpiFontLoadingFactor` - // factor by which font size should be multiplied at loading time to get a similar - // visible size on different OSes. - // The size will be equivalent to a size given for a 96 PPI screen - float DpiFontLoadingFactor() { + // factor by which font size should be multiplied at loading time to get a similar + // visible size on different OSes. + // The size will be equivalent to a size given for a 96 PPI screen + float DpiFontLoadingFactor() const { float r = dpiWindowSizeFactor / fontRenderingScale; return r; }; // `roDisplayFramebufferScale` - // When rendering, the internal frame buffer size might be bigger than the - // size (in "virtual screen coordinate" pixels) of the window. - // For example: - // - on macOS retina screens, the frame buffer size will be twice the window size - // (and roDisplayFramebufferScale will be 2, 2) - // - on Windows, the frame buffer size will be the same as the window size. - // (since virtual screen coordinate pixels are the same as physical screen pixels on Windows) + // When rendering, the internal frame buffer size might be bigger than the + // size (in "virtual screen coordinate" pixels) of the window. + // For example: + // - on macOS retina screens, the frame buffer size will be twice the window size + // (and roDisplayFramebufferScale will be 2, 2) + // - on Windows, the frame buffer size will be the same as the window size. + // (since virtual screen coordinate pixels are the same as physical screen pixels on Windows) // - // This is an output-only value: it will be set by the platform backend - // after it was initialized (any change you make to it at startup will not be used) - // It mirrors the value inside ImGui::GetIO().DisplayFramebufferScale. + // This is an output-only value: it will be set by the platform backend + // after it was initialized (any change you make to it at startup will not be used) + // It mirrors the value inside ImGui::GetIO().DisplayFramebufferScale. ImVec2 roDisplayFramebufferScale = ImVec2(0.f, 0.f); }; diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 168fc0b9..cd4b80a3 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -438,24 +438,42 @@ void ReadDpiAwareParams(const std::string& appIniSettingLocation, DpiAwareParams } -void AbstractRunner::SetupDpiAwareParams() +void _CheckDpiAwareParamsChanges(const std::string& msg) { - ReadDpiAwareParams(IniSettingsLocation(params), ¶ms.dpiAwareParams); - if (params.dpiAwareParams.dpiWindowSizeFactor == 0.f) + static bool isFirstTime = true; + auto& dpiAwareParams = HelloImGui::GetRunnerParams()->dpiAwareParams; + auto& io = ImGui::GetIO(); + if (isFirstTime) { - #ifdef HELLOIMGUI_HAS_DIRECTX11 - // The current implementation of Dx11 backend does not support changing the window size - params.dpiAwareParams.dpiWindowSizeFactor = 1.f; - #endif - params.dpiAwareParams.dpiWindowSizeFactor = mBackendWindowHelper->GetWindowSizeDpiScaleFactor(mWindow); + isFirstTime = false; + printf("%s\n", msg.c_str()); + printf("dpiAwareParams: dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor); + printf("dpiAwareParams: fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); + printf(" ImGui FontGlobalScale: %f\n", ImGui::GetIO().FontGlobalScale); + printf("dpiAwareParams: DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); + printf("dpiAwareParams: roDisplayFramebufferScale=%f, %f\n", dpiAwareParams.roDisplayFramebufferScale.x, dpiAwareParams.roDisplayFramebufferScale.y); + auto fbs = ImGui::GetIO().DisplayFramebufferScale; + printf(" ImGui DisplayFramebufferScale: %f,%f\n", fbs.x, fbs.y); + printf("-------------------------------------------------------------\n"); } - if (params.dpiAwareParams.fontRenderingScale == 0.f) + if (dpiAwareParams.fontRenderingScale != io.FontGlobalScale) + { + printf("Warning: fontRenderingScale != ImGui::GetIO().FontGlobalScale\n"); + } + if (dpiAwareParams.roDisplayFramebufferScale.x != io.DisplayFramebufferScale.x) { - float fontSizeIncreaseFactor = 1.f; + printf("Warning: roDisplayFramebufferScale != ImGui::GetIO().DisplayFramebufferScale\n"); + } +} - #ifdef __EMSCRIPTEN__ - // Query the brower to ask for devicePixelRatio + +float _DefaultOsFontRenderingScale() +{ + float fontSizeIncreaseFactor = 1.f; + + #ifdef __EMSCRIPTEN__ + // Query the brower to ask for devicePixelRatio double windowDevicePixelRatio = EM_ASM_DOUBLE( { var scale = window.devicePixelRatio; return scale; @@ -464,17 +482,38 @@ void AbstractRunner::SetupDpiAwareParams() printf("window.devicePixelRatio=%lf\n", windowDevicePixelRatio); fontSizeIncreaseFactor = windowDevicePixelRatio; + #endif + #ifdef HELLOIMGUI_MACOS + // Crisp fonts on macOS: + // cf https://github.com/ocornut/imgui/issues/5301 + // Issue with macOS is that it pretends screen has 2x fewer pixels than it actually does. + // This simplifies application development in most cases, but in our case we happen to render fonts at 1x scale + // while screen renders at 2x scale. + fontSizeIncreaseFactor = (float) NSScreen.mainScreen.backingScaleFactor; + #endif + + return 1.0f / fontSizeIncreaseFactor; +} + + +void AbstractRunner::SetupDpiAwareParams() +{ + ReadDpiAwareParams(IniSettingsLocation(params), ¶ms.dpiAwareParams); + if (params.dpiAwareParams.dpiWindowSizeFactor == 0.f) + { + #ifdef HELLOIMGUI_HAS_DIRECTX11 + // The current implementation of Dx11 backend does not support changing the window size + params.dpiAwareParams.dpiWindowSizeFactor = 1.f; #endif - #ifdef HELLOIMGUI_MACOS - // Crisp fonts on macOS: - // cf https://github.com/ocornut/imgui/issues/5301 - // Issue with macOS is that it pretends screen has 2x fewer pixels than it actually does. - // This simplifies application development in most cases, but in our case we happen to render fonts at 1x scale - // while screen renders at 2x scale. - fontSizeIncreaseFactor = (float) NSScreen.mainScreen.backingScaleFactor; - #endif + params.dpiAwareParams.dpiWindowSizeFactor = mBackendWindowHelper->GetWindowSizeDpiScaleFactor(mWindow); + } - params.dpiAwareParams.fontRenderingScale = 1.0f / fontSizeIncreaseFactor; + if (params.dpiAwareParams.fontRenderingScale == 0.f) + { + if (params.remoteParams.enableRemoting) + params.dpiAwareParams.fontRenderingScale = 1.f; + else + params.dpiAwareParams.fontRenderingScale = _DefaultOsFontRenderingScale(); } ImGui::GetIO().FontGlobalScale = params.dpiAwareParams.fontRenderingScale; @@ -486,9 +525,12 @@ void AbstractRunner::SetupDpiAwareParams() // (using their own backend abstraction). // There is a slight chance of discrepancy here, However, GetDisplayFramebufferScale() and DearImGui // do get the same results for SDL and GLFW under Windows Linux macOS, Android, iOS. - ImGui::GetIO().DisplayFramebufferScale = params.dpiAwareParams.roDisplayFramebufferScale; + auto& io = ImGui::GetIO(); + io.DisplayFramebufferScale = displayFramebufferScale; // dpiAwareParams.roDisplayFramebufferScale is an output-only value (for information only) params.dpiAwareParams.roDisplayFramebufferScale = displayFramebufferScale; + + _CheckDpiAwareParamsChanges("Setup End"); } @@ -1187,6 +1229,8 @@ void AbstractRunner::CreateFramesAndRender() #endif mIdxFrame += 1; + + _CheckDpiAwareParamsChanges("EndCreateFrameAndRenderer"); } // Idling for non emscripten, where HelloImGui is responsible for the main loop. From 9feb807a04def96bdd8f703835cc10d4cc3d3db1 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 11:27:40 +0200 Subject: [PATCH 19/57] net_imgui_remote_display app: call SetFontDPIScale(fontRenderingScale) --- .../netimgui_remote_display.cpp | 43 +++---------------- 1 file changed, 7 insertions(+), 36 deletions(-) diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index e741bd25..26f1c14d 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -1,5 +1,5 @@ #include "NetImguiServer_App.h" - +#include "NetImguiServer_UI.h" // @SAMPLE_EDIT @@ -27,7 +27,7 @@ int main(int argc, char **argv) { - auto init_net_imgui_server = [&]() + auto pass_cmd_line_args_to_server = [&]() { // Start the NetImgui server std::string cmdArgs; @@ -39,47 +39,18 @@ int main(int argc, char **argv) exit(1); }; - auto handle_dpi_awareness = []() - { - // @SAMPLE_EDIT (DPI Awareness) - - // float scaleX, scaleY; - // ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); - // glfwGetWindowContentScale(bd->Window, &scaleX, &scaleY); - // - // float maxScale = scaleX > scaleY ? scaleX : scaleY; - // float windowDPI = (float)(NetImguiServer::UI::kWindowDPIDefault) * maxScale; // = kWindowDPIDefault=96 - // NetImguiServer::UI::SetWindowDPI((int)windowDPI); - // ImGui::GetIO().FontGlobalScale = NetImguiServer::UI::GetFontDPIScale(); - - - // HelloImGui::GetRunnerParams()->dpiAwareParams.fontRenderingScale; - // HelloImGui::GetRunnerParams()->dpiAwareParams.dpiWindowSizeFactor; - // HelloImGui::GetRunnerParams()->dpiAwareParams.DpiFontLoadingFactor(); - float windowDPI = HelloImGui::GetRunnerParams()->dpiAwareParams.fontRenderingScale - * (float)(NetImguiServer::UI::kWindowDPIDefault); // 96 - //windowDPI = 48.f; - //printf("windowDPI: %f\n", windowDPI); - //NetImguiServer::UI::SetWindowDPI((int)windowDPI); - - // See void FontCreationCallback(float PreviousDPIScale, float NewDPIScale) - // in SampleFontDPI.cpp ?? - - }; - - // Runner Params HelloImGui::RunnerParams runnerParams; - runnerParams.callbacks.PostInit = [&init_net_imgui_server]() { - init_net_imgui_server(); - //ImGui::GetIO().ConfigFlags = ImGui::GetIO().ConfigFlags | ImGuiConfigFlags_DockingEnable; + runnerParams.callbacks.PostInit = [&pass_cmd_line_args_to_server]() { + pass_cmd_line_args_to_server(); + auto fontRenderingScale = HelloImGui::GetRunnerParams()->dpiAwareParams.fontRenderingScale; + NetImguiServer::UI::SetFontDPIScale(fontRenderingScale); }; - runnerParams.callbacks.PreNewFrame = [&handle_dpi_awareness]() { + runnerParams.callbacks.PreNewFrame = []() { // Request each client to update their drawing content NetImguiServer::App::UpdateRemoteContent(); - handle_dpi_awareness(); }; runnerParams.callbacks.ShowGui = []() { From 9459bce90c21085b9f39ab89bd6f7d40d6576dcd Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 11:30:16 +0200 Subject: [PATCH 20/57] update submodule netImgui --- external/netImgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/netImgui b/external/netImgui index f50cff46..3e667331 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit f50cff468fd7fce3aa96c4f0d338aa607d4180c5 +Subproject commit 3e667331afb66ef77f7e16ff952ebf20f42b3a86 From 8e2927be0673d7208c5492a14d9db4b08c2a6329 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 11:46:57 +0200 Subject: [PATCH 21/57] fix windows warning / vulkan --- src/hello_imgui/internal/backend_impls/rendering_vulkan_sdl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello_imgui/internal/backend_impls/rendering_vulkan_sdl.cpp b/src/hello_imgui/internal/backend_impls/rendering_vulkan_sdl.cpp index cbf3d9a9..98d08740 100644 --- a/src/hello_imgui/internal/backend_impls/rendering_vulkan_sdl.cpp +++ b/src/hello_imgui/internal/backend_impls/rendering_vulkan_sdl.cpp @@ -35,7 +35,7 @@ namespace HelloImGui // Create Window Surface VkSurfaceKHR surface; - VkResult err; + //VkResult err; if (SDL_Vulkan_CreateSurface(window, gVkGlobals.Instance, &surface) == 0) { IM_ASSERT(0 && "Failed to create Vulkan surface"); From 898c32992f1cc9c4f67a2bf4e6362e26c1397ea5 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 11:47:12 +0200 Subject: [PATCH 22/57] netimgui: simple windows fixes --- external/netImgui | 2 +- src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/external/netImgui b/external/netImgui index 3e667331..9682073a 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 3e667331afb66ef77f7e16ff952ebf20f42b3a86 +Subproject commit 9682073ad062d9b9501a95322c461f888df3c67f diff --git a/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp b/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp index 32167ccd..d7f90d29 100644 --- a/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp +++ b/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp @@ -6,6 +6,11 @@ #include "hello_imgui/hello_imgui.h" #include +#ifdef _WIN32 +#include +#include +#endif + namespace NetImguiServer { namespace App { From f10510c4afa270f0f6cc480aa80c1509445a2e0e Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 12:47:30 +0200 Subject: [PATCH 23/57] update netImgui --- external/netImgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/netImgui b/external/netImgui index 9682073a..178d784b 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 9682073ad062d9b9501a95322c461f888df3c67f +Subproject commit 178d784b83e6bcdbd259fd6d220c51e241e8b89f From ac2bf15095c8a23df078f307ab2826370b6fd353 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 14:53:36 +0200 Subject: [PATCH 24/57] Suppress BackendWindowHelper::GetDisplayFramebufferScale / forced by ImGui backends! --- src/hello_imgui/doc_api.md | 1 - src/hello_imgui/doc_params.md | 40 +++++++------------ src/hello_imgui/dpi_aware.h | 15 ------- .../backend_impls/abstract_runner.cpp | 26 +++--------- .../backend_window_helper.h | 4 +- .../glfw_window_helper.cpp | 5 +-- .../glfw_window_helper.h | 1 - .../null_window_helper.h | 1 - .../sdl_window_helper.cpp | 9 ----- .../backend_window_helper/sdl_window_helper.h | 1 - .../internal/backend_impls/null_config.h | 3 -- 11 files changed, 24 insertions(+), 82 deletions(-) diff --git a/src/hello_imgui/doc_api.md b/src/hello_imgui/doc_api.md index c48080e6..fdebc670 100644 --- a/src/hello_imgui/doc_api.md +++ b/src/hello_imgui/doc_api.md @@ -458,7 +458,6 @@ Under windows, it will always be (1,1). Under macOS / linux, it will reflect the It will typically be (2,2) on a macOS retina screen. Notes: -- As a convenience, `ImGui::GetIO().DisplayFramebufferScale` is mirrored in `HelloImGui::DpiAwareParams::roDisplayFramebufferScale`. - You cannot change DisplayFramebufferScale manually, it will be reset at each new frame, by asking the platform backend. diff --git a/src/hello_imgui/doc_params.md b/src/hello_imgui/doc_params.md index e92d870c..1298d1f3 100644 --- a/src/hello_imgui/doc_params.md +++ b/src/hello_imgui/doc_params.md @@ -886,8 +886,9 @@ struct DpiAwareParams { // `dpiWindowSizeFactor` // factor by which window size should be multiplied to get a similar - // visible size on different OSes. This affects the size of the window, - // but *not* the size of widgets and text. + // physical size on different OSes (as if they were all displayed on a 96 PPI screen). + // This affects the size of native app windows, + // but *not* imgui Windows, and *not* the size of widgets and text. // In a standard environment (i.e. outside of Hello ImGui), an application with a size of 960x480 pixels, // may have a physical size (in mm or inches) that varies depending on the screen DPI, and the OS. // @@ -903,36 +904,23 @@ struct DpiAwareParams // `fontRenderingScale` // factor (that is either 1 or < 1.) by which fonts glyphs should be scaled at rendering time. - // On macOS retina screens, it will be 0.5, since macOS APIs hide the real resolution of the screen. - // Changing this value will *not* change the visible font size on the screen, however it will - // affect the size of the loaded glyphs. - // For example, if fontRenderingScale=0.5 (which is the default on a macOS retina screen), - // a font size of 16 will be loaded as if it was 32, and will be rendered at half size. - // This leads to a better rendering quality on some platforms. + // On macOS retina screens, it will be 0.5, since macOS APIs hide the real resolution of the screen. + // Changing this value will *not* change the visible font size on the screen, however it will + // affect the size of the loaded glyphs. + // For example, if fontRenderingScale=0.5 (which is the default on a macOS retina screen), + // a font size of 16 will be loaded as if it was 32, and will be rendered at half size. + // This leads to a better rendering quality on some platforms. + // (This parameter will be used to set ImGui::GetIO().FontGlobalScale at startup) float fontRenderingScale = 0.0f; // `dpiFontLoadingFactor` - // factor by which font size should be multiplied at loading time to get a similar - // visible size on different OSes. - // The size will be equivalent to a size given for a 96 PPI screen - float DpiFontLoadingFactor() { + // factor by which font size should be multiplied at loading time to get a similar + // visible size on different OSes. + // The size will be equivalent to a size given for a 96 PPI screen + float DpiFontLoadingFactor() const { float r = dpiWindowSizeFactor / fontRenderingScale; return r; }; - - // `roDisplayFramebufferScale` - // When rendering, the internal frame buffer size might be bigger than the - // size (in "virtual screen coordinate" pixels) of the window. - // For example: - // - on macOS retina screens, the frame buffer size will be twice the window size - // (and roDisplayFramebufferScale will be 2, 2) - // - on Windows, the frame buffer size will be the same as the window size. - // (since virtual screen coordinate pixels are the same as physical screen pixels on Windows) - // - // This is an output-only value: it will be set by the platform backend - // after it was initialized (any change you make to it at startup will not be used) - // It mirrors the value inside ImGui::GetIO().DisplayFramebufferScale. - ImVec2 roDisplayFramebufferScale = ImVec2(0.f, 0.f); }; // ---------------------------------------------------------------------------- diff --git a/src/hello_imgui/dpi_aware.h b/src/hello_imgui/dpi_aware.h index fccf5038..99879ff4 100644 --- a/src/hello_imgui/dpi_aware.h +++ b/src/hello_imgui/dpi_aware.h @@ -76,20 +76,6 @@ struct DpiAwareParams float r = dpiWindowSizeFactor / fontRenderingScale; return r; }; - - // `roDisplayFramebufferScale` - // When rendering, the internal frame buffer size might be bigger than the - // size (in "virtual screen coordinate" pixels) of the window. - // For example: - // - on macOS retina screens, the frame buffer size will be twice the window size - // (and roDisplayFramebufferScale will be 2, 2) - // - on Windows, the frame buffer size will be the same as the window size. - // (since virtual screen coordinate pixels are the same as physical screen pixels on Windows) - // - // This is an output-only value: it will be set by the platform backend - // after it was initialized (any change you make to it at startup will not be used) - // It mirrors the value inside ImGui::GetIO().DisplayFramebufferScale. - ImVec2 roDisplayFramebufferScale = ImVec2(0.f, 0.f); }; // ---------------------------------------------------------------------------- @@ -203,7 +189,6 @@ Under windows, it will always be (1,1). Under macOS / linux, it will reflect the It will typically be (2,2) on a macOS retina screen. Notes: -- As a convenience, `ImGui::GetIO().DisplayFramebufferScale` is mirrored in `HelloImGui::DpiAwareParams::roDisplayFramebufferScale`. - You cannot change DisplayFramebufferScale manually, it will be reset at each new frame, by asking the platform backend. diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index cd4b80a3..31453908 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -451,19 +451,18 @@ void _CheckDpiAwareParamsChanges(const std::string& msg) printf("dpiAwareParams: fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); printf(" ImGui FontGlobalScale: %f\n", ImGui::GetIO().FontGlobalScale); printf("dpiAwareParams: DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); - printf("dpiAwareParams: roDisplayFramebufferScale=%f, %f\n", dpiAwareParams.roDisplayFramebufferScale.x, dpiAwareParams.roDisplayFramebufferScale.y); + printf("dpiAwareParams: io.DisplayFramebufferScale=%f, %f\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); auto fbs = ImGui::GetIO().DisplayFramebufferScale; printf(" ImGui DisplayFramebufferScale: %f,%f\n", fbs.x, fbs.y); printf("-------------------------------------------------------------\n"); } - if (dpiAwareParams.fontRenderingScale != io.FontGlobalScale) - { - printf("Warning: fontRenderingScale != ImGui::GetIO().FontGlobalScale\n"); - } - if (dpiAwareParams.roDisplayFramebufferScale.x != io.DisplayFramebufferScale.x) + bool didFontGlobalScaleChange = dpiAwareParams.fontRenderingScale != io.FontGlobalScale; + + if (didFontGlobalScaleChange) { - printf("Warning: roDisplayFramebufferScale != ImGui::GetIO().DisplayFramebufferScale\n"); + printf("Warning: didDpiAwareParamsChange=:true\n"); + dpiAwareParams.fontRenderingScale = io.FontGlobalScale; } } @@ -517,19 +516,6 @@ void AbstractRunner::SetupDpiAwareParams() } ImGui::GetIO().FontGlobalScale = params.dpiAwareParams.fontRenderingScale; - // - // DisplayFramebufferScale - // - ImVec2 displayFramebufferScale = mBackendWindowHelper->GetDisplayFramebufferScale(mWindow); - // Note: ImGui_ImplGlfw_NewFrame, ImGui_ImplSDL2_NewFrame, ... will also set ImGui::GetIO().DisplayFramebufferScale - // (using their own backend abstraction). - // There is a slight chance of discrepancy here, However, GetDisplayFramebufferScale() and DearImGui - // do get the same results for SDL and GLFW under Windows Linux macOS, Android, iOS. - auto& io = ImGui::GetIO(); - io.DisplayFramebufferScale = displayFramebufferScale; - // dpiAwareParams.roDisplayFramebufferScale is an output-only value (for information only) - params.dpiAwareParams.roDisplayFramebufferScale = displayFramebufferScale; - _CheckDpiAwareParamsChanges("Setup End"); } diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/backend_window_helper.h b/src/hello_imgui/internal/backend_impls/backend_window_helper/backend_window_helper.h index e447470c..bbec66c9 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/backend_window_helper.h +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/backend_window_helper.h @@ -61,8 +61,8 @@ namespace HelloImGui { namespace BackendApi virtual void WaitForEventTimeout(double timeout_seconds) = 0; - // Return the ratio FrameBufferSize / WindowSize - virtual ImVec2 GetDisplayFramebufferScale(WindowPointer window) = 0; + // (ImGui backends handle this by themselves) + //virtual ImVec2 GetDisplayFramebufferScale(WindowPointer window) = 0; // Return the ratio by which the window size should be scaled to account for HighDPI // (i.e. the same size given at creation create the same physical size in mm on the screen) diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp index b04d7893..a6d496a3 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.cpp @@ -189,11 +189,10 @@ namespace HelloImGui { namespace BackendApi glfwWaitEventsTimeout(timeout_seconds); } - ImVec2 GlfwWindowHelper::GetDisplayFramebufferScale(HelloImGui::BackendApi::WindowPointer window) + ImVec2 _GetWindowContentScale(HelloImGui::BackendApi::WindowPointer window) { float x_scale, y_scale; glfwGetWindowContentScale((GLFWwindow *) window, &x_scale, &y_scale); - printf("GlfwWindowHelper::GetDisplayFramebufferScale: %f, %f\n", x_scale, y_scale); return ImVec2(x_scale, y_scale); } @@ -202,7 +201,7 @@ namespace HelloImGui { namespace BackendApi #ifdef __APPLE__ return 1.f; #else - ImVec2 scale = GetDisplayFramebufferScale(window); + ImVec2 scale = _GetWindowContentScale(window); return scale.x; #endif } diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.h b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.h index 4d1f65b8..f7f35fa3 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.h +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/glfw_window_helper.h @@ -29,7 +29,6 @@ namespace HelloImGui { namespace BackendApi void WaitForEventTimeout(double timeout_seconds) override; - ImVec2 GetDisplayFramebufferScale(WindowPointer window) override; float GetWindowSizeDpiScaleFactor(WindowPointer window) override; void HideWindow(WindowPointer window) override; diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h b/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h index 9138d171..88e45266 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h @@ -35,7 +35,6 @@ namespace HelloImGui { namespace BackendApi std::this_thread::sleep_for(std::chrono::milliseconds((int)(timeout_seconds * 1000))); } - ImVec2 GetDisplayFramebufferScale(WindowPointer window) override { return NullConfig::GetDisplayFramebufferScale(); } float GetWindowSizeDpiScaleFactor(WindowPointer window) override { return NullConfig::GetWindowSizeDpiScaleFactor(); } void HideWindow(WindowPointer window) override {} diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.cpp b/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.cpp index df8bc5af..b5858301 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.cpp +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.cpp @@ -200,15 +200,6 @@ namespace HelloImGui { namespace BackendApi SDL_WaitEventTimeout(NULL, timeout_ms); } - ImVec2 SdlWindowHelper::GetDisplayFramebufferScale(WindowPointer window) - { - int win_w, win_h, fb_w, fb_h; - SDL_GetWindowSize((SDL_Window *) window, &win_w, &win_h); - SDL_GL_GetDrawableSize((SDL_Window *) window, &fb_w, &fb_h); - return ImVec2((float)fb_w / win_w, (float)fb_h / win_h); - } - - float SdlWindowHelper::GetWindowSizeDpiScaleFactor(WindowPointer window) { #if TARGET_OS_MAC // is true for any software platform that's derived from macOS, which includes iOS, watchOS, and tvOS diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.h b/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.h index 1381ba79..3633e97b 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.h +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/sdl_window_helper.h @@ -38,7 +38,6 @@ namespace HelloImGui { namespace BackendApi void WaitForEventTimeout(double timeout_seconds) override; - ImVec2 GetDisplayFramebufferScale(WindowPointer window) override; float GetWindowSizeDpiScaleFactor(WindowPointer window) override; void HideWindow(WindowPointer window) override; diff --git a/src/hello_imgui/internal/backend_impls/null_config.h b/src/hello_imgui/internal/backend_impls/null_config.h index 1d91b4b5..87a99862 100644 --- a/src/hello_imgui/internal/backend_impls/null_config.h +++ b/src/hello_imgui/internal/backend_impls/null_config.h @@ -21,9 +21,6 @@ namespace NullConfig return {GetScreenBounds()}; } - ImVec2 GetDisplayFramebufferScale() { - return {1.f, 1.f}; - } float GetWindowSizeDpiScaleFactor() { return 1.f; } } From 9b3823bf2f80f1ff84c1528d2fc3d0973ecdff7b Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 15:07:50 +0200 Subject: [PATCH 25/57] abstract_runner: fix dx11 issue --- src/hello_imgui/internal/backend_impls/abstract_runner.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 31453908..1983f991 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -501,8 +501,11 @@ void AbstractRunner::SetupDpiAwareParams() if (params.dpiAwareParams.dpiWindowSizeFactor == 0.f) { #ifdef HELLOIMGUI_HAS_DIRECTX11 + if (params.rendererBackendType == HelloImGui::RendererBackendType::DirectX11) + { // The current implementation of Dx11 backend does not support changing the window size params.dpiAwareParams.dpiWindowSizeFactor = 1.f; + } #endif params.dpiAwareParams.dpiWindowSizeFactor = mBackendWindowHelper->GetWindowSizeDpiScaleFactor(mWindow); } From a6fd6199fe25db9ca98d461e3f24bea1d048a0ce Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 16:40:44 +0200 Subject: [PATCH 26/57] NetImgui: Fight FrameBufferDisplayScale --- external/netImgui | 2 +- src/netimgui_remote_display/netimgui_remote_display.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/external/netImgui b/external/netImgui index 178d784b..08371419 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 178d784b83e6bcdbd259fd6d220c51e241e8b89f +Subproject commit 08371419f9d3b75c7e6a666cead87be69050da99 diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 26f1c14d..c16ff342 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -44,8 +44,7 @@ int main(int argc, char **argv) runnerParams.callbacks.PostInit = [&pass_cmd_line_args_to_server]() { pass_cmd_line_args_to_server(); - auto fontRenderingScale = HelloImGui::GetRunnerParams()->dpiAwareParams.fontRenderingScale; - NetImguiServer::UI::SetFontDPIScale(fontRenderingScale); + NetImguiServer::UI::SetUseServerDisplayFramebufferScale(true); }; runnerParams.callbacks.PreNewFrame = []() { From c175b6364c37a902a305f10c13a5b871678df884 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 17:30:13 +0200 Subject: [PATCH 27/57] DPI Settings: transmit FontGlobalScale --- external/netImgui | 2 +- src/netimgui_remote_display/netimgui_remote_display.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/external/netImgui b/external/netImgui index 08371419..a452723b 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 08371419f9d3b75c7e6a666cead87be69050da99 +Subproject commit a452723b70445d94664978fa42eb5c6ef596949f diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index c16ff342..00b69bdd 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -44,7 +44,7 @@ int main(int argc, char **argv) runnerParams.callbacks.PostInit = [&pass_cmd_line_args_to_server]() { pass_cmd_line_args_to_server(); - NetImguiServer::UI::SetUseServerDisplayFramebufferScale(true); + NetImguiServer::UI::SetUseServerDisplayDpiSettings(true); }; runnerParams.callbacks.PreNewFrame = []() { From 21d1612d82249f21d8de4666c299e1998077d54f Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 18:16:41 +0200 Subject: [PATCH 28/57] Netimgui: DPI Settings: transmit WindowDPISizeFactor --- external/netImgui | 2 +- .../backend_impls/abstract_runner.cpp | 64 +++++++++++++------ .../netimgui_remote_display.cpp | 2 +- 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/external/netImgui b/external/netImgui index a452723b..07a4efe5 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit a452723b70445d94664978fa42eb5c6ef596949f +Subproject commit 07a4efe560fd5230b08f3324da950f80210f280a diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 1983f991..c5d50dcd 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -438,32 +438,56 @@ void ReadDpiAwareParams(const std::string& appIniSettingLocation, DpiAwareParams } -void _CheckDpiAwareParamsChanges(const std::string& msg) +void _LogDpiParams(const HelloImGui::DpiAwareParams& dpiAwareParams) { - static bool isFirstTime = true; - auto& dpiAwareParams = HelloImGui::GetRunnerParams()->dpiAwareParams; + auto &io = ImGui::GetIO(); + printf("dpiAwareParams: dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor); + printf("dpiAwareParams: fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); + printf("dpiAwareParams: DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); + printf(" ImGui FontGlobalScale: %f\n", io.FontGlobalScale); + printf(" ImGui DisplayFramebufferScale=%f, %f\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); +} + + +void _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) +{ + auto& dpiAwareParams = params.dpiAwareParams; auto& io = ImGui::GetIO(); + + static bool isFirstTime = true; if (isFirstTime) { - isFirstTime = false; - printf("%s\n", msg.c_str()); - printf("dpiAwareParams: dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor); - printf("dpiAwareParams: fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); - printf(" ImGui FontGlobalScale: %f\n", ImGui::GetIO().FontGlobalScale); - printf("dpiAwareParams: DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); - printf("dpiAwareParams: io.DisplayFramebufferScale=%f, %f\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); - auto fbs = ImGui::GetIO().DisplayFramebufferScale; - printf(" ImGui DisplayFramebufferScale: %f,%f\n", fbs.x, fbs.y); - printf("-------------------------------------------------------------\n"); + _LogDpiParams(dpiAwareParams); + isFirstTime = false; } - bool didFontGlobalScaleChange = dpiAwareParams.fontRenderingScale != io.FontGlobalScale; - + // Check changes + bool didFontGlobalScaleChange = dpiAwareParams.fontRenderingScale != io.FontGlobalScale; if (didFontGlobalScaleChange) - { - printf("Warning: didDpiAwareParamsChange=:true\n"); + { + printf("Warning: didFontGlobalScaleChange=:true\n"); dpiAwareParams.fontRenderingScale = io.FontGlobalScale; - } + } + + bool didDpiWindowSizeFactorChange = false; +#ifdef HELLOIMGUI_WITH_NETIMGUI + if (params.remoteParams.enableRemoting) + { + float newWindowDPISizeFactor = NetImgui::GetWindowDPISizeFactor(); + didDpiWindowSizeFactorChange = dpiAwareParams.dpiWindowSizeFactor != newWindowDPISizeFactor; + if (didDpiWindowSizeFactorChange) + { + printf("Warning: didDpiWindowSizeFactorChange=:true (from netImgui)\n"); + dpiAwareParams.dpiWindowSizeFactor = newWindowDPISizeFactor; + } + } +#endif + + if (didDpiWindowSizeFactorChange || didFontGlobalScaleChange) + { + printf("New DpiAwareParams:\n"); + _LogDpiParams(dpiAwareParams); + } } @@ -519,7 +543,7 @@ void AbstractRunner::SetupDpiAwareParams() } ImGui::GetIO().FontGlobalScale = params.dpiAwareParams.fontRenderingScale; - _CheckDpiAwareParamsChanges("Setup End"); + _CheckDpiAwareParamsChanges(params); } @@ -1219,7 +1243,7 @@ void AbstractRunner::CreateFramesAndRender() mIdxFrame += 1; - _CheckDpiAwareParamsChanges("EndCreateFrameAndRenderer"); + _CheckDpiAwareParamsChanges(params); } // Idling for non emscripten, where HelloImGui is responsible for the main loop. diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 00b69bdd..49a46d2c 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -44,7 +44,7 @@ int main(int argc, char **argv) runnerParams.callbacks.PostInit = [&pass_cmd_line_args_to_server]() { pass_cmd_line_args_to_server(); - NetImguiServer::UI::SetUseServerDisplayDpiSettings(true); + NetImguiServer::UI::SetUseServerDisplayDPISettings(true); }; runnerParams.callbacks.PreNewFrame = []() { From e0d7bbbb937c0cd62a1d259fcd8c45648bb34c45 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 18:31:20 +0200 Subject: [PATCH 29/57] Add PoorManLog --- .../backend_impls/abstract_runner.cpp | 12 ++++--- src/hello_imgui/internal/poor_man_log.cpp | 33 +++++++++++++++++++ src/hello_imgui/internal/poor_man_log.h | 4 +++ 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 src/hello_imgui/internal/poor_man_log.cpp create mode 100644 src/hello_imgui/internal/poor_man_log.h diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index c5d50dcd..cc5a5c2f 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -7,6 +7,7 @@ #include "hello_imgui/internal/menu_statusbar.h" #include "hello_imgui/internal/platform/ini_folder_locations.h" #include "hello_imgui/internal/inicpp.h" +#include "hello_imgui/internal/poor_man_log.h" #include "imgui.h" #include "hello_imgui/internal/imgui_global_context.h" // must be included before imgui_internal.h @@ -441,11 +442,12 @@ void ReadDpiAwareParams(const std::string& appIniSettingLocation, DpiAwareParams void _LogDpiParams(const HelloImGui::DpiAwareParams& dpiAwareParams) { auto &io = ImGui::GetIO(); - printf("dpiAwareParams: dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor); - printf("dpiAwareParams: fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); - printf("dpiAwareParams: DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); - printf(" ImGui FontGlobalScale: %f\n", io.FontGlobalScale); - printf(" ImGui DisplayFramebufferScale=%f, %f\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); + std::stringstream msg; + PoorManLog("dpiAwareParams: dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor); + PoorManLog("dpiAwareParams: fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); + PoorManLog("dpiAwareParams: DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); + PoorManLog(" ImGui FontGlobalScale: %f\n", io.FontGlobalScale); + PoorManLog(" ImGui DisplayFramebufferScale=%f, %f\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); } diff --git a/src/hello_imgui/internal/poor_man_log.cpp b/src/hello_imgui/internal/poor_man_log.cpp new file mode 100644 index 00000000..3307150b --- /dev/null +++ b/src/hello_imgui/internal/poor_man_log.cpp @@ -0,0 +1,33 @@ +#include +#include +#include + + +namespace HelloImGui +{ + std::string _DoSnPrintf(const char* fmt, ...) + { + va_list args; + va_start(args, fmt); + char buffer[2000]; + vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); + return std::string(buffer); + } + + + void PoorManLog(const char* msg, ...) + { + // call _DoSnPrintf + va_list args; + va_start(args, msg); + std::string buffer = _DoSnPrintf(msg, args); + va_end(args); + + #ifdef _MSC_VER + OutputDebugStringA(buffer.c_str()); + #else + printf("%s", buffer.c_str()); + #endif + } +} diff --git a/src/hello_imgui/internal/poor_man_log.h b/src/hello_imgui/internal/poor_man_log.h new file mode 100644 index 00000000..e1594791 --- /dev/null +++ b/src/hello_imgui/internal/poor_man_log.h @@ -0,0 +1,4 @@ +namespace HelloImGui +{ + void PoorManLog(const char* msg, ...); +} From 0da5f1ffd911abf6945d9e24eef350c8fc0556a6 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 18:50:57 +0200 Subject: [PATCH 30/57] fix poor_man_log --- src/hello_imgui/internal/poor_man_log.cpp | 40 ++++++++++------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/hello_imgui/internal/poor_man_log.cpp b/src/hello_imgui/internal/poor_man_log.cpp index 3307150b..3aad6f7b 100644 --- a/src/hello_imgui/internal/poor_man_log.cpp +++ b/src/hello_imgui/internal/poor_man_log.cpp @@ -2,32 +2,26 @@ #include #include +#ifdef _MSC_VER +#include +#endif + namespace HelloImGui { - std::string _DoSnPrintf(const char* fmt, ...) - { - va_list args; - va_start(args, fmt); - char buffer[2000]; - vsnprintf(buffer, sizeof(buffer), fmt, args); - va_end(args); - return std::string(buffer); - } - +void PoorManLog(const char* msg, ...) +{ + va_list args; + va_start(args, msg); + char buffer[2000]; + vsnprintf(buffer, sizeof(buffer), msg, args); + va_end(args); - void PoorManLog(const char* msg, ...) - { - // call _DoSnPrintf - va_list args; - va_start(args, msg); - std::string buffer = _DoSnPrintf(msg, args); - va_end(args); +#ifdef _MSC_VER + OutputDebugString(buffer); +#else + printf("%s", buffer); +#endif +} - #ifdef _MSC_VER - OutputDebugStringA(buffer.c_str()); - #else - printf("%s", buffer.c_str()); - #endif - } } From ce18809c6a9fd601949678ff507f473ef242db6d Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 18:52:48 +0200 Subject: [PATCH 31/57] Call NetImguiServer::UI::SetWindowDPISizeFactor --- external/netImgui | 2 +- src/netimgui_remote_display/netimgui_remote_display.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/external/netImgui b/external/netImgui index 07a4efe5..ea5d9fa8 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 07a4efe560fd5230b08f3324da950f80210f280a +Subproject commit ea5d9fa81f40c42561e7e072f65f5213aff8eef0 diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 49a46d2c..ab337672 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -45,6 +45,8 @@ int main(int argc, char **argv) runnerParams.callbacks.PostInit = [&pass_cmd_line_args_to_server]() { pass_cmd_line_args_to_server(); NetImguiServer::UI::SetUseServerDisplayDPISettings(true); + float windowDPISizeFactor = HelloImGui::GetRunnerParams()->dpiAwareParams.dpiWindowSizeFactor; + NetImguiServer::UI::SetWindowDPISizeFactor(windowDPISizeFactor); }; runnerParams.callbacks.PreNewFrame = []() { From 78859f9e77f1b62be4c6195a1108fdba1ac1d7c8 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 20:35:09 +0200 Subject: [PATCH 32/57] Add LoadFontDpiResponsive --- src/hello_imgui/hello_imgui_font.h | 32 ++++++-- src/hello_imgui/impl/hello_imgui_font.cpp | 56 +++++++++++++- .../impl/imgui_default_settings.cpp | 4 +- .../backend_impls/abstract_runner.cpp | 73 +++++++++++++------ 4 files changed, 131 insertions(+), 34 deletions(-) diff --git a/src/hello_imgui/hello_imgui_font.h b/src/hello_imgui/hello_imgui_font.h index ad6ff82a..e6fd08d8 100644 --- a/src/hello_imgui/hello_imgui_font.h +++ b/src/hello_imgui/hello_imgui_font.h @@ -53,17 +53,35 @@ namespace HelloImGui ImFontConfig fontConfigFontAwesome = ImFontConfig(); }; - // When loading fonts, use HelloImGui::LoadFont(FontLoadingParams) - // =============================================================== - // instead of ImGui::GetIO().Fonts->AddFontFromFileTTF(), because it will - // automatically adjust the font size to account for HighDPI, and will spare - // you headaches when trying to get consistent font size across different OSes. - // see FontLoadingParams and ImFontConfig + // A font that will be automatically resized to account for changes in DPI + // (use LoadAdaptiveFont instead of LoadFont to get this behavior) + struct FontDpiResponsive + { + ImFont* font = nullptr; + std::string fontFilename; + float fontSize = 0.f; + FontLoadingParams fontLoadingParams; + }; + + // !!! When loading fonts, use + // HelloImGui::LoadFont(FontLoadingParams) + // or + // HelloImGui::LoadDpiResponsiveFont(FontLoadingParams) + // + // Use these functions instead of ImGui::GetIO().Fonts->AddFontFromFileTTF(), + // because they will automatically adjust the font size to account for HighDPI, + // and will spare you headaches when trying to get consistent font size across different OSes. + + // Loads a font with the specified parameters (this font will not adapt to DPI changes after startup) ImFont* LoadFont(const std::string & fontFilename, float fontSize, const FontLoadingParams & params = {}); - // @@md + // Loads a font with the specified parameters (this font will adapt to DPI changes after startup) + // (only fonts loaded with LoadAdaptiveFont will adapt to DPI changes. Avoid mixing LoadFont/LoadFontDpiResponsive) + FontDpiResponsive* LoadFontDpiResponsive(const std::string & fontFilename, float fontSize, + const FontLoadingParams & params = {}); + // @@md // // Deprecated API below, kept for compatibility (uses LoadFont internally) diff --git a/src/hello_imgui/impl/hello_imgui_font.cpp b/src/hello_imgui/impl/hello_imgui_font.cpp index 4df4e2b9..fa67ff7c 100644 --- a/src/hello_imgui/impl/hello_imgui_font.cpp +++ b/src/hello_imgui/impl/hello_imgui_font.cpp @@ -9,6 +9,8 @@ #include "imgui_freetype.h" #endif +#include + #ifdef IOS #include "hello_imgui/internal/platform/getAppleBundleResourcePath.h" #endif @@ -132,7 +134,7 @@ namespace HelloImGui } - ImFont* LoadFont(const std::string & fontFilename, float fontSize_, const FontLoadingParams& params_) + ImFont* _LoadFontImpl(const std::string & fontFilename, float fontSize_, const FontLoadingParams& params_) { gDidCallHelloImGuiLoadFontTTF = true; @@ -209,7 +211,57 @@ namespace HelloImGui return font; } - ImFont* LoadFontTTF(const std::string & fontFilename, float fontSize, bool useFullGlyphRange, ImFontConfig config) + std::vector gAllDpiResponsiveFonts; + + + ImFont* LoadFont(const std::string & fontFilename, float fontSize_, const FontLoadingParams& params_) + { + printf("LoadFont(%s, %f)\n", fontFilename.c_str(), fontSize_); + return _LoadFontImpl(fontFilename, fontSize_, params_); + } + + FontDpiResponsive* LoadFontDpiResponsive(const std::string & fontFilename, float fontSize, + const FontLoadingParams & fontLoadingParams) + { + // Ensure that we have enough capacity, so that pointers remain valid + constexpr size_t maxFonts = 100; + if (gAllDpiResponsiveFonts.capacity() == 0) + gAllDpiResponsiveFonts.reserve(maxFonts); + // Whine if we are about to exceed the capacity + IM_ASSERT(gAllDpiResponsiveFonts.size() < maxFonts - 1 && "Too many fonts loaded"); + // Insert a new element at the end of the vector + gAllDpiResponsiveFonts.push_back({ nullptr, fontFilename, fontSize, fontLoadingParams }); + + // Get the pointer to the newly inserted element (which we will return) + FontDpiResponsive* dpiResponsiveFont = &gAllDpiResponsiveFonts.back(); + + printf("LoadFontDpiResponsive(%s, %f)\n", fontFilename.c_str(), fontSize); + dpiResponsiveFont->font = _LoadFontImpl(fontFilename, fontSize, fontLoadingParams); + dpiResponsiveFont->fontSize = fontSize; + dpiResponsiveFont->fontFilename = fontFilename; + dpiResponsiveFont->fontLoadingParams = fontLoadingParams; + return dpiResponsiveFont; + } + + void _ReloadAllDpiResponsiveFonts() + { + printf("_ReloadAllDpiResponsiveFonts\n"); + auto& imguiFonts = ImGui::GetIO().Fonts; + imguiFonts->Clear(); + for (auto & dpiResponsiveFont : gAllDpiResponsiveFonts) + { + float fontSize = dpiResponsiveFont.fontSize; + const std::string & fontFilename = dpiResponsiveFont.fontFilename; + const FontLoadingParams & fontLoadingParams = dpiResponsiveFont.fontLoadingParams; + ImFont* newFont = _LoadFontImpl(fontFilename, fontSize, fontLoadingParams); + dpiResponsiveFont.font = newFont; + } + bool buildSuccess = imguiFonts->Build(); + IM_ASSERT(buildSuccess && "_ReloadAllDpiResponsiveFonts: Failed to build fonts"); + } + + + ImFont* LoadFontTTF(const std::string & fontFilename, float fontSize, bool useFullGlyphRange, ImFontConfig config) { FontLoadingParams fontLoadingParams; if (useFullGlyphRange) diff --git a/src/hello_imgui/impl/imgui_default_settings.cpp b/src/hello_imgui/impl/imgui_default_settings.cpp index 768478f4..0ce2134d 100644 --- a/src/hello_imgui/impl/imgui_default_settings.cpp +++ b/src/hello_imgui/impl/imgui_default_settings.cpp @@ -25,7 +25,7 @@ void LoadDefaultFont_WithFontAwesomeIcons() return; } - ImFont* font = LoadFont(fontFilename, fontSize); + auto font = LoadFontDpiResponsive(fontFilename, fontSize); if (defaultIconFont == HelloImGui::DefaultIconFont::NoIcons) return; @@ -43,7 +43,7 @@ void LoadDefaultFont_WithFontAwesomeIcons() HelloImGui::FontLoadingParams fontParams; fontParams.mergeToLastFont = true; fontParams.useFullGlyphRange = true; - font = LoadFont(iconFontFile, fontSize, fontParams); + font = LoadFontDpiResponsive(iconFontFile, fontSize, fontParams); (void) font; } diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index cc5a5c2f..9573039d 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -74,6 +74,9 @@ namespace HelloImGui // Encapsulated inside hello_imgui_screenshot.cpp void setFinalAppWindowScreenshotRgbBuffer(const ImageBuffer& b); +// Encapsulated inside hello_imgui_font.cpp +void _ReloadAllDpiResponsiveFonts(); + // ===================================================================================================================== // @@ -165,6 +168,11 @@ class NetImGuiWrapper } } + void sendFonts() + { + _sendFonts_Impl(); + } + private: void InitiateConnection() { @@ -175,7 +183,7 @@ class NetImGuiWrapper NetImgui::ConnectToApp(clientName().c_str(), remoteParams().serverHost.c_str(), remoteParams().serverPort); std::this_thread::sleep_for(std::chrono::milliseconds(100)); ++ mNbConnectionsTentatives; - sendFonts(); + _sendFonts_Impl(); } std::string clientName() @@ -192,9 +200,8 @@ class NetImGuiWrapper HelloImGui::NetImGuiParams& remoteParams() { return HelloImGui::GetRunnerParams()->remoteParams; } HelloImGui::RunnerParams& runnerParams() { return *HelloImGui::GetRunnerParams(); } - void sendFonts() + void _sendFonts_Impl() { - printf("NetImGuiWrapper: sendFonts\n"); const ImFontAtlas* pFonts = ImGui::GetIO().Fonts; if( pFonts->TexPixelsAlpha8) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) { @@ -439,30 +446,24 @@ void ReadDpiAwareParams(const std::string& appIniSettingLocation, DpiAwareParams } -void _LogDpiParams(const HelloImGui::DpiAwareParams& dpiAwareParams) +void _LogDpiParams(const std::string& origin, const HelloImGui::DpiAwareParams& dpiAwareParams) { auto &io = ImGui::GetIO(); std::stringstream msg; - PoorManLog("dpiAwareParams: dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor); - PoorManLog("dpiAwareParams: fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); - PoorManLog("dpiAwareParams: DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); - PoorManLog(" ImGui FontGlobalScale: %f\n", io.FontGlobalScale); - PoorManLog(" ImGui DisplayFramebufferScale=%f, %f\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); + PoorManLog("DpiAwareParams: %s\n", origin.c_str()); + PoorManLog(" dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor); + PoorManLog(" fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); + PoorManLog(" DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); + PoorManLog(" (ImGui FontGlobalScale: %f)\n", io.FontGlobalScale); + PoorManLog(" (ImGui DisplayFramebufferScale=%f, %f)\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); } -void _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) +bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) { auto& dpiAwareParams = params.dpiAwareParams; auto& io = ImGui::GetIO(); - static bool isFirstTime = true; - if (isFirstTime) - { - _LogDpiParams(dpiAwareParams); - isFirstTime = false; - } - // Check changes bool didFontGlobalScaleChange = dpiAwareParams.fontRenderingScale != io.FontGlobalScale; if (didFontGlobalScaleChange) @@ -488,8 +489,11 @@ void _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) if (didDpiWindowSizeFactorChange || didFontGlobalScaleChange) { printf("New DpiAwareParams:\n"); - _LogDpiParams(dpiAwareParams); + _LogDpiParams("_CheckDpiAwareParamsChanges (changed!)", dpiAwareParams); + return true; } + else + return false; } @@ -545,7 +549,7 @@ void AbstractRunner::SetupDpiAwareParams() } ImGui::GetIO().FontGlobalScale = params.dpiAwareParams.fontRenderingScale; - _CheckDpiAwareParamsChanges(params); + _LogDpiParams("SetupDpiAwareParams", params.dpiAwareParams); } @@ -856,8 +860,8 @@ void AbstractRunner::Setup() // This should be done before Impl_LinkPlatformAndRenderBackends() // because, in the case of glfw ImGui_ImplGlfw_InstallCallbacks - // will chain the user callbacks with ImGui callbacks; and PostInit() - // is a good place for the user to install callbacks + // will chain the user callbacks with ImGui callbacks; + // and PostInit() is a good place for the user to install callbacks if (params.callbacks.PostInit_AddPlatformBackendCallbacks) params.callbacks.PostInit_AddPlatformBackendCallbacks(); @@ -911,7 +915,10 @@ void AbstractRunner::Setup() #ifdef HELLOIMGUI_WITH_NETIMGUI if (params.remoteParams.enableRemoting) - gNetImGuiWrapper = std::make_unique(); + { + gNetImGuiWrapper = std::make_unique(); + gNetImGuiWrapper->sendFonts(); + } #endif } @@ -1153,6 +1160,13 @@ void AbstractRunner::CreateFramesAndRender() mRenderingBackendCallbacks->Impl_DestroyFontTexture(); mRenderingBackendCallbacks->Impl_CreateFontTexture(); params.callbacks.LoadAdditionalFonts = nullptr; + #ifdef HELLOIMGUI_WITH_NETIMGUI + if (params.remoteParams.enableRemoting) + { + gNetImGuiWrapper = std::make_unique(); + gNetImGuiWrapper->sendFonts(); + } + #endif } } @@ -1245,7 +1259,20 @@ void AbstractRunner::CreateFramesAndRender() mIdxFrame += 1; - _CheckDpiAwareParamsChanges(params); + if (_CheckDpiAwareParamsChanges(params)) + { + mRenderingBackendCallbacks->Impl_DestroyFontTexture(); + _ReloadAllDpiResponsiveFonts(); + // cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects + mRenderingBackendCallbacks->Impl_CreateFontTexture(); + #ifdef HELLOIMGUI_WITH_NETIMGUI + if (params.remoteParams.enableRemoting) + { + gNetImGuiWrapper = std::make_unique(); + gNetImGuiWrapper->sendFonts(); + } + #endif + } } // Idling for non emscripten, where HelloImGui is responsible for the main loop. From d678aab9418e184808022d9c3213b7f33e02ecb2 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 20:55:11 +0200 Subject: [PATCH 33/57] abrunner: simple fix --- src/hello_imgui/internal/backend_impls/abstract_runner.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 9573039d..16b4fcf0 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -1257,10 +1257,9 @@ void AbstractRunner::CreateFramesAndRender() } #endif - mIdxFrame += 1; - if (_CheckDpiAwareParamsChanges(params)) { + printf("_CheckDpiAwareParamsChanges returned true => reload all fonts\n"); mRenderingBackendCallbacks->Impl_DestroyFontTexture(); _ReloadAllDpiResponsiveFonts(); // cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects @@ -1273,6 +1272,8 @@ void AbstractRunner::CreateFramesAndRender() } #endif } + + mIdxFrame += 1; } // Idling for non emscripten, where HelloImGui is responsible for the main loop. From 3e57dfbf593db6c2b606f06545c9b8ed95e8ae56 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 20:59:55 +0200 Subject: [PATCH 34/57] test fonts on demo classic --- .../hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp b/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp index 864ed95e..45e64bd4 100644 --- a/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp +++ b/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp @@ -77,6 +77,8 @@ int main(int , char *[]) { params.imGuiWindowParams.showMenuBar = true; params.imGuiWindowParams.showMenu_App = false; + params.remoteParams.enableRemoting = true; + HelloImGui::Run(params); return 0; } From d3882aa64727d3d433aeb825b49fb42da8095998 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 21:32:36 +0200 Subject: [PATCH 35/57] Add param onlyUseFontDpiResponsive --- src/hello_imgui/dpi_aware.h | 5 +++++ src/hello_imgui/impl/hello_imgui_font.cpp | 19 +++++++++++++++- .../impl/imgui_default_settings.cpp | 20 ++++++++++++----- .../backend_impls/abstract_runner.cpp | 22 ++++++++++--------- .../hello_imgui_demo_classic.main.cpp | 7 +++--- 5 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/hello_imgui/dpi_aware.h b/src/hello_imgui/dpi_aware.h index 99879ff4..d2d1fa63 100644 --- a/src/hello_imgui/dpi_aware.h +++ b/src/hello_imgui/dpi_aware.h @@ -68,6 +68,11 @@ struct DpiAwareParams // (This parameter will be used to set ImGui::GetIO().FontGlobalScale at startup) float fontRenderingScale = 0.0f; + // `onlyUseFontDpiResponsive` + // If true, guarantees that only HelloImGui::LoadDpiResponsiveFont will be used to load fonts. + // (also for the default font) + bool onlyUseFontDpiResponsive = false; + // `dpiFontLoadingFactor` // factor by which font size should be multiplied at loading time to get a similar // visible size on different OSes. diff --git a/src/hello_imgui/impl/hello_imgui_font.cpp b/src/hello_imgui/impl/hello_imgui_font.cpp index fa67ff7c..f2326b3d 100644 --- a/src/hello_imgui/impl/hello_imgui_font.cpp +++ b/src/hello_imgui/impl/hello_imgui_font.cpp @@ -212,10 +212,18 @@ namespace HelloImGui } std::vector gAllDpiResponsiveFonts; + bool gWasLoadFontBareCalled = false; + bool gWasLoadFontDpiResponsiveCalled = false; ImFont* LoadFont(const std::string & fontFilename, float fontSize_, const FontLoadingParams& params_) { + IM_ASSERT((!gWasLoadFontDpiResponsiveCalled) && "If using LoadFontDpiResponsive(), only use it, and do not use LoadFont()!"); + + auto runnerParams = HelloImGui::GetRunnerParams(); + IM_ASSERT(! runnerParams->dpiAwareParams.onlyUseFontDpiResponsive && "If runnerParams->dpiAwareParams.onlyUseFontDpiResponsive is true, you must use LoadFontDpiResponsive() instead of LoadFont()"); + + gWasLoadFontBareCalled = true; printf("LoadFont(%s, %f)\n", fontFilename.c_str(), fontSize_); return _LoadFontImpl(fontFilename, fontSize_, params_); } @@ -223,6 +231,9 @@ namespace HelloImGui FontDpiResponsive* LoadFontDpiResponsive(const std::string & fontFilename, float fontSize, const FontLoadingParams & fontLoadingParams) { + IM_ASSERT((!gWasLoadFontBareCalled) && "If using LoadFontDpiResponsive(), only use it, and do not use LoadFont()!"); + gWasLoadFontDpiResponsiveCalled = true; + // Ensure that we have enough capacity, so that pointers remain valid constexpr size_t maxFonts = 100; if (gAllDpiResponsiveFonts.capacity() == 0) @@ -243,8 +254,13 @@ namespace HelloImGui return dpiResponsiveFont; } - void _ReloadAllDpiResponsiveFonts() + bool _ReloadAllDpiResponsiveFonts() { + if (gWasLoadFontBareCalled) + { + fprintf(stderr, "_ReloadAllDpiResponsiveFonts failed: ony call LoadFontDpiResponsive if you want this to work\n"); + return false; + } printf("_ReloadAllDpiResponsiveFonts\n"); auto& imguiFonts = ImGui::GetIO().Fonts; imguiFonts->Clear(); @@ -258,6 +274,7 @@ namespace HelloImGui } bool buildSuccess = imguiFonts->Build(); IM_ASSERT(buildSuccess && "_ReloadAllDpiResponsiveFonts: Failed to build fonts"); + return true; } diff --git a/src/hello_imgui/impl/imgui_default_settings.cpp b/src/hello_imgui/impl/imgui_default_settings.cpp index 0ce2134d..38e03a03 100644 --- a/src/hello_imgui/impl/imgui_default_settings.cpp +++ b/src/hello_imgui/impl/imgui_default_settings.cpp @@ -14,7 +14,8 @@ namespace ImGuiDefaultSettings void LoadDefaultFont_WithFontAwesomeIcons() { - auto defaultIconFont = HelloImGui::GetRunnerParams()->callbacks.defaultIconFont; + auto runnerParams = HelloImGui::GetRunnerParams(); + auto defaultIconFont = runnerParams->callbacks.defaultIconFont; float fontSize = 15.f; std::string fontFilename = "fonts/DroidSans.ttf"; @@ -25,8 +26,14 @@ void LoadDefaultFont_WithFontAwesomeIcons() return; } - auto font = LoadFontDpiResponsive(fontFilename, fontSize); - if (defaultIconFont == HelloImGui::DefaultIconFont::NoIcons) + bool useDpiResponsiveFonts = runnerParams->dpiAwareParams.onlyUseFontDpiResponsive; + + if (useDpiResponsiveFonts) + LoadFontDpiResponsive(fontFilename, fontSize); + else + LoadFont(fontFilename, fontSize); + + if (defaultIconFont == HelloImGui::DefaultIconFont::NoIcons) return; std::string iconFontFile; @@ -43,8 +50,11 @@ void LoadDefaultFont_WithFontAwesomeIcons() HelloImGui::FontLoadingParams fontParams; fontParams.mergeToLastFont = true; fontParams.useFullGlyphRange = true; - font = LoadFontDpiResponsive(iconFontFile, fontSize, fontParams); - (void) font; + + if (useDpiResponsiveFonts) + LoadFontDpiResponsive(iconFontFile, fontSize, fontParams); + else + LoadFont(iconFontFile, fontSize, fontParams); } void SetupDefaultImGuiConfig() diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 16b4fcf0..aed91efb 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -75,7 +75,7 @@ namespace HelloImGui void setFinalAppWindowScreenshotRgbBuffer(const ImageBuffer& b); // Encapsulated inside hello_imgui_font.cpp -void _ReloadAllDpiResponsiveFonts(); +bool _ReloadAllDpiResponsiveFonts(); // ===================================================================================================================== @@ -1260,17 +1260,19 @@ void AbstractRunner::CreateFramesAndRender() if (_CheckDpiAwareParamsChanges(params)) { printf("_CheckDpiAwareParamsChanges returned true => reload all fonts\n"); - mRenderingBackendCallbacks->Impl_DestroyFontTexture(); - _ReloadAllDpiResponsiveFonts(); - // cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects - mRenderingBackendCallbacks->Impl_CreateFontTexture(); - #ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) + if (_ReloadAllDpiResponsiveFonts()) { - gNetImGuiWrapper = std::make_unique(); - gNetImGuiWrapper->sendFonts(); + // cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects + mRenderingBackendCallbacks->Impl_DestroyFontTexture(); + mRenderingBackendCallbacks->Impl_CreateFontTexture(); + #ifdef HELLOIMGUI_WITH_NETIMGUI + if (params.remoteParams.enableRemoting) + { + gNetImGuiWrapper = std::make_unique(); + gNetImGuiWrapper->sendFonts(); + } + #endif } - #endif } mIdxFrame += 1; diff --git a/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp b/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp index 45e64bd4..3fa420d7 100644 --- a/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp +++ b/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp @@ -2,12 +2,12 @@ // Demonstrate how to load additional fonts (fonts - part 1/3) -ImFont * gCustomFont = nullptr; +HelloImGui::FontDpiResponsive * gCustomFont = nullptr; void MyLoadFonts() { HelloImGui::ImGuiDefaultSettings::LoadDefaultFont_WithFontAwesomeIcons(); // The font that is loaded first is the default font - gCustomFont = HelloImGui::LoadFont("fonts/Akronim-Regular.ttf", 40.f); // will be loaded from the assets folder + gCustomFont = HelloImGui::LoadFontDpiResponsive("fonts/Akronim-Regular.ttf", 40.f); // will be loaded from the assets folder } @@ -38,7 +38,7 @@ int main(int , char *[]) { ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. // Demo custom font usage (fonts - part 3/3) - ImGui::PushFont(gCustomFont); + ImGui::PushFont(gCustomFont->font); ImGui::Text("Custom font"); ImGui::PopFont(); @@ -77,6 +77,7 @@ int main(int , char *[]) { params.imGuiWindowParams.showMenuBar = true; params.imGuiWindowParams.showMenu_App = false; + params.dpiAwareParams.onlyUseFontDpiResponsive = true; params.remoteParams.enableRemoting = true; HelloImGui::Run(params); From aeedc1e82e836a8c3a7fed019c6dc3e4e06dc5b9 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 21:35:08 +0200 Subject: [PATCH 36/57] demo docking: use responsive fonts --- src/hello_imgui/impl/hello_imgui_font.cpp | 2 +- .../hello_imgui_demodocking.main.cpp | 53 ++++++++++--------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/hello_imgui/impl/hello_imgui_font.cpp b/src/hello_imgui/impl/hello_imgui_font.cpp index f2326b3d..05cf90f8 100644 --- a/src/hello_imgui/impl/hello_imgui_font.cpp +++ b/src/hello_imgui/impl/hello_imgui_font.cpp @@ -231,7 +231,7 @@ namespace HelloImGui FontDpiResponsive* LoadFontDpiResponsive(const std::string & fontFilename, float fontSize, const FontLoadingParams & fontLoadingParams) { - IM_ASSERT((!gWasLoadFontBareCalled) && "If using LoadFontDpiResponsive(), only use it, and do not use LoadFont()!"); + IM_ASSERT((!gWasLoadFontBareCalled) && "If using LoadFontDpiResponsive(), set runnerParams.dpiAwareParams.onlyUseFontDpiResponsive=true and do not not use LoadFont()!"); gWasLoadFontDpiResponsiveCalled = true; // Ensure that we have enough capacity, so that pointers remain valid diff --git a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp index 31d5e4a2..9acdfdc6 100644 --- a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp +++ b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp @@ -62,10 +62,10 @@ struct AppState MyAppSettings myAppSettings; // This values will be stored in the application settings - ImFont* TitleFont = nullptr; - ImFont* ColorFont = nullptr; - ImFont* EmojiFont = nullptr; - ImFont* LargeIconFont = nullptr; + HelloImGui::FontDpiResponsive *TitleFont; + HelloImGui::FontDpiResponsive *ColorFont; + HelloImGui::FontDpiResponsive *EmojiFont; + HelloImGui::FontDpiResponsive *LargeIconFont; }; @@ -74,24 +74,27 @@ struct AppState ////////////////////////////////////////////////////////////////////////// void LoadFonts(AppState& appState) // This is called by runnerParams.callbacks.LoadAdditionalFonts { - HelloImGui::GetRunnerParams()->callbacks.defaultIconFont = HelloImGui::DefaultIconFont::FontAwesome6; + auto runnerParams = HelloImGui::GetRunnerParams(); + runnerParams->dpiAwareParams.onlyUseFontDpiResponsive=true; + + runnerParams->callbacks.defaultIconFont = HelloImGui::DefaultIconFont::FontAwesome6; // First, load the default font (the default font should be loaded first) HelloImGui::ImGuiDefaultSettings::LoadDefaultFont_WithFontAwesomeIcons(); // Then load the other fonts - appState.TitleFont = HelloImGui::LoadFont("fonts/DroidSans.ttf", 18.f); + appState.TitleFont = HelloImGui::LoadFontDpiResponsive("fonts/DroidSans.ttf", 18.f); HelloImGui::FontLoadingParams fontLoadingParamsEmoji; fontLoadingParamsEmoji.useFullGlyphRange = true; - appState.EmojiFont = HelloImGui::LoadFont("fonts/NotoEmoji-Regular.ttf", 24.f, fontLoadingParamsEmoji); + appState.EmojiFont = HelloImGui::LoadFontDpiResponsive("fonts/NotoEmoji-Regular.ttf", 24.f, fontLoadingParamsEmoji); HelloImGui::FontLoadingParams fontLoadingParamsLargeIcon; fontLoadingParamsLargeIcon.useFullGlyphRange = true; - appState.LargeIconFont = HelloImGui::LoadFont("fonts/fontawesome-webfont.ttf", 24.f, fontLoadingParamsLargeIcon); + appState.LargeIconFont = HelloImGui::LoadFontDpiResponsive("fonts/fontawesome-webfont.ttf", 24.f, fontLoadingParamsLargeIcon); #ifdef IMGUI_ENABLE_FREETYPE // Found at https://www.colorfonts.wtf/ HelloImGui::FontLoadingParams fontLoadingParamsColor; fontLoadingParamsColor.loadColor = true; - appState.ColorFont = HelloImGui::LoadFont("fonts/Playbox/Playbox-FREE.otf", 24.f, fontLoadingParamsColor); + appState.ColorFont = HelloImGui::LoadFontDpiResponsive("fonts/Playbox/Playbox-FREE.otf", 24.f, fontLoadingParamsColor); #endif } @@ -139,7 +142,7 @@ void SaveMyAppSettings(const AppState& appState) // Display a button that will hide the application window void DemoHideWindow(AppState& appState) { - ImGui::PushFont(appState.TitleFont); ImGui::Text("Hide app window"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Hide app window"); ImGui::PopFont(); static double lastHideTime = -1.; if (ImGui::Button("Hide")) { @@ -169,7 +172,7 @@ void DemoShowAdditionalWindow(AppState& appState) // * either make them initially invisible, and exclude them from the view menu (such as shown here) // * or modify runnerParams.dockingParams.dockableWindows inside the callback RunnerCallbacks.PreNewFrame const char* windowName = "Additional Window"; - ImGui::PushFont(appState.TitleFont); ImGui::Text("Dynamically add window"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Dynamically add window"); ImGui::PopFont(); if (ImGui::Button("Show additional window")) { auto additionalWindowPtr = HelloImGui::GetRunnerParams()->dockingParams.dockableWindowOfName(windowName); @@ -185,7 +188,7 @@ void DemoShowAdditionalWindow(AppState& appState) void DemoLogs(AppState& appState) { - ImGui::PushFont(appState.TitleFont); ImGui::Text("Log Demo"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Log Demo"); ImGui::PopFont(); ImGui::BeginGroup(); // Edit a float using a slider from 0.0f to 1.0f @@ -209,7 +212,7 @@ void DemoLogs(AppState& appState) void DemoUserSettings(AppState& appState) { - ImGui::PushFont(appState.TitleFont); ImGui::Text("User settings"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("User settings"); ImGui::PopFont(); ImGui::BeginGroup(); ImGui::SetNextItemWidth(HelloImGui::EmSize(7.f)); ImGui::InputText("Name", &appState.myAppSettings.name); @@ -223,7 +226,7 @@ void DemoUserSettings(AppState& appState) void DemoRocket(AppState& appState) { - ImGui::PushFont(appState.TitleFont); ImGui::Text("Status Bar Demo"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Status Bar Demo"); ImGui::PopFont(); ImGui::BeginGroup(); if (appState.rocket_state == AppState::RocketState::Init) { @@ -260,7 +263,7 @@ void DemoRocket(AppState& appState) void DemoDockingFlags(AppState& appState) { - ImGui::PushFont(appState.TitleFont); ImGui::Text("Main dock space node flags"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Main dock space node flags"); ImGui::PopFont(); ImGui::TextWrapped(R"( This will edit the ImGuiDockNodeFlags for "MainDockSpace". Most flags are inherited by children dock spaces. @@ -295,13 +298,13 @@ Most flags are inherited by children dock spaces. void GuiWindowLayoutCustomization(AppState& appState) { - ImGui::PushFont(appState.TitleFont); ImGui::Text("Switch between layouts"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Switch between layouts"); ImGui::PopFont(); ImGui::Text("with the menu \"View/Layouts\""); if (ImGui::IsItemHovered()) ImGui::SetTooltip("Each layout remembers separately the modifications applied by the user, \nand the selected layout is restored at startup"); ImGui::Separator(); - ImGui::PushFont(appState.TitleFont); ImGui::Text("Change the theme"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Change the theme"); ImGui::PopFont(); ImGui::Text("with the menu \"View/Theme\""); if (ImGui::IsItemHovered()) ImGui::SetTooltip("The selected theme is remembered and restored at startup"); @@ -314,7 +317,7 @@ void GuiWindowLayoutCustomization(AppState& appState) void DemoAssets(AppState& appState) { - ImGui::PushFont(appState.TitleFont); ImGui::Text("Image From Asset"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Image From Asset"); ImGui::PopFont(); HelloImGui::BeginGroupColumn(); ImGui::Dummy(HelloImGui::EmToVec2(0.f, 0.45f)); @@ -325,7 +328,7 @@ void DemoAssets(AppState& appState) void DemoFonts(AppState& appState) { - ImGui::PushFont(appState.TitleFont); ImGui::Text("Fonts"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Fonts"); ImGui::PopFont(); ImGui::TextWrapped("Mix icons " ICON_FA_FACE_SMILE " and text " ICON_FA_ROCKET ""); if (ImGui::IsItemHovered()) ImGui::SetTooltip("Example with Font Awesome Icons"); @@ -334,7 +337,7 @@ void DemoFonts(AppState& appState) ImGui::BeginGroup(); { - ImGui::PushFont(appState.EmojiFont); + ImGui::PushFont(appState.EmojiFont->font); // ✌️ (Victory Hand Emoji) ImGui::Text(U8_TO_CHAR(u8"\U0000270C\U0000FE0F")); ImGui::SameLine(); @@ -361,7 +364,7 @@ void DemoFonts(AppState& appState) #ifdef IMGUI_ENABLE_FREETYPE ImGui::Text("Colored Fonts"); - ImGui::PushFont(appState.ColorFont); + ImGui::PushFont(appState.ColorFont->font); ImGui::Text("C O L O R !"); ImGui::PopFont(); if (ImGui::IsItemHovered()) @@ -371,7 +374,7 @@ void DemoFonts(AppState& appState) void DemoThemes(AppState& appState) { - ImGui::PushFont(appState.TitleFont); ImGui::Text("Themes"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont->font); ImGui::Text("Themes"); ImGui::PopFont(); auto& tweakedTheme = HelloImGui::GetRunnerParams()->imGuiWindowParams.tweakedTheme; ImGui::BeginGroup(); @@ -453,7 +456,7 @@ void ShowAppMenuItems() void ShowTopToolbar(AppState& appState) { - ImGui::PushFont(appState.LargeIconFont); + ImGui::PushFont(appState.LargeIconFont->font); if (ImGui::Button(ICON_FA_POWER_OFF)) HelloImGui::GetRunnerParams()->appShallExit = true; @@ -474,7 +477,7 @@ void ShowTopToolbar(AppState& appState) void ShowRightToolbar(AppState& appState) { - ImGui::PushFont(appState.LargeIconFont); + ImGui::PushFont(appState.LargeIconFont->font); if (ImGui::Button(ICON_FA_CIRCLE_ARROW_LEFT)) HelloImGui::Log(HelloImGui::LogLevel::Info, "Clicked on Circle left in the right toolbar"); @@ -794,6 +797,8 @@ int main(int, char**) //runnerParams.dpiAwareParams.dpiWindowSizeFactor = 1.0f; //runnerParams.dpiAwareParams.fontRenderingScale = 1.0f; + runnerParams.platformBackendType = HelloImGui::PlatformBackendType::Sdl; + HelloImGui::Run(runnerParams); // Note: with ImGuiBundle, it is also possible to use ImmApp::Run(...) return 0; From 7f515ee3b01919e6a82c2604284b5ce2948d8170 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 21:45:52 +0200 Subject: [PATCH 37/57] clean demos --- .../hello_imgui_demo_classic.main.cpp | 10 +++------- .../hello_imgui_demodocking.main.cpp | 4 ---- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp b/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp index 3fa420d7..8f237310 100644 --- a/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp +++ b/src/hello_imgui_demos/hello_imgui_demo_classic/hello_imgui_demo_classic.main.cpp @@ -5,9 +5,9 @@ HelloImGui::FontDpiResponsive * gCustomFont = nullptr; void MyLoadFonts() { - - HelloImGui::ImGuiDefaultSettings::LoadDefaultFont_WithFontAwesomeIcons(); // The font that is loaded first is the default font - gCustomFont = HelloImGui::LoadFontDpiResponsive("fonts/Akronim-Regular.ttf", 40.f); // will be loaded from the assets folder + HelloImGui::GetRunnerParams()->dpiAwareParams.onlyUseFontDpiResponsive = true; + HelloImGui::ImGuiDefaultSettings::LoadDefaultFont_WithFontAwesomeIcons(); // The font that is loaded first is the default font + gCustomFont = HelloImGui::LoadFontDpiResponsive("fonts/Akronim-Regular.ttf", 40.f); // will be loaded from the assets folder } @@ -76,10 +76,6 @@ int main(int , char *[]) { params.imGuiWindowParams.showMenuBar = true; params.imGuiWindowParams.showMenu_App = false; - - params.dpiAwareParams.onlyUseFontDpiResponsive = true; - params.remoteParams.enableRemoting = true; - HelloImGui::Run(params); return 0; } diff --git a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp index 9acdfdc6..d57e8fa4 100644 --- a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp +++ b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp @@ -794,10 +794,6 @@ int main(int, char**) //runnerParams.rendererBackendType = HelloImGui::RendererBackendType::Vulkan; runnerParams.remoteParams.enableRemoting = true; - //runnerParams.dpiAwareParams.dpiWindowSizeFactor = 1.0f; - //runnerParams.dpiAwareParams.fontRenderingScale = 1.0f; - - runnerParams.platformBackendType = HelloImGui::PlatformBackendType::Sdl; HelloImGui::Run(runnerParams); // Note: with ImGuiBundle, it is also possible to use ImmApp::Run(...) From d34378314cbaca81a7ee1e90ecaa64169079204c Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 22:39:17 +0200 Subject: [PATCH 38/57] Call _CheckDpiAwareParamsChanges first --- .../backend_impls/abstract_runner.cpp | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index aed91efb..0194a509 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -232,6 +232,7 @@ class NetImGuiWrapper }; std::unique_ptr gNetImGuiWrapper; +bool gWaitingForRemoteDpiInfo = false; #endif // ===================================================================================================================== // @@ -1023,6 +1024,24 @@ void AbstractRunner::CreateFramesAndRender() } #endif + if (_CheckDpiAwareParamsChanges(params)) // Reload fonts if DPI scale changed + { + if (_ReloadAllDpiResponsiveFonts()) + { + printf("_CheckDpiAwareParamsChanges returned true => reloaded all fonts\n"); + // cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects + mRenderingBackendCallbacks->Impl_DestroyFontTexture(); + mRenderingBackendCallbacks->Impl_CreateFontTexture(); + #ifdef HELLOIMGUI_WITH_NETIMGUI + if (params.remoteParams.enableRemoting) + { + gNetImGuiWrapper = std::make_unique(); + gNetImGuiWrapper->sendFonts(); + } + #endif + } + } + if (foldable_region) // Update frame rate stats { _UpdateFrameRateStats(); @@ -1226,7 +1245,7 @@ void AbstractRunner::CreateFramesAndRender() // iii/ At the end of the second frame, we measure the size of the widgets and use it as the application window size, if the user required auto size // ==> Note: RenderGui() may measure the size of the window and resize it if mIdxFrame==1 // RenderGui may call many user callbacks, so it should not be inside SCOPED_RELEASE_GIL_ON_MAIN_THREAD - RenderGui(); + RenderGui(); if (params.callbacks.BeforeImGuiRender) params.callbacks.BeforeImGuiRender(); @@ -1257,24 +1276,6 @@ void AbstractRunner::CreateFramesAndRender() } #endif - if (_CheckDpiAwareParamsChanges(params)) - { - printf("_CheckDpiAwareParamsChanges returned true => reload all fonts\n"); - if (_ReloadAllDpiResponsiveFonts()) - { - // cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects - mRenderingBackendCallbacks->Impl_DestroyFontTexture(); - mRenderingBackendCallbacks->Impl_CreateFontTexture(); - #ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) - { - gNetImGuiWrapper = std::make_unique(); - gNetImGuiWrapper->sendFonts(); - } - #endif - } - } - mIdxFrame += 1; } From 435d5d1528561f869ff004bc454ee7c6699e6ac0 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 22:39:40 +0200 Subject: [PATCH 39/57] _ReloadAllDpiResponsiveFonts: return false if not font --- src/hello_imgui/impl/hello_imgui_font.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hello_imgui/impl/hello_imgui_font.cpp b/src/hello_imgui/impl/hello_imgui_font.cpp index 05cf90f8..1ad92962 100644 --- a/src/hello_imgui/impl/hello_imgui_font.cpp +++ b/src/hello_imgui/impl/hello_imgui_font.cpp @@ -261,6 +261,8 @@ namespace HelloImGui fprintf(stderr, "_ReloadAllDpiResponsiveFonts failed: ony call LoadFontDpiResponsive if you want this to work\n"); return false; } + if (gAllDpiResponsiveFonts.empty()) + return false; printf("_ReloadAllDpiResponsiveFonts\n"); auto& imguiFonts = ImGui::GetIO().Fonts; imguiFonts->Clear(); From c9cb4324080bfefee9ce7ffb8b08baf532a9a323 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Fri, 12 Apr 2024 23:47:12 +0200 Subject: [PATCH 40/57] Disable FPS idling settings when remoting --- external/netImgui | 2 +- src/hello_imgui/impl/hello_imgui.cpp | 11 ++++++ src/hello_imgui/impl/hello_imgui_font.cpp | 8 ++--- .../backend_impls/abstract_runner.cpp | 35 ++++++++++++------- src/hello_imgui/internal/docking_details.cpp | 19 ++++++---- src/hello_imgui/internal/menu_statusbar.cpp | 30 ++++++++++------ 6 files changed, 70 insertions(+), 35 deletions(-) diff --git a/external/netImgui b/external/netImgui index ea5d9fa8..dcfe5c49 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit ea5d9fa81f40c42561e7e072f65f5213aff8eef0 +Subproject commit dcfe5c49e487ea584dc966e89a87e6c303594dcd diff --git a/src/hello_imgui/impl/hello_imgui.cpp b/src/hello_imgui/impl/hello_imgui.cpp index b43194af..e014c223 100644 --- a/src/hello_imgui/impl/hello_imgui.cpp +++ b/src/hello_imgui/impl/hello_imgui.cpp @@ -240,6 +240,17 @@ ImGuiTestEngine* GetImGuiTestEngine() { return nullptr; } #endif +bool _isDisplayingOnRemoteServer() +{ + return true; + #ifdef HELLOIMGUI_WITH_NETIMGUI + return HelloImGui::GetRunnerParams()->remoteParams.enableRemoting; + #else + return false; + #endif +} + + void SaveUserPref(const std::string& userPrefName, const std::string& userPrefContent) { gLastRunner->SaveUserPref(userPrefName, userPrefContent); diff --git a/src/hello_imgui/impl/hello_imgui_font.cpp b/src/hello_imgui/impl/hello_imgui_font.cpp index 1ad92962..20900fce 100644 --- a/src/hello_imgui/impl/hello_imgui_font.cpp +++ b/src/hello_imgui/impl/hello_imgui_font.cpp @@ -254,16 +254,16 @@ namespace HelloImGui return dpiResponsiveFont; } - bool _ReloadAllDpiResponsiveFonts() + bool _reloadAllDpiResponsiveFonts() { if (gWasLoadFontBareCalled) { - fprintf(stderr, "_ReloadAllDpiResponsiveFonts failed: ony call LoadFontDpiResponsive if you want this to work\n"); + fprintf(stderr, "_reloadAllDpiResponsiveFonts failed: ony call LoadFontDpiResponsive if you want this to work\n"); return false; } if (gAllDpiResponsiveFonts.empty()) return false; - printf("_ReloadAllDpiResponsiveFonts\n"); + printf("_reloadAllDpiResponsiveFonts\n"); auto& imguiFonts = ImGui::GetIO().Fonts; imguiFonts->Clear(); for (auto & dpiResponsiveFont : gAllDpiResponsiveFonts) @@ -275,7 +275,7 @@ namespace HelloImGui dpiResponsiveFont.font = newFont; } bool buildSuccess = imguiFonts->Build(); - IM_ASSERT(buildSuccess && "_ReloadAllDpiResponsiveFonts: Failed to build fonts"); + IM_ASSERT(buildSuccess && "_reloadAllDpiResponsiveFonts: Failed to build fonts"); return true; } diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 0194a509..1fa067eb 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -75,7 +75,8 @@ namespace HelloImGui void setFinalAppWindowScreenshotRgbBuffer(const ImageBuffer& b); // Encapsulated inside hello_imgui_font.cpp -bool _ReloadAllDpiResponsiveFonts(); +bool _reloadAllDpiResponsiveFonts(); +bool _isDisplayingOnRemoteServer(); // ===================================================================================================================== @@ -990,6 +991,7 @@ void AbstractRunner::RenderGui() void _UpdateFrameRateStats(); // See hello_imgui.cpp + void AbstractRunner::CreateFramesAndRender() { // Notes: @@ -1026,7 +1028,7 @@ void AbstractRunner::CreateFramesAndRender() if (_CheckDpiAwareParamsChanges(params)) // Reload fonts if DPI scale changed { - if (_ReloadAllDpiResponsiveFonts()) + if (_reloadAllDpiResponsiveFonts()) { printf("_CheckDpiAwareParamsChanges returned true => reloaded all fonts\n"); // cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects @@ -1042,12 +1044,6 @@ void AbstractRunner::CreateFramesAndRender() } } - if (foldable_region) // Update frame rate stats - { - _UpdateFrameRateStats(); - // printf("Render frame %i, fps=%.1f\n", mIdxFrame, HelloImGui::FrameRate()); - } - if (foldable_region) // basic layout checks { // SCOPED_RELEASE_GIL_ON_MAIN_THREAD start SCOPED_RELEASE_GIL_ON_MAIN_THREAD; @@ -1151,7 +1147,7 @@ void AbstractRunner::CreateFramesAndRender() #ifndef __EMSCRIPTEN__ // Idling for non emscripten, where HelloImGui is responsible for the main loop. // This form of idling will call WaitForEventTimeout(), which may call sleep(): - IdleBySleeping(); + IdleBySleeping(); #endif // Poll Events (this fills GImGui.InputEventsQueue) @@ -1168,7 +1164,13 @@ void AbstractRunner::CreateFramesAndRender() #endif } // SCOPED_RELEASE_GIL_ON_MAIN_THREAD end - if (foldable_region) // Load additional fonts during execution + if (foldable_region) // Update frame rate stats + { + _UpdateFrameRateStats(); + // printf("Render frame %i, fps=%.1f\n", mIdxFrame, HelloImGui::FrameRate()); + } + + if (foldable_region) // Load additional fonts during execution { if (params.callbacks.LoadAdditionalFonts != nullptr) { @@ -1286,9 +1288,18 @@ void AbstractRunner::IdleBySleeping() #ifdef HELLOIMGUI_WITH_TEST_ENGINE if (params.useImGuiTestEngine && TestEngineCallbacks::IsRunningTest()) return; - #endif + #endif + + if (_isDisplayingOnRemoteServer()) + { + // if displaying remote, the FPS is limited on the server to a value between 30 and 60 fps + // We cannot idle too slow, other the GUI becomes really sluggish + // Ideally, we should ask the server about it current refresh rate + // (At the moment, we can only deliver 30fps) + params.fpsIdling.fpsIdle = 30.f; + } - assert(params.fpsIdling.fpsIdle >= 0.f); + assert(params.fpsIdling.fpsIdle >= 0.f); params.fpsIdling.isIdling = false; if ((params.fpsIdling.fpsIdle > 0.f) && params.fpsIdling.enableIdling) { diff --git a/src/hello_imgui/internal/docking_details.cpp b/src/hello_imgui/internal/docking_details.cpp index 557f393b..b630cbd9 100644 --- a/src/hello_imgui/internal/docking_details.cpp +++ b/src/hello_imgui/internal/docking_details.cpp @@ -13,6 +13,10 @@ namespace HelloImGui { +// From hello_imgui.cpp +bool _isDisplayingOnRemoteServer(); + + void _Themes_MenuGui(RunnerParams& runnerParams); // see hello_imgui_themes.cpp std::map gImGuiSplitIDs; @@ -171,14 +175,15 @@ void MenuView_Misc(RunnerParams& runnerParams) if (ImGui::MenuItem("View Status bar##xxxx", nullptr, runnerParams.imGuiWindowParams.showStatusBar)) runnerParams.imGuiWindowParams.showStatusBar = ! runnerParams.imGuiWindowParams.showStatusBar; - if (ImGui::BeginMenu("FPS")) - { - if (ImGui::MenuItem("FPS in status bar##xxxx", nullptr, runnerParams.imGuiWindowParams.showStatus_Fps)) - runnerParams.imGuiWindowParams.showStatus_Fps = ! runnerParams.imGuiWindowParams.showStatus_Fps; + if (ImGui::BeginMenu("FPS")) + { + if (ImGui::MenuItem("FPS in status bar##xxxx", nullptr, runnerParams.imGuiWindowParams.showStatus_Fps)) + runnerParams.imGuiWindowParams.showStatus_Fps = ! runnerParams.imGuiWindowParams.showStatus_Fps; - ImGui::MenuItem("Enable Idling", nullptr, &runnerParams.fpsIdling.enableIdling); - ImGui::EndMenu(); - } + if (! _isDisplayingOnRemoteServer()) + ImGui::MenuItem("Enable Idling", nullptr, &runnerParams.fpsIdling.enableIdling); + ImGui::EndMenu(); + } if (runnerParams.imGuiWindowParams.showMenu_View_Themes) Theme_MenuGui(runnerParams.imGuiWindowParams.tweakedTheme); diff --git a/src/hello_imgui/internal/menu_statusbar.cpp b/src/hello_imgui/internal/menu_statusbar.cpp index 563c9ccc..198d3176 100644 --- a/src/hello_imgui/internal/menu_statusbar.cpp +++ b/src/hello_imgui/internal/menu_statusbar.cpp @@ -11,6 +11,8 @@ namespace HelloImGui { +bool _isDisplayingOnRemoteServer(); // from hello_imgui.cpp + namespace Menu_StatusBar { @@ -97,17 +99,23 @@ void ShowStatusBar(RunnerParams & params) if (params.imGuiWindowParams.showStatus_Fps) { - float dy = ImGui::GetFontSize() * 0.15f; - - ImGui::SameLine(ImGui::GetIO().DisplaySize.x - 14.f * ImGui::GetFontSize()); - - const char* idlingInfo = params.fpsIdling.isIdling ? " (Idling)" : ""; - - ImGui::SetCursorPosY(ImGui::GetCursorPosY() - dy); // The checkbox seems visually misaligned, let's fix this - ImGui::Checkbox("Enable idling", ¶ms.fpsIdling.enableIdling); - ImGui::SameLine(); - ImGui::SetCursorPosY(ImGui::GetCursorPosY() - dy); - ImGui::Text("FPS: %.1f%s", HelloImGui::FrameRate(), idlingInfo); + if (_isDisplayingOnRemoteServer()) + { + ImGui::SameLine(ImGui::GetIO().DisplaySize.x - 5.f * ImGui::GetFontSize()); + ImGui::Text("FPS: %.1f", HelloImGui::FrameRate()); + } + else + { + float dy = ImGui::GetFontSize() * 0.15f; + + ImGui::SameLine(ImGui::GetIO().DisplaySize.x - 14.f * ImGui::GetFontSize()); + const char* idlingInfo = params.fpsIdling.isIdling ? " (Idling)" : ""; + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - dy); // The checkbox seems visually misaligned, let's fix this + ImGui::Checkbox("Enable idling", ¶ms.fpsIdling.enableIdling); + ImGui::SameLine(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - dy); + ImGui::Text("FPS: %.1f%s", HelloImGui::FrameRate(), idlingInfo); + } } ImGui::End(); From 6a332e6316a2c55f79903cc50717177b102d8a57 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Sat, 13 Apr 2024 00:36:38 +0200 Subject: [PATCH 41/57] Doc / Fonts --- src/hello_imgui/doc_api.md | 48 ++++++++++++++++++++++-------- src/hello_imgui/doc_params.md | 5 ++++ src/hello_imgui/dpi_aware.h | 6 ++-- src/hello_imgui/hello_imgui_font.h | 37 +++++++++++++---------- 4 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/hello_imgui/doc_api.md b/src/hello_imgui/doc_api.md index fdebc670..b8d30682 100644 --- a/src/hello_imgui/doc_api.md +++ b/src/hello_imgui/doc_api.md @@ -57,8 +57,16 @@ float EmSize(float nbLines); # Load fonts See [hello_imgui_font.h](https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/hello_imgui_font.h). ```cpp + + // When loading fonts, use + // HelloImGui::LoadFont(..) + // or + // HelloImGui::LoadDpiResponsiveFont() // - // When loading fonts, use HelloImGui::LoadFont(fontFilename, fontSize, fontLoadingParams) + // Use these functions instead of ImGui::GetIO().Fonts->AddFontFromFileTTF(), + // because they will automatically adjust the font size to account for HighDPI, + // and will help you to get consistent font size across different OSes. + // // Font loading parameters: several options are available (color, merging, range, ...) struct FontLoadingParams @@ -101,14 +109,30 @@ See [hello_imgui_font.h](https://github.com/pthom/hello_imgui/blob/master/src/he ImFontConfig fontConfigFontAwesome = ImFontConfig(); }; - // When loading fonts, use HelloImGui::LoadFont(FontLoadingParams) - // =============================================================== - // instead of ImGui::GetIO().Fonts->AddFontFromFileTTF(), because it will - // automatically adjust the font size to account for HighDPI, and will spare - // you headaches when trying to get consistent font size across different OSes. - // see FontLoadingParams and ImFontConfig - ImFont* LoadFont(const std::string & fontFilename, float fontSize, - const FontLoadingParams & params = {}); + // A font that will be automatically resized to account for changes in DPI + // (use LoadAdaptiveFont instead of LoadFont to get this behavior) + struct FontDpiResponsive + { + ImFont* font = nullptr; + std::string fontFilename; + float fontSize = 0.f; + FontLoadingParams fontLoadingParams; + }; + + + // Loads a font with the specified parameters + // (this font will not adapt to DPI changes after startup) + ImFont* LoadFont( + const std::string & fontFilename, float fontSize, + const FontLoadingParams & params = {}); + + // Loads a font with the specified parameters + // This font will adapt to DPI changes after startup. + // Only fonts loaded with LoadAdaptiveFont will adapt to DPI changes: + // avoid mixing LoadFont/LoadFontDpiResponsive) + FontDpiResponsive* LoadFontDpiResponsive( + const std::string & fontFilename, float fontSize, + const FontLoadingParams & params = {}); ``` @@ -469,12 +493,12 @@ It is typically 1 on windows, and 0.5 on macOS retina screens. ## How to load fonts with the correct size -### Using HelloImGui::LoadFont +### Using HelloImGui (recommended) -[`HelloImGui::LoadFont()`](https://pthom.github.io/hello_imgui/book/doc_api.html#load-fonts) will load fonts +[`HelloImGui::LoadFont()` and `HelloImGui::LoadFontDpiResponsive`](https://pthom.github.io/hello_imgui/book/doc_api.html#load-fonts) will load fonts with the correct size, taking into account the DPI scaling. -### Using Dear ImGui's AddFontFromFileTTF(): +### Using Dear ImGui `ImGui::GetIO().Fonts->AddFontFromFileTTF()` loads a font with a given size, in *physical pixels*. If for example, DisplayFramebufferScale is (2,2), and you load a font with a size of 16, it will by default be rendered diff --git a/src/hello_imgui/doc_params.md b/src/hello_imgui/doc_params.md index 1298d1f3..07225bd9 100644 --- a/src/hello_imgui/doc_params.md +++ b/src/hello_imgui/doc_params.md @@ -913,6 +913,11 @@ struct DpiAwareParams // (This parameter will be used to set ImGui::GetIO().FontGlobalScale at startup) float fontRenderingScale = 0.0f; + // `onlyUseFontDpiResponsive` + // If true, guarantees that only HelloImGui::LoadDpiResponsiveFont will be used to load fonts. + // (also for the default font) + bool onlyUseFontDpiResponsive = false; + // `dpiFontLoadingFactor` // factor by which font size should be multiplied at loading time to get a similar // visible size on different OSes. diff --git a/src/hello_imgui/dpi_aware.h b/src/hello_imgui/dpi_aware.h index d2d1fa63..41939f90 100644 --- a/src/hello_imgui/dpi_aware.h +++ b/src/hello_imgui/dpi_aware.h @@ -205,12 +205,12 @@ It is typically 1 on windows, and 0.5 on macOS retina screens. ## How to load fonts with the correct size -### Using HelloImGui::LoadFont +### Using HelloImGui (recommended) -[`HelloImGui::LoadFont()`](https://pthom.github.io/hello_imgui/book/doc_api.html#load-fonts) will load fonts +[`HelloImGui::LoadFont()` and `HelloImGui::LoadFontDpiResponsive`](https://pthom.github.io/hello_imgui/book/doc_api.html#load-fonts) will load fonts with the correct size, taking into account the DPI scaling. -### Using Dear ImGui's AddFontFromFileTTF(): +### Using Dear ImGui `ImGui::GetIO().Fonts->AddFontFromFileTTF()` loads a font with a given size, in *physical pixels*. If for example, DisplayFramebufferScale is (2,2), and you load a font with a size of 16, it will by default be rendered diff --git a/src/hello_imgui/hello_imgui_font.h b/src/hello_imgui/hello_imgui_font.h index e6fd08d8..6c04d7d5 100644 --- a/src/hello_imgui/hello_imgui_font.h +++ b/src/hello_imgui/hello_imgui_font.h @@ -9,8 +9,16 @@ namespace HelloImGui using ImWcharPair = std::array; // @@md#Fonts + + // When loading fonts, use + // HelloImGui::LoadFont(..) + // or + // HelloImGui::LoadDpiResponsiveFont() // - // When loading fonts, use HelloImGui::LoadFont(fontFilename, fontSize, fontLoadingParams) + // Use these functions instead of ImGui::GetIO().Fonts->AddFontFromFileTTF(), + // because they will automatically adjust the font size to account for HighDPI, + // and will help you to get consistent font size across different OSes. + // // Font loading parameters: several options are available (color, merging, range, ...) struct FontLoadingParams @@ -63,23 +71,20 @@ namespace HelloImGui FontLoadingParams fontLoadingParams; }; - // !!! When loading fonts, use - // HelloImGui::LoadFont(FontLoadingParams) - // or - // HelloImGui::LoadDpiResponsiveFont(FontLoadingParams) - // - // Use these functions instead of ImGui::GetIO().Fonts->AddFontFromFileTTF(), - // because they will automatically adjust the font size to account for HighDPI, - // and will spare you headaches when trying to get consistent font size across different OSes. - // Loads a font with the specified parameters (this font will not adapt to DPI changes after startup) - ImFont* LoadFont(const std::string & fontFilename, float fontSize, - const FontLoadingParams & params = {}); + // Loads a font with the specified parameters + // (this font will not adapt to DPI changes after startup) + ImFont* LoadFont( + const std::string & fontFilename, float fontSize, + const FontLoadingParams & params = {}); - // Loads a font with the specified parameters (this font will adapt to DPI changes after startup) - // (only fonts loaded with LoadAdaptiveFont will adapt to DPI changes. Avoid mixing LoadFont/LoadFontDpiResponsive) - FontDpiResponsive* LoadFontDpiResponsive(const std::string & fontFilename, float fontSize, - const FontLoadingParams & params = {}); + // Loads a font with the specified parameters + // This font will adapt to DPI changes after startup. + // Only fonts loaded with LoadAdaptiveFont will adapt to DPI changes: + // avoid mixing LoadFont/LoadFontDpiResponsive) + FontDpiResponsive* LoadFontDpiResponsive( + const std::string & fontFilename, float fontSize, + const FontLoadingParams & params = {}); // @@md From 9a929525dcdc61fc88b3ff80fa074fe885935e8a Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 17 Apr 2024 17:20:07 +0200 Subject: [PATCH 42/57] remote: Simplify DPI: add SetFullDPISettings --- external/netImgui | 2 +- .../internal/backend_impls/abstract_runner.cpp | 16 +--------------- .../netimgui_remote_display.cpp | 9 ++++++--- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/external/netImgui b/external/netImgui index dcfe5c49..cfa49fe1 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit dcfe5c49e487ea584dc966e89a87e6c303594dcd +Subproject commit cfa49fe1844e87d0e3c2cc4f5e1e5468792e6145 diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 1fa067eb..a05ef1b6 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -474,21 +474,7 @@ bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) dpiAwareParams.fontRenderingScale = io.FontGlobalScale; } - bool didDpiWindowSizeFactorChange = false; -#ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) - { - float newWindowDPISizeFactor = NetImgui::GetWindowDPISizeFactor(); - didDpiWindowSizeFactorChange = dpiAwareParams.dpiWindowSizeFactor != newWindowDPISizeFactor; - if (didDpiWindowSizeFactorChange) - { - printf("Warning: didDpiWindowSizeFactorChange=:true (from netImgui)\n"); - dpiAwareParams.dpiWindowSizeFactor = newWindowDPISizeFactor; - } - } -#endif - - if (didDpiWindowSizeFactorChange || didFontGlobalScaleChange) + if (didFontGlobalScaleChange) { printf("New DpiAwareParams:\n"); _LogDpiParams("_CheckDpiAwareParamsChanges (changed!)", dpiAwareParams); diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index ab337672..19d2c4c0 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -44,13 +44,16 @@ int main(int argc, char **argv) runnerParams.callbacks.PostInit = [&pass_cmd_line_args_to_server]() { pass_cmd_line_args_to_server(); - NetImguiServer::UI::SetUseServerDisplayDPISettings(true); - float windowDPISizeFactor = HelloImGui::GetRunnerParams()->dpiAwareParams.dpiWindowSizeFactor; - NetImguiServer::UI::SetWindowDPISizeFactor(windowDPISizeFactor); + // KK3 set font scale here }; runnerParams.callbacks.PreNewFrame = []() { // Request each client to update their drawing content + NetImguiServer::UI::SetFullDPISettings( + ImGui::GetIO().DisplayFramebufferScale, + 1.f / HelloImGui::DpiFontLoadingFactor() + ); + NetImguiServer::App::UpdateRemoteContent(); }; From 5cbc334b25d78d93f4515bd606fce76e118973f1 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 17 Apr 2024 18:23:44 +0200 Subject: [PATCH 43/57] remote: Simplify DPI: add GetFontLoadingRatio --- external/netImgui | 2 +- .../backend_impls/abstract_runner.cpp | 24 ++++++++++++++++++- .../netimgui_remote_display.cpp | 6 +---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/external/netImgui b/external/netImgui index cfa49fe1..6130d019 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit cfa49fe1844e87d0e3c2cc4f5e1e5468792e6145 +Subproject commit 6130d0198cfd757cc654263dcde40c434969e645 diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index a05ef1b6..fc360b75 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -474,7 +474,29 @@ bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) dpiAwareParams.fontRenderingScale = io.FontGlobalScale; } - if (didFontGlobalScaleChange) + bool didFontLoadingRatioChangeOnRemoteServer = false; +#ifdef HELLOIMGUI_WITH_NETIMGUI + if (params.remoteParams.enableRemoting) + { + float newFontLoadingRatio = NetImgui::GetFontLoadingRatio(); + float currentFontLoadingRatio = dpiAwareParams.DpiFontLoadingFactor(); + if (fabs(currentFontLoadingRatio - newFontLoadingRatio) > 0.001f) + { + didFontLoadingRatioChangeOnRemoteServer = true; + + float oldDpiWindowSizeFactor = dpiAwareParams.dpiWindowSizeFactor; + dpiAwareParams.dpiWindowSizeFactor = dpiAwareParams.dpiWindowSizeFactor * newFontLoadingRatio / currentFontLoadingRatio; + float new_diff = fabs(dpiAwareParams.DpiFontLoadingFactor() - newFontLoadingRatio); + IM_ASSERT(new_diff < 0.001f); + printf("Warning: didFontLoadingRatioChange=true \n" + " currentFontLoadingRatio=%f newFontLoadingRatio=%f\n" + " oldDpiWindowSizeFactor=%f newDpiWindowSizeFactor=%f\n", + currentFontLoadingRatio, newFontLoadingRatio, oldDpiWindowSizeFactor, dpiAwareParams.dpiWindowSizeFactor); + } + } +#endif + + if (didFontGlobalScaleChange || didFontLoadingRatioChangeOnRemoteServer) { printf("New DpiAwareParams:\n"); _LogDpiParams("_CheckDpiAwareParamsChanges (changed!)", dpiAwareParams); diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 19d2c4c0..6669a511 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -49,11 +49,7 @@ int main(int argc, char **argv) runnerParams.callbacks.PreNewFrame = []() { // Request each client to update their drawing content - NetImguiServer::UI::SetFullDPISettings( - ImGui::GetIO().DisplayFramebufferScale, - 1.f / HelloImGui::DpiFontLoadingFactor() - ); - + NetImguiServer::UI::SetUseServerDPISettings(HelloImGui::DpiFontLoadingFactor()); NetImguiServer::App::UpdateRemoteContent(); }; From 5791593c424458f689d4edb04c8f8a668ca11bc3 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 17 Apr 2024 18:30:54 +0200 Subject: [PATCH 44/57] if remoting, can call ScaleAllSizes --- src/hello_imgui/internal/backend_impls/abstract_runner.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index fc360b75..bfe83c4f 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -485,7 +485,9 @@ bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) didFontLoadingRatioChangeOnRemoteServer = true; float oldDpiWindowSizeFactor = dpiAwareParams.dpiWindowSizeFactor; - dpiAwareParams.dpiWindowSizeFactor = dpiAwareParams.dpiWindowSizeFactor * newFontLoadingRatio / currentFontLoadingRatio; + float ratioScaling = newFontLoadingRatio / currentFontLoadingRatio; + dpiAwareParams.dpiWindowSizeFactor = dpiAwareParams.dpiWindowSizeFactor * ratioScaling; + ImGui::GetStyle().ScaleAllSizes(ratioScaling); float new_diff = fabs(dpiAwareParams.DpiFontLoadingFactor() - newFontLoadingRatio); IM_ASSERT(new_diff < 0.001f); printf("Warning: didFontLoadingRatioChange=true \n" From 5f572631dbd7cca47933dd2b7ea063e6514d6200 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 17 Apr 2024 18:39:52 +0200 Subject: [PATCH 45/57] fixup if remoting, can call ScaleAllSizes --- src/hello_imgui/internal/backend_impls/abstract_runner.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index bfe83c4f..ff382ba4 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -606,6 +606,7 @@ void AbstractRunner::HandleDpiOnSecondFrame() #endif // High DPI handling on windows & linux + if (!_isDisplayingOnRemoteServer()) { float dpiScale = params.dpiAwareParams.dpiWindowSizeFactor; if ( dpiScale > 1.f) From 8fb77bc50f1b5c8823e166dbc6a197b156c11314 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 17 Apr 2024 18:55:02 +0200 Subject: [PATCH 46/57] remoting/ API --- external/netImgui | 2 +- src/hello_imgui/internal/backend_impls/abstract_runner.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/external/netImgui b/external/netImgui index 6130d019..650ff9a4 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 6130d0198cfd757cc654263dcde40c434969e645 +Subproject commit 650ff9a4abd750caeeddf6ea98f34908e40b2e23 diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index ff382ba4..6df80099 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -478,7 +478,7 @@ bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) #ifdef HELLOIMGUI_WITH_NETIMGUI if (params.remoteParams.enableRemoting) { - float newFontLoadingRatio = NetImgui::GetFontLoadingRatio(); + float newFontLoadingRatio = NetImgui::GetFontSizeLoadingRatio(); float currentFontLoadingRatio = dpiAwareParams.DpiFontLoadingFactor(); if (fabs(currentFontLoadingRatio - newFontLoadingRatio) > 0.001f) { From 6e41f1f4579bf37a7e61a264f53c604dee8d1d69 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 17 Apr 2024 19:10:03 +0200 Subject: [PATCH 47/57] remoting/ API2 --- external/netImgui | 2 +- src/netimgui_remote_display/netimgui_remote_display.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/external/netImgui b/external/netImgui index 650ff9a4..30caeae9 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 650ff9a4abd750caeeddf6ea98f34908e40b2e23 +Subproject commit 30caeae95c1f741b8fb6eda60194531d81627dec diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 6669a511..df9bbce8 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -44,12 +44,11 @@ int main(int argc, char **argv) runnerParams.callbacks.PostInit = [&pass_cmd_line_args_to_server]() { pass_cmd_line_args_to_server(); - // KK3 set font scale here + NetImguiServer::UI::SetUseServerDPISettings(HelloImGui::DpiFontLoadingFactor()); }; runnerParams.callbacks.PreNewFrame = []() { // Request each client to update their drawing content - NetImguiServer::UI::SetUseServerDPISettings(HelloImGui::DpiFontLoadingFactor()); NetImguiServer::App::UpdateRemoteContent(); }; From 9a41caa17bc69f45a23f730c04190eb712a70734 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 17 Apr 2024 19:15:06 +0200 Subject: [PATCH 48/57] remoting/ API3 --- external/netImgui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/netImgui b/external/netImgui index 30caeae9..77775e88 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 30caeae95c1f741b8fb6eda60194531d81627dec +Subproject commit 77775e886036290ffc5033a2ed7f7843fdcf409a From 0d7aa8ab5d7448863a85863e724fbcbcfb06efbd Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Wed, 17 Apr 2024 21:52:37 +0200 Subject: [PATCH 49/57] Remote: can transmit window size --- external/netImgui | 2 +- src/hello_imgui/app_window_params.h | 2 + src/hello_imgui/hello_imgui.h | 4 ++ src/hello_imgui/impl/hello_imgui.cpp | 6 ++- .../backend_impls/abstract_runner.cpp | 50 +++++++++++++++++-- .../internal/backend_impls/abstract_runner.h | 1 + .../null_window_helper.h | 12 ++++- src/hello_imgui/runner_params.h | 5 ++ .../hello_imgui_demodocking.main.cpp | 1 + .../netimgui_remote_display.cpp | 4 ++ 10 files changed, 78 insertions(+), 9 deletions(-) diff --git a/external/netImgui b/external/netImgui index 77775e88..94ebd9f7 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 77775e886036290ffc5033a2ed7f7843fdcf409a +Subproject commit 94ebd9f779accb4d3798bad7ddd3e208d52f7c8b diff --git a/src/hello_imgui/app_window_params.h b/src/hello_imgui/app_window_params.h index 1d2931a6..4c467f83 100644 --- a/src/hello_imgui/app_window_params.h +++ b/src/hello_imgui/app_window_params.h @@ -62,6 +62,8 @@ struct WindowGeometry // Size of the application window // used if fullScreenMode==NoFullScreen and sizeAuto==false. Default=(800, 600) + // The size will be handled as if it was specified for a 96PPI screen + // (i.e. a given size will correspond to the same physical size on different screens, whatever their DPI) ScreenSize size = DefaultWindowSize; // If sizeAuto=true, adapt the app window size to the presented widgets. diff --git a/src/hello_imgui/hello_imgui.h b/src/hello_imgui/hello_imgui.h index aaea975a..8547e8dd 100644 --- a/src/hello_imgui/hello_imgui.h +++ b/src/hello_imgui/hello_imgui.h @@ -112,6 +112,10 @@ ImGuiTestEngine* GetImGuiTestEngine(); // "Sdl - Vulkan" std::string GetBackendDescription(); +// `ChangeWindowSize(const ScreenSize &windowSize)`: sets the window size +// (useful if you want to change the window size during execution) +void ChangeWindowSize(const ScreenSize &windowSize); + // @@md diff --git a/src/hello_imgui/impl/hello_imgui.cpp b/src/hello_imgui/impl/hello_imgui.cpp index e014c223..fa16b9ff 100644 --- a/src/hello_imgui/impl/hello_imgui.cpp +++ b/src/hello_imgui/impl/hello_imgui.cpp @@ -239,10 +239,14 @@ ImGuiTestEngine* GetImGuiTestEngine() { return GHImGuiTestEngine; } ImGuiTestEngine* GetImGuiTestEngine() { return nullptr; } #endif +void ChangeWindowSize(const ScreenSize &windowSize) +{ + gLastRunner->ChangeWindowSize(windowSize); +} + bool _isDisplayingOnRemoteServer() { - return true; #ifdef HELLOIMGUI_WITH_NETIMGUI return HelloImGui::GetRunnerParams()->remoteParams.enableRemoting; #else diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 6df80099..7e64eb3b 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -169,10 +169,15 @@ class NetImGuiWrapper } } - void sendFonts() - { - _sendFonts_Impl(); - } + void sendFonts() + { + _sendFonts_Impl(); + } + + bool isConnected() + { + return NetImgui::IsConnected(); + } private: void InitiateConnection() @@ -184,7 +189,7 @@ class NetImGuiWrapper NetImgui::ConnectToApp(clientName().c_str(), remoteParams().serverHost.c_str(), remoteParams().serverPort); std::this_thread::sleep_for(std::chrono::milliseconds(100)); ++ mNbConnectionsTentatives; - _sendFonts_Impl(); + _sendFonts_Impl(); } std::string clientName() @@ -235,6 +240,17 @@ class NetImGuiWrapper std::unique_ptr gNetImGuiWrapper; bool gWaitingForRemoteDpiInfo = false; #endif + +bool _isConnectedToRemoteServer() +{ +#ifdef HELLOIMGUI_WITH_NETIMGUI + if (!_isDisplayingOnRemoteServer()) + return false; + return gNetImGuiWrapper->isConnected(); +#else + return false; +#endif +} // ===================================================================================================================== // // ===================================================================================================================== @@ -304,6 +320,12 @@ bool AbstractRunner::WantAutoSize() #endif } +void AbstractRunner::ChangeWindowSize(HelloImGui::ScreenSize windowSize) +{ + auto bounds = mBackendWindowHelper->GetWindowBounds(mWindow); + bounds.size = windowSize; + mBackendWindowHelper->SetWindowBounds(mWindow, bounds); +} bool AbstractRunner::ShallSizeWindowRelativeTo96Ppi() { @@ -1149,6 +1171,24 @@ void AbstractRunner::CreateFramesAndRender() mBackendWindowHelper->ShowWindow(mWindow); } } + + // Transmit window size to remote server + #ifdef HELLOIMGUI_WITH_NETIMGUI + if (_isConnectedToRemoteServer() && (mIdxFrame > 3) && params.remoteParams.transmitWindowSize) + { + static bool wasSizeTransmitted = false; + if (!wasSizeTransmitted) + { + wasSizeTransmitted = true; + auto windowSize = params.appWindowParams.windowGeometry.size; + // When running on a remote server, we do not know the window DPI factor, + // so we treat the window size as if it was 96PPI + uint16_t width_96PPI = (uint16_t)windowSize[0]; + uint16_t height_96PPI = (uint16_t)windowSize[1]; + NetImgui::SetWindowSize_96PPI(width_96PPI, height_96PPI); + } + } + #endif } // SCOPED_RELEASE_GIL_ON_MAIN_THREAD end if(foldable_region) // Handle idling diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.h b/src/hello_imgui/internal/backend_impls/abstract_runner.h index cf6bef1b..a76459e9 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.h +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.h @@ -37,6 +37,7 @@ class AbstractRunner // For jupyter notebook, which displays a screenshot post execution ImageBuffer ScreenshotRgb() { return mRenderingBackendCallbacks->Impl_ScreenshotRgb_3D(); } + void ChangeWindowSize(ScreenSize windowSize); void LayoutSettings_SwitchLayout(const std::string& layoutName); diff --git a/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h b/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h index 88e45266..c5f7e31c 100644 --- a/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h +++ b/src/hello_imgui/internal/backend_impls/backend_window_helper/null_window_helper.h @@ -20,6 +20,7 @@ namespace HelloImGui { namespace BackendApi // It is only a class in order to enforce a consistent API between backends. public: WindowPointer CreateWindow(AppWindowParams &appWindowParams, const BackendOptions& backendOptions) override { + mWindowBounds.size = appWindowParams.windowGeometry.size; return nullptr; } @@ -28,8 +29,12 @@ namespace HelloImGui { namespace BackendApi bool IsWindowIconified(WindowPointer window) override { return false; } void RaiseWindow(WindowPointer window) override {} - ScreenBounds GetWindowBounds(WindowPointer window) override { return {}; } - void SetWindowBounds(WindowPointer window, ScreenBounds windowBounds) override {} + ScreenBounds GetWindowBounds(WindowPointer window) override { + return mWindowBounds; + } + void SetWindowBounds(WindowPointer window, ScreenBounds windowBounds) override { + mWindowBounds = windowBounds; + } void WaitForEventTimeout(double timeout_seconds) override { std::this_thread::sleep_for(std::chrono::milliseconds((int)(timeout_seconds * 1000))); @@ -41,6 +46,9 @@ namespace HelloImGui { namespace BackendApi void ShowWindow(WindowPointer window) override {} bool IsWindowHidden(WindowPointer window) override { return false; } + private: + ScreenBounds mWindowBounds = {}; + }; }} // namespace HelloImGui { namespace BackendApi diff --git a/src/hello_imgui/runner_params.h b/src/hello_imgui/runner_params.h index 567aa572..bcf8f5f0 100644 --- a/src/hello_imgui/runner_params.h +++ b/src/hello_imgui/runner_params.h @@ -161,6 +161,9 @@ struct NetImGuiParams // This is unused since it is the client (i.e. the app logic) that connects to the server, // using NetImgui::ConnectToApp uint32_t clientPort = 8889; + + // If true, transmit the window size to the server + bool transmitWindowSize = false; }; // @@md @@ -350,6 +353,8 @@ struct SimpleRunnerParams // `windowSize`: _ScreenSize, default={800, 600}_. // Size of the window + // The size will be handled as if it was specified for a 96PPI screen + // (i.e. a given size will correspond to the same physical size on different screens, whatever their DPI) ScreenSize windowSize = DefaultWindowSize; // `fpsIdle`: _float, default=9_. diff --git a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp index d57e8fa4..dc582eb0 100644 --- a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp +++ b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp @@ -794,6 +794,7 @@ int main(int, char**) //runnerParams.rendererBackendType = HelloImGui::RendererBackendType::Vulkan; runnerParams.remoteParams.enableRemoting = true; + runnerParams.remoteParams.transmitWindowSize = true; HelloImGui::Run(runnerParams); // Note: with ImGuiBundle, it is also possible to use ImmApp::Run(...) diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index df9bbce8..2f433ab3 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -42,6 +42,10 @@ int main(int argc, char **argv) // Runner Params HelloImGui::RunnerParams runnerParams; + NetImguiServer::UI::SetCallbackWindowSize96PPI([](uint16_t width, uint16_t height) { + HelloImGui::ChangeWindowSize({(int)width, (int)height}); + }); + runnerParams.callbacks.PostInit = [&pass_cmd_line_args_to_server]() { pass_cmd_line_args_to_server(); NetImguiServer::UI::SetUseServerDPISettings(HelloImGui::DpiFontLoadingFactor()); From 3be6adbb0f6a8a77a439005324bb41517671a01f Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 18 Apr 2024 10:38:47 +0200 Subject: [PATCH 50/57] Customizable runner logs --- external/netImgui | 2 +- src/hello_imgui/impl/hello_imgui_font.cpp | 4 +- .../backend_impls/abstract_runner.cpp | 39 +++++++++++++------ .../netimgui_remote_display.cpp | 3 ++ 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/external/netImgui b/external/netImgui index 94ebd9f7..0178485a 160000 --- a/external/netImgui +++ b/external/netImgui @@ -1 +1 @@ -Subproject commit 94ebd9f779accb4d3798bad7ddd3e208d52f7c8b +Subproject commit 0178485ae8253f17f4595659bbdfe859c4e9f991 diff --git a/src/hello_imgui/impl/hello_imgui_font.cpp b/src/hello_imgui/impl/hello_imgui_font.cpp index 20900fce..30b07c43 100644 --- a/src/hello_imgui/impl/hello_imgui_font.cpp +++ b/src/hello_imgui/impl/hello_imgui_font.cpp @@ -224,7 +224,7 @@ namespace HelloImGui IM_ASSERT(! runnerParams->dpiAwareParams.onlyUseFontDpiResponsive && "If runnerParams->dpiAwareParams.onlyUseFontDpiResponsive is true, you must use LoadFontDpiResponsive() instead of LoadFont()"); gWasLoadFontBareCalled = true; - printf("LoadFont(%s, %f)\n", fontFilename.c_str(), fontSize_); + //printf("LoadFont(%s, %f)\n", fontFilename.c_str(), fontSize_); return _LoadFontImpl(fontFilename, fontSize_, params_); } @@ -246,7 +246,7 @@ namespace HelloImGui // Get the pointer to the newly inserted element (which we will return) FontDpiResponsive* dpiResponsiveFont = &gAllDpiResponsiveFonts.back(); - printf("LoadFontDpiResponsive(%s, %f)\n", fontFilename.c_str(), fontSize); + //printf("LoadFontDpiResponsive(%s, %f)\n", fontFilename.c_str(), fontSize); dpiResponsiveFont->font = _LoadFontImpl(fontFilename, fontSize, fontLoadingParams); dpiResponsiveFont->fontSize = fontSize; dpiResponsiveFont->fontFilename = fontFilename; diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 7e64eb3b..53e1936b 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -68,6 +68,21 @@ // +//#define ENABLE_DPI_LOG // Enable or disable logging for DPI info +#define ENABLE_NETIMGUI_LOG // Enable or disable logging for NetImgui remoting + +#ifdef ENABLE_DPI_LOG +#define DpiLog PoorManLog +#else +#define DpiLog(...) +#endif + +#ifdef ENABLE_NETIMGUI_LOG +#define NetimguiLog PoorManLog +#else +#define NetimguiLog(...) +#endif + namespace HelloImGui { @@ -182,7 +197,7 @@ class NetImGuiWrapper private: void InitiateConnection() { - printf("NetImGuiWrapper: InitiateConnection\n"); + NetimguiLog("NetImGuiWrapper: InitiateConnection\n"); mNetImguiRaii.release(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); mNetImguiRaii = std::make_unique(); @@ -225,7 +240,7 @@ class NetImGuiWrapper void LogStatus(const std::string& msg) { - printf("NetImGuiWrapper: %s\n", msg.c_str()); + NetimguiLog("NetImGuiWrapper: %s\n", msg.c_str()); } private: // Members @@ -474,12 +489,12 @@ void _LogDpiParams(const std::string& origin, const HelloImGui::DpiAwareParams& { auto &io = ImGui::GetIO(); std::stringstream msg; - PoorManLog("DpiAwareParams: %s\n", origin.c_str()); - PoorManLog(" dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor); - PoorManLog(" fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); - PoorManLog(" DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); - PoorManLog(" (ImGui FontGlobalScale: %f)\n", io.FontGlobalScale); - PoorManLog(" (ImGui DisplayFramebufferScale=%f, %f)\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); + DpiLog("DpiAwareParams: %s\n", origin.c_str()); + DpiLog(" dpiWindowSizeFactor=%f\n", dpiAwareParams.dpiWindowSizeFactor); + DpiLog(" fontRenderingScale=%f\n", dpiAwareParams.fontRenderingScale); + DpiLog(" DpiFontLoadingFactor()=%f\n", dpiAwareParams.DpiFontLoadingFactor()); + DpiLog(" (ImGui FontGlobalScale: %f)\n", io.FontGlobalScale); + DpiLog(" (ImGui DisplayFramebufferScale=%f, %f)\n", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); } @@ -492,7 +507,7 @@ bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) bool didFontGlobalScaleChange = dpiAwareParams.fontRenderingScale != io.FontGlobalScale; if (didFontGlobalScaleChange) { - printf("Warning: didFontGlobalScaleChange=:true\n"); + DpiLog("Warning: didFontGlobalScaleChange=:true\n"); dpiAwareParams.fontRenderingScale = io.FontGlobalScale; } @@ -512,7 +527,7 @@ bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) ImGui::GetStyle().ScaleAllSizes(ratioScaling); float new_diff = fabs(dpiAwareParams.DpiFontLoadingFactor() - newFontLoadingRatio); IM_ASSERT(new_diff < 0.001f); - printf("Warning: didFontLoadingRatioChange=true \n" + DpiLog("Warning: didFontLoadingRatioChange=true \n" " currentFontLoadingRatio=%f newFontLoadingRatio=%f\n" " oldDpiWindowSizeFactor=%f newDpiWindowSizeFactor=%f\n", currentFontLoadingRatio, newFontLoadingRatio, oldDpiWindowSizeFactor, dpiAwareParams.dpiWindowSizeFactor); @@ -522,7 +537,7 @@ bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) if (didFontGlobalScaleChange || didFontLoadingRatioChangeOnRemoteServer) { - printf("New DpiAwareParams:\n"); + DpiLog("New DpiAwareParams:\n"); _LogDpiParams("_CheckDpiAwareParamsChanges (changed!)", dpiAwareParams); return true; } @@ -1063,7 +1078,7 @@ void AbstractRunner::CreateFramesAndRender() { if (_reloadAllDpiResponsiveFonts()) { - printf("_CheckDpiAwareParamsChanges returned true => reloaded all fonts\n"); + DpiLog("_CheckDpiAwareParamsChanges returned true => reloaded all fonts\n"); // cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects mRenderingBackendCallbacks->Impl_DestroyFontTexture(); mRenderingBackendCallbacks->Impl_CreateFontTexture(); diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 2f433ab3..3c3d0a2d 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -42,6 +42,9 @@ int main(int argc, char **argv) // Runner Params HelloImGui::RunnerParams runnerParams; + NetImguiServer::UI::SetAllowOnlyOneClient(); + NetImguiServer::UI::SetHideMainMenu(); + NetImguiServer::UI::SetCallbackWindowSize96PPI([](uint16_t width, uint16_t height) { HelloImGui::ChangeWindowSize({(int)width, (int)height}); }); From 2138c7b2d24e8a3f715517003477edf06384aa14 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 18 Apr 2024 10:42:33 +0200 Subject: [PATCH 51/57] remote display app: runnerParams.fpsIdling.fpsIdle=30 --- src/netimgui_remote_display/netimgui_remote_display.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/netimgui_remote_display/netimgui_remote_display.cpp index 3c3d0a2d..5687bfe8 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/netimgui_remote_display/netimgui_remote_display.cpp @@ -74,6 +74,8 @@ int main(int argc, char **argv) // runnerParams.dpiAwareParams.dpiWindowSizeFactor = 1.0f; // runnerParams.dpiAwareParams.fontRenderingScale = 1.0f; + runnerParams.fpsIdling.fpsIdle = 30.f; + // Start the HelloImGui runner HelloImGui::Run(runnerParams); } From 48eb9c750ab8a69c3310bdfe4d87d29022c7be24 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 18 Apr 2024 13:20:52 +0200 Subject: [PATCH 52/57] Remote: work on integration --- CMakeLists.txt | 13 +++--- CMakePresets.json | 11 +---- hello_imgui_cmake/hello_imgui_build_lib.cmake | 3 +- src/CMakeLists.txt | 4 +- src/hello_imgui/doc_params.md | 2 +- .../backend_impls/abstract_runner.cpp | 6 +-- src/hello_imgui/remote_params.h | 39 +++++++++++++++++ src/hello_imgui/runner_params.h | 43 ++----------------- src/hello_imgui_remote/CMakeLists.txt | 4 ++ .../netimgui_remote_display/CMakeLists.txt | 14 +++--- .../NetImguiServer_HAL_Glfw.cpp | 0 .../netimgui_remote_display.cpp | 4 +- 12 files changed, 71 insertions(+), 72 deletions(-) create mode 100644 src/hello_imgui/remote_params.h create mode 100644 src/hello_imgui_remote/CMakeLists.txt rename src/{ => hello_imgui_remote}/netimgui_remote_display/CMakeLists.txt (63%) rename src/{ => hello_imgui_remote}/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp (100%) rename src/{ => hello_imgui_remote}/netimgui_remote_display/netimgui_remote_display.cpp (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87b0f04e..fd21b948 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,13 +95,6 @@ option(HELLOIMGUI_HAS_NULL "Null rendering backend" OFF) # for testing and remo option(HELLOIMGUI_NULL_BACKEND "Use Null rendering/platform backend" OFF) # # do not remove this line (used by the script that generates the documentation) -#------------------------------------------------------------------------------ -# Options / Remoting -#------------------------------------------------------------------------------ -# Using https://github.com/sammyfreg/netImgui, you can use HelloImGui with remote rendering -# (this is useful for example to render ImGui on a remote device, or to render ImGui in a web browser) -option(HELLOIMGUI_WITH_NETIMGUI "Use netImgui for remote rendering" OFF) - #------------------------------------------------------------------------------ # Options / Freetype #------------------------------------------------------------------------------ @@ -303,6 +296,12 @@ mark_as_advanced(HELLO_IMGUI_IMGUI_SHARED) # option(HELLOIMGUI_USE_IMGUI_CMAKE_PACKAGE "Use imgui from cmake package (provided by vcpkg for example) * Must be on docking branch*" OFF) +#------------------------------------------------------------------------------ +# Options / Remoting +#------------------------------------------------------------------------------ +# Using https://github.com/sammyfreg/netImgui, you can use HelloImGui with remote rendering +# (Unsupported, and highly experimental. Requires a specific fork of netImgui) +option(HELLOIMGUI_WITH_NETIMGUI "Use netImgui for remote rendering" OFF) ############################################################################### # End of options diff --git a/CMakePresets.json b/CMakePresets.json index fdaaa20c..80848259 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -29,16 +29,7 @@ "HELLOIMGUI_HAS_VULKAN": "ON", "HELLOIMGUI_HAS_DIRECTX11": "ON", "HELLOIMGUI_HAS_DIRECTX12": "ON", - "HELLOIMGUI_HAS_NULL": "ON", - "HELLOIMGUI_WITH_NETIMGUI": "ON" - } - }, - { - "name": "build_netimgui", - "description": "Build with netImgui.", - "cacheVariables": { - "HELLOIMGUI_NULL_BACKEND": "ON", - "HELLOIMGUI_WITH_NETIMGUI": "ON" + "HELLOIMGUI_HAS_NULL": "ON" } }, { diff --git a/hello_imgui_cmake/hello_imgui_build_lib.cmake b/hello_imgui_cmake/hello_imgui_build_lib.cmake index eac7c56a..cf2ed055 100644 --- a/hello_imgui_cmake/hello_imgui_build_lib.cmake +++ b/hello_imgui_cmake/hello_imgui_build_lib.cmake @@ -1115,13 +1115,14 @@ function(him_log_configuration) # set imgui_source_dir to the relative path of HELLOIMGUI_IMGUI_SOURCE_DIR versus this project file(RELATIVE_PATH imgui_source_dir ${HELLOIMGUI_BASEPATH} ${HELLOIMGUI_IMGUI_SOURCE_DIR}) + # Use netImGui: ${HELLOIMGUI_WITH_NETIMGUI} + set(msg " =========================================================================== Hello ImGui build options: =========================================================================== Platform Backend(s): ${active_platform_backends} Rendering Backend(s): ${active_rendering_backends} - Use netImGui: ${HELLOIMGUI_WITH_NETIMGUI} --------------------------------------------------------------------------- Options: HELLOIMGUI_USE_FREETYPE: ${HELLOIMGUI_USE_FREETYPE} (${HELLOIMGUI_FREETYPE_SELECTED_INFO}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 57c198ec..c979011f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,4 @@ endif() if(HELLOIMGUI_BUILD_TESTS) add_subdirectory(hello_imgui_tests) endif() -if(HELLOIMGUI_WITH_NETIMGUI AND HELLOIMGUI_HAS_OPENGL3 AND HELLOIMGUI_USE_GLFW3) - add_subdirectory(netimgui_remote_display) -endif() +add_subdirectory(hello_imgui_remote) diff --git a/src/hello_imgui/doc_params.md b/src/hello_imgui/doc_params.md index 07225bd9..1051a161 100644 --- a/src/hello_imgui/doc_params.md +++ b/src/hello_imgui/doc_params.md @@ -152,7 +152,7 @@ struct RunnerParams RendererBackendType rendererBackendType = RendererBackendType::FirstAvailable; // --------------- RemoteParams ------------------- - NetImGuiParams remoteParams; + RemoteParams remoteParams; // --------------- Settings ------------------- diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 53e1936b..0c1212bb 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -209,16 +209,14 @@ class NetImGuiWrapper std::string clientName() { - std::string clientName = remoteParams().clientName; - if (clientName.empty()) - clientName = runnerParams().appWindowParams.windowTitle; + std::string clientName = runnerParams().appWindowParams.windowTitle; if (clientName.empty()) clientName = "HelloImGui"; clientName += "##" + std::to_string(ImGui::GetTime()); return clientName; } - HelloImGui::NetImGuiParams& remoteParams() { return HelloImGui::GetRunnerParams()->remoteParams; } + HelloImGui::RemoteParams& remoteParams() { return HelloImGui::GetRunnerParams()->remoteParams; } HelloImGui::RunnerParams& runnerParams() { return *HelloImGui::GetRunnerParams(); } void _sendFonts_Impl() diff --git a/src/hello_imgui/remote_params.h b/src/hello_imgui/remote_params.h new file mode 100644 index 00000000..a0eb5827 --- /dev/null +++ b/src/hello_imgui/remote_params.h @@ -0,0 +1,39 @@ +#pragma once +#include + +namespace HelloImGui +{ + + +// @@md#RemoteParams + +// RemoteParams is a struct that contains the settings for displaying the application on a remote device. +// using https://github.com/sammyfreg/netImgui +// This will only work if the application is compiled with the option -DHELLOIMGUI_WITH_NETIMGUI=ON +// Highly experimental and not supported. Requires a specific version of netImgui, which is not published. +struct RemoteParams +{ + bool enableRemoting = false; + + bool exitWhenServerDisconnected = false; + double durationMaxDisconnected = 30.0; + + // The server host (if empty, will use "localhost") + // The server is the app that simply displays the application on a remote device + std::string serverHost = "localhost"; + // The server port (default is 8888) + uint32_t serverPort = 8888; + + // The client port (default is 8889) + // This is unused since it is the client (i.e. the app logic) that connects to the server, + // using NetImgui::ConnectToApp + uint32_t clientPort = 8889; + + // If true, transmit the window size to the server + bool transmitWindowSize = false; +}; + +// @@md + + +} // namespace HelloImGui \ No newline at end of file diff --git a/src/hello_imgui/runner_params.h b/src/hello_imgui/runner_params.h index bcf8f5f0..37a4d9ea 100644 --- a/src/hello_imgui/runner_params.h +++ b/src/hello_imgui/runner_params.h @@ -4,6 +4,7 @@ #include "hello_imgui/runner_callbacks.h" #include "hello_imgui/docking_params.h" #include "hello_imgui/backend_pointers.h" +#include "hello_imgui/remote_params.h" #include "hello_imgui/renderer_backend_options.h" #include "hello_imgui/dpi_aware.h" #include @@ -131,42 +132,6 @@ struct FpsIdling }; // @@md -// -------------------------------------------------------------------------------------------------------------------- - -// -------------------------------------------------------------------------------------------------------------------- - -// @@md#NetImGuiParams - -// NetImGuiParams is a struct that contains the settings for displaying the application on a remote device. -// using https://github.com/sammyfreg/netImgui -// (This will only work if the application is compiled with the option -DHELLOIMGUI_WITH_NETIMGUI=ON) -struct NetImGuiParams -{ - bool enableRemoting = false; - - bool exitWhenServerDisconnected = false; - double durationMaxDisconnected = 30.0; - - // Name of the client (if empty, will use params.appWindowParams.windowTitle) - // (The client is the app that contains the application logic) - std::string clientName = ""; - - // The server host (if empty, will use "localhost") - // The server is the app that simply displays the application on a remote device - std::string serverHost = "localhost"; - // The server port (default is 8888) - uint32_t serverPort = 8888; - - // The client port (default is 8889) - // This is unused since it is the client (i.e. the app logic) that connects to the server, - // using NetImgui::ConnectToApp - uint32_t clientPort = 8889; - - // If true, transmit the window size to the server - bool transmitWindowSize = false; -}; - -// @@md // -------------------------------------------------------------------------------------------------------------------- @@ -231,9 +196,6 @@ struct RunnerParams // Only useful when multiple rendering backend are compiled and available. RendererBackendType rendererBackendType = RendererBackendType::FirstAvailable; - // --------------- RemoteParams ------------------- - NetImGuiParams remoteParams; - // --------------- Settings ------------------- @@ -297,6 +259,9 @@ struct RunnerParams // Set the application refresh rate // (only used on emscripten: 0 stands for "let the app or the browser decide") int emscripten_fps = 0; + + // Parameters for Remote display (experimental, unsupported) + RemoteParams remoteParams; }; // @@md diff --git a/src/hello_imgui_remote/CMakeLists.txt b/src/hello_imgui_remote/CMakeLists.txt new file mode 100644 index 00000000..eee882e8 --- /dev/null +++ b/src/hello_imgui_remote/CMakeLists.txt @@ -0,0 +1,4 @@ +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") +if(HELLOIMGUI_WITH_NETIMGUI AND HELLOIMGUI_HAS_OPENGL3) + add_subdirectory(netimgui_remote_display) +endif() diff --git a/src/netimgui_remote_display/CMakeLists.txt b/src/hello_imgui_remote/netimgui_remote_display/CMakeLists.txt similarity index 63% rename from src/netimgui_remote_display/CMakeLists.txt rename to src/hello_imgui_remote/netimgui_remote_display/CMakeLists.txt index 5059d715..5bd8850c 100644 --- a/src/netimgui_remote_display/CMakeLists.txt +++ b/src/hello_imgui_remote/netimgui_remote_display/CMakeLists.txt @@ -4,9 +4,6 @@ endif() if (NOT HELLOIMGUI_HAS_OPENGL3) message(FATAL_ERROR "HELLOIMGUI_HAS_OPENGL3 is not enabled, and required for hello_imgui_remote_display") endif() -if (NOT HELLOIMGUI_USE_GLFW3) - message(FATAL_ERROR "HELLOIMGUI_USE_GLFW3 is not enabled, and required for hello_imgui_remote_display") -endif() set(hal_gl3_cpp_file ${NETIMGUI_DIR}/Code/ServerApp/Source/GlfwGL3/NetImguiServer_HAL_GL3.cpp) @@ -14,5 +11,12 @@ set(sources ${hal_gl3_cpp_file} netimgui_remote_display.cpp NetImguiServer_HAL_G hello_imgui_add_app(netimgui_remote_display ${sources}) target_compile_definitions(net_imgui_server_lib PUBLIC NETIMGUI_SERVER_APP_BACKEND_GLFW_GL3=1) target_link_libraries(netimgui_remote_display PRIVATE net_imgui_server_lib) -find_package(OpenGL REQUIRED) -target_link_libraries(netimgui_remote_display PRIVATE OpenGL::GL) +if(NOT EMSCRIPTEN) + find_package(OpenGL REQUIRED) + target_link_libraries(netimgui_remote_display PRIVATE OpenGL::GL) +endif() + +if (EMSCRIPTEN) + # emcmake cmake .. -DCMAKE_BUILD_TYPE=Release -DHELLOIMGUI_WITH_NETIMGUI=ON -DHELLOIMGUI_EMSCRIPTEN_PTHREAD=ON + target_link_options(netimgui_remote_display PRIVATE -lwebsocket.js -sPROXY_POSIX_SOCKETS -pthread -sPTHREAD_POOL_SIZE=4 ) +endif() diff --git a/src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp b/src/hello_imgui_remote/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp similarity index 100% rename from src/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp rename to src/hello_imgui_remote/netimgui_remote_display/NetImguiServer_HAL_Glfw.cpp diff --git a/src/netimgui_remote_display/netimgui_remote_display.cpp b/src/hello_imgui_remote/netimgui_remote_display/netimgui_remote_display.cpp similarity index 98% rename from src/netimgui_remote_display/netimgui_remote_display.cpp rename to src/hello_imgui_remote/netimgui_remote_display/netimgui_remote_display.cpp index 5687bfe8..7308018b 100644 --- a/src/netimgui_remote_display/netimgui_remote_display.cpp +++ b/src/hello_imgui_remote/netimgui_remote_display/netimgui_remote_display.cpp @@ -42,8 +42,8 @@ int main(int argc, char **argv) // Runner Params HelloImGui::RunnerParams runnerParams; - NetImguiServer::UI::SetAllowOnlyOneClient(); - NetImguiServer::UI::SetHideMainMenu(); + //NetImguiServer::UI::SetAllowOnlyOneClient(); + //NetImguiServer::UI::SetHideMainMenu(); NetImguiServer::UI::SetCallbackWindowSize96PPI([](uint16_t width, uint16_t height) { HelloImGui::ChangeWindowSize({(int)width, (int)height}); From 5b1d57e8e3563faa64c0433878bfc50f75931af7 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 18 Apr 2024 15:00:02 +0200 Subject: [PATCH 53/57] Extract remote_display_handler --- src/hello_imgui/impl/hello_imgui.cpp | 9 +- .../backend_impls/abstract_runner.cpp | 293 ++--------------- .../internal/backend_impls/abstract_runner.h | 6 + .../backend_impls/remote_display_handler.cpp | 305 ++++++++++++++++++ .../backend_impls/remote_display_handler.h | 41 +++ src/hello_imgui/internal/docking_details.cpp | 4 +- src/hello_imgui/internal/menu_statusbar.cpp | 4 +- 7 files changed, 387 insertions(+), 275 deletions(-) create mode 100644 src/hello_imgui/internal/backend_impls/remote_display_handler.cpp create mode 100644 src/hello_imgui/internal/backend_impls/remote_display_handler.h diff --git a/src/hello_imgui/impl/hello_imgui.cpp b/src/hello_imgui/impl/hello_imgui.cpp index fa16b9ff..5b2357a8 100644 --- a/src/hello_imgui/impl/hello_imgui.cpp +++ b/src/hello_imgui/impl/hello_imgui.cpp @@ -244,14 +244,9 @@ void ChangeWindowSize(const ScreenSize &windowSize) gLastRunner->ChangeWindowSize(windowSize); } - -bool _isDisplayingOnRemoteServer() +bool ShouldDisplayOnRemoteServer() { - #ifdef HELLOIMGUI_WITH_NETIMGUI - return HelloImGui::GetRunnerParams()->remoteParams.enableRemoting; - #else - return false; - #endif + return gLastRunner->ShouldDisplayOnRemoteServer(); } diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index 0c1212bb..a2c0ec30 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -22,10 +22,6 @@ #define SCOPED_RELEASE_GIL_ON_MAIN_THREAD #endif -#ifdef HELLOIMGUI_WITH_NETIMGUI -#include "NetImgui_Api.h" -#endif - #include #include #include @@ -69,7 +65,7 @@ //#define ENABLE_DPI_LOG // Enable or disable logging for DPI info -#define ENABLE_NETIMGUI_LOG // Enable or disable logging for NetImgui remoting +#define ENABLE_DPI_LOG #ifdef ENABLE_DPI_LOG #define DpiLog PoorManLog @@ -77,12 +73,6 @@ #define DpiLog(...) #endif -#ifdef ENABLE_NETIMGUI_LOG -#define NetimguiLog PoorManLog -#else -#define NetimguiLog(...) -#endif - namespace HelloImGui { @@ -91,186 +81,11 @@ void setFinalAppWindowScreenshotRgbBuffer(const ImageBuffer& b); // Encapsulated inside hello_imgui_font.cpp bool _reloadAllDpiResponsiveFonts(); -bool _isDisplayingOnRemoteServer(); - - -// ===================================================================================================================== -// -// ===================================================================================================================== -#ifdef HELLOIMGUI_WITH_NETIMGUI -struct NetImGuiRaii { - NetImGuiRaii() { NetImgui::Startup(); } - ~NetImGuiRaii() { NetImgui::Shutdown(); } -}; - - -class NetImGuiWrapper -{ -public: - NetImGuiWrapper() = default; - ~NetImGuiWrapper() = default; - - void HeartBeat() - { - if (mNetImguiRaii == nullptr) - { - InitiateConnection(); - return; - } - - int nbConnectionsPending = mNbConnectionsTentatives - mNbConnectionsSuccess - mNbConnectionsFailures; - IM_ASSERT(nbConnectionsPending == 0 || nbConnectionsPending == 1); - - if (nbConnectionsPending == 1) - { - if (NetImgui::IsConnected()) - { - LogStatus("Connection success...\n"); - ++ mNbConnectionsSuccess; - mLastConnectionSuccess = true; - } - else if (NetImgui::IsConnectionPending()) - { - LogStatus("Connection pending...\n"); - } - else - { - LogStatus("Connection failure...\n"); - ++ mNbConnectionsFailures; - mLastConnectionSuccess = false; - } - } - else // nbConnectionsPending == 0 - { - if (mLastConnectionSuccess) - { - if (!NetImgui::IsConnected()) - { - if (remoteParams().exitWhenServerDisconnected) - { - LogStatus("Connection lost... Exiting\n"); - runnerParams().appShallExit = true; - } - else - { - mTimePointConnectionEnded = HelloImGui::Internal::ClockSeconds(); - LogStatus("Connection lost... Reconnecting\n"); - InitiateConnection(); - } - } - } - else // Last connection was a failure - { - LogStatus("Last connection was a failure... Reconnecting\n"); - InitiateConnection(); - } - } - - // Exit if failure since too long - { - bool isDisconnected = !mLastConnectionSuccess; - if (isDisconnected) - { - double disconnectionTime = HelloImGui::Internal::ClockSeconds() - mTimePointConnectionEnded; - std::string msg = "Disconnected since " + std::to_string(disconnectionTime) + "s"; - LogStatus(msg); - bool isTooLong = disconnectionTime > remoteParams().durationMaxDisconnected; - if (isTooLong) - { - LogStatus("Too long disconnected... Exiting\n"); - runnerParams().appShallExit = true; - } - } - } - } - - void sendFonts() - { - _sendFonts_Impl(); - } - - bool isConnected() - { - return NetImgui::IsConnected(); - } - -private: - void InitiateConnection() - { - NetimguiLog("NetImGuiWrapper: InitiateConnection\n"); - mNetImguiRaii.release(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - mNetImguiRaii = std::make_unique(); - NetImgui::ConnectToApp(clientName().c_str(), remoteParams().serverHost.c_str(), remoteParams().serverPort); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ++ mNbConnectionsTentatives; - _sendFonts_Impl(); - } - - std::string clientName() - { - std::string clientName = runnerParams().appWindowParams.windowTitle; - if (clientName.empty()) - clientName = "HelloImGui"; - clientName += "##" + std::to_string(ImGui::GetTime()); - return clientName; - } - - HelloImGui::RemoteParams& remoteParams() { return HelloImGui::GetRunnerParams()->remoteParams; } - HelloImGui::RunnerParams& runnerParams() { return *HelloImGui::GetRunnerParams(); } - - void _sendFonts_Impl() - { - const ImFontAtlas* pFonts = ImGui::GetIO().Fonts; - if( pFonts->TexPixelsAlpha8) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) - { - uint8_t* pPixelData(nullptr); int width(0), height(0); - ImGui::GetIO().Fonts->GetTexDataAsAlpha8(&pPixelData, &width, &height); - NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtA8); - } - if( pFonts->TexPixelsRGBA32) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) - { - uint8_t* pPixelData(nullptr); int width(0), height(0); - ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pPixelData, &width, &height); - NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtRGBA8); - } - } - - void LogStatus(const std::string& msg) - { - NetimguiLog("NetImGuiWrapper: %s\n", msg.c_str()); - } - -private: // Members - std::unique_ptr mNetImguiRaii; - int mNbConnectionsTentatives = 0; - int mNbConnectionsSuccess = 0; - int mNbConnectionsFailures = 0; - bool mLastConnectionSuccess = false; - double mTimePointConnectionEnded = 0.0; -}; - -std::unique_ptr gNetImGuiWrapper; -bool gWaitingForRemoteDpiInfo = false; -#endif - -bool _isConnectedToRemoteServer() -{ -#ifdef HELLOIMGUI_WITH_NETIMGUI - if (!_isDisplayingOnRemoteServer()) - return false; - return gNetImGuiWrapper->isConnected(); -#else - return false; -#endif -} -// ===================================================================================================================== -// -// ===================================================================================================================== +bool ShouldDisplayOnRemoteServer(); AbstractRunner::AbstractRunner(RunnerParams ¶ms_) - : params(params_) {} +: params(params_) {} #ifndef USEHACK @@ -496,7 +311,7 @@ void _LogDpiParams(const std::string& origin, const HelloImGui::DpiAwareParams& } -bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) +bool AbstractRunner::CheckDpiAwareParamsChanges() { auto& dpiAwareParams = params.dpiAwareParams; auto& io = ImGui::GetIO(); @@ -509,29 +324,7 @@ bool _CheckDpiAwareParamsChanges(HelloImGui::RunnerParams& params) dpiAwareParams.fontRenderingScale = io.FontGlobalScale; } - bool didFontLoadingRatioChangeOnRemoteServer = false; -#ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) - { - float newFontLoadingRatio = NetImgui::GetFontSizeLoadingRatio(); - float currentFontLoadingRatio = dpiAwareParams.DpiFontLoadingFactor(); - if (fabs(currentFontLoadingRatio - newFontLoadingRatio) > 0.001f) - { - didFontLoadingRatioChangeOnRemoteServer = true; - - float oldDpiWindowSizeFactor = dpiAwareParams.dpiWindowSizeFactor; - float ratioScaling = newFontLoadingRatio / currentFontLoadingRatio; - dpiAwareParams.dpiWindowSizeFactor = dpiAwareParams.dpiWindowSizeFactor * ratioScaling; - ImGui::GetStyle().ScaleAllSizes(ratioScaling); - float new_diff = fabs(dpiAwareParams.DpiFontLoadingFactor() - newFontLoadingRatio); - IM_ASSERT(new_diff < 0.001f); - DpiLog("Warning: didFontLoadingRatioChange=true \n" - " currentFontLoadingRatio=%f newFontLoadingRatio=%f\n" - " oldDpiWindowSizeFactor=%f newDpiWindowSizeFactor=%f\n", - currentFontLoadingRatio, newFontLoadingRatio, oldDpiWindowSizeFactor, dpiAwareParams.dpiWindowSizeFactor); - } - } -#endif + bool didFontLoadingRatioChangeOnRemoteServer = mRemoteDisplayHandler.CheckDpiAwareParamsChanges(); if (didFontGlobalScaleChange || didFontLoadingRatioChangeOnRemoteServer) { @@ -641,7 +434,7 @@ void AbstractRunner::HandleDpiOnSecondFrame() #endif // High DPI handling on windows & linux - if (!_isDisplayingOnRemoteServer()) + if (!ShouldDisplayOnRemoteServer()) { float dpiScale = params.dpiAwareParams.dpiWindowSizeFactor; if ( dpiScale > 1.f) @@ -961,13 +754,9 @@ void AbstractRunner::Setup() } params.callbacks.SetupImGuiStyle(); -#ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) - { - gNetImGuiWrapper = std::make_unique(); - gNetImGuiWrapper->sendFonts(); - } -#endif + // Create a remote display handler if needed + mRemoteDisplayHandler.Create(); + mRemoteDisplayHandler.SendFonts(); } @@ -1065,14 +854,10 @@ void AbstractRunner::CreateFramesAndRender() // (it is here only to make the code more readable, and to enable to collapse blocks of code) constexpr bool foldable_region = true; -#ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) // Hande NetImGui connection - { - gNetImGuiWrapper->HeartBeat(); - } -#endif + // Will display on remote server if needed + mRemoteDisplayHandler.Heartbeat(); - if (_CheckDpiAwareParamsChanges(params)) // Reload fonts if DPI scale changed + if (CheckDpiAwareParamsChanges()) // Reload fonts if DPI scale changed { if (_reloadAllDpiResponsiveFonts()) { @@ -1080,13 +865,8 @@ void AbstractRunner::CreateFramesAndRender() // cf https://github.com/ocornut/imgui/issues/6547: we need to recreate the rendering backend device objects mRenderingBackendCallbacks->Impl_DestroyFontTexture(); mRenderingBackendCallbacks->Impl_CreateFontTexture(); - #ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) - { - gNetImGuiWrapper = std::make_unique(); - gNetImGuiWrapper->sendFonts(); - } - #endif + + mRemoteDisplayHandler.SendFonts(); } } @@ -1185,23 +965,12 @@ void AbstractRunner::CreateFramesAndRender() } } - // Transmit window size to remote server - #ifdef HELLOIMGUI_WITH_NETIMGUI - if (_isConnectedToRemoteServer() && (mIdxFrame > 3) && params.remoteParams.transmitWindowSize) + // Transmit window size to remote server (if needed) + if ((mIdxFrame > 3) && params.remoteParams.transmitWindowSize) { - static bool wasSizeTransmitted = false; - if (!wasSizeTransmitted) - { - wasSizeTransmitted = true; - auto windowSize = params.appWindowParams.windowGeometry.size; - // When running on a remote server, we do not know the window DPI factor, - // so we treat the window size as if it was 96PPI - uint16_t width_96PPI = (uint16_t)windowSize[0]; - uint16_t height_96PPI = (uint16_t)windowSize[1]; - NetImgui::SetWindowSize_96PPI(width_96PPI, height_96PPI); - } + auto windowSize = params.appWindowParams.windowGeometry.size; + mRemoteDisplayHandler.TransmitWindowSizeToDisplay(windowSize); } - #endif } // SCOPED_RELEASE_GIL_ON_MAIN_THREAD end if(foldable_region) // Handle idling @@ -1245,13 +1014,8 @@ void AbstractRunner::CreateFramesAndRender() mRenderingBackendCallbacks->Impl_DestroyFontTexture(); mRenderingBackendCallbacks->Impl_CreateFontTexture(); params.callbacks.LoadAdditionalFonts = nullptr; - #ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) - { - gNetImGuiWrapper = std::make_unique(); - gNetImGuiWrapper->sendFonts(); - } - #endif + + mRemoteDisplayHandler.SendFonts(); } } @@ -1354,7 +1118,7 @@ void AbstractRunner::IdleBySleeping() return; #endif - if (_isDisplayingOnRemoteServer()) + if (ShouldDisplayOnRemoteServer()) { // if displaying remote, the FPS is limited on the server to a value between 30 and 60 fps // We cannot idle too slow, other the GUI becomes really sluggish @@ -1492,13 +1256,7 @@ void AbstractRunner::TearDown(bool gotException) TestEngineCallbacks::TearDown_ImGuiContextDestroyed(); #endif -#ifdef HELLOIMGUI_WITH_NETIMGUI - if (params.remoteParams.enableRemoting) - { - IM_ASSERT(gNetImGuiWrapper != nullptr); - gNetImGuiWrapper.release(); - } -#endif + mRemoteDisplayHandler.Shutdown(); } @@ -1511,4 +1269,11 @@ std::string AbstractRunner::LoadUserPref(const std::string& userPrefName) return HelloImGuiIniSettings::LoadUserPref(IniSettingsLocation(params), userPrefName); } +bool AbstractRunner::ShouldDisplayOnRemoteServer() +{ + return mRemoteDisplayHandler.ShouldDisplayOnRemoteServer(); +} + + + } // namespace HelloImGui diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.h b/src/hello_imgui/internal/backend_impls/abstract_runner.h index a76459e9..01f7d874 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.h +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.h @@ -4,6 +4,7 @@ #include "hello_imgui/internal/backend_impls/backend_window_helper/backend_window_helper.h" #include "hello_imgui/internal/backend_impls/backend_window_helper/window_geometry_helper.h" #include "hello_imgui/internal/backend_impls/rendering_callbacks.h" +#include "hello_imgui/internal/backend_impls/remote_display_handler.h" #include "hello_imgui/runner_params.h" #include @@ -40,6 +41,8 @@ class AbstractRunner void ChangeWindowSize(ScreenSize windowSize); void LayoutSettings_SwitchLayout(const std::string& layoutName); + bool ShouldDisplayOnRemoteServer(); + void SaveUserPref(const std::string& userPrefName, const std::string& userPrefContent); std::string LoadUserPref(const std::string& userPrefName); @@ -84,6 +87,7 @@ class AbstractRunner void InitRenderBackendCallbacks(); void SetupDpiAwareParams(); + bool CheckDpiAwareParamsChanges(); void PrepareWindowGeometry(); void HandleDpiOnSecondFrame(); void MakeWindowSizeRelativeTo96Ppi_IfRequired(); @@ -111,6 +115,8 @@ class AbstractRunner // Callbacks related to the rendering backend (OpenGL, ...) RenderingCallbacksPtr mRenderingBackendCallbacks; + + RemoteDisplayHandler mRemoteDisplayHandler; }; diff --git a/src/hello_imgui/internal/backend_impls/remote_display_handler.cpp b/src/hello_imgui/internal/backend_impls/remote_display_handler.cpp new file mode 100644 index 00000000..8f5f8d47 --- /dev/null +++ b/src/hello_imgui/internal/backend_impls/remote_display_handler.cpp @@ -0,0 +1,305 @@ +#ifdef HELLOIMGUI_WITH_NETIMGUI +#include "NetImgui_Api.h" +#endif + +#include "hello_imgui/internal/backend_impls/remote_display_handler.h" +#include "hello_imgui/hello_imgui.h" +#include "hello_imgui/internal/poor_man_log.h" +#include "hello_imgui/internal/clock_seconds.h" + +#include +#include + +#define ENABLE_NETIMGUI_LOG // Enable or disable logging for NetImgui remoting +#ifdef ENABLE_NETIMGUI_LOG +#define NetimguiLog PoorManLog +#else +#define NetimguiLog(...) +#endif + + +namespace HelloImGui +{ +#ifdef HELLOIMGUI_WITH_NETIMGUI + namespace NetimguiUtils + { + // ===================================================================================================================== + // + // ===================================================================================================================== + struct NetImGuiRaii { + NetImGuiRaii() { NetImgui::Startup(); } + ~NetImGuiRaii() { NetImgui::Shutdown(); } + }; + + + class NetImGuiWrapper + { + public: + NetImGuiWrapper() = default; + ~NetImGuiWrapper() = default; + + void HeartBeat() + { + if (mNetImguiRaii == nullptr) + { + InitiateConnection(); + return; + } + + int nbConnectionsPending = mNbConnectionsTentatives - mNbConnectionsSuccess - mNbConnectionsFailures; + IM_ASSERT(nbConnectionsPending == 0 || nbConnectionsPending == 1); + + if (nbConnectionsPending == 1) + { + if (NetImgui::IsConnected()) + { + LogStatus("Connection success...\n"); + ++ mNbConnectionsSuccess; + mLastConnectionSuccess = true; + } + else if (NetImgui::IsConnectionPending()) + { + LogStatus("Connection pending...\n"); + } + else + { + LogStatus("Connection failure...\n"); + ++ mNbConnectionsFailures; + mLastConnectionSuccess = false; + } + } + else // nbConnectionsPending == 0 + { + if (mLastConnectionSuccess) + { + if (!NetImgui::IsConnected()) + { + if (remoteParams().exitWhenServerDisconnected) + { + LogStatus("Connection lost... Exiting\n"); + runnerParams().appShallExit = true; + } + else + { + mTimePointConnectionEnded = HelloImGui::Internal::ClockSeconds(); + LogStatus("Connection lost... Reconnecting\n"); + InitiateConnection(); + } + } + } + else // Last connection was a failure + { + LogStatus("Last connection was a failure... Reconnecting\n"); + InitiateConnection(); + } + } + + // Exit if failure since too long + { + bool isDisconnected = !mLastConnectionSuccess; + if (isDisconnected) + { + double disconnectionTime = HelloImGui::Internal::ClockSeconds() - mTimePointConnectionEnded; + std::string msg = "Disconnected since " + std::to_string(disconnectionTime) + "s"; + LogStatus(msg); + bool isTooLong = disconnectionTime > remoteParams().durationMaxDisconnected; + if (isTooLong) + { + LogStatus("Too long disconnected... Exiting\n"); + runnerParams().appShallExit = true; + } + } + } + } + + void sendFonts() + { + _sendFonts_Impl(); + } + + bool isConnected() + { + return NetImgui::IsConnected(); + } + + private: + void InitiateConnection() + { + NetimguiLog("NetImGuiWrapper: InitiateConnection\n"); + mNetImguiRaii.release(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + mNetImguiRaii = std::make_unique(); + NetImgui::ConnectToApp(clientName().c_str(), remoteParams().serverHost.c_str(), remoteParams().serverPort); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + ++ mNbConnectionsTentatives; + _sendFonts_Impl(); + } + + std::string clientName() + { + std::string clientName = runnerParams().appWindowParams.windowTitle; + if (clientName.empty()) + clientName = "HelloImGui"; + clientName += "##" + std::to_string(ImGui::GetTime()); + return clientName; + } + + HelloImGui::RemoteParams& remoteParams() { return HelloImGui::GetRunnerParams()->remoteParams; } + HelloImGui::RunnerParams& runnerParams() { return *HelloImGui::GetRunnerParams(); } + + void _sendFonts_Impl() + { + const ImFontAtlas* pFonts = ImGui::GetIO().Fonts; + if( pFonts->TexPixelsAlpha8) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) + { + uint8_t* pPixelData(nullptr); int width(0), height(0); + ImGui::GetIO().Fonts->GetTexDataAsAlpha8(&pPixelData, &width, &height); + NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtA8); + } + if( pFonts->TexPixelsRGBA32) // && (pFonts->TexPixelsAlpha8 != client.mpFontTextureData || client.mFontTextureID != pFonts->TexID )) + { + uint8_t* pPixelData(nullptr); int width(0), height(0); + ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pPixelData, &width, &height); + NetImgui::SendDataTexture(pFonts->TexID, pPixelData, static_cast(width), static_cast(height), NetImgui::eTexFormat::kTexFmtRGBA8); + } + } + + void LogStatus(const std::string& msg) + { + NetimguiLog("NetImGuiWrapper: %s\n", msg.c_str()); + } + + private: // Members + std::unique_ptr mNetImguiRaii; + int mNbConnectionsTentatives = 0; + int mNbConnectionsSuccess = 0; + int mNbConnectionsFailures = 0; + bool mLastConnectionSuccess = false; + double mTimePointConnectionEnded = 0.0; + }; + + std::unique_ptr gNetImGuiWrapper; + + + bool UpdateDpiAwareParams_Netimgui() + { + bool didFontLoadingRatioChangeOnRemoteServer = false; + auto& dpiAwareParams = HelloImGui::GetRunnerParams()->dpiAwareParams; + + float newFontLoadingRatio = NetImgui::GetFontSizeLoadingRatio(); + float currentFontLoadingRatio = dpiAwareParams.DpiFontLoadingFactor(); + if (fabs(currentFontLoadingRatio - newFontLoadingRatio) > 0.001f) + { + didFontLoadingRatioChangeOnRemoteServer = true; + + float oldDpiWindowSizeFactor = dpiAwareParams.dpiWindowSizeFactor; + float ratioScaling = newFontLoadingRatio / currentFontLoadingRatio; + dpiAwareParams.dpiWindowSizeFactor = dpiAwareParams.dpiWindowSizeFactor * ratioScaling; + ImGui::GetStyle().ScaleAllSizes(ratioScaling); + float new_diff = fabs(dpiAwareParams.DpiFontLoadingFactor() - newFontLoadingRatio); + IM_ASSERT(new_diff < 0.001f); + NetimguiLog("UpdateDpiAwareParams_Netimgui: didFontLoadingRatioChange=true \n" + " currentFontLoadingRatio=%f newFontLoadingRatio=%f\n" + " oldDpiWindowSizeFactor=%f newDpiWindowSizeFactor=%f\n", + currentFontLoadingRatio, newFontLoadingRatio, oldDpiWindowSizeFactor, dpiAwareParams.dpiWindowSizeFactor); + } + return didFontLoadingRatioChangeOnRemoteServer; + } + + // ===================================================================================================================== + // + // ===================================================================================================================== + } // namespace NetimguiUtils +#endif + + +bool RemoteDisplayHandler::IsConnectedToServer() +{ + #ifndef HELLOIMGUI_WITH_NETIMGUI + return false; + #else + if (!ShouldDisplayOnRemoteServer()) + return false; + return NetimguiUtils::gNetImGuiWrapper->isConnected(); + #endif +} + +bool RemoteDisplayHandler::ShouldDisplayOnRemoteServer() +{ + #ifdef HELLOIMGUI_WITH_NETIMGUI + return HelloImGui::GetRunnerParams()->remoteParams.enableRemoting; + #else + return false; + #endif +} + +bool RemoteDisplayHandler::CheckDpiAwareParamsChanges() +{ + if (!IsConnectedToServer()) + return false; + #ifdef HELLOIMGUI_WITH_NETIMGUI + return NetimguiUtils::UpdateDpiAwareParams_Netimgui(); + #else + return false; + #endif +} + +void RemoteDisplayHandler::Create() +{ + if (!ShouldDisplayOnRemoteServer()) + return; + IM_ASSERT(!IsConnectedToServer() && "RemoteDisplayHandler::Create: Already connected to server"); + #ifdef HELLOIMGUI_WITH_NETIMGUI + NetimguiUtils::gNetImGuiWrapper = std::make_unique(); + #endif +} + +void RemoteDisplayHandler::Shutdown() +{ + if (!IsConnectedToServer()) + return; + #ifdef HELLOIMGUI_WITH_NETIMGUI + NetimguiUtils::gNetImGuiWrapper.reset(); + #endif +} + +void RemoteDisplayHandler::Heartbeat() +{ + if (!ShouldDisplayOnRemoteServer()) + return; + #ifdef HELLOIMGUI_WITH_NETIMGUI + NetimguiUtils::gNetImGuiWrapper->HeartBeat(); + #endif +} + +void RemoteDisplayHandler::TransmitWindowSizeToDisplay(ScreenSize windowSize) +{ + if (IsConnectedToServer()) + { + static bool wasSizeTransmitted = false; + if (!wasSizeTransmitted) + { + wasSizeTransmitted = true; + // When running on a remote server, we do not know the window DPI factor, + // so we treat the window size as if it was 96PPI + uint16_t width_96PPI = (uint16_t)windowSize[0]; + uint16_t height_96PPI = (uint16_t)windowSize[1]; + #ifdef HELLOIMGUI_WITH_NETIMGUI + NetImgui::SetWindowSize_96PPI(width_96PPI, height_96PPI); + #endif + } + } +} + +void RemoteDisplayHandler::SendFonts() +{ + if (ShouldDisplayOnRemoteServer()) + { + #ifdef HELLOIMGUI_WITH_NETIMGUI + NetimguiUtils::gNetImGuiWrapper = std::make_unique(); + NetimguiUtils::gNetImGuiWrapper->sendFonts(); + #endif + } +} + +} \ No newline at end of file diff --git a/src/hello_imgui/internal/backend_impls/remote_display_handler.h b/src/hello_imgui/internal/backend_impls/remote_display_handler.h new file mode 100644 index 00000000..56c65423 --- /dev/null +++ b/src/hello_imgui/internal/backend_impls/remote_display_handler.h @@ -0,0 +1,41 @@ +#pragma once +#include "hello_imgui/screen_bounds.h" + +namespace HelloImGui +{ + class RemoteDisplayHandler + { + public: + // Will initialize the remote display handler + // (do nothing if no remote display is configured/compiled) + void Create(); + + // Will shut down the remote display handler + // (do nothing if no remote display is configured/compiled) + void Shutdown(); + + // Will update the remote display handler + // (do nothing if no remote display is configured/compiled) + void Heartbeat(); + + // Will send the window size to the remote display + // (do nothing if no remote display is configured/compiled) + void TransmitWindowSizeToDisplay(ScreenSize windowSize); + + // Will send the fonts to the remote display + // (do nothing if no remote display is configured/compiled) + void SendFonts(); + + // Returns true if the application should display on a remote server + // (return false if no remote display is configured/compiled) + bool ShouldDisplayOnRemoteServer(); + + // Returns true if the application is connected to a remote server + // (return false if no remote display is configured/compiled) + bool IsConnectedToServer(); + + // May update GetRunnerParams()->dpiAwareParams by interrogating the remote display + // (return false if no remote display is configured/compiled) + bool CheckDpiAwareParamsChanges(); + }; +} \ No newline at end of file diff --git a/src/hello_imgui/internal/docking_details.cpp b/src/hello_imgui/internal/docking_details.cpp index b630cbd9..218cda9d 100644 --- a/src/hello_imgui/internal/docking_details.cpp +++ b/src/hello_imgui/internal/docking_details.cpp @@ -14,7 +14,7 @@ namespace HelloImGui { // From hello_imgui.cpp -bool _isDisplayingOnRemoteServer(); +bool ShouldDisplayOnRemoteServer(); void _Themes_MenuGui(RunnerParams& runnerParams); // see hello_imgui_themes.cpp @@ -180,7 +180,7 @@ void MenuView_Misc(RunnerParams& runnerParams) if (ImGui::MenuItem("FPS in status bar##xxxx", nullptr, runnerParams.imGuiWindowParams.showStatus_Fps)) runnerParams.imGuiWindowParams.showStatus_Fps = ! runnerParams.imGuiWindowParams.showStatus_Fps; - if (! _isDisplayingOnRemoteServer()) + if (! ShouldDisplayOnRemoteServer()) ImGui::MenuItem("Enable Idling", nullptr, &runnerParams.fpsIdling.enableIdling); ImGui::EndMenu(); } diff --git a/src/hello_imgui/internal/menu_statusbar.cpp b/src/hello_imgui/internal/menu_statusbar.cpp index 198d3176..9d36144b 100644 --- a/src/hello_imgui/internal/menu_statusbar.cpp +++ b/src/hello_imgui/internal/menu_statusbar.cpp @@ -11,7 +11,7 @@ namespace HelloImGui { -bool _isDisplayingOnRemoteServer(); // from hello_imgui.cpp +bool ShouldDisplayOnRemoteServer(); // from hello_imgui.cpp namespace Menu_StatusBar { @@ -99,7 +99,7 @@ void ShowStatusBar(RunnerParams & params) if (params.imGuiWindowParams.showStatus_Fps) { - if (_isDisplayingOnRemoteServer()) + if (ShouldDisplayOnRemoteServer()) { ImGui::SameLine(ImGui::GetIO().DisplaySize.x - 5.f * ImGui::GetFontSize()); ImGui::Text("FPS: %.1f", HelloImGui::FrameRate()); From 83f3ae8b3b757516ef0e5f4453d32f1ca3a83660 Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 18 Apr 2024 15:55:23 +0200 Subject: [PATCH 54/57] Remove submodule netImgui --- .gitmodules | 3 --- external/.gitignore | 1 + external/netImgui | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) delete mode 160000 external/netImgui diff --git a/.gitmodules b/.gitmodules index 1733de0e..55bacb4e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,6 +7,3 @@ [submodule "_example_integration"] path = _example_integration url = https://github.com/pthom/hello_imgui_template.git -[submodule "external/netImgui"] - path = external/netImgui - url = https://github.com/pthom/netImgui.git diff --git a/external/.gitignore b/external/.gitignore index fea25349..972ae40c 100644 --- a/external/.gitignore +++ b/external/.gitignore @@ -1,3 +1,4 @@ SDL SDL2-*/ qtimgui/ +netImgui/ diff --git a/external/netImgui b/external/netImgui deleted file mode 160000 index 0178485a..00000000 --- a/external/netImgui +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0178485ae8253f17f4595659bbdfe859c4e9f991 From f3c877128d23664586318b15b248170fc540f90f Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 18 Apr 2024 15:55:30 +0200 Subject: [PATCH 55/57] doc --- src/hello_imgui/doc_api.md | 24 +++++++++++++++--------- src/hello_imgui/doc_params.md | 10 +++++++--- src/hello_imgui/hello_imgui_font.h | 18 +++++++++--------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/hello_imgui/doc_api.md b/src/hello_imgui/doc_api.md index b8d30682..75b4470f 100644 --- a/src/hello_imgui/doc_api.md +++ b/src/hello_imgui/doc_api.md @@ -109,15 +109,17 @@ See [hello_imgui_font.h](https://github.com/pthom/hello_imgui/blob/master/src/he ImFontConfig fontConfigFontAwesome = ImFontConfig(); }; - // A font that will be automatically resized to account for changes in DPI - // (use LoadAdaptiveFont instead of LoadFont to get this behavior) - struct FontDpiResponsive - { - ImFont* font = nullptr; - std::string fontFilename; - float fontSize = 0.f; - FontLoadingParams fontLoadingParams; - }; + // A font that will be automatically resized to account for changes in DPI + // Use LoadAdaptiveFont instead of LoadFont to get this behavior. + // Fonts loaded with LoadAdaptiveFont will be reloaded during execution + // if ImGui::GetIO().FontGlobalScale is changed. + struct FontDpiResponsive + { + ImFont* font = nullptr; + std::string fontFilename; + float fontSize = 0.f; + FontLoadingParams fontLoadingParams; + }; // Loads a font with the specified parameters @@ -290,6 +292,10 @@ ImGuiTestEngine* GetImGuiTestEngine(); // "Sdl - Vulkan" std::string GetBackendDescription(); +// `ChangeWindowSize(const ScreenSize &windowSize)`: sets the window size +// (useful if you want to change the window size during execution) +void ChangeWindowSize(const ScreenSize &windowSize); + ``` ---- diff --git a/src/hello_imgui/doc_params.md b/src/hello_imgui/doc_params.md index 1051a161..d93376ff 100644 --- a/src/hello_imgui/doc_params.md +++ b/src/hello_imgui/doc_params.md @@ -70,6 +70,8 @@ struct SimpleRunnerParams // `windowSize`: _ScreenSize, default={800, 600}_. // Size of the window + // The size will be handled as if it was specified for a 96PPI screen + // (i.e. a given size will correspond to the same physical size on different screens, whatever their DPI) ScreenSize windowSize = DefaultWindowSize; // `fpsIdle`: _float, default=9_. @@ -151,9 +153,6 @@ struct RunnerParams // Only useful when multiple rendering backend are compiled and available. RendererBackendType rendererBackendType = RendererBackendType::FirstAvailable; - // --------------- RemoteParams ------------------- - RemoteParams remoteParams; - // --------------- Settings ------------------- @@ -217,6 +216,9 @@ struct RunnerParams // Set the application refresh rate // (only used on emscripten: 0 stands for "let the app or the browser decide") int emscripten_fps = 0; + + // Parameters for Remote display (experimental, unsupported) + RemoteParams remoteParams; }; ``` @@ -605,6 +607,8 @@ struct WindowGeometry // Size of the application window // used if fullScreenMode==NoFullScreen and sizeAuto==false. Default=(800, 600) + // The size will be handled as if it was specified for a 96PPI screen + // (i.e. a given size will correspond to the same physical size on different screens, whatever their DPI) ScreenSize size = DefaultWindowSize; // If sizeAuto=true, adapt the app window size to the presented widgets. diff --git a/src/hello_imgui/hello_imgui_font.h b/src/hello_imgui/hello_imgui_font.h index c43da301..c4c751e5 100644 --- a/src/hello_imgui/hello_imgui_font.h +++ b/src/hello_imgui/hello_imgui_font.h @@ -61,17 +61,17 @@ namespace HelloImGui ImFontConfig fontConfigFontAwesome = ImFontConfig(); }; - // A font that will be automatically resized to account for changes in DPI - // Use LoadAdaptiveFont instead of LoadFont to get this behavior. + // A font that will be automatically resized to account for changes in DPI + // Use LoadAdaptiveFont instead of LoadFont to get this behavior. // Fonts loaded with LoadAdaptiveFont will be reloaded during execution // if ImGui::GetIO().FontGlobalScale is changed. - struct FontDpiResponsive - { - ImFont* font = nullptr; - std::string fontFilename; - float fontSize = 0.f; - FontLoadingParams fontLoadingParams; - }; + struct FontDpiResponsive + { + ImFont* font = nullptr; + std::string fontFilename; + float fontSize = 0.f; + FontLoadingParams fontLoadingParams; + }; // Loads a font with the specified parameters From 1fea449e88300fccc70db15534b2aec0fd61edfb Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 18 Apr 2024 16:02:33 +0200 Subject: [PATCH 56/57] No ENABLE_DPI_LOG --- src/hello_imgui/internal/backend_impls/abstract_runner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index dcb584c3..10820389 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -64,7 +64,7 @@ //#define ENABLE_DPI_LOG // Enable or disable logging for DPI info -#define ENABLE_DPI_LOG +//#define ENABLE_DPI_LOG #ifdef ENABLE_DPI_LOG #define DpiLog PoorManLog From 9715db096c2e8e47da92b653e6308a98604476ce Mon Sep 17 00:00:00 2001 From: Pascal Thomet Date: Thu, 18 Apr 2024 16:08:50 +0200 Subject: [PATCH 57/57] disable remoting on demodocking --- .../hello_imgui_demodocking/hello_imgui_demodocking.main.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp index dc582eb0..2de557b1 100644 --- a/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp +++ b/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp @@ -793,9 +793,6 @@ int main(int, char**) //runnerParams.platformBackendType = HelloImGui::PlatformBackendType::Sdl; //runnerParams.rendererBackendType = HelloImGui::RendererBackendType::Vulkan; - runnerParams.remoteParams.enableRemoting = true; - runnerParams.remoteParams.transmitWindowSize = true; - HelloImGui::Run(runnerParams); // Note: with ImGuiBundle, it is also possible to use ImmApp::Run(...) return 0;