diff --git a/hello_imgui_example.ini b/hello_imgui_example.ini index 28f653a8..c8fdcd7d 100644 --- a/hello_imgui_example.ini +++ b/hello_imgui_example.ini @@ -47,12 +47,17 @@ ; UseCoreProfile = true ; UseForwardCompat = false -; `AntiAliasingSamples` -; If not zero, this value will be used to reduce the number of samples used for anti-aliasing. -; This is used only when running with Glfw + OpenGL (which is the default) -; Notes: -; - by default, we query the maximum number of samples supported by the hardwareand we use this value -; - if you set this value to a non-zero value, it will be used instead of the maximum value -; (except if it is greater than the maximum value, in which case a warning will be issued) -; (it will be via `glfwWindowHint(GLFW_SAMPLES, AntiAliasingSamples);`) -; AntiAliasingSamples=16 +; `AntiAliasingSamples` +; If > 0, this value will be used to set the number of samples used for anti-aliasing. +; This is used only when running with Glfw + OpenGL (which is the default) +; Notes: +; - we query the maximum number of samples supported by the hardware, via glGetIntegerv(GL_MAX_SAMPLES) +; - if you set this value to a non-zero value, it will be used instead of the default value of 8 +; (except if it is greater than the maximum supported value, in which case a warning will be issued) +; - if you set this value to 0, anti-aliasing will be disabled +; +; AntiAliasingSamples has a strong impact on the quality of the text rendering +; - 0: no anti-aliasing +; - 8: optimal +; - 16: optimal if using imgui-node-editor and you want to render very small text when unzooming +;AntiAliasingSamples=8 diff --git a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp index fb5f413d..18970c0c 100644 --- a/src/hello_imgui/internal/backend_impls/abstract_runner.cpp +++ b/src/hello_imgui/internal/backend_impls/abstract_runner.cpp @@ -253,18 +253,8 @@ void AbstractRunner::ReadOpenGlOptions() // you may set them manually: // (1) Either by setting them programmatically in your application // (set their values in `runnerParams.rendererBackendOptions.openGlOptions`) - // (2) Either by setting them in a `hello_imgui.ini` file in the current folder, or any of its parent folders. - // (this is useful when you want to set them for a specific app or set of apps, without modifying the app code) - // Note: if several methods are used, the order of priority is (1) > (2) - // - // Example content of a hello_imgui.ini file: - // ------------------------------ - // [OpenGlOptions] - // GlslVersion = 130 - // MajorVersion = 3 - // MinorVersion = 2 - // UseCoreProfile = true - // UseForwardCompat = false + // (2) Either by setting them in a `hello_imgui.ini` file. See hello_imgui/hello_imgui_example.ini for more info + // Note: if several methods are used, the order of priority is (1) > (2) // If options specified by the program, do not read them. if (params.rendererBackendOptions.openGlOptions.has_value()) @@ -277,8 +267,9 @@ void AbstractRunner::ReadOpenGlOptions() auto useCoreProfile = HelloImGuiIniAnyParentFolder::readBoolValue(openGlSection, "UseCoreProfile"); auto useForwardCompat = HelloImGuiIniAnyParentFolder::readBoolValue(openGlSection, "UseForwardCompat"); auto glslVersion = HelloImGuiIniAnyParentFolder::readStringValue(openGlSection, "GlslVersion"); + auto antiAliasingSamples = HelloImGuiIniAnyParentFolder::readIntValue(openGlSection, "AntiAliasingSamples"); - bool isAnySettingsSpecified = majorVersion.has_value() || minorVersion.has_value() || useCoreProfile.has_value() || useForwardCompat.has_value() || glslVersion.has_value(); + bool isAnySettingsSpecified = majorVersion.has_value() || minorVersion.has_value() || useCoreProfile.has_value() || useForwardCompat.has_value() || glslVersion.has_value() || antiAliasingSamples.has_value(); if (isAnySettingsSpecified) { @@ -294,6 +285,8 @@ void AbstractRunner::ReadOpenGlOptions() openGlOptions.UseForwardCompat = useForwardCompat.value(); if (glslVersion.has_value()) openGlOptions.GlslVersion = glslVersion.value(); + if (antiAliasingSamples.has_value()) + openGlOptions.AntiAliasingSamples = antiAliasingSamples.value(); } } diff --git a/src/hello_imgui/internal/backend_impls/opengl_setup_helper/opengl_setup_glfw.cpp b/src/hello_imgui/internal/backend_impls/opengl_setup_helper/opengl_setup_glfw.cpp index 7feabcbc..8dd45eb4 100644 --- a/src/hello_imgui/internal/backend_impls/opengl_setup_helper/opengl_setup_glfw.cpp +++ b/src/hello_imgui/internal/backend_impls/opengl_setup_helper/opengl_setup_glfw.cpp @@ -9,6 +9,63 @@ namespace HelloImGui { namespace BackendApi { + static int QueryMaxAntiAliasingSamples() + { + // First create a dummy window to make OpenGL context current + GLFWwindow* dummyWindow = [] + { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + return glfwCreateWindow(64, 32, "Dummy", NULL, NULL); + }(); + + if (!dummyWindow) + IM_ASSERT(false && "Failed to create temporary window."); + glfwMakeContextCurrent(dummyWindow); + + // Init OpenGL loader + OpenGlSetupGlfw openGlSetupGlfw; + openGlSetupGlfw.InitGlLoader(); + + GLint maxSamples; + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + + glfwDestroyWindow(dummyWindow); + + return maxSamples; + } + + static void ApplyAntiAliasingSamples(OpenGlOptions& openGlOptions) + { + int userQuerySamples = openGlOptions.AntiAliasingSamples; + int maxGpuSamples = QueryMaxAntiAliasingSamples(); + int effectiveSamples = 8; + + if (effectiveSamples > maxGpuSamples) + effectiveSamples = maxGpuSamples; + + if (userQuerySamples == 0) + effectiveSamples = 0; + else if (userQuerySamples > 0) + { + if (userQuerySamples > maxGpuSamples) + fprintf(stderr, "Warning: user requested %d samples, but GPU supports only %d samples. Using %d samples instead.\n", userQuerySamples, maxGpuSamples, maxGpuSamples); + if (userQuerySamples <= maxGpuSamples) + effectiveSamples = userQuerySamples; + } + + if (effectiveSamples > 0) + { + glEnable(GL_MULTISAMPLE); + glfwWindowHint(GLFW_SAMPLES, effectiveSamples); + } + else + { + glfwWindowHint(GLFW_SAMPLES, 0); + } + } static void ApplyOpenGlOptions(OpenGlOptions& openGlOptions) { @@ -18,6 +75,8 @@ namespace HelloImGui { namespace BackendApi glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); if (openGlOptions.UseForwardCompat) glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + + ApplyAntiAliasingSamples(openGlOptions); } static OpenGlOptions MakeOpenGlOptions() @@ -28,6 +87,8 @@ namespace HelloImGui { namespace BackendApi OpenGlOptions openGlOptions; + openGlOptions.AntiAliasingSamples = -1; // -1 <=> not set, will use the default value of 8 + // // Compute MajorVersion, MinorVersion, UseCoreProfile, UseForwardCompat // diff --git a/src/hello_imgui/renderer_backend_options.h b/src/hello_imgui/renderer_backend_options.h index 33695b2a..a714157f 100644 --- a/src/hello_imgui/renderer_backend_options.h +++ b/src/hello_imgui/renderer_backend_options.h @@ -25,16 +25,9 @@ namespace HelloImGui // (set their values in `runnerParams.rendererBackendOptions.openGlOptions`) // (2) Either by setting them in a `hello_imgui.ini` file in the current folder, or any of its parent folders. // (this is useful when you want to set them for a specific app or set of apps, without modifying the app code) +// See hello_imgui/hello_imgui_example.ini for an example of such a file. // Note: if several methods are used, the order of priority is (1) > (2) // -// Example content of a ini file: -// ------------------------------ -// [OpenGlOptions] -// GlslVersion = 130 -// MajorVersion = 3 -// MinorVersion = 2 -// UseCoreProfile = true -// UseForwardCompat = false struct OpenGlOptions { // Could be for example: @@ -51,6 +44,21 @@ struct OpenGlOptions bool UseCoreProfile = true; // OpenGL Forward Compatibility (required on macOS) bool UseForwardCompat = true; + + // `AntiAliasingSamples` + // If > 0, this value will be used to set the number of samples used for anti-aliasing. + // This is used only when running with Glfw + OpenGL (which is the default) + // Notes: + // - we query the maximum number of samples supported by the hardware, via glGetIntegerv(GL_MAX_SAMPLES) + // - if you set this value to a non-zero value, it will be used instead of the default value of 8 + // (except if it is greater than the maximum supported value, in which case a warning will be issued) + // - if you set this value to 0, anti-aliasing will be disabled + // + // AntiAliasingSamples has a strong impact on the quality of the text rendering + // - 0: no anti-aliasing + // - 8: optimal + // - 16: optimal if using imgui-node-editor and you want to render very small text when unzooming + int AntiAliasingSamples = -1; // -1 <=> not set (will use the default value of 8) }; // @@md