Skip to content

Commit

Permalink
Merge branch 'netimgui_merge'
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Apr 18, 2024
2 parents d375506 + 9715db0 commit 382289e
Show file tree
Hide file tree
Showing 45 changed files with 1,476 additions and 234 deletions.
7 changes: 6 additions & 1 deletion CMakeLists.txt
Expand Up @@ -95,7 +95,6 @@ option(HELLOIMGUI_HAS_NULL "Null rendering backend" OFF) # for testing and remo
option(HELLOIMGUI_NULL_BACKEND "Use Null rendering/platform backend" OFF)
# </Backends> # do not remove this line (used by the script that generates the documentation)


#------------------------------------------------------------------------------
# Options / Freetype
#------------------------------------------------------------------------------
Expand Down Expand Up @@ -297,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
Expand Down
7 changes: 0 additions & 7 deletions CMakePresets.json
Expand Up @@ -32,13 +32,6 @@
"HELLOIMGUI_HAS_NULL": "ON"
}
},
{
"name": "build_null_backend",
"description": "Build with null backend.",
"cacheVariables": {
"HELLOIMGUI_NULL_BACKEND": "ON"
}
},
{
"name": "build_vcpkg_default",
"description": "Build with vcpkg default settings (opengl3 + sdl and glfw). You need to create a build directory and run from it",
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion docs_src/_toc.yml
Expand Up @@ -6,7 +6,7 @@ root: intro

chapters:
- file: get_started
- file: doc_api
- file: doc_params
- file: doc_api
- file: build

1 change: 1 addition & 0 deletions docs_src/process_md_docs.py
1 change: 1 addition & 0 deletions external/.gitignore
@@ -1,3 +1,4 @@
SDL
SDL2-*/
qtimgui/
netImgui/
46 changes: 44 additions & 2 deletions hello_imgui_cmake/hello_imgui_build_lib.cmake
Expand Up @@ -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
###################################################################################################
Expand Down Expand Up @@ -1079,12 +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}
Platform Backend(s): ${active_platform_backends}
Rendering Backend(s): ${active_rendering_backends}
---------------------------------------------------------------------------
Options:
HELLOIMGUI_USE_FREETYPE: ${HELLOIMGUI_USE_FREETYPE} (${HELLOIMGUI_FREETYPE_SELECTED_INFO})
Expand Down Expand Up @@ -1185,6 +1223,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()
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Expand Up @@ -6,3 +6,4 @@ endif()
if(HELLOIMGUI_BUILD_TESTS)
add_subdirectory(hello_imgui_tests)
endif()
add_subdirectory(hello_imgui_remote)
2 changes: 2 additions & 0 deletions src/hello_imgui/app_window_params.h
Expand Up @@ -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.
Expand Down
152 changes: 120 additions & 32 deletions src/hello_imgui/doc_api.md
Expand Up @@ -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
Expand Down Expand Up @@ -101,14 +109,32 @@ 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.
// 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
// (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 = {});
```

Expand Down Expand Up @@ -266,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);
```

----
Expand Down Expand Up @@ -408,42 +438,100 @@ 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_
## 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:
- 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.
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
## How to load fonts with the correct size
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.
### Using HelloImGui (recommended)
[`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.
## Dpi aware Font scaling
### Using Dear ImGui
`ImGui::GetIO().Fonts->AddFontFromFileTTF()` loads a font with a given size, in *physical pixels*.
`HelloImGui::LoadFont()` will load fonts with the correct size, taking into account the DPI scaling.
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.
If you prefer to use `ImGui::GetIO().Fonts->AddFontFromFileTTF()`, there are two things to know:
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.
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)
## Reproducible physical window sizes (in mm or inches)
`HelloImGui::ImGuiDefaultFontGlobalScale()` returns the default value that should be stored inside `ImGui::GetIO().FontGlobalScale`.
### 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.
2. You should adjust the font size when loading a font:
To get a similar window size on different OSes/DPI, you should multiply the window size by `HelloImGui::DpiWindowSizeFactor()`.
`HelloImGui::DpiFontLoadingFactor()` returns a factor by which you shall multiply your font sizes when loading them.
Note: DpiWindowSizeFactor() is equal to `CurrentScreenPixelPerInch / 96` under windows and linux, and always 1 under macOS.
`HelloImGui::DpiFontLoadingFactor()` corresponds to:
`DpiWindowSizeFactor() * 1.f / ImGui::GetIO().FontGlobalScale`
## Fine tune DPI Handling
where DpiWindowSizeFactor() is equal to `CurrentScreenPixelPerInch / 96`
under windows and linux, 1 under macOS
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.
40 changes: 1 addition & 39 deletions src/hello_imgui/doc_api.src.md
Expand Up @@ -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}

0 comments on commit 382289e

Please sign in to comment.