From 61b19489f1ba35934d9114c034b24eb5bff149e7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 12 Feb 2021 16:34:22 +0100 Subject: [PATCH 1/9] Made a change to CalcWindowSizeAfterConstraint() which MSVC optimizer seems to trip on. (read on) We seldomly modify a local ImVec2 passed as parameter. This should be perfectly legal but libigl stumbled on a what may be a MSVC optimizer bug? Only seven function in the codebase modify as 'ImVec2 parameter' but this is the only static one (and fairly small that is) which may tempt optimizer to perform optimizations over caller-callee boundaries? While we can't explain it fully yet and I assume it may haunt us back someday. Might also be chain reaction from some unobvious UB but can't see it right now... Link: https://github.com/libigl/libigl/issues/1669 --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 0e401332..efc322aa 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5097,9 +5097,10 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags) return window; } -static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size) +static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, const ImVec2& size_desired) { ImGuiContext& g = *GImGui; + ImVec2 new_size = size_desired; if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint) { // Using -1,-1 on either X/Y axis to preserve the current size. From 30b7545841463f7bb117fe37af71990922153ae4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 15 Feb 2021 18:10:14 +0100 Subject: [PATCH 2/9] Version 1.82 WIP --- docs/CHANGELOG.txt | 5 +++++ imgui.cpp | 2 +- imgui.h | 6 +++--- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- imgui_widgets.cpp | 2 +- 8 files changed, 14 insertions(+), 9 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 24f9f40c..3372fd50 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -31,6 +31,11 @@ HOW TO UPDATE? - Please report any issue! +----------------------------------------------------------------------- + VERSION 1.82 WIP (In Progresss) +----------------------------------------------------------------------- + + ----------------------------------------------------------------------- VERSION 1.81 (Released 2021-02-10) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index efc322aa..39776a1d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.81 +// dear imgui, v1.82 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index 408969ad..78349979 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.81 +// dear imgui, v1.82 WIP // (headers) // Help: @@ -59,8 +59,8 @@ Index of this file: // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) -#define IMGUI_VERSION "1.81" -#define IMGUI_VERSION_NUM 18100 +#define IMGUI_VERSION "1.82 WIP" +#define IMGUI_VERSION_NUM 18101 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_HAS_TABLE diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 90e91aa0..e42aba99 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.81 +// dear imgui, v1.82 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 5c11a5b3..5186103a 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.81 +// dear imgui, v1.82 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index 39caf6b6..86ecb069 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.81 +// dear imgui, v1.82 WIP // (internal structures/api) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 61a84f9f..bcaf7157 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.81 +// dear imgui, v1.82 WIP // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index d2a4d1dc..038adb12 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.81 +// dear imgui, v1.82 WIP // (widgets code) /* From 9576dfd5e737e254cdd21293158cb219d19c0016 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Tue, 16 Feb 2021 10:33:29 +0200 Subject: [PATCH 3/9] CI: Use workflow_run to trigger scheduled builds and static analysis. Scheduled builds now are triggered by a dummy "scheduled" workflow that is invoked by the timer. This gives forks an ability to disable scheduled builds while maintaining ability to perform CI builds in forked repository. Similarly static analysis is invoked on completion of "build" workflow, ensuring analysis is performed with every build. Also should build workflow triggers change, we do not need to replicate same changes in static analysis workflow file. --- .github/workflows/build.yml | 52 +++++++++++++++------------ .github/workflows/scheduled.yml | 15 ++++++++ .github/workflows/static-analysis.yml | 10 ++++-- docs/CHANGELOG.txt | 9 +++-- 4 files changed, 59 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/scheduled.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 352cdcb3..888593e0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,8 +3,16 @@ name: build on: push: pull_request: - schedule: - - cron: '0 9 * * *' + workflow_run: + # Use a workflow as a trigger of scheduled builds. Forked repositories can disable scheduled builds by disabling + # "scheduled" workflow, while maintaining ability to perform local CI builds. + workflows: + - scheduled + branches: + - master + - docking + types: + - requested jobs: Windows: @@ -98,22 +106,22 @@ jobs: - name: Build Win32 example_glfw_opengl3 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj /p:Platform=Win32 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build Win32 example_glfw_vulkan shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj /p:Platform=Win32 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build Win32 example_sdl_vulkan shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj /p:Platform=Win32 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build Win32 example_sdl_opengl2 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build Win32 example_sdl_opengl3 shell: cmd @@ -122,7 +130,7 @@ jobs: - name: Build Win32 example_sdl_directx11 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_directx11/example_sdl_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build Win32 example_win32_directx9 shell: cmd @@ -135,12 +143,12 @@ jobs: - name: Build Win32 example_win32_directx11 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build x64 example_glfw_opengl2 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build x64 example_glfw_opengl3 shell: cmd @@ -153,17 +161,17 @@ jobs: - name: Build x64 example_sdl_vulkan shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_vulkan/example_sdl_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build x64 example_sdl_opengl2 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_opengl2/example_sdl_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build x64 example_sdl_opengl3 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl_opengl3/example_sdl_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build x64 example_sdl_directx11 shell: cmd @@ -172,17 +180,17 @@ jobs: - name: Build x64 example_win32_directx9 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=x64 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build x64 example_win32_directx10 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=x64 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build x64 example_win32_directx11 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release' - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build x64 example_win32_directx12 shell: cmd @@ -344,17 +352,17 @@ jobs: - name: Build example_glfw_opengl3 run: make -C examples/example_glfw_opengl3 - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build example_sdl_opengl2 run: make -C examples/example_sdl_opengl2 - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build example_sdl_opengl3 run: make -C examples/example_sdl_opengl3 MacOS: - runs-on: macOS-latest + runs-on: macos-latest steps: - uses: actions/checkout@v2 @@ -392,7 +400,7 @@ jobs: - name: Build example_glfw_opengl3 run: make -C examples/example_glfw_opengl3 - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build example_glfw_metal run: make -C examples/example_glfw_metal @@ -402,7 +410,7 @@ jobs: - name: Build example_sdl_opengl2 run: make -C examples/example_sdl_opengl2 - if: github.event_name == 'schedule' + if: github.event_name == 'workflow_run' - name: Build example_sdl_opengl3 run: make -C examples/example_sdl_opengl3 @@ -414,7 +422,7 @@ jobs: run: xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2 iOS: - runs-on: macOS-latest + runs-on: macos-latest steps: - uses: actions/checkout@v2 @@ -460,7 +468,7 @@ jobs: discord-webhook: ${{ secrets.DISCORD_CI_WEBHOOK }} github-token: ${{ github.token }} action-task: discord-jobs - discord-filter: "'{{ github.branch }}'.match(/master|docking|tables/g) != null && '{{ run.conclusion }}' != '{{ last_run.conclusion }}'" + discord-filter: "'{{ github.branch }}'.match(/master|docking/g) != null && '{{ run.conclusion }}' != '{{ last_run.conclusion }}'" discord-username: GitHub Actions discord-job-new-failure-message: '' discord-job-fixed-failure-message: '' diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml new file mode 100644 index 00000000..2a08578f --- /dev/null +++ b/.github/workflows/scheduled.yml @@ -0,0 +1,15 @@ +# +# This is a dummy workflow used to trigger scheduled builds. Forked repositories most likely should disable this +# workflow to avoid daily builds of inactive repositories. +# +name: scheduled + +on: + schedule: + - cron: '0 9 * * *' + +jobs: + scheduled: + runs-on: ubuntu-latest + steps: + - run: exit 0 diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 7a9b573e..d3b7d50b 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -1,8 +1,12 @@ name: static-analysis on: - push: {} - pull_request: {} + workflow_run: + # Perform static analysis together with build workflow. Build triggers of "build" workflow do not need to be repeated here. + workflows: + - build + types: + - requested jobs: PVS-Studio: @@ -51,7 +55,7 @@ jobs: discord-webhook: ${{ secrets.DISCORD_CI_WEBHOOK }} github-token: ${{ github.token }} action-task: discord-jobs - discord-filter: "'{{ github.branch }}'.match(/master|docking|tables/g) != null && '{{ run.conclusion }}' != '{{ last_run.conclusion }}'" + discord-filter: "'{{ github.branch }}'.match(/master|docking/g) != null && '{{ run.conclusion }}' != '{{ last_run.conclusion }}'" discord-username: GitHub Actions discord-job-new-failure-message: '' discord-job-fixed-failure-message: '' diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3372fd50..877de107 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -35,6 +35,11 @@ HOW TO UPDATE? VERSION 1.82 WIP (In Progresss) ----------------------------------------------------------------------- +Other Changes: + +- CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if + scheduled builds builds are not required. [@rokups] + ----------------------------------------------------------------------- VERSION 1.81 (Released 2021-02-10) @@ -68,9 +73,9 @@ Other Changes: - Code using (0,0) as a way to signify "upper-left of the host window" should use GetMainViewport()->Pos. - Code using io.DisplaySize as a way to signify "size of the host window" should use GetMainViewport()->Size. - We are also exposing a work area in ImGuiViewport ('WorkPos', 'WorkSize' vs 'Pos', 'Size' for full area): - - For a Platform Window, the work area is generally the full area minus space used by menu-bars. + - For a Platform Window, the work area is generally the full area minus space used by menu-bars. - For a Platform Monitor, the work area is generally the full area minus space used by task-bars. - - All of this has been the case in 'docking' branch for a long time. What we've done is merely merging + - All of this has been the case in 'docking' branch for a long time. What we've done is merely merging a small chunk of the multi-viewport logic into 'master' to standardize some concepts ahead of time. - Tables: Fixed PopItemWidth() or multi-components items not restoring per-colum ItemWidth correctly. (#3760) - Window: Fixed minor title bar text clipping issue when FramePadding is small/zero and there are no From b47aa46d81403419e308eb3b26077a4940f800df Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 16 Feb 2021 16:53:56 +0100 Subject: [PATCH 4/9] Tables: TableSetupColumn() user id uses ImGuiID as intended (typedef ImU32). internals: added GetCurrentTable(), LeftMostEnabledColumn. Demo/docs tweaks. --- docs/BACKENDS.md | 11 ++++++++--- imgui.h | 4 ++-- imgui_demo.cpp | 18 +++++++++++------- imgui_internal.h | 4 +++- imgui_tables.cpp | 17 ++++++++++------- 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/docs/BACKENDS.md b/docs/BACKENDS.md index 7a723cc7..ad9a0235 100644 --- a/docs/BACKENDS.md +++ b/docs/BACKENDS.md @@ -9,13 +9,13 @@ your application or engine to easily integrate Dear ImGui.** Each backend is typ e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc. - The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data.
- e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp]((https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp)), Vulkan ([imgui_impl_vulkan.cpp]((https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp)), etc. + e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp), etc. - For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.
e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)), Marmalade ([imgui_impl_marmalade.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_marmalade.cpp)). If you end up creating a custom backend for your engine, you may want to do the same. An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources. -For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details. +For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details. ### What are backends @@ -36,7 +36,7 @@ Dear ImGui is highly portable and only requires a few things to run and render, - Optional: multi-viewports support. etc. -This is essentially what each backends are doing + obligatory portability cruft. +This is essentially what each backends are doing + obligatory portability cruft. Using default backends ensure you can get all those features including the ones that would be harder to implement on your side (e.g. multi-viewports support). It is important to understand the difference between the core Dear ImGui library (files in the root folder) and backends which we are describing here (backends/ folder). @@ -46,6 +46,11 @@ and backends which we are describing here (backends/ folder). e.g. you can get creative and use software rendering or render remotely on a different machine. +### Integrating a backend + +See "Getting Started" section of [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for more details. + + ### List of backends In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder: diff --git a/imgui.h b/imgui.h index 78349979..507f11ac 100644 --- a/imgui.h +++ b/imgui.h @@ -701,7 +701,7 @@ namespace ImGui // - You may manually submit headers using TableNextRow() + TableHeader() calls, but this is only useful in // some advanced use cases (e.g. adding custom widgets in header row). // - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled. - IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImU32 user_id = 0); + IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImGuiID user_id = 0); IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled. IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used) @@ -711,7 +711,7 @@ namespace ImGui // since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may // wastefully sort your data every frame! // - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable(). - IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting). + IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting). // Tables: Miscellaneous functions // - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index. IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index e42aba99..da7fb2de 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -4856,6 +4856,9 @@ static void ShowDemoWindowTables() ImGui::TreePop(); } + // In this example we'll expose most table flags and settings. + // For specific flags and settings refer to the corresponding section for more detailed explanation. + // This section is mostly useful to experiment with combining certain flags or settings with each others. //ImGui::SetNextItemOpen(true, ImGuiCond_Once); // [DEBUG] if (open_action != -1) ImGui::SetNextItemOpen(open_action != 0); @@ -4994,7 +4997,7 @@ static void ShowDemoWindowTables() ImGui::TreePop(); } - // Recreate/reset item list if we changed the number of items + // Update item list if we changed the number of items static ImVector items; static ImVector selection; static bool items_need_sort = false; @@ -5016,6 +5019,7 @@ static void ShowDemoWindowTables() ImVec2 table_scroll_cur, table_scroll_max; // For debug display const ImDrawList* table_draw_list = NULL; // " + // Submit table const float inner_width_to_use = (flags & ImGuiTableFlags_ScrollX) ? inner_width_with_scroll : 0.0f; if (ImGui::BeginTable("table_advanced", 6, flags, outer_size_enabled ? outer_size_value : ImVec2(0, 0), inner_width_to_use)) { @@ -5074,9 +5078,9 @@ static void ShowDemoWindowTables() const bool item_is_selected = selection.contains(item->ID); ImGui::PushID(item->ID); ImGui::TableNextRow(ImGuiTableRowFlags_None, row_min_height); - ImGui::TableNextColumn(); // For the demo purpose we can select among different type of items submitted in the first column + ImGui::TableSetColumnIndex(0); char label[32]; sprintf(label, "%04d", item->ID); if (contents_type == CT_Text) @@ -5107,14 +5111,14 @@ static void ShowDemoWindowTables() } } - if (ImGui::TableNextColumn()) + if (ImGui::TableSetColumnIndex(1)) ImGui::TextUnformatted(item->Name); // Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity, // and we are currently sorting on the column showing the Quantity. // To avoid triggering a sort while holding the button, we only trigger it when the button has been released. // You will probably need a more advanced system in your code if you want to automatically sort when a specific entry changes. - if (ImGui::TableNextColumn()) + if (ImGui::TableSetColumnIndex(2)) { if (ImGui::SmallButton("Chop")) { item->Quantity += 1; } if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; } @@ -5123,16 +5127,16 @@ static void ShowDemoWindowTables() if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; } } - if (ImGui::TableNextColumn()) + if (ImGui::TableSetColumnIndex(3)) ImGui::Text("%d", item->Quantity); - ImGui::TableNextColumn(); + ImGui::TableSetColumnIndex(4); if (show_wrapped_text) ImGui::TextWrapped("Lorem ipsum dolor sit amet"); else ImGui::Text("Lorem ipsum dolor sit amet"); - if (ImGui::TableNextColumn()) + if (ImGui::TableSetColumnIndex(5)) ImGui::Text("1234"); ImGui::PopID(); diff --git a/imgui_internal.h b/imgui_internal.h index 86ecb069..81e3c738 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2091,9 +2091,10 @@ struct ImGuiTable ImGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held. ImGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared) ImGuiTableColumnIdx ReorderColumnDir; // -1 or +1 + ImGuiTableColumnIdx LeftMostEnabledColumn; // Index of left-most non-hidden column. + ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column. ImGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column. ImGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column. - ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column. ImGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot ImGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset) @@ -2349,6 +2350,7 @@ namespace ImGui IMGUI_API void TablePopBackgroundChannel(); // Tables: Internals + inline ImGuiTable* GetCurrentTable() { ImGuiContext& g = *GImGui; return g.CurrentTable; } IMGUI_API ImGuiTable* TableFindByID(ImGuiID id); IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f); IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count); diff --git a/imgui_tables.cpp b/imgui_tables.cpp index bcaf7157..a34ab42f 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -687,13 +687,14 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) table->ColumnsEnabledCount = 0; table->EnabledMaskByIndex = 0x00; table->EnabledMaskByDisplayOrder = 0x00; + table->LeftMostEnabledColumn = -1; table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE // [Part 1] Apply/lock Enabled and Order states. Calculate auto/ideal width for columns. Count fixed/stretch columns. // Process columns in their visible orders as we are building the Prev/Next indices. int count_fixed = 0; // Number of columns that have fixed sizing policies int count_stretch = 0; // Number of columns that have stretch sizing policies - int last_visible_column_idx = -1; + int prev_visible_column_idx = -1; bool has_auto_fit_request = false; bool has_resizable = false; float stretch_sum_width_auto = 0.0f; @@ -741,14 +742,16 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) } // Mark as enabled and link to previous/next enabled column - column->PrevEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx; + column->PrevEnabledColumn = (ImGuiTableColumnIdx)prev_visible_column_idx; column->NextEnabledColumn = -1; - if (last_visible_column_idx != -1) - table->Columns[last_visible_column_idx].NextEnabledColumn = (ImGuiTableColumnIdx)column_n; + if (prev_visible_column_idx != -1) + table->Columns[prev_visible_column_idx].NextEnabledColumn = (ImGuiTableColumnIdx)column_n; + else + table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n; column->IndexWithinEnabledSet = table->ColumnsEnabledCount++; table->EnabledMaskByIndex |= (ImU64)1 << column_n; table->EnabledMaskByDisplayOrder |= (ImU64)1 << column->DisplayOrder; - last_visible_column_idx = column_n; + prev_visible_column_idx = column_n; IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder); // Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping) @@ -778,8 +781,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) } if ((table->Flags & ImGuiTableFlags_Sortable) && table->SortSpecsCount == 0 && !(table->Flags & ImGuiTableFlags_SortTristate)) table->IsSortSpecsDirty = true; - table->RightMostEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx; - IM_ASSERT(table->RightMostEnabledColumn >= 0); + table->RightMostEnabledColumn = (ImGuiTableColumnIdx)prev_visible_column_idx; + IM_ASSERT(table->LeftMostEnabledColumn >= 0 && table->RightMostEnabledColumn >= 0); // [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible // to avoid the column fitting having to wait until the first visible frame of the child container (may or not be a good thing). From f107693d9b0b390968400343c9cfd130591c22c7 Mon Sep 17 00:00:00 2001 From: thedmd Date: Wed, 17 Feb 2021 12:55:25 +0100 Subject: [PATCH 5/9] Improve on automatic circle segment count calculation. (#3808) --- imgui.cpp | 6 +++--- imgui.h | 3 ++- imgui_demo.cpp | 40 +++++++++++++++++++++++++++++++--------- imgui_draw.cpp | 32 +++++++++++++++++++------------- imgui_internal.h | 31 +++++++++++++++++++++++++------ 5 files changed, 80 insertions(+), 32 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 39776a1d..268093ac 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -986,7 +986,7 @@ ImGuiStyle::ImGuiStyle() AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.). CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. - CircleSegmentMaxError = 1.60f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. + CircleTessellationMaxError = 0.25f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. // Default theme ImGui::StyleColorsDark(this); @@ -3878,7 +3878,7 @@ void ImGui::NewFrame() virtual_space.Add(g.Viewports[n]->GetMainRect()); g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4(); g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; - g.DrawListSharedData.SetCircleSegmentMaxError(g.Style.CircleSegmentMaxError); + g.DrawListSharedData.SetCircleTessellationMaxError(g.Style.CircleTessellationMaxError); g.DrawListSharedData.InitialFlags = ImDrawListFlags_None; if (g.Style.AntiAliasedLines) g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines; @@ -7056,7 +7056,7 @@ static void ImGui::ErrorCheckNewFrameSanityChecks() IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()?"); IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()?"); IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!"); - IM_ASSERT(g.Style.CircleSegmentMaxError > 0.0f && "Invalid style setting!"); + IM_ASSERT(g.Style.CircleTessellationMaxError > 0.0f && "Invalid style setting!"); IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting!"); // Allows us to avoid a few clamps in color computations IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting."); IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right); diff --git a/imgui.h b/imgui.h index 507f11ac..db424721 100644 --- a/imgui.h +++ b/imgui.h @@ -1723,7 +1723,7 @@ struct ImGuiStyle bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. - float CircleSegmentMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. + float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. ImVec4 Colors[ImGuiCol_COUNT]; IMGUI_API ImGuiStyle(); @@ -2463,6 +2463,7 @@ struct ImDrawList IMGUI_API void _OnChangedClipRect(); IMGUI_API void _OnChangedTextureID(); IMGUI_API void _OnChangedVtxOffset(); + IMGUI_API int _CalcCircleAutoSegmentCount(float radius) const; }; // All draw data to render a Dear ImGui frame diff --git a/imgui_demo.cpp b/imgui_demo.cpp index da7fb2de..3d9395e6 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -6034,22 +6034,44 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f; // When editing the "Circle Segment Max Error" value, draw a preview of its effect on auto-tessellated circles. - ImGui::DragFloat("Circle Segment Max Error", &style.CircleSegmentMaxError, 0.01f, 0.10f, 10.0f, "%.2f"); + ImGui::DragFloat("Circle Tessellation Max Error", &style.CircleTessellationMaxError , 0.005f, 0.10f, 10.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp); if (ImGui::IsItemActive()) { ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos()); ImGui::BeginTooltip(); - ImVec2 p = ImGui::GetCursorScreenPos(); + ImGui::TextUnformatted("N - number of segments"); + ImGui::TextUnformatted("R - radius"); + ImGui::Spacing(); ImDrawList* draw_list = ImGui::GetWindowDrawList(); - float RAD_MIN = 10.0f, RAD_MAX = 80.0f; - float off_x = 10.0f; - for (int n = 0; n < 7; n++) + const float min_widget_width = ImGui::CalcTextSize("N: MM\nR: MM.MM").x; + float RAD_MIN = 5.0f, RAD_MAX = 80.0f; + for (int n = 0; n < 9; n++) { - const float rad = RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (7.0f - 1.0f); - draw_list->AddCircle(ImVec2(p.x + off_x + rad, p.y + RAD_MAX), rad, ImGui::GetColorU32(ImGuiCol_Text), 0); - off_x += 10.0f + rad * 2.0f; + const float rad = RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (9.0f - 1.0f); + + const int segment_count = draw_list->_CalcCircleAutoSegmentCount(rad); + + ImGui::BeginGroup(); + ImGui::Text("R: %.f", rad); + ImGui::Text("N: %d", segment_count); + + const float circle_diameter = rad * 2.0f; + const float canvas_width = IM_MAX(min_widget_width, circle_diameter); + const float offset_x = floorf(canvas_width * 0.5f); + const float offset_y = floorf(RAD_MAX); + const ImVec2 p = ImGui::GetCursorScreenPos(); + draw_list->AddCircle(ImVec2(p.x + offset_x, p.y + offset_y), rad, ImGui::GetColorU32(ImGuiCol_Text)); + + ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2)); + ImGui::Text("N: %d", segment_count); + + const ImVec2 p2 = ImGui::GetCursorScreenPos(); + draw_list->AddCircleFilled(ImVec2(p2.x + offset_x, p2.y + offset_y), rad, ImGui::GetColorU32(ImGuiCol_Text)); + + ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2)); + ImGui::EndGroup(); + ImGui::SameLine(); } - ImGui::Dummy(ImVec2(off_x, RAD_MAX * 2.0f)); ImGui::EndTooltip(); } ImGui::SameLine(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 5186103a..8a031911 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -376,7 +376,7 @@ ImDrawListSharedData::ImDrawListSharedData() } } -void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error) +void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error) { if (CircleSegmentMaxError == max_error) return; @@ -384,8 +384,7 @@ void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error) for (int i = 0; i < IM_ARRAYSIZE(CircleSegmentCounts); i++) { const float radius = (float)i; - const int segment_count = (i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : 0; - CircleSegmentCounts[i] = (ImU8)ImMin(segment_count, 255); + CircleSegmentCounts[i] = (ImU8)((i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : 0); } } @@ -543,6 +542,21 @@ void ImDrawList::_OnChangedVtxOffset() curr_cmd->VtxOffset = _CmdHeader.VtxOffset; } +int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const +{ + int num_segments = 0; + + const int radius_idx = (int)ImCeil(radius); // Use ceil to never reduce accuracy + + // Automatic segment count + if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts)) + num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value + else + num_segments = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError); + + return num_segments; +} + // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect) { @@ -1286,11 +1300,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu if (num_segments <= 0) { // Automatic segment count - const int radius_idx = (int)radius; - if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts)) - num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value - else - num_segments = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError); + num_segments = _CalcCircleAutoSegmentCount(radius); } else { @@ -1316,11 +1326,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, if (num_segments <= 0) { // Automatic segment count - const int radius_idx = (int)radius; - if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts)) - num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value - else - num_segments = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError); + num_segments = _CalcCircleAutoSegmentCount(radius); } else { diff --git a/imgui_internal.h b/imgui_internal.h index 81e3c738..c8405c7f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -617,10 +617,29 @@ struct IMGUI_API ImChunkStream //----------------------------------------------------------------------------- // ImDrawList: Helper function to calculate a circle's segment count given its radius and a "maximum error" value. -// FIXME: the minimum number of auto-segment may be undesirably high for very small radiuses (e.g. 1.0f) -#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 12 +// +// Estimation of number of circle segment based on error is derived using method described in +// this post (https://stackoverflow.com/a/2244088/15194693). +// Number of segments (N) is calculated using equation: +// +// +- -+ +// | pi | +// N = ceil | --------------------- | where r > 0, error <= r +// | acos(1 - error / r) | +// +- -+ +// +// Note: +// Equation is significantly simpler that one in the post thanks for choosing segment +// that is perpendicular to X axis. Follow steps in the article from this starting condition +// and you will get this result. +// +// Rendering circles with an odd number of segments, while mathematically correct will produce +// asymmetrical results on the raster grid. Therefore we're rounding N to next even number. +// (7 became 8, 11 became 12, but 8 will still be 8). +// +#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 4 #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512 -#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp((int)((IM_PI * 2.0f) / ImAcos(((_RAD) - (_MAXERROR)) / (_RAD))), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX) +#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp((((int)ImCeil(IM_PI / ImAcos(1 - ImMin((_MAXERROR), (_RAD)) / (_RAD))) + 1) / 2) * 2, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX) // ImDrawList: You may set this to higher values (e.g. 2 or 3) to increase tessellation of fast rounded corners path. #ifndef IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER @@ -641,11 +660,11 @@ struct IMGUI_API ImDrawListSharedData // [Internal] Lookup tables ImVec2 ArcFastVtx[12 * IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER]; // FIXME: Bake rounded corners fill/borders in atlas - ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead) - const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas + ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead) + const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas ImDrawListSharedData(); - void SetCircleSegmentMaxError(float max_error); + void SetCircleTessellationMaxError(float max_error); }; struct ImDrawDataBuilder From fb15d8c85829cddc82ba2b528344766cc607b988 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 17 Feb 2021 13:06:26 +0100 Subject: [PATCH 6/9] Improve on automatic circle segment count calculation. (#3808) Amends --- docs/CHANGELOG.txt | 8 ++++++++ imgui.cpp | 3 ++- imgui_demo.cpp | 38 ++++++++++++++++++-------------------- imgui_draw.cpp | 11 +++-------- imgui_internal.h | 29 ++++++++++------------------- 5 files changed, 41 insertions(+), 48 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 877de107..d65c0bc1 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -35,8 +35,16 @@ HOW TO UPDATE? VERSION 1.82 WIP (In Progresss) ----------------------------------------------------------------------- +Breaking Changes: + + - Style: renamed rarely used style.CircleSegmentMaxError (old default = 1.60f) + to style.CircleTessellationMaxError (new default = 0.30f) as its meaning changed. (#3808) [@thedmd] + Other Changes: +- ImDrawList: AddCircle, AddCircleFilled(): Tweaked default segment count calculation to honor MaxError + with more accuracy. Made default segment count always even for better looking result. (#3808) [@thedmd] +- ImDrawList: AddCircle, AddCircleFilled(): New default for style. - CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if scheduled builds builds are not required. [@rokups] diff --git a/imgui.cpp b/imgui.cpp index 268093ac..dfba47e3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -375,6 +375,7 @@ CODE When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2021/02/17 (1.82) - renamed rarely used style.CircleSegmentMaxError (old default = 1.60f) to style.CircleTessellationMaxError (new default = 0.30f) as the meaning of the value changed. - 2021/02/03 (1.81) - renamed ListBoxHeader(const char* label, ImVec2 size) to BeginListBox(). Kept inline redirection function (will obsolete). - removed ListBoxHeader(const char* label, int items_count, int height_in_items = -1) in favor of specifying size. Kept inline redirection function (will obsolete). - renamed ListBoxFooter() to EndListBox(). Kept inline redirection function (will obsolete). @@ -986,7 +987,7 @@ ImGuiStyle::ImGuiStyle() AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.). CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. - CircleTessellationMaxError = 0.25f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. + CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. // Default theme ImGui::StyleColorsDark(this); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 3d9395e6..b7815ab4 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -6034,41 +6034,39 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f; // When editing the "Circle Segment Max Error" value, draw a preview of its effect on auto-tessellated circles. - ImGui::DragFloat("Circle Tessellation Max Error", &style.CircleTessellationMaxError , 0.005f, 0.10f, 10.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp); + ImGui::DragFloat("Circle Tessellation Max Error", &style.CircleTessellationMaxError , 0.005f, 0.10f, 5.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp); if (ImGui::IsItemActive()) { ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos()); ImGui::BeginTooltip(); - ImGui::TextUnformatted("N - number of segments"); - ImGui::TextUnformatted("R - radius"); + ImGui::TextUnformatted("(R = radius, N = number of segments)"); ImGui::Spacing(); ImDrawList* draw_list = ImGui::GetWindowDrawList(); - const float min_widget_width = ImGui::CalcTextSize("N: MM\nR: MM.MM").x; - float RAD_MIN = 5.0f, RAD_MAX = 80.0f; - for (int n = 0; n < 9; n++) + const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x; + for (int n = 0; n < 8; n++) { - const float rad = RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (9.0f - 1.0f); - - const int segment_count = draw_list->_CalcCircleAutoSegmentCount(rad); + const float RAD_MIN = 5.0f; + const float RAD_MAX = 70.0f; + const float rad = RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f); ImGui::BeginGroup(); - ImGui::Text("R: %.f", rad); - ImGui::Text("N: %d", segment_count); - const float circle_diameter = rad * 2.0f; - const float canvas_width = IM_MAX(min_widget_width, circle_diameter); - const float offset_x = floorf(canvas_width * 0.5f); - const float offset_y = floorf(RAD_MAX); - const ImVec2 p = ImGui::GetCursorScreenPos(); - draw_list->AddCircle(ImVec2(p.x + offset_x, p.y + offset_y), rad, ImGui::GetColorU32(ImGuiCol_Text)); + ImGui::Text("R: %.f\nN: %d", rad, draw_list->_CalcCircleAutoSegmentCount(rad)); + const float canvas_width = IM_MAX(min_widget_width, rad * 2.0f); + const float offset_x = floorf(canvas_width * 0.5f); + const float offset_y = floorf(RAD_MAX); + + const ImVec2 p1 = ImGui::GetCursorScreenPos(); + draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad, ImGui::GetColorU32(ImGuiCol_Text)); ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2)); - ImGui::Text("N: %d", segment_count); - const ImVec2 p2 = ImGui::GetCursorScreenPos(); + /* + const ImVec2 p2 = ImGui::GetCursorScreenPos(); draw_list->AddCircleFilled(ImVec2(p2.x + offset_x, p2.y + offset_y), rad, ImGui::GetColorU32(ImGuiCol_Text)); - ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2)); + */ + ImGui::EndGroup(); ImGui::SameLine(); } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 8a031911..b0770eda 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -544,17 +544,12 @@ void ImDrawList::_OnChangedVtxOffset() int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const { - int num_segments = 0; - - const int radius_idx = (int)ImCeil(radius); // Use ceil to never reduce accuracy - // Automatic segment count + const int radius_idx = (int)(radius + 0.999f); // ceil to never reduce accuracy if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts)) - num_segments = _Data->CircleSegmentCounts[radius_idx]; // Use cached value + return _Data->CircleSegmentCounts[radius_idx]; // Use cached value else - num_segments = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError); - - return num_segments; + return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError); } // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) diff --git a/imgui_internal.h b/imgui_internal.h index c8405c7f..e85230dc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -617,29 +617,20 @@ struct IMGUI_API ImChunkStream //----------------------------------------------------------------------------- // ImDrawList: Helper function to calculate a circle's segment count given its radius and a "maximum error" value. -// -// Estimation of number of circle segment based on error is derived using method described in -// this post (https://stackoverflow.com/a/2244088/15194693). +// Estimation of number of circle segment based on error is derived using method described in https://stackoverflow.com/a/2244088/15194693 // Number of segments (N) is calculated using equation: -// -// +- -+ -// | pi | -// N = ceil | --------------------- | where r > 0, error <= r -// | acos(1 - error / r) | -// +- -+ -// -// Note: -// Equation is significantly simpler that one in the post thanks for choosing segment -// that is perpendicular to X axis. Follow steps in the article from this starting condition -// and you will get this result. +// N = ceil ( pi / acos(1 - error / r) ) where r > 0, error <= r +// Our equation is significantly simpler that one in the post thanks for choosing segment that is +// perpendicular to X axis. Follow steps in the article from this starting condition and you will +// will get this result. // // Rendering circles with an odd number of segments, while mathematically correct will produce -// asymmetrical results on the raster grid. Therefore we're rounding N to next even number. -// (7 became 8, 11 became 12, but 8 will still be 8). +// asymmetrical results on the raster grid. Therefore we're rounding N to next even number (7->8, 8->8, 9->10 etc.) // +#define IM_ROUNDUP_TO_EVEN(_V) ((((_V) + 1) / 2) * 2) #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 4 #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512 -#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp((((int)ImCeil(IM_PI / ImAcos(1 - ImMin((_MAXERROR), (_RAD)) / (_RAD))) + 1) / 2) * 2, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX) +#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp(IM_ROUNDUP_TO_EVEN((int)ImCeil(IM_PI / ImAcos(1 - ImMin((_MAXERROR), (_RAD)) / (_RAD)))), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX) // ImDrawList: You may set this to higher values (e.g. 2 or 3) to increase tessellation of fast rounded corners path. #ifndef IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER @@ -660,8 +651,8 @@ struct IMGUI_API ImDrawListSharedData // [Internal] Lookup tables ImVec2 ArcFastVtx[12 * IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER]; // FIXME: Bake rounded corners fill/borders in atlas - ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead) - const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas + ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead) + const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas ImDrawListSharedData(); void SetCircleTessellationMaxError(float max_error); From 27a5bdb9160e571b14053b13a48df9d83265a571 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 17 Feb 2021 19:41:02 +0100 Subject: [PATCH 7/9] Backends: Win32: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1. + Added other helpers for reference (unused currently, other features will want them) --- backends/imgui_impl_win32.cpp | 5 ++++- docs/CHANGELOG.txt | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 848dfab9..64454dd5 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -28,6 +28,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1. // 2021-01-25: Inputs: Dynamically loading XInput DLL. // 2020-12-04: Misc: Fixed setting of io.DisplaySize to invalid/uninitialized data when after hwnd has been closed. // 2020-03-03: Inputs: Calling AddInputCharacterUTF16() to support surrogate pairs leading to codepoint >= 0x10000 (for more complete CJK inputs) @@ -409,7 +410,9 @@ static BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp) cond = ::VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); return ::VerifyVersionInfoW(&osvi, mask, cond); } -#define IsWindows8Point1OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WINBLUE +#define IsWindowsVistaOrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA +#define IsWindows8OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WIN8 +#define IsWindows8Point1OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0603), LOBYTE(0x0603), 0) // _WIN32_WINNT_WINBLUE #endif #ifndef DPI_ENUMS_DECLARED diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d65c0bc1..c41e3151 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -37,8 +37,8 @@ HOW TO UPDATE? Breaking Changes: - - Style: renamed rarely used style.CircleSegmentMaxError (old default = 1.60f) - to style.CircleTessellationMaxError (new default = 0.30f) as its meaning changed. (#3808) [@thedmd] +- Style: renamed rarely used style.CircleSegmentMaxError (old default = 1.60f) + to style.CircleTessellationMaxError (new default = 0.30f) as its meaning changed. (#3808) [@thedmd] Other Changes: From bda12e5fdd829e44e01a25aac015e156f3dad761 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 17 Feb 2021 19:29:07 +0100 Subject: [PATCH 8/9] Backends: Rework blending equation to preserve alpha in output buffer accross all backends. (#2693, #2764, #2766, #2873, #3447, #3813, #3816) Some of the viewport ideas from #2766 are not in there yet (e.g. Vulkan: setting compositeAlpha based on cap.supportedCompositeAlpha) --- backends/imgui_impl_allegro5.cpp | 3 ++- backends/imgui_impl_dx10.cpp | 5 +++-- backends/imgui_impl_dx11.cpp | 5 +++-- backends/imgui_impl_dx12.cpp | 5 +++-- backends/imgui_impl_dx9.cpp | 4 ++++ backends/imgui_impl_metal.mm | 5 +++-- backends/imgui_impl_opengl2.cpp | 1 + backends/imgui_impl_opengl3.cpp | 3 ++- backends/imgui_impl_vulkan.cpp | 5 +++-- backends/imgui_impl_wgpu.cpp | 3 ++- docs/CHANGELOG.txt | 6 +++++- 11 files changed, 31 insertions(+), 14 deletions(-) diff --git a/backends/imgui_impl_allegro5.cpp b/backends/imgui_impl_allegro5.cpp index db608e02..c4832b6b 100644 --- a/backends/imgui_impl_allegro5.cpp +++ b/backends/imgui_impl_allegro5.cpp @@ -15,6 +15,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: Change blending equation to preserve alpha in output buffer. // 2020-08-10: Inputs: Fixed horizontal mouse wheel direction. // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. @@ -68,7 +69,7 @@ struct ImDrawVertAllegro static void ImGui_ImplAllegro5_SetupRenderState(ImDrawData* draw_data) { // Setup blending - al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); + al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); // Setup orthographic projection matrix // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). diff --git a/backends/imgui_impl_dx10.cpp b/backends/imgui_impl_dx10.cpp index 422f6529..28842755 100644 --- a/backends/imgui_impl_dx10.cpp +++ b/backends/imgui_impl_dx10.cpp @@ -11,6 +11,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: DirectX10: Change blending equation to preserve alpha in output buffer. // 2019-07-21: DirectX10: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData(). // 2019-05-29: DirectX10: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-04-30: DirectX10: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. @@ -439,8 +440,8 @@ bool ImGui_ImplDX10_CreateDeviceObjects() desc.SrcBlend = D3D10_BLEND_SRC_ALPHA; desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA; desc.BlendOp = D3D10_BLEND_OP_ADD; - desc.SrcBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; - desc.DestBlendAlpha = D3D10_BLEND_ZERO; + desc.SrcBlendAlpha = D3D10_BLEND_ONE; + desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA; desc.BlendOpAlpha = D3D10_BLEND_OP_ADD; desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL; g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState); diff --git a/backends/imgui_impl_dx11.cpp b/backends/imgui_impl_dx11.cpp index 3edfeae6..f114cdc1 100644 --- a/backends/imgui_impl_dx11.cpp +++ b/backends/imgui_impl_dx11.cpp @@ -11,6 +11,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer. // 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled). // 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore. // 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. @@ -451,8 +452,8 @@ bool ImGui_ImplDX11_CreateDeviceObjects() desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState); diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index 39ca8f8d..860fe660 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -15,6 +15,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: DirectX12: Change blending equation to preserve alpha in output buffer. // 2021-01-11: DirectX12: Improve Windows 7 compatibility (for D3D12On7) by loading d3d12.dll dynamically. // 2020-09-16: DirectX12: Avoid rendering calls with zero-sized scissor rectangle since it generates a validation layer warning. // 2020-09-08: DirectX12: Clarified support for building on 32-bit systems by redefining ImTextureID. @@ -585,8 +586,8 @@ bool ImGui_ImplDX12_CreateDeviceObjects() desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; + desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE; + desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; } diff --git a/backends/imgui_impl_dx9.cpp b/backends/imgui_impl_dx9.cpp index 2a575e81..44dea337 100644 --- a/backends/imgui_impl_dx9.cpp +++ b/backends/imgui_impl_dx9.cpp @@ -11,6 +11,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: DirectX9: Change blending equation to preserve alpha in output buffer. // 2019-05-29: DirectX9: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-04-30: DirectX9: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. // 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). @@ -67,6 +68,9 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data) g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + g_pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + g_pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); + g_pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index b67c3ef3..cb57c123 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -11,6 +11,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: Metal: Change blending equation to preserve alpha in output buffer. // 2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst. // 2019-05-29: Metal: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-04-30: Metal: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. @@ -386,10 +387,10 @@ void ImGui_ImplMetal_DestroyDeviceObjects() pipelineDescriptor.colorAttachments[0].pixelFormat = self.framebufferDescriptor.colorPixelFormat; pipelineDescriptor.colorAttachments[0].blendingEnabled = YES; pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; - pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; - pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha; pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat; pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat; diff --git a/backends/imgui_impl_opengl2.cpp b/backends/imgui_impl_opengl2.cpp index 1419e2d8..5771049c 100644 --- a/backends/imgui_impl_opengl2.cpp +++ b/backends/imgui_impl_opengl2.cpp @@ -81,6 +81,7 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // In order to composite our output buffer we need to preserve alpha glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp index f3b2a937..b582851e 100644 --- a/backends/imgui_impl_opengl3.cpp +++ b/backends/imgui_impl_opengl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: OpenGL: Change blending equation to preserve alpha in output buffer. // 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state. // 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state. // 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x) @@ -247,7 +248,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 44a555a5..d8c00e9b 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: Vulkan: Change blending equation to preserve alpha in output buffer. // 2021-01-27: Vulkan: Added support for custom function load and IMGUI_IMPL_VULKAN_NO_PROTOTYPES by using ImGui_ImplVulkan_LoadFunctions(). // 2020-11-11: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation. // 2020-09-07: Vulkan: Added VkPipeline parameter to ImGui_ImplVulkan_RenderDrawData (default to one passed to ImGui_ImplVulkan_Init). @@ -815,8 +816,8 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; color_attachment[0].colorBlendOp = VK_BLEND_OP_ADD; - color_attachment[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - color_attachment[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; + color_attachment[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + color_attachment[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; color_attachment[0].alphaBlendOp = VK_BLEND_OP_ADD; color_attachment[0].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index 089dbfd7..1eb290a3 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -12,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-02-18: Change blending equation to preserve alpha in output buffer. // 2021-01-28: Initial version. #include "imgui.h" @@ -638,7 +639,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects() { color_state.format = g_renderTargetFormat; color_state.alphaBlend.operation = WGPUBlendOperation_Add; - color_state.alphaBlend.srcFactor = WGPUBlendFactor_SrcAlpha; + color_state.alphaBlend.srcFactor = WGPUBlendFactor_One; color_state.alphaBlend.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; color_state.colorBlend.operation = WGPUBlendOperation_Add; color_state.colorBlend.srcFactor = WGPUBlendFactor_SrcAlpha; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index c41e3151..4a87a64b 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -45,7 +45,11 @@ Other Changes: - ImDrawList: AddCircle, AddCircleFilled(): Tweaked default segment count calculation to honor MaxError with more accuracy. Made default segment count always even for better looking result. (#3808) [@thedmd] - ImDrawList: AddCircle, AddCircleFilled(): New default for style. -- CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if +- Backends: OpenGL, Vulkan, DX9, DX10, DX11, DX12, Metal, WebGPU, Allegro: Rework blending equation to + preserve alpha in output buffer (using SrcBlendAlpha = ONE, DstBlendAlpha = ONE_MINUS_SRC_ALPHA consistently + accross all backends), facilitating compositing of the output buffer with another buffer. + (#2693, #2764, #2766, #2873, #3447, #3813, #3816) [@ocornut, @thedmd, @ShawnM427, @Ubpa, @aiekick] +- CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if scheduled builds builds are not required. [@rokups] From 6a161b878943241ddecbeee4ae27103dbd2d33d0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 17 Feb 2021 19:29:39 +0100 Subject: [PATCH 9/9] Examples: Reworked setup of clear color to be compatible with transparent values. (#2693, #2764, #2766, #2873, #3447, #3813, #3816) --- docs/CHANGELOG.txt | 1 + examples/example_allegro5/main.cpp | 2 +- examples/example_apple_metal/main.mm | 2 +- examples/example_apple_opengl2/main.mm | 2 +- examples/example_emscripten_opengl3/main.cpp | 2 +- examples/example_emscripten_wgpu/main.cpp | 2 +- examples/example_glfw_metal/main.mm | 2 +- examples/example_glfw_opengl2/main.cpp | 2 +- examples/example_glfw_opengl3/main.cpp | 2 +- examples/example_glfw_vulkan/main.cpp | 5 ++++- examples/example_glut_opengl2/main.cpp | 2 +- examples/example_sdl_directx11/main.cpp | 3 ++- examples/example_sdl_metal/main.mm | 2 +- examples/example_sdl_opengl2/main.cpp | 2 +- examples/example_sdl_opengl3/main.cpp | 2 +- examples/example_sdl_vulkan/main.cpp | 5 ++++- examples/example_win32_directx10/main.cpp | 3 ++- examples/example_win32_directx11/main.cpp | 3 ++- examples/example_win32_directx12/main.cpp | 11 +++++++---- examples/example_win32_directx9/main.cpp | 4 ++-- 20 files changed, 36 insertions(+), 23 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4a87a64b..25b3848f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,6 +49,7 @@ Other Changes: preserve alpha in output buffer (using SrcBlendAlpha = ONE, DstBlendAlpha = ONE_MINUS_SRC_ALPHA consistently accross all backends), facilitating compositing of the output buffer with another buffer. (#2693, #2764, #2766, #2873, #3447, #3813, #3816) [@ocornut, @thedmd, @ShawnM427, @Ubpa, @aiekick] +- Examples: Reworked setup of clear color to be compatible with transparent values. - CI: Use a dedicated "scheduled" workflow to trigger scheduled builds. Forks may disable this workflow if scheduled builds builds are not required. [@rokups] diff --git a/examples/example_allegro5/main.cpp b/examples/example_allegro5/main.cpp index fefcd76d..c60b1736 100644 --- a/examples/example_allegro5/main.cpp +++ b/examples/example_allegro5/main.cpp @@ -121,7 +121,7 @@ int main(int, char**) // Rendering ImGui::Render(); - al_clear_to_color(al_map_rgba_f(clear_color.x, clear_color.y, clear_color.z, clear_color.w)); + al_clear_to_color(al_map_rgba_f(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w)); ImGui_ImplAllegro5_RenderDrawData(ImGui::GetDrawData()); al_flip_display(); } diff --git a/examples/example_apple_metal/main.mm b/examples/example_apple_metal/main.mm index 015aee90..273811d3 100644 --- a/examples/example_apple_metal/main.mm +++ b/examples/example_apple_metal/main.mm @@ -245,7 +245,7 @@ MTLRenderPassDescriptor* renderPassDescriptor = view.currentRenderPassDescriptor; if (renderPassDescriptor != nil) { - renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0], clear_color[1], clear_color[2], clear_color[3]); + renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0] * clear_color[3], clear_color[1] * clear_color[3], clear_color[2] * clear_color[3], clear_color[3]); // Here, you could do additional rendering work, including other passes as necessary. diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index 5bcc9ea4..9af396b6 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -97,7 +97,7 @@ GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); glViewport(0, 0, width, height); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + 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_ImplOpenGL2_RenderDrawData(draw_data); diff --git a/examples/example_emscripten_opengl3/main.cpp b/examples/example_emscripten_opengl3/main.cpp index 0c926660..875ecbb6 100644 --- a/examples/example_emscripten_opengl3/main.cpp +++ b/examples/example_emscripten_opengl3/main.cpp @@ -167,7 +167,7 @@ static void main_loop(void* arg) ImGui::Render(); SDL_GL_MakeCurrent(g_Window, g_GLContext); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + 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()); SDL_GL_SwapWindow(g_Window); diff --git a/examples/example_emscripten_wgpu/main.cpp b/examples/example_emscripten_wgpu/main.cpp index 9b72ba9b..a9da9320 100644 --- a/examples/example_emscripten_wgpu/main.cpp +++ b/examples/example_emscripten_wgpu/main.cpp @@ -205,7 +205,7 @@ static void main_loop(void* window) WGPURenderPassColorAttachmentDescriptor color_attachments = {}; color_attachments.loadOp = WGPULoadOp_Clear; color_attachments.storeOp = WGPUStoreOp_Store; - color_attachments.clearColor = { clear_color.x, clear_color.y, clear_color.z, clear_color.w }; + color_attachments.clearColor = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; color_attachments.attachment = wgpuSwapChainGetCurrentTextureView(wgpu_swap_chain); WGPURenderPassDescriptor render_pass_desc = {}; render_pass_desc.colorAttachmentCount = 1; diff --git a/examples/example_glfw_metal/main.mm b/examples/example_glfw_metal/main.mm index d818dba0..2ef6acdf 100644 --- a/examples/example_glfw_metal/main.mm +++ b/examples/example_glfw_metal/main.mm @@ -99,7 +99,7 @@ int main(int, char**) id drawable = [layer nextDrawable]; id commandBuffer = [commandQueue commandBuffer]; - renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0], clear_color[1], clear_color[2], clear_color[3]); + renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0] * clear_color[3], clear_color[1] * clear_color[3], clear_color[2] * clear_color[3], clear_color[3]); renderPassDescriptor.colorAttachments[0].texture = drawable.texture; renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; diff --git a/examples/example_glfw_opengl2/main.cpp b/examples/example_glfw_opengl2/main.cpp index fc25ff7f..ee785b1f 100644 --- a/examples/example_glfw_opengl2/main.cpp +++ b/examples/example_glfw_opengl2/main.cpp @@ -132,7 +132,7 @@ int main(int, char**) int display_w, display_h; glfwGetFramebufferSize(window, &display_w, &display_h); glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + 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); // If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp index 434c9f2d..cae62e59 100644 --- a/examples/example_glfw_opengl3/main.cpp +++ b/examples/example_glfw_opengl3/main.cpp @@ -196,7 +196,7 @@ int main(int, char**) int display_w, display_h; glfwGetFramebufferSize(window, &display_w, &display_h); glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + 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()); diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 230d21dc..d2e4004e 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -520,7 +520,10 @@ int main(int, char**) const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); if (!is_minimized) { - memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); + wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w; + wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w; + wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w; + wd->ClearValue.color.float32[3] = clear_color.w; FrameRender(wd, draw_data); FramePresent(wd); } diff --git a/examples/example_glut_opengl2/main.cpp b/examples/example_glut_opengl2/main.cpp index ecb1ece2..f45ffe34 100644 --- a/examples/example_glut_opengl2/main.cpp +++ b/examples/example_glut_opengl2/main.cpp @@ -76,7 +76,7 @@ void glut_display_func() ImGui::Render(); ImGuiIO& io = ImGui::GetIO(); glViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + 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); //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound, but prefer using the GL3+ code. ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); diff --git a/examples/example_sdl_directx11/main.cpp b/examples/example_sdl_directx11/main.cpp index 5a80115d..46da1c59 100644 --- a/examples/example_sdl_directx11/main.cpp +++ b/examples/example_sdl_directx11/main.cpp @@ -155,8 +155,9 @@ int main(int, char**) // Rendering ImGui::Render(); + const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); - g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color); + g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); g_pSwapChain->Present(1, 0); // Present with vsync diff --git a/examples/example_sdl_metal/main.mm b/examples/example_sdl_metal/main.mm index 1f33503d..efbccf4c 100644 --- a/examples/example_sdl_metal/main.mm +++ b/examples/example_sdl_metal/main.mm @@ -107,7 +107,7 @@ int main(int, char**) id drawable = [layer nextDrawable]; id commandBuffer = [commandQueue commandBuffer]; - renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0], clear_color[1], clear_color[2], clear_color[3]); + renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0] * clear_color[3], clear_color[1] * clear_color[3], clear_color[2] * clear_color[3], clear_color[3]); renderPassDescriptor.colorAttachments[0].texture = drawable.texture; renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; diff --git a/examples/example_sdl_opengl2/main.cpp b/examples/example_sdl_opengl2/main.cpp index 72898d46..016b3083 100644 --- a/examples/example_sdl_opengl2/main.cpp +++ b/examples/example_sdl_opengl2/main.cpp @@ -137,7 +137,7 @@ int main(int, char**) // Rendering ImGui::Render(); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + 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); //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); diff --git a/examples/example_sdl_opengl3/main.cpp b/examples/example_sdl_opengl3/main.cpp index e8c68ae5..b3a1c482 100644 --- a/examples/example_sdl_opengl3/main.cpp +++ b/examples/example_sdl_opengl3/main.cpp @@ -198,7 +198,7 @@ int main(int, char**) // Rendering ImGui::Render(); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + 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()); SDL_GL_SwapWindow(window); diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index 0f21b060..ea038bac 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -521,7 +521,10 @@ int main(int, char**) const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); if (!is_minimized) { - memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); + wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w; + wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w; + wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w; + wd->ClearValue.color.float32[3] = clear_color.w; FrameRender(wd, draw_data); FramePresent(wd); } diff --git a/examples/example_win32_directx10/main.cpp b/examples/example_win32_directx10/main.cpp index edde4060..2a131c18 100644 --- a/examples/example_win32_directx10/main.cpp +++ b/examples/example_win32_directx10/main.cpp @@ -140,8 +140,9 @@ int main(int, char**) // Rendering ImGui::Render(); + const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; g_pd3dDevice->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); - g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color); + g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData()); g_pSwapChain->Present(1, 0); // Present with vsync diff --git a/examples/example_win32_directx11/main.cpp b/examples/example_win32_directx11/main.cpp index 1ae4dfea..dd14c2e1 100644 --- a/examples/example_win32_directx11/main.cpp +++ b/examples/example_win32_directx11/main.cpp @@ -140,8 +140,9 @@ int main(int, char**) // Rendering ImGui::Render(); + const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); - g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color); + g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); g_pSwapChain->Present(1, 0); // Present with vsync diff --git a/examples/example_win32_directx12/main.cpp b/examples/example_win32_directx12/main.cpp index 20da6ac3..0ce990a8 100644 --- a/examples/example_win32_directx12/main.cpp +++ b/examples/example_win32_directx12/main.cpp @@ -193,7 +193,8 @@ int main(int, char**) g_pd3dCommandList->ResourceBarrier(1, &barrier); // Render Dear ImGui graphics - g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], (float*)&clear_color, 0, NULL); + const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; + g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], clear_color_with_alpha, 0, NULL); g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, NULL); g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap); ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), g_pd3dCommandList); @@ -329,9 +330,11 @@ bool CreateDeviceD3D(HWND hWnd) { IDXGIFactory4* dxgiFactory = NULL; IDXGISwapChain1* swapChain1 = NULL; - if (CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)) != S_OK || - dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &sd, NULL, NULL, &swapChain1) != S_OK || - swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain)) != S_OK) + if (CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)) != S_OK) + return false; + if (dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &sd, NULL, NULL, &swapChain1) != S_OK) + return false; + if (swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain)) != S_OK) return false; swapChain1->Release(); dxgiFactory->Release(); diff --git a/examples/example_win32_directx9/main.cpp b/examples/example_win32_directx9/main.cpp index 0b0d27cf..54e7026a 100644 --- a/examples/example_win32_directx9/main.cpp +++ b/examples/example_win32_directx9/main.cpp @@ -141,7 +141,7 @@ int main(int, char**) g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*255.0f), (int)(clear_color.y*255.0f), (int)(clear_color.z*255.0f), (int)(clear_color.w*255.0f)); + D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*clear_color.w*255.0f), (int)(clear_color.y*clear_color.w*255.0f), (int)(clear_color.z*clear_color.w*255.0f), (int)(clear_color.w*255.0f)); g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, clear_col_dx, 1.0f, 0); if (g_pd3dDevice->BeginScene() >= 0) { @@ -178,7 +178,7 @@ bool CreateDeviceD3D(HWND hWnd) ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); g_d3dpp.Windowed = TRUE; g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // Need to use an explicit format with alpha if needing per-pixel alpha composition. g_d3dpp.EnableAutoDepthStencil = TRUE; g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Present with vsync