diff --git a/.github/ISSUE_TEMPLATE/issue_template.yml b/.github/ISSUE_TEMPLATE/issue_template.yml index 6ed62493a..dda2213c3 100644 --- a/.github/ISSUE_TEMPLATE/issue_template.yml +++ b/.github/ISSUE_TEMPLATE/issue_template.yml @@ -14,6 +14,7 @@ body: attributes: value: | **Prerequisites:** + - I am not using a LLM to think or write for me. Please distill information to what's necessary and meaningful. - I have read [Frequently Asked Questions](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md). - I have read [Contributing Guidelines -> General Advices](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#getting-started--general-advice). - I have read [Contributing Guidelines -> How to open an Issue](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#how-to-open-an-issue). diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 27cb3e1dd..8061997cf 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,7 +6,7 @@ 3. Consider running the [imgui_test_suite](https://github.com/ocornut/imgui_test_engine) or adding new tests to test for expected behaviors. -4. PLEASE DO NOT SUBMIT AI SLOP OR AUTOMATED REPORTS. Submissions that are lacking proper human review/judgement before being passed to us are not welcome. +4. PLEASE DO NOT SUBMIT AI SLOP OR AUTOMATED AI REPORTS. Submissions that are lacking proper human review/judgement before being passed to us are not welcome. Do not let a LLM AI write most of the text for you. 5. Clear this template before submitting your PR. diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index 543d65216..452fe3d18 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2026-08-31: Update to compile with wgpu-native 29.0. (#9377, #9532, #9530) // 2026-08-18: Fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport() when FramebufferScale is >1.0f. (#9515, #8628) // 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378) // 2026-03-25: Added support for WGVK native backend via IMGUI_IMPL_WEBGPU_BACKEND_WGVK define, with SPIRV shaders if WGSL is not available. (#9316, #9246, #9257) @@ -68,12 +69,6 @@ #error Emscripten <4.0.10 with '-sUSE_WEBGPU=1' is not supported anymore. #endif -#if defined IMGUI_IMPL_WEBGPU_BACKEND_DAWN || defined IMGUI_IMPL_WEBGPU_BACKEND_WGVK -// Dawn renamed WGPUProgrammableStageDescriptor to WGPUComputeState (see: https://github.com/webgpu-native/webgpu-headers/pull/413) -// Using type alias until WGPU adopts the same naming convention (#8369) -using WGPUProgrammableStageDescriptor = WGPUComputeState; -#endif - // Dear ImGui prototypes from imgui_internal.h extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed); #define MEMALIGN(_SIZE,_ALIGN) (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align (copied from IM_ALIGN() macro). @@ -319,7 +314,7 @@ static void SafeRelease(FrameResources& res) SafeRelease(res.VertexBufferHost); } -static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(const char* wgsl_source) +static WGPUComputeState ImGui_ImplWGPU_CreateShaderModuleWGSL(const char* wgsl_source) { ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); IM_UNUSED(bd); @@ -346,7 +341,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(con pop_cb.userdata1 = &validation_error; wgpuDevicePopErrorScope(bd->wgpuDevice, pop_cb); - WGPUProgrammableStageDescriptor stage_desc = {}; + WGPUComputeState stage_desc = {}; if (module && !validation_error) { stage_desc.module = module; @@ -359,7 +354,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(con return stage_desc; } -static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleSPIRV(const void* spirv_binary, size_t spirv_length) +static WGPUComputeState ImGui_ImplWGPU_CreateShaderModuleSPIRV(const void* spirv_binary, size_t spirv_length) { ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); @@ -371,7 +366,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleSPIRV(co WGPUShaderModuleDescriptor desc = {}; desc.nextInChain = (WGPUChainedStruct*)&spirv_desc; - WGPUProgrammableStageDescriptor stage_desc = {}; + WGPUComputeState stage_desc = {}; stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc); stage_desc.entryPoint = { "main", WGPU_STRLEN }; @@ -445,7 +440,7 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas // Setup viewport int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); - wgpuRenderPassEncoderSetViewport(ctx, 0, 0, fb_width, fb_height, 0, 1); + wgpuRenderPassEncoderSetViewport(ctx, 0, 0, (float)fb_width, (float)fb_height, 0, 1); // Bind shader and vertex buffers wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert)); @@ -774,7 +769,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects() graphics_pipeline_desc.layout = wgpuDeviceCreatePipelineLayout(bd->wgpuDevice, &layout_desc); // Create the vertex shader - WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_vert_wgsl); + WGPUComputeState vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_vert_wgsl); if (!vertex_shader_desc.module) vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleSPIRV(__shader_vert_spirv, sizeof(__shader_vert_spirv)); graphics_pipeline_desc.vertex.module = vertex_shader_desc.module; graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint; @@ -782,15 +777,9 @@ bool ImGui_ImplWGPU_CreateDeviceObjects() // Vertex input configuration WGPUVertexAttribute attribute_desc[] = { -#if defined IMGUI_IMPL_WEBGPU_BACKEND_DAWN || defined IMGUI_IMPL_WEBGPU_BACKEND_WGVK { nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 }, { nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 }, { nullptr, WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 }, -#else - { WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 }, - { WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 }, - { WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 }, -#endif }; WGPUVertexBufferLayout buffer_layouts[1]; @@ -803,7 +792,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects() graphics_pipeline_desc.vertex.buffers = buffer_layouts; // Create the pixel shader - WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_frag_wgsl); + WGPUComputeState pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_frag_wgsl); if (!pixel_shader_desc.module) pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleSPIRV(__shader_frag_spirv, sizeof(__shader_frag_spirv)); // Create the blending setup @@ -996,11 +985,7 @@ void ImGui_ImplWGPU_NewFrame() bool ImGui_ImplWGPU_IsSurfaceStatusError(WGPUSurfaceGetCurrentTextureStatus status) { -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK) return (status == WGPUSurfaceGetCurrentTextureStatus_Error); -#else - return (status == WGPUSurfaceGetCurrentTextureStatus_OutOfMemory || status == WGPUSurfaceGetCurrentTextureStatus_DeviceLost); -#endif } bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextureStatus status) @@ -1013,7 +998,6 @@ bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextureStatus } // Helpers to obtain a string -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK) const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type) { switch (type) @@ -1036,7 +1020,7 @@ const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type) default: return "Unknown"; } } -#elif !defined(__EMSCRIPTEN__) +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__) const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level) { switch (level) diff --git a/backends/imgui_impl_wgpu.h b/backends/imgui_impl_wgpu.h index 492486401..0e344603f 100644 --- a/backends/imgui_impl_wgpu.h +++ b/backends/imgui_impl_wgpu.h @@ -97,10 +97,9 @@ bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextur void ImGui_ImplWGPU_DebugPrintAdapterInfo(const WGPUAdapter& adapter); const char* ImGui_ImplWGPU_GetBackendTypeName(WGPUBackendType type); const char* ImGui_ImplWGPU_GetAdapterTypeName(WGPUAdapterType type); -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type); const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type); -#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__) const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level); #endif diff --git a/docs/BACKENDS.md b/docs/BACKENDS.md index c86671cb6..dc80d4be7 100644 --- a/docs/BACKENDS.md +++ b/docs/BACKENDS.md @@ -72,7 +72,7 @@ For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder: -List of Platforms Backends: +List of Platform Backends: imgui_impl_android.cpp ; Android native app API imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/ diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 61510001f..28e7231f1 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -52,22 +52,47 @@ Breaking Changes: Other Changes: +- Drags, Sliders: + - Fixed an overflow using `ImGuiSliderFlags_Logarithmic` with S32/S64 types which + leads to clamped interactions. (#9526, #3361, #1823, #1316, #642) [@lailoken] +- TreeNode: + - Fixed issues/asserts with 32+ deep trees when using ImGuiTreeNodeFlags_DrawLinesXXX + features or other features requiring stack storage. (#9509) [@lasrod] - Fonts: - Reworked `AddFontDefault()` to use `io.DisplayFrameBufferScale` as part of the heuristic to select `AddFontDefaultVector()` by default, effectively using ProggyForever instead of ProggyClean on most Apple/Retina setups by default. +- ColorEdit: + - ColorButton, ColorEdit, ColorPicker: cancel-out alpha caused by BeginDisabled() so + disabled color buttons have the same color as non-disabled oness. (#9511) + - ColorButton: fixed issues/inconsistencies with checkerboard rendering when combining + color alpha and global style alpha. (#9511) [@enjmiah, @ocornut] +- Misc: + - Fixed `GetBackgroundDrawList()`/`GetForegroundDrawList()` not being properly reset + every frame when cumulated session time is very large (e.g. a few days). [@lailoken] + - Added `IM_NODEBUGSTEP` helper to tag functions with `__declspec(non_user_code)` (MSVC) + or `[[gnu::artificial]]` (Clang/GCC) in order to provide a hint to debuggers to skip + trivial functions when stepping into. + - Tagged various trivial functions using `IM_NODEBUGSTEP`: `ImVec2()`, `ImVec4()` etc. + and various operators. - ImDrawList: - Per-viewport FramebufferScale for Apple/Retina screen is applied to draw lists: - AA Fringe is scaled accordingly. - Circle and Curves tessellation error are scaled accordingly. + - Reworked assert in PushTexture() to allow convenience grace period of using a + texture that was queue for destroy during the frame. Make it safe to stick to + an existing texture during the frame. (#9528, #8465) - Backends: - QNX: added QNX Screen backend. (#9492) [@mgorchak-blackberry] - SDL2: fixed querying framebuffer scale/density when using Metal without going through a SDL_Renderer. (#5592) [@lailoken] - WebGPU: fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport()` when when `FramebufferScale` is >1.0f. (#9515, #8628) [@WayU] + - WebGPU: update to build with wgpu-native 29.0+. (#9377, #9532, #9530) [@lucascompython, @ivan-enzhaev] - Examples: - - SDL2+Metal: create Metal context without using a SDL_Renderer. + - MSVC: disabled /JMC in Visual Studio projects (unnecessary overhead). + - GLFW/SDL2/SDL3+WebGPU: fixed running with wgpu-native missing `wgpuInstanceWaitAny()`. (#9377) + - SDL2+Metal: create Metal context without using a `SDL_Renderer`. - QNX+OpenGL3, QNX+Vulkan: added QNX Screen examples. (#9492) [@mgorchak-blackberry] - OSX+OpenGL3: added example_apple_opengl3/ (OSX/Cocoa + OpenGL 3.2 Core profile). diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index fb946c4b3..699209f3a 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -3,7 +3,7 @@ ## Index - [Getting Started & General Advice](#getting-started--general-advice) -- [Issues vs Discussions](#issues-vs-discussions) +- [Using "Issues" for almost everything!](using-issues-for-almost-everything) - [How to open an Issue](#how-to-open-an-issue) - [How to open a Pull Request](#how-to-open-a-pull-request) - [Copyright / Contributor License Agreement](#copyright--contributor-license-agreement) @@ -23,18 +23,20 @@ - If you get a crash or assert, use a debugger to locate the line triggering it and read the comments around. - Please don't be a [Help Vampire](https://slash7.com/2006/12/22/vampires/). -## 'Issues' vs 'Discussions' +## Using "Issues" for almost everything! -We are happy to use 'Issues' for many type of open-ended questions. We are encouraging 'Issues' becoming an enormous, centralized and cross-referenced database of Dear ImGui contents. +We are happy to use 'Issues' for many type of open-ended questions. +We are encouraging 'Issues' becoming an enormous, centralized and cross-referenced database of Dear ImGui contents. -Only if you: +- Need help using the API? Open an Issue! +- Want to suggest a feature? Open an Issue! +- etc. + +ONLY IN THOSE CASE you can use the [Discussions forums](https://github.com/ocornut/imgui/discussions) - Cannot BUILD or LINK examples. - Cannot BUILD, or LINK, or RUN Dear ImGui in your application or custom engine. -- Cannot LOAD a font. -Then please [use the Discussions forums](https://github.com/ocornut/imgui/discussions) instead of opening an issue. - -If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an Issue. Any form of discussions is welcome as a new issue. +If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an Issue. Any form of discussions is welcome as a new Issue. ## How to open an issue diff --git a/examples/example_allegro5/example_allegro5.vcxproj b/examples/example_allegro5/example_allegro5.vcxproj index aa8a752d7..36c55bb10 100644 --- a/examples/example_allegro5/example_allegro5.vcxproj +++ b/examples/example_allegro5/example_allegro5.vcxproj @@ -92,6 +92,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -107,6 +108,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj b/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj index bce5781f4..18d95894f 100644 --- a/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj +++ b/examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj @@ -92,6 +92,7 @@ Disabled ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -107,6 +108,7 @@ Disabled ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj b/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj index cd59daed3..3e9d71e13 100644 --- a/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj +++ b/examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj @@ -92,6 +92,7 @@ Disabled ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -107,6 +108,7 @@ Disabled ..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj b/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj index 6f44abfec..492aa0e3f 100644 --- a/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj +++ b/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj @@ -93,6 +93,7 @@ ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true @@ -109,6 +110,7 @@ ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_glfw_wgpu/CMakeLists.txt b/examples/example_glfw_wgpu/CMakeLists.txt index 4eaaee762..b76054877 100644 --- a/examples/example_glfw_wgpu/CMakeLists.txt +++ b/examples/example_glfw_wgpu/CMakeLists.txt @@ -1,10 +1,3 @@ -# Building for desktop with Dawn: -# 1. git clone https://github.com/google/dawn dawn -# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn -# 3. cmake --build build -# The resulting binary will be found at one of the following locations: -# * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe] - # Building for desktop with WGPU-Native: # 1. download WGPU-Native autogenerated binary modules for your platform/compiler from: https://github.com/gfx-rs/wgpu-native/releases # 2. unzip the downloaded file in your_preferred_folder @@ -13,7 +6,14 @@ # The resulting binary will be found at one of the following locations: # * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe] -# Building for desktop with WGVK (MUCH EASIER) +# Building for desktop with Dawn: (VERY LONG TO BUILD) +# 1. git clone https://github.com/google/dawn dawn +# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn +# 3. cmake --build build +# The resulting binary will be found at one of the following locations: +# * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe] + +# Building for desktop with WGVK: # 1. git clone https://github.com/manuel5975p/WGVK wgvk # 2. cmake -B build -DIMGUI_WGVK_DIR=wgvk # 3. cmake --build build @@ -29,7 +29,7 @@ # 4. emrun build/index.html cmake_minimum_required(VERSION 3.22) # Dawn requires CMake >= 3.22 -project(imgui_example_glfw_wgpu C CXX) +project(example_glfw_wgpu C CXX) set(IMGUI_EXECUTABLE example_glfw_wgpu) diff --git a/examples/example_glfw_wgpu/main.cpp b/examples/example_glfw_wgpu/main.cpp index fcd37301a..6773cbc78 100644 --- a/examples/example_glfw_wgpu/main.cpp +++ b/examples/example_glfw_wgpu/main.cpp @@ -345,29 +345,25 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2) { IM_UNUSED(userdata2); - if (status == WGPURequestAdapterStatus_Success) + if (status != WGPURequestAdapterStatus_Success) { - WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1; - *extAdapter = adapter; - } - else - { - printf("Request_adapter status=%#.8x message=%.*s\n", status, (int) message.length, message.data); + printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data); + return; } + WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1; + *extAdapter = adapter; } static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2) { IM_UNUSED(userdata2); - if (status == WGPURequestDeviceStatus_Success) + if (status != WGPURequestDeviceStatus_Success) { - WGPUDevice* extDevice = (WGPUDevice*)userdata1; - *extDevice = device; - } - else - { - printf("Request_device status=%#.8x message=%.*s\n", status, (int) message.length, message.data); + printf("Request_device status=%#.8x message=%.*s\n", status, (int)message.length, message.data); + return; } + WGPUDevice* extDevice = (WGPUDevice*)userdata1; + *extDevice = device; } static WGPUAdapter RequestAdapter(WGPUInstance& instance) @@ -381,8 +377,10 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance) adapterCallbackInfo.userdata1 = &local_adapter; WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo); +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) WGPUFutureWaitInfo waitInfo = { future, false }; wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); +#endif IM_ASSERT(local_adapter && "Error on Adapter request"); return local_adapter; } @@ -394,15 +392,20 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter) deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; deviceCallbackInfo.callback = handle_request_device; deviceCallbackInfo.userdata1 = &local_device; + WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo); +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) WGPUFutureWaitInfo waitInfo = { future, false }; wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); +#else + IM_UNUSED(instance); +#endif IM_ASSERT(local_device && "Error on Device request"); return local_device; } #endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU -bool InitWGPU(GLFWwindow* window) +static bool InitWGPU(GLFWwindow* window) { WGPUTextureFormat preferred_fmt = WGPUTextureFormat_Undefined; // acquired from SurfaceCapabilities @@ -451,7 +454,7 @@ bool InitWGPU(GLFWwindow* window) #if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) wgpuSetLogCallback( - [](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr + [](WGPULogLevel level, WGPUStringView msg, void*) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr ); wgpuSetLogLevel(WGPULogLevel_Warn); #endif diff --git a/examples/example_glut_opengl2/example_glut_opengl2.vcxproj b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj index 2e12665d5..bdd9af440 100644 --- a/examples/example_glut_opengl2/example_glut_opengl2.vcxproj +++ b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj @@ -92,6 +92,7 @@ Disabled $(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -107,6 +108,7 @@ Disabled $(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_null/example_null.vcxproj b/examples/example_null/example_null.vcxproj index 75fd43b44..61e388f96 100644 --- a/examples/example_null/example_null.vcxproj +++ b/examples/example_null/example_null.vcxproj @@ -88,6 +88,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories); /utf-8 %(AdditionalOptions) + false true @@ -102,6 +103,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories); /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj b/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj index 2bcc7097c..afa9d5de4 100644 --- a/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj +++ b/examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj @@ -93,6 +93,7 @@ Disabled ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -108,6 +109,7 @@ Disabled ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj b/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj index aca6edc5d..35b7ed7df 100644 --- a/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj +++ b/examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj @@ -92,6 +92,7 @@ Disabled ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -107,6 +108,7 @@ Disabled ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj b/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj index d0cb96ba1..b5a80197e 100644 --- a/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj +++ b/examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj @@ -92,6 +92,7 @@ Disabled ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -107,6 +108,7 @@ Disabled ..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj b/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj index 86b883a69..9d7951be8 100644 --- a/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj +++ b/examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj @@ -93,6 +93,7 @@ Disabled ..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -108,6 +109,7 @@ Disabled ..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj b/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj index 4bedc45d8..b2269bc9d 100644 --- a/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj +++ b/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj @@ -93,6 +93,7 @@ ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true @@ -109,6 +110,7 @@ ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl2_wgpu/CMakeLists.txt b/examples/example_sdl2_wgpu/CMakeLists.txt index aff4a184f..0a8fed305 100644 --- a/examples/example_sdl2_wgpu/CMakeLists.txt +++ b/examples/example_sdl2_wgpu/CMakeLists.txt @@ -1,10 +1,3 @@ -# Building for desktop with Dawn: -# 1. git clone https://github.com/google/dawn dawn -# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn -# 3. cmake --build build -# The resulting binary will be found at one of the following locations: -# * build/example_sdl2_wgpu[.exe] or build/Debug/example_sdl2_wgpu[.exe] - # Building for desktop with WGPU-Native: # 1. download WGPU-Native autogenerated binary modules for your platform/compiler from: https://github.com/gfx-rs/wgpu-native/releases # 2. unzip the downloaded file in your_preferred_folder @@ -13,7 +6,14 @@ # The resulting binary will be found at one of the following locations: # * build/example_sdl2_wgpu[.exe] or build/Debug/example_sdl2_wgpu[.exe] -# Building for desktop with WGVK (MUCH EASIER) +# Building for desktop with Dawn: (VERY LONG TO BUILD) +# 1. git clone https://github.com/google/dawn dawn +# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn +# 3. cmake --build build +# The resulting binary will be found at one of the following locations: +# * build/example_sdl2_wgpu[.exe] or build/Debug/example_sdl2_wgpu[.exe] + +# Building for desktop with WGVK: # 1. git clone https://github.com/manuel5975p/WGVK wgvk # 2. cmake -B build -DIMGUI_WGVK_DIR=wgvk # 3. cmake --build build @@ -29,7 +29,7 @@ # 4. emrun build/index.html cmake_minimum_required(VERSION 3.22) # Dawn requires CMake >= 3.22 -project(imgui_example_sdl2_wgpu C CXX) +project(example_sdl2_wgpu C CXX) set(IMGUI_EXECUTABLE example_sdl2_wgpu) @@ -37,7 +37,7 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE) endif() -set(CMAKE_CXX_STANDARD 10) # Dawn requires C++20 +set(CMAKE_CXX_STANDARD 20) # Dawn requires C++20 # Dear ImGui set(IMGUI_DIR ../../) diff --git a/examples/example_sdl2_wgpu/main.cpp b/examples/example_sdl2_wgpu/main.cpp index 6898d03cd..b0fa54179 100644 --- a/examples/example_sdl2_wgpu/main.cpp +++ b/examples/example_sdl2_wgpu/main.cpp @@ -330,29 +330,25 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2) { IM_UNUSED(userdata2); - if (status == WGPURequestAdapterStatus_Success) - { - WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1; - *extAdapter = adapter; - } - else + if (status != WGPURequestAdapterStatus_Success) { printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data); + return; } + WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1; + *extAdapter = adapter; } static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2) { IM_UNUSED(userdata2); - if (status == WGPURequestDeviceStatus_Success) - { - WGPUDevice* extDevice = (WGPUDevice*)userdata1; - *extDevice = device; - } - else + if (status != WGPURequestDeviceStatus_Success) { printf("Request_device status=%#.8x message=%.*s\n", status, (int)message.length, message.data); + return; } + WGPUDevice* extDevice = (WGPUDevice*)userdata1; + *extDevice = device; } static WGPUAdapter RequestAdapter(WGPUInstance& instance) @@ -366,8 +362,10 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance) adapterCallbackInfo.userdata1 = &local_adapter; WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo); +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) WGPUFutureWaitInfo waitInfo = { future, false }; wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); +#endif IM_ASSERT(local_adapter && "Error on Adapter request"); return local_adapter; } @@ -379,9 +377,14 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter) deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; deviceCallbackInfo.callback = handle_request_device; deviceCallbackInfo.userdata1 = &local_device; + WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo); +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) WGPUFutureWaitInfo waitInfo = { future, false }; wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); +#else + IM_UNUSED(instance); +#endif IM_ASSERT(local_device && "Error on Device request"); return local_device; } @@ -437,7 +440,7 @@ static bool InitWGPU(SDL_Window* window) #if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) wgpuSetLogCallback( - [](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr + [](WGPULogLevel level, WGPUStringView msg, void*) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr ); wgpuSetLogLevel(WGPULogLevel_Warn); #endif diff --git a/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj b/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj index f38d290c6..057874196 100644 --- a/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj +++ b/examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj @@ -93,6 +93,7 @@ Disabled ..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -108,6 +109,7 @@ Disabled ..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj b/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj index c470f88bb..dbe1fa915 100644 --- a/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj +++ b/examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj @@ -92,6 +92,7 @@ Disabled ..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -107,6 +108,7 @@ Disabled ..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj b/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj index 02b0d35f2..bd83258d8 100644 --- a/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj +++ b/examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj @@ -93,6 +93,7 @@ ..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories) _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true @@ -109,6 +110,7 @@ ..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories) _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj b/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj index f42014544..35fc962ad 100644 --- a/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj +++ b/examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj @@ -92,6 +92,7 @@ Disabled ..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true @@ -107,6 +108,7 @@ Disabled ..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj b/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj index af1144789..c3a200cf5 100644 --- a/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj +++ b/examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj @@ -93,6 +93,7 @@ ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories) _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true @@ -109,6 +110,7 @@ ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories) _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_sdl3_wgpu/CMakeLists.txt b/examples/example_sdl3_wgpu/CMakeLists.txt index b7b05881d..b05dcd459 100644 --- a/examples/example_sdl3_wgpu/CMakeLists.txt +++ b/examples/example_sdl3_wgpu/CMakeLists.txt @@ -29,7 +29,7 @@ # 5. emrun build/index.html cmake_minimum_required(VERSION 3.22) # Dawn requires CMake >= 3.22 -project(imgui_example_sdl3_wgpu C CXX) +project(example_sdl3_wgpu C CXX) set(IMGUI_EXECUTABLE example_sdl3_wgpu) diff --git a/examples/example_sdl3_wgpu/main.cpp b/examples/example_sdl3_wgpu/main.cpp index 6b9a24e11..c66748f80 100644 --- a/examples/example_sdl3_wgpu/main.cpp +++ b/examples/example_sdl3_wgpu/main.cpp @@ -341,29 +341,25 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2) { IM_UNUSED(userdata2); - if (status == WGPURequestAdapterStatus_Success) - { - WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1; - *extAdapter = adapter; - } - else + if (status != WGPURequestAdapterStatus_Success) { printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data); + return; } + WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1; + *extAdapter = adapter; } static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2) { IM_UNUSED(userdata2); - if (status == WGPURequestDeviceStatus_Success) - { - WGPUDevice* extDevice = (WGPUDevice*)userdata1; - *extDevice = device; - } - else + if (status != WGPURequestDeviceStatus_Success) { printf("Request_device status=%#.8x message=%.*s\n", status, (int)message.length, message.data); + return; } + WGPUDevice* extDevice = (WGPUDevice*)userdata1; + *extDevice = device; } static WGPUAdapter RequestAdapter(WGPUInstance& instance) @@ -377,8 +373,10 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance) adapterCallbackInfo.userdata1 = &local_adapter; WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo); +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) WGPUFutureWaitInfo waitInfo = { future, false }; wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); +#endif IM_ASSERT(local_adapter && "Error on Adapter request"); return local_adapter; } @@ -390,9 +388,14 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter) deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; deviceCallbackInfo.callback = handle_request_device; deviceCallbackInfo.userdata1 = &local_device; + WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo); +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) WGPUFutureWaitInfo waitInfo = { future, false }; wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); +#else + IM_UNUSED(instance); +#endif IM_ASSERT(local_device && "Error on Device request"); return local_device; } @@ -448,7 +451,7 @@ static bool InitWGPU(SDL_Window* window) #if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) wgpuSetLogCallback( - [](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr + [](WGPULogLevel level, WGPUStringView msg, void*) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr ); wgpuSetLogLevel(WGPULogLevel_Warn); #endif diff --git a/examples/example_win32_directx10/example_win32_directx10.vcxproj b/examples/example_win32_directx10/example_win32_directx10.vcxproj index 7fb767702..add37ed97 100644 --- a/examples/example_win32_directx10/example_win32_directx10.vcxproj +++ b/examples/example_win32_directx10/example_win32_directx10.vcxproj @@ -88,6 +88,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories); /utf-8 %(AdditionalOptions) + false true @@ -102,6 +103,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories); /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_win32_directx11/example_win32_directx11.vcxproj b/examples/example_win32_directx11/example_win32_directx11.vcxproj index 9e89353d4..ed0b509a8 100644 --- a/examples/example_win32_directx11/example_win32_directx11.vcxproj +++ b/examples/example_win32_directx11/example_win32_directx11.vcxproj @@ -88,6 +88,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories); /utf-8 %(AdditionalOptions) + false true @@ -102,6 +103,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories); /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_win32_directx12/example_win32_directx12.vcxproj b/examples/example_win32_directx12/example_win32_directx12.vcxproj index c4b81e76f..27b501d85 100644 --- a/examples/example_win32_directx12/example_win32_directx12.vcxproj +++ b/examples/example_win32_directx12/example_win32_directx12.vcxproj @@ -89,6 +89,7 @@ ..\..;..\..\backends;%(AdditionalIncludeDirectories) _UNICODE;UNICODE;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true @@ -104,6 +105,7 @@ ..\..;..\..\backends;%(AdditionalIncludeDirectories) _UNICODE;UNICODE;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_win32_directx9/example_win32_directx9.vcxproj b/examples/example_win32_directx9/example_win32_directx9.vcxproj index c5efda38b..84e16c9c6 100644 --- a/examples/example_win32_directx9/example_win32_directx9.vcxproj +++ b/examples/example_win32_directx9/example_win32_directx9.vcxproj @@ -88,6 +88,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; /utf-8 %(AdditionalOptions) + false true @@ -102,6 +103,7 @@ Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include; /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_win32_opengl3/example_win32_opengl3.vcxproj b/examples/example_win32_opengl3/example_win32_opengl3.vcxproj index b9b42677c..2ffb7d413 100644 --- a/examples/example_win32_opengl3/example_win32_opengl3.vcxproj +++ b/examples/example_win32_opengl3/example_win32_opengl3.vcxproj @@ -88,6 +88,7 @@ Disabled ..\..;..\..\backends; /utf-8 %(AdditionalOptions) + false true @@ -102,6 +103,7 @@ Disabled ..\..;..\..\backends; /utf-8 %(AdditionalOptions) + false true diff --git a/examples/example_win32_vulkan/example_win32_vulkan.vcxproj b/examples/example_win32_vulkan/example_win32_vulkan.vcxproj index f3ba4aa61..bede521e2 100644 --- a/examples/example_win32_vulkan/example_win32_vulkan.vcxproj +++ b/examples/example_win32_vulkan/example_win32_vulkan.vcxproj @@ -89,6 +89,7 @@ ..\..;..\..\backends;%VULKAN_SDK%\include;%(AdditionalIncludeDirectories) _UNICODE;UNICODE;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true @@ -104,6 +105,7 @@ ..\..;..\..\backends;%VULKAN_SDK%\include;%(AdditionalIncludeDirectories) _UNICODE;UNICODE;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) + false true diff --git a/imconfig.h b/imconfig.h index b40db3898..a25fa89af 100644 --- a/imconfig.h +++ b/imconfig.h @@ -107,15 +107,18 @@ // This will be inlined as part of ImVec2 and ImVec4 class declarations. /* #define IM_VEC2_CLASS_EXTRA \ - constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \ - operator MyVec2() const { return MyVec2(x,y); } + IM_NODEBUGSTEP constexpr inline ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \ + IM_NODEBUGSTEP inline operator MyVec2() const { return MyVec2(x,y); } -#define IM_VEC4_CLASS_EXTRA \ - constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \ - operator MyVec4() const { return MyVec4(x,y,z,w); } +#define IM_VEC4_CLASS_EXTRA \ + IM_NODEBUGSTEP constexpr inline ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \ + IM_NODEBUGSTEP inline operator MyVec4() const { return MyVec4(x,y,z,w); } */ -//---- ...Or use Dear ImGui's own very basic math operators. +//---- ...Or use Dear ImGui's own basic math operators in every file including imgui.h: +//#ifndef IMGUI_DEFINE_MATH_OPERATORS //#define IMGUI_DEFINE_MATH_OPERATORS +//#endif +//---- ...Or manually '#define IMGUI_DEFINE_MATH_OPERATORS' before '#include "imgui.h"' to use from one file. //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). diff --git a/imgui.cpp b/imgui.cpp index 98db04810..3e3f14d4c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5424,12 +5424,13 @@ static ImDrawList* GetViewportBgFgDrawList(ImGuiViewportP* viewport, size_t draw } // Our ImDrawList system requires that there is always a command - if (viewport->BgFgDrawListsLastTimeActive[drawlist_no] != (float)g.Time) + if (viewport->BgFgDrawListsLastFrameActive[drawlist_no] != g.FrameCount) { draw_list->_ResetForNewFrame(); draw_list->_SetPixelDensity(viewport->FramebufferScale.x); draw_list->PushTexture(g.IO.Fonts->TexRef); draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false); + viewport->BgFgDrawListsLastFrameActive[drawlist_no] = g.FrameCount; viewport->BgFgDrawListsLastTimeActive[drawlist_no] = (float)g.Time; } return draw_list; @@ -6466,7 +6467,7 @@ void ImGui::Render() for (ImGuiViewportP* viewport : g.Viewports) { InitViewportDrawData(viewport); - if (viewport->BgFgDrawLists[0] != NULL && viewport->BgFgDrawListsLastTimeActive[0] == (float)g.Time) + if (viewport->BgFgDrawLists[0] != NULL && viewport->BgFgDrawListsLastFrameActive[0] == g.FrameCount) AddDrawListToDrawDataEx(&viewport->DrawDataP, viewport->DrawDataBuilder.Layers[0], GetBackgroundDrawList(viewport)); } @@ -6498,7 +6499,7 @@ void ImGui::Render() FlattenDrawDataIntoSingleLayer(&viewport->DrawDataBuilder); // Add foreground ImDrawList (for each active viewport) - if (viewport->BgFgDrawLists[1] != NULL && viewport->BgFgDrawListsLastTimeActive[1] == (float)g.Time) + if (viewport->BgFgDrawLists[1] != NULL && viewport->BgFgDrawListsLastFrameActive[1] == g.FrameCount) AddDrawListToDrawDataEx(&viewport->DrawDataP, viewport->DrawDataBuilder.Layers[0], GetForegroundDrawList(viewport)); // We call _PopUnusedDrawCmd() last thing, as RenderDimmedBackgrounds() rely on a valid command being there (especially in docking branch). @@ -21994,7 +21995,7 @@ static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext*, const char* t ::CloseClipboard(); } -#elif defined(__APPLE__) && TARGET_OS_OSX && defined(IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS) +#elif defined(__APPLE__) && defined(TARGET_OS_OSX) && TARGET_OS_OSX && defined(IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS) #include // Use old API to avoid need for separate .mm file static PasteboardRef main_clipboard = 0; @@ -22584,7 +22585,7 @@ void ImGui::DebugNodeTexture(ImTextureData* tex, int int_id, const ImFontAtlasRe Checkbox("Show used rect", &cfg->ShowTextureUsedRect); PushStyleVar(ImGuiStyleVar_ImageBorderSize, ImMax(1.0f, g.Style.ImageBorderSize)); ImVec2 p = GetCursorScreenPos(); - if (tex->WantDestroyNextFrame) + if (tex->Status == ImTextureStatus_WantDestroy || tex->Status == ImTextureStatus_Destroyed) Dummy(ImVec2((float)tex->Width, (float)tex->Height)); else ImageWithBg(tex->GetTexRef(), ImVec2((float)tex->Width, (float)tex->Height), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); diff --git a/imgui.h b/imgui.h index c35b4d74a..7a34d1827 100644 --- a/imgui.h +++ b/imgui.h @@ -30,7 +30,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.93.0 WIP" -#define IMGUI_VERSION_NUM 19294 +#define IMGUI_VERSION_NUM 19295 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 #define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch. @@ -130,6 +130,16 @@ Index of this file: #define IM_MSVC_RUNTIME_CHECKS_RESTORE #endif +// Alternative to using a .natstepfilter file or other scripts in misc/debuggers/ to skip debug-stepping selected trivial functions. +// If you get a compiler error or warning related to use, please report it to us! +#if (defined(__clang__) && (__clang_major__ >= 7)) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) +#define IM_NODEBUGSTEP [[gnu::artificial]] +#elif defined(_MSC_VER) && (_MSC_VER >= 1915) +#define IM_NODEBUGSTEP __declspec(non_user_code) +#else +#define IM_NODEBUGSTEP +#endif + // Warnings #ifdef _MSC_VER #pragma warning (push) @@ -299,11 +309,11 @@ typedef void (*ImGuiMemFreeFunc)(void* ptr, void* user_data); IM_MSVC_RUNTIME_CHECKS_OFF struct ImVec2 { - float x, y; - constexpr ImVec2() : x(0.0f), y(0.0f) { } - constexpr ImVec2(float _x, float _y) : x(_x), y(_y) { } - float& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((float*)(void*)(char*)this)[idx]; } // We very rarely use this [] operator, so the assert overhead is fine. - float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const float*)(const void*)(const char*)this)[idx]; } + float x, y; + IM_NODEBUGSTEP constexpr inline ImVec2() : x(0.0f), y(0.0f) { } + IM_NODEBUGSTEP constexpr inline ImVec2(float _x, float _y) : x(_x), y(_y) { } + float& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((float*)(void*)(char*)this)[idx]; } // We very rarely use this [] operator, so the assert overhead is fine. + float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const float*)(const void*)(const char*)this)[idx]; } #ifdef IM_VEC2_CLASS_EXTRA IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2. #endif @@ -312,9 +322,9 @@ struct ImVec2 // ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type] struct ImVec4 { - float x, y, z, w; - constexpr ImVec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { } - constexpr ImVec4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) { } + float x, y, z, w; + IM_NODEBUGSTEP constexpr inline ImVec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { } + IM_NODEBUGSTEP constexpr inline ImVec4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) { } #ifdef IM_VEC4_CLASS_EXTRA IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4. #endif @@ -2345,13 +2355,13 @@ struct ImVector inline int size_in_bytes() const { return Size * (int)sizeof(T); } inline int max_size() const { return 0x7FFFFFFF / (int)sizeof(T); } inline int capacity() const { return Capacity; } - inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Data[i]; } - inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Data[i]; } + IM_NODEBUGSTEP inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Data[i]; } + IM_NODEBUGSTEP inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Data[i]; } - inline T* begin() { return Data; } - inline const T* begin() const { return Data; } - inline T* end() { return Data + Size; } - inline const T* end() const { return Data + Size; } + IM_NODEBUGSTEP inline T* begin() { return Data; } + IM_NODEBUGSTEP inline const T* begin() const { return Data; } + IM_NODEBUGSTEP inline T* end() { return Data + Size; } + IM_NODEBUGSTEP inline const T* end() const { return Data + Size; } inline T& front() { IM_ASSERT(Size > 0); return Data[0]; } inline const T& front() const { IM_ASSERT(Size > 0); return Data[0]; } inline T& back() { IM_ASSERT(Size > 0); return Data[Size - 1]; } @@ -3074,41 +3084,41 @@ struct ImGuiListClipper #define IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED IM_MSVC_RUNTIME_CHECKS_OFF // ImVec2 operators -inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); } -inline ImVec2 operator*(const float lhs, const ImVec2& rhs) { return ImVec2(lhs * rhs.x, lhs * rhs.y); } -inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); } -inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } -inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); } -inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } -inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); } -inline ImVec2 operator+(const ImVec2& lhs) { return lhs; } -inline ImVec2 operator-(const ImVec2& lhs) { return ImVec2(-lhs.x, -lhs.y); } -inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } -inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } -inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } -inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } -inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; } -inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; } -inline bool operator==(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } -inline bool operator!=(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y; } +IM_NODEBUGSTEP inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); } +IM_NODEBUGSTEP inline ImVec2 operator*(const float lhs, const ImVec2& rhs) { return ImVec2(lhs * rhs.x, lhs * rhs.y); } +IM_NODEBUGSTEP inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); } +IM_NODEBUGSTEP inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } +IM_NODEBUGSTEP inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); } +IM_NODEBUGSTEP inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } +IM_NODEBUGSTEP inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); } +IM_NODEBUGSTEP inline ImVec2 operator+(const ImVec2& lhs) { return lhs; } +IM_NODEBUGSTEP inline ImVec2 operator-(const ImVec2& lhs) { return ImVec2(-lhs.x, -lhs.y); } +IM_NODEBUGSTEP inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } +IM_NODEBUGSTEP inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } +IM_NODEBUGSTEP inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } +IM_NODEBUGSTEP inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } +IM_NODEBUGSTEP inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; } +IM_NODEBUGSTEP inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; } +IM_NODEBUGSTEP inline bool operator==(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } +IM_NODEBUGSTEP inline bool operator!=(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y; } // ImVec4 operators -inline ImVec4 operator*(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); } -inline ImVec4 operator*(const float lhs, const ImVec4& rhs) { return ImVec4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w); } -inline ImVec4 operator/(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs); } -inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); } -inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); } -inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); } -inline ImVec4 operator/(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w); } -inline ImVec4 operator+(const ImVec4& lhs) { return lhs; } -inline ImVec4 operator-(const ImVec4& lhs) { return ImVec4(-lhs.x, -lhs.y, -lhs.z, -lhs.w); } -inline ImVec4& operator*=(ImVec4& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; lhs.z *= rhs; lhs.w *= rhs; return lhs; } -inline ImVec4& operator/=(ImVec4& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; lhs.z /= rhs; lhs.w /= rhs; return lhs; } -inline ImVec4& operator+=(ImVec4& lhs, const ImVec4& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; lhs.z += rhs.z; lhs.w += rhs.w; return lhs; } -inline ImVec4& operator-=(ImVec4& lhs, const ImVec4& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; lhs.z -= rhs.z; lhs.w -= rhs.w; return lhs; } -inline ImVec4& operator*=(ImVec4& lhs, const ImVec4& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; lhs.z *= rhs.z; lhs.w *= rhs.w; return lhs; } -inline ImVec4& operator/=(ImVec4& lhs, const ImVec4& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; lhs.z /= rhs.z; lhs.w /= rhs.w; return lhs; } -inline bool operator==(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w; } -inline bool operator!=(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z || lhs.w != rhs.w; } +IM_NODEBUGSTEP inline ImVec4 operator*(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); } +IM_NODEBUGSTEP inline ImVec4 operator*(const float lhs, const ImVec4& rhs) { return ImVec4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w); } +IM_NODEBUGSTEP inline ImVec4 operator/(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs); } +IM_NODEBUGSTEP inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); } +IM_NODEBUGSTEP inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); } +IM_NODEBUGSTEP inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); } +IM_NODEBUGSTEP inline ImVec4 operator/(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w); } +IM_NODEBUGSTEP inline ImVec4 operator+(const ImVec4& lhs) { return lhs; } +IM_NODEBUGSTEP inline ImVec4 operator-(const ImVec4& lhs) { return ImVec4(-lhs.x, -lhs.y, -lhs.z, -lhs.w); } +IM_NODEBUGSTEP inline ImVec4& operator*=(ImVec4& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; lhs.z *= rhs; lhs.w *= rhs; return lhs; } +IM_NODEBUGSTEP inline ImVec4& operator/=(ImVec4& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; lhs.z /= rhs; lhs.w /= rhs; return lhs; } +IM_NODEBUGSTEP inline ImVec4& operator+=(ImVec4& lhs, const ImVec4& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; lhs.z += rhs.z; lhs.w += rhs.w; return lhs; } +IM_NODEBUGSTEP inline ImVec4& operator-=(ImVec4& lhs, const ImVec4& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; lhs.z -= rhs.z; lhs.w -= rhs.w; return lhs; } +IM_NODEBUGSTEP inline ImVec4& operator*=(ImVec4& lhs, const ImVec4& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; lhs.z *= rhs.z; lhs.w *= rhs.w; return lhs; } +IM_NODEBUGSTEP inline ImVec4& operator/=(ImVec4& lhs, const ImVec4& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; lhs.z /= rhs.z; lhs.w /= rhs.w; return lhs; } +IM_NODEBUGSTEP inline bool operator==(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w; } +IM_NODEBUGSTEP inline bool operator!=(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z || lhs.w != rhs.w; } IM_MSVC_RUNTIME_CHECKS_RESTORE #endif diff --git a/imgui_draw.cpp b/imgui_draw.cpp index d2c8e68b7..2072b6317 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -705,7 +705,7 @@ void ImDrawList::PushTexture(ImTextureRef tex_ref) _TextureStack.push_back(tex_ref); _CmdHeader.TexRef = tex_ref; if (tex_ref._TexData != NULL) - IM_ASSERT(tex_ref._TexData->WantDestroyNextFrame == false); + IM_ASSERT(tex_ref._TexData->Status != ImTextureStatus_WantDestroy && tex_ref._TexData->Status != ImTextureStatus_Destroyed); _OnChangedTexture(); } @@ -6225,26 +6225,33 @@ ImDrawFlags ImGui::CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRe // Helper for ColorPicker4() // NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that. // Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether. -// FIXME: uses ImGui::GetColorU32 -void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, ImDrawFlags flags) +void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float alpha, float grid_step, ImVec2 grid_off, float rounding, ImDrawFlags flags) { if ((flags & ImDrawFlags_RoundCornersMask_) == 0) - flags = ImDrawFlags_RoundCornersDefault_; + flags = ImDrawFlags_RoundCornersAll; if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) { - ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col)); - ImU32 col_bg2 = GetColorU32(ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col)); - draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags); + IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f); + const ImU32 a_mask = (ImU32)(alpha * 255.0f) << IM_COL32_A_SHIFT; + ImU32 col_bg1 = (ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col) & ~IM_COL32_A_MASK) | a_mask; + ImU32 col_bg2 = (ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col) & ~IM_COL32_A_MASK) | a_mask; + const bool dual_layer = (alpha == 1.0f); // Dual layer is faster but incorrect if blending. + if (dual_layer) + draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags); int yi = 0; for (float y = p_min.y + grid_off.y; y < p_max.y; y += grid_step, yi++) { - float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y); + float y1 = ImClamp((float)(int)y, p_min.y, p_max.y), y2 = ImMin((float)(int)(y + grid_step), p_max.y); if (y2 <= y1) continue; - for (float x = p_min.x + grid_off.x + ((yi ^ 1) & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f) + + const float x_start_off = dual_layer ? (((yi ^ 1) & 1) * grid_step) : 0.0f; + const float x_step = dual_layer ? (grid_step * 2.0f) : (grid_step); + int xi = 0; + for (float x = p_min.x + grid_off.x + x_start_off; x < p_max.x; x += x_step, xi++) { - float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x); + float x1 = ImClamp((float)(int)x, p_min.x, p_max.x), x2 = ImMin((float)(int)(x + grid_step), p_max.x); if (x2 <= x1) continue; ImDrawFlags cell_flags = ImDrawFlags_RoundCornersNone; // FIXME: Could use CalcRoundingFlagsForRectInRect() @@ -6253,7 +6260,8 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p // Combine flags cell_flags = (flags == ImDrawFlags_RoundCornersNone || cell_flags == ImDrawFlags_RoundCornersNone) ? ImDrawFlags_RoundCornersNone : (cell_flags & flags); - draw_list->AddRectFilled(ImVec2(x1, y1), ImVec2(x2, y2), col_bg2, rounding, cell_flags); + ImU32 col_bg = dual_layer ? col_bg2 : (((yi + xi) & 1) ? col_bg2 : col_bg1); + draw_list->AddRectFilled(ImVec2(x1, y1), ImVec2(x2, y2), col_bg, rounding, cell_flags); } } } diff --git a/imgui_internal.h b/imgui_internal.h index c9625142d..038ee34fa 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -576,25 +576,25 @@ IM_MSVC_RUNTIME_CHECKS_OFF struct ImVec1 { float x; - constexpr ImVec1() : x(0.0f) { } - constexpr ImVec1(float _x) : x(_x) { } + IM_NODEBUGSTEP constexpr inline ImVec1() : x(0.0f) { } + IM_NODEBUGSTEP constexpr inline ImVec1(float _x) : x(_x) { } }; // Helper: ImVec2i (2D vector, integer) struct ImVec2i { int x, y; - constexpr ImVec2i() : x(0), y(0) {} - constexpr ImVec2i(int _x, int _y) : x(_x), y(_y) {} + IM_NODEBUGSTEP constexpr inline ImVec2i() : x(0), y(0) {} + IM_NODEBUGSTEP constexpr inline ImVec2i(int _x, int _y) : x(_x), y(_y) {} }; // Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage) struct ImVec2ih { short x, y; - constexpr ImVec2ih() : x(0), y(0) {} - constexpr ImVec2ih(short _x, short _y) : x(_x), y(_y) {} - constexpr explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {} + IM_NODEBUGSTEP constexpr inline ImVec2ih() : x(0), y(0) {} + IM_NODEBUGSTEP constexpr inline ImVec2ih(short _x, short _y) : x(_x), y(_y) {} + IM_NODEBUGSTEP constexpr inline explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {} }; // Helper: ImRect (2D axis aligned bounding-box) @@ -604,10 +604,10 @@ struct IMGUI_API ImRect ImVec2 Min; // Upper-left ImVec2 Max; // Lower-right - constexpr ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {} - constexpr ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} - constexpr ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} - constexpr ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} + IM_NODEBUGSTEP constexpr inline ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {} + IM_NODEBUGSTEP constexpr inline ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} + IM_NODEBUGSTEP constexpr inline ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} + IM_NODEBUGSTEP constexpr inline ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); } ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); } @@ -709,13 +709,13 @@ struct ImSpan inline bool empty() const { return Data == DataEnd; } inline int size() const { return (int)(ptrdiff_t)(DataEnd - Data); } inline int size_in_bytes() const { return (int)(ptrdiff_t)(DataEnd - Data) * (int)sizeof(T); } - inline T& operator[](int i) { T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; } - inline const T& operator[](int i) const { const T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; } - inline T* begin() { return Data; } - inline const T* begin() const { return Data; } - inline T* end() { return DataEnd; } - inline const T* end() const { return DataEnd; } + IM_NODEBUGSTEP inline T& operator[](int i) { T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; } + IM_NODEBUGSTEP inline const T& operator[](int i) const { const T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; } + IM_NODEBUGSTEP inline T* begin() { return Data; } + IM_NODEBUGSTEP inline const T* begin() const { return Data; } + IM_NODEBUGSTEP inline T* end() { return DataEnd; } + IM_NODEBUGSTEP inline const T* end() const { return DataEnd; } // Utilities inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < DataEnd); const ptrdiff_t off = it - Data; return (int)off; } @@ -2180,8 +2180,9 @@ struct ImGuiViewportP : public ImGuiViewport float LastAlpha; bool LastFocusedHadNavWindow;// Instead of maintaining a LastFocusedWindow (which may harder to correctly maintain), we merely store weither NavWindow != NULL last time the viewport was focused. short PlatformMonitor; - float BgFgDrawListsLastTimeActive[2]; // Last frame number the background (0) and foreground (1) draw lists were used ImDrawList* BgFgDrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays. + int BgFgDrawListsLastFrameActive[2]; // Last frame the background (0) and foreground (1) draw lists were used. + float BgFgDrawListsLastTimeActive[2]; // Timestamps for Gc. ImDrawData DrawDataP; ImDrawDataBuilder DrawDataBuilder; // Temporary data while building final ImDrawData ImVec2 LastPlatformPos; @@ -2197,7 +2198,7 @@ struct ImGuiViewportP : public ImGuiViewport ImVec2 BuildWorkInsetMin; // Work Area inset accumulator for current frame, to become next frame's WorkInset ImVec2 BuildWorkInsetMax; // " - ImGuiViewportP() { Window = NULL; Idx = -1; LastFrameActive = LastFocusedStampCount = -1; BgFgDrawListsLastTimeActive[0] = BgFgDrawListsLastTimeActive[1] = -1.0f; LastNameHash = 0; Alpha = LastAlpha = 1.0f; LastFocusedHadNavWindow = false; PlatformMonitor = -1; BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } + ImGuiViewportP() { Window = NULL; Idx = -1; LastFrameActive = LastFocusedStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; LastFocusedHadNavWindow = false; PlatformMonitor = -1; BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; BgFgDrawListsLastFrameActive[0] = BgFgDrawListsLastFrameActive[1] = -1; BgFgDrawListsLastTimeActive[0] = BgFgDrawListsLastTimeActive[1] = -1.0; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } ~ImGuiViewportP() { if (BgFgDrawLists[0]) IM_DELETE(BgFgDrawLists[0]); if (BgFgDrawLists[1]) IM_DELETE(BgFgDrawLists[1]); } void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; } @@ -2900,7 +2901,7 @@ struct IMGUI_API ImGuiWindowTempData ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs. ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items measurement int TreeDepth; // Current tree depth. - ImU32 TreeHasStackDataDepthMask; // Store whether given depth has ImGuiTreeNodeStackData data. Could be turned into a ImU64 if necessary. + ImU32 TreeHasStackDataDepthMask; // Store whether given depth has ImGuiTreeNodeStackData data. Could be turned into a ImU64 if necessary. Sync any changes with TREE_NODE_MAX_DEPTH/TREE_NODE_GET_DEPTH_MASK! ImU32 TreeRecordsClippedNodesY2Mask; // Store whether we should keep recording Y2. Cleared when passing clip max. Equivalent TreeHasStackDataDepthMask value should always be set. ImVector ChildWindows; ImGuiStorage* StateStorage; // Current persistent per-window storage (store e.g. tree node open/close state) @@ -4018,7 +4019,7 @@ namespace ImGui IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool borders = true, float rounding = 0.0f); IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); IMGUI_API void RenderColorComponentMarker(const ImRect& bb, ImU32 col, float rounding); - IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0); + IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float alpha, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0); IMGUI_API void RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags = ImGuiNavRenderCursorFlags_None, float rounding = -1.0f); // Navigation highlight #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS inline void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags = ImGuiNavRenderCursorFlags_None) { RenderNavCursor(bb, id, flags); } // Renamed in 1.91.4 diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 665cfc512..eb94bb3a4 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3013,7 +3013,7 @@ float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, T result = 0.0f; // Workaround for values that are in-range but below our fudge else if (v_clamped >= v_max_fudged) result = 1.0f; // Workaround for values that are in-range but above our fudge - else if ((v_min * v_max) < 0.0f) // Range crosses zero, so split into two portions + else if (((FLOATTYPE)v_min * (FLOATTYPE)v_max) < 0.0f) // Range crosses zero, so split into two portions { float zero_point_center = (-(float)v_min) / ((float)v_max - (float)v_min); // The zero point in parametric space. There's an argument we should take the logarithmic nature into account when calculating this, but for now this should do (and the most common case of a symmetrical range works fine) float zero_point_snap_L = zero_point_center - zero_deadzone_halfsize; @@ -3067,7 +3067,7 @@ TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, T float t_with_flip = flipped ? (1.0f - t) : t; // t, but flipped if necessary to account for us flipping the range - if ((v_min * v_max) < 0.0f) // Range crosses zero, so we have to do this in two parts + if (((FLOATTYPE)v_min * (FLOATTYPE)v_max) < 0.0f) // Range crosses zero, so we have to do this in two parts { float zero_point_center = (-(float)ImMin(v_min, v_max)) / ImAbs((float)v_max - (float)v_min); // The zero point in parametric space float zero_point_snap_L = zero_point_center - zero_deadzone_halfsize; @@ -6136,6 +6136,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl const bool is_readonly = ((g.NextItemData.ItemFlagsSet | g.CurrentItemFlags) & ImGuiItemFlags_ReadOnly) != 0; g.NextItemData.ClearFlags(); + const float backup_alpha = g.Style.Alpha; + if (g.DisabledStackSize > 0) + g.Style.Alpha = g.DisabledAlphaBackup; // Cancel out effect of BeginDisabled() for color swatches. + PushID(label); const bool set_current_color_edit_id = (g.ColorEditCurrentID == 0); if (set_current_color_edit_id) @@ -6475,7 +6479,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl { float alpha = ImSaturate(col[3]); ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); - RenderColorRectWithAlphaCheckerboard(draw_list, bar1_bb.Min, bar1_bb.Max, 0, bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f)); + RenderColorRectWithAlphaCheckerboard(draw_list, bar1_bb.Min, bar1_bb.Max, IM_COL32(0,0,0,0), style.Alpha, bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f)); draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, user_col32_striped_of_alpha, user_col32_striped_of_alpha, user_col32_striped_of_alpha & ~IM_COL32_A_MASK, user_col32_striped_of_alpha & ~IM_COL32_A_MASK); float bar1_line_y = IM_ROUND(picker_pos.y + (1.0f - alpha) * sv_picker_size); RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); @@ -6493,6 +6497,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl g.ColorEditCurrentID = 0; PopID(); + if (g.DisabledStackSize > 0) + g.Style.Alpha = backup_alpha; + return value_changed; } @@ -6528,31 +6535,30 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl ImVec4 col_rgb_without_alpha(col_rgb.x, col_rgb.y, col_rgb.z, 1.0f); float grid_step = ImMin(size.x, size.y) / 2.99f; float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); - ImRect bb_inner = bb; - float off = 0.0f; - if ((flags & ImGuiColorEditFlags_NoBorder) == 0) - { - off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts. - bb_inner.Expand(off); - } + + const float backup_alpha = g.Style.Alpha; + if (g.DisabledStackSize > 0) + g.Style.Alpha = g.DisabledAlphaBackup; // Cancel out effect of BeginDisabled() for color swatches. if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f) { - float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f); + float mid_x = IM_ROUND((bb.Min.x + bb.Max.x) * 0.5f); if ((flags & ImGuiColorEditFlags_AlphaNoBg) == 0) - RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawFlags_RoundCornersRight); + RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, ColorConvertFloat4ToU32(col_rgb), g.Style.Alpha, grid_step, ImVec2(-grid_step, 0.0f), rounding, ImDrawFlags_RoundCornersRight); else - window->DrawList->AddRectFilled(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), rounding, ImDrawFlags_RoundCornersRight); - window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft); + window->DrawList->AddRectFilled(ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, GetColorU32(col_rgb), rounding, ImDrawFlags_RoundCornersRight); + window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft); } else { // Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaOpaque) ? col_rgb_without_alpha : col_rgb; if (col_source.w < 1.0f && (flags & ImGuiColorEditFlags_AlphaNoBg) == 0) - RenderColorRectWithAlphaCheckerboard(window->DrawList, bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding); + RenderColorRectWithAlphaCheckerboard(window->DrawList, bb.Min, bb.Max, ColorConvertFloat4ToU32(col_source), g.Style.Alpha, grid_step, ImVec2(0.0f, 0.0f), rounding); else - window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding); + window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(col_source), rounding); } + if (g.DisabledStackSize > 0) + g.Style.Alpha = backup_alpha; RenderNavCursor(bb, id); if ((flags & ImGuiColorEditFlags_NoBorder) == 0) { @@ -6896,7 +6902,7 @@ bool ImGui::TreeNodeUpdateNextOpen(ImGuiID storage_id, ImGuiTreeNodeFlags flags) } // Store ImGuiTreeNodeStackData for just submitted node. -// Currently only supports 32 level deep and we are fine with (1 << Depth) overflowing into a zero, easy to increase. +// Currently only supports 32 level deep. Easy to increase to e.g. 64. static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1) { ImGuiContext& g = *GImGui; @@ -6919,6 +6925,9 @@ static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1) window->DC.TreeRecordsClippedNodesY2Mask |= (1 << window->DC.TreeDepth); } +#define TREE_NODE_MAX_DEPTH 32 +#define TREE_NODE_GET_DEPTH_MASK(_DEPTH) (((ImU32)(_DEPTH) < TREE_NODE_MAX_DEPTH) ? (1u << (_DEPTH)) : 0u) + bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end) { ImGuiWindow* window = GetCurrentWindow(); @@ -6995,7 +7004,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l if ((flags & ImGuiTreeNodeFlags_DrawLinesMask_) == 0) flags |= g.Style.TreeLinesFlags; const bool draw_tree_lines = (flags & (ImGuiTreeNodeFlags_DrawLinesFull | ImGuiTreeNodeFlags_DrawLinesToNodes)) && (frame_bb.Min.y < window->ClipRect.Max.y) && (g.Style.TreeLinesSize > 0.0f); - if (!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + if (!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen) && window->DC.TreeDepth < TREE_NODE_MAX_DEPTH) { store_tree_node_stack_data = draw_tree_lines; if ((flags & ImGuiTreeNodeFlags_NavLeftJumpsToParent) && !g.NavIdIsAlive) @@ -7006,12 +7015,16 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l const bool is_leaf = (flags & ImGuiTreeNodeFlags_Leaf) != 0; if (!is_visible) { - if ((flags & ImGuiTreeNodeFlags_DrawLinesToNodes) && (window->DC.TreeRecordsClippedNodesY2Mask & (1 << (window->DC.TreeDepth - 1)))) + if (flags & ImGuiTreeNodeFlags_DrawLinesToNodes) { - ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1]; - parent_data->DrawLinesToNodesY2 = ImMax(parent_data->DrawLinesToNodesY2, window->DC.CursorPos.y); // Don't need to aim to mid Y position as we are clipped anyway. - if (frame_bb.Min.y >= window->ClipRect.Max.y) - window->DC.TreeRecordsClippedNodesY2Mask &= ~(1 << (window->DC.TreeDepth - 1)); // Done + const ImU32 tree_depth_mask = TREE_NODE_GET_DEPTH_MASK(window->DC.TreeDepth - 1); + if (window->DC.TreeRecordsClippedNodesY2Mask & tree_depth_mask) + { + ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1]; + parent_data->DrawLinesToNodesY2 = ImMax(parent_data->DrawLinesToNodesY2, window->DC.CursorPos.y); // Don't need to aim to mid Y position as we are clipped anyway. + if (frame_bb.Min.y >= window->ClipRect.Max.y) + window->DC.TreeRecordsClippedNodesY2Mask &= ~tree_depth_mask; // Done + } } if (is_open && store_tree_node_stack_data) TreeNodeStoreStackData(flags, text_pos.x - text_offset_x); // Call before TreePushOverrideID() @@ -7208,7 +7221,7 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (window->DC.TreeDepth == 0 || (window->DC.TreeHasStackDataDepthMask & (1 << (window->DC.TreeDepth - 1))) == 0) + if ((window->DC.TreeHasStackDataDepthMask & TREE_NODE_GET_DEPTH_MASK(window->DC.TreeDepth - 1)) == 0) return; ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1]; @@ -7292,8 +7305,7 @@ void ImGui::TreePop() Unindent(); window->DC.TreeDepth--; - ImU32 tree_depth_mask = (1 << window->DC.TreeDepth); - + ImU32 tree_depth_mask = TREE_NODE_GET_DEPTH_MASK(window->DC.TreeDepth); if (window->DC.TreeHasStackDataDepthMask & tree_depth_mask) { const ImGuiTreeNodeStackData* data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1]; diff --git a/misc/debuggers/README.txt b/misc/debuggers/README.txt index ad6f491fe..22a66a075 100644 --- a/misc/debuggers/README.txt +++ b/misc/debuggers/README.txt @@ -1,12 +1,14 @@ -HELPER FILES FOR POPULAR DEBUGGERS +----------------------------------------------------------------------------- + HELPER FILES FOR POPULAR DEBUGGERS +----------------------------------------------------------------------------- imgui.gdb - GDB: disable stepping into trivial functions. + GDB: disable stepping into trivial functions (*1). (read comments inside file for details) imgui.natstepfilter - Visual Studio Debugger: disable stepping into trivial functions. + Visual Studio Debugger: disable stepping into trivial functions (*1). (read comments inside file for details) imgui.natvis @@ -15,7 +17,23 @@ imgui.natvis (read comments inside file for details) imgui_lldb.py - LLDB-based debuggers (*): synthetic children provider and summaries for Dear ImGui types. + LLDB-based debuggers (*2): synthetic children provider and summaries for Dear ImGui types. With this, types like ImVector<> will be displayed nicely in the debugger. (read comments inside file for details) - (*) Xcode, Android Studio, may be used from VS Code, C++Builder, CLion, Eclipse etc. + (*2) Xcode, Android Studio, may be used from VS Code, C++Builder, CLion, Eclipse etc. + +----------------------------------------------------------------------------- + NEW! DISABLED STEPPING INTO TRIVIAL FUNCTIONS +----------------------------------------------------------------------------- + +Since 1.93.0 WIP (September 2026), +Dear ImGui uses a IM_NODEBUGSTEP macro to tag functions with __declspec(non_user_code) +or [[gnu::artificial]] to automatically tell debuggers to skip them. + +(*1) Assuming the new IM_NODEBUGSTEP macro works, using imgui.natstepfilter etc. +may become unnecessary. Exact side effects on user experience yet to be clarified. + +Additional references: + https://maskray.me/blog/skipping-boring-functions-in-debuggers + and https://news.ycombinator.com/item?id=42547576 + diff --git a/misc/debuggers/imgui.gdb b/misc/debuggers/imgui.gdb index 000ff6eb9..1229d0588 100644 --- a/misc/debuggers/imgui.gdb +++ b/misc/debuggers/imgui.gdb @@ -9,4 +9,5 @@ # * https://sourceware.org/gdb/current/onlinedocs/gdb/Init-File-in-the-Current-Directory.html#Init-File-in-the-Current-Directory # Disable stepping into trivial functions +# ...since Dear ImGui 1.93.0 WIP (September 2026): we use a IM_NODEBUGSTEP() macro to provide the equivalent feature via [[gnu::artificial]]. skip -rfunction Im(Vec2|Vec4|Strv|Vector|Span)::.+ diff --git a/misc/debuggers/imgui.natstepfilter b/misc/debuggers/imgui.natstepfilter index 6825c9346..82a30aa79 100644 --- a/misc/debuggers/imgui.natstepfilter +++ b/misc/debuggers/imgui.natstepfilter @@ -14,6 +14,8 @@ If you have multiple VS version installed, the version that matters is the one y of (not the compiling toolset). This is supported since Visual Studio 2012. More information at: https://docs.microsoft.com/en-us/visualstudio/debugger/just-my-code?view=vs-2019#BKMK_C___Just_My_Code + +Since Dear ImGui 1.93.0 WIP (September 2026): we use a IM_NODEBUGSTEP() macro to provide the equivalent feature via __declspec(non_user_code). --> diff --git a/misc/single_file/imgui_single_file.h b/misc/single_file/imgui_single_file.h index 7ca31e0fe..bea1cb6b6 100644 --- a/misc/single_file/imgui_single_file.h +++ b/misc/single_file/imgui_single_file.h @@ -1,14 +1,14 @@ // dear imgui: single-file wrapper include // We use this to validate compiling all *.cpp files in a same compilation unit. -// Users of that technique (also called "Unity builds") can generally provide this themselves, -// so we don't really recommend you use this in your projects. +// Users of that technique (also called "Unity builds") can generally provide this themselves easily. // Do this: // #define IMGUI_IMPLEMENTATION -// Before you include this file in *one* C++ file to create the implementation. +// #include "imgui_single_file.h" +// In *one* C++ file to create the implementation. // Using this in your project will leak the contents of imgui_internal.h and ImVec2 operators in this compilation unit. -#ifdef IMGUI_IMPLEMENTATION +#if defined(IMGUI_IMPLEMENTATION) && !defined(IMGUI_DEFINE_MATH_OPERATORS) #define IMGUI_DEFINE_MATH_OPERATORS #endif