diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 045f2c6c2..904b84feb 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -29,6 +29,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2025-10-15: Vulkan: Added IMGUI_IMPL_VULKAN_VOLK_FILENAME to configure path to volk.h header. (#9008) // 2025-09-26: *BREAKING CHANGE*: moved some fields in ImGui_ImplVulkan_InitInfo: init_info.RenderPass --> init_info.PipelineInfoMain.RenderPass, init_info.Subpass --> init_info.PipelineInfoMain.Subpass, init_info.MSAASamples --> init_info.PipelineInfoMain.MSAASamples, init_info.PipelineRenderingCreateInfo --> init_info.PipelineInfoMain.PipelineRenderingCreateInfo. // 2025-09-26: *BREAKING CHANGE*: renamed ImGui_ImplVulkan_MainPipelineCreateInfo to ImGui_ImplVulkan_PipelineInfo. Introduced very recently so shouldn't affect many users. // 2025-09-26: *BREAKING CHANGE*: helper ImGui_ImplVulkanH_CreateOrResizeWindow() added a VkImageUsageFlags image_usage` argument, default to VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT if 0. diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index ad89cb9e4..f48eb8115 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -42,9 +42,14 @@ // If you have no idea what this is, leave it alone! //#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES -// Convenience support for Volk +// [Configuration] Convenience support for Volk // (you can also technically use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().) +// (When using Volk from directory outside your include directories list you can specify full path to the volk.h header, +// for example when using Volk from VulkanSDK and using include_directories(${Vulkan_INCLUDE_DIRS})' from 'find_package(Vulkan REQUIRED)') //#define IMGUI_IMPL_VULKAN_USE_VOLK +//#define IMGUI_IMPL_VULKAN_VOLK_FILENAME +//#define IMGUI_IMPL_VULKAN_VOLK_FILENAME // Default +// Reminder: make those changes in your imconfig.h file, not here! #if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES) #define VK_NO_PROTOTYPES @@ -55,7 +60,11 @@ // Vulkan includes #ifdef IMGUI_IMPL_VULKAN_USE_VOLK +#ifdef IMGUI_IMPL_VULKAN_VOLK_FILENAME +#include IMGUI_IMPL_VULKAN_VOLK_FILENAME +#else #include +#endif #else #include #endif diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index 16238f8c5..5f95b3dda 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -1,6 +1,6 @@ // dear imgui: Renderer for WebGPU -// This needs to be used along with a Platform Binding (e.g. GLFW) -// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.) +// This needs to be used along with a Platform Binding (e.g. GLFW, SDL2, SDL3) +// (Please note that WebGPU is a recent API, may not be supported by all browser, and its ecosystem is generally a mess) // Implemented features: // [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef! @@ -10,6 +10,8 @@ // Missing features or Issues: // [ ] Renderer: Multi-viewport support (multiple windows), useful for desktop. +// Read imgui_impl_wgpu.h about how to use the IMGUI_IMPL_WEBGPU_BACKEND_WGPU or IMGUI_IMPL_WEBGPU_BACKEND_DAWN flags. + // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // Learn about Dear ImGui: @@ -20,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2025-10-16: Update to compile with Dawn and Emscripten's 4.0.10+ '--use-port=emdawnwebgpu' ports. (#8381, #8898) // 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown. // 2025-06-12: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. (#8465) // 2025-02-26: Recreate image bind groups during render. (#8426, #8046, #7765, #8027) + Update for latest webgpu-native changes. @@ -48,20 +51,20 @@ #include "imgui.h" -// When targeting native platforms (i.e. NOT Emscripten), one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN -// or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details. -#ifndef __EMSCRIPTEN__ - #if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) == defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) - #error exactly one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be defined! - #endif -#else - #if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) - #error neither IMGUI_IMPL_WEBGPU_BACKEND_DAWN nor IMGUI_IMPL_WEBGPU_BACKEND_WGPU may be defined if targeting emscripten! - #endif -#endif - #ifndef IMGUI_DISABLE #include "imgui_impl_wgpu.h" + +// One of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details. +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) == defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#error Exactly one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be defined! +#endif + +// This condition is true when it's built with EMSCRIPTEN using -sUSE_WEBGPU=1 flag (deprecated from 4.0.10) +// This condition is false for all other 3 cases: WGPU-Native, DAWN-Native or DAWN-EMSCRIPTEN (using --use-port=emdawnwebgpu flag) +#if defined(__EMSCRIPTEN__) && defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN +#endif + #include #include @@ -261,7 +264,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c { ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) WGPUShaderSourceWGSL wgsl_desc = {}; wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL; wgsl_desc.code = { wgsl_source, WGPU_STRLEN }; @@ -277,7 +280,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c WGPUProgrammableStageDescriptor stage_desc = {}; stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc); -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) stage_desc.entryPoint = { "main", WGPU_STRLEN }; #else stage_desc.entryPoint = "main"; @@ -400,9 +403,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder WGPUBufferDescriptor vb_desc = { nullptr, +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) + { "Dear ImGui Vertex buffer", WGPU_STRLEN, }, +#else "Dear ImGui Vertex buffer", -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) - WGPU_STRLEN, #endif WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex, MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4), @@ -427,9 +431,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder WGPUBufferDescriptor ib_desc = { nullptr, +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) + { "Dear ImGui Index buffer", WGPU_STRLEN, }, +#else "Dear ImGui Index buffer", -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) - WGPU_STRLEN, #endif WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index, MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4), @@ -562,7 +567,7 @@ void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex) // Create texture WGPUTextureDescriptor tex_desc = {}; -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) tex_desc.label = { "Dear ImGui Texture", WGPU_STRLEN }; #else tex_desc.label = "Dear ImGui Texture"; @@ -607,7 +612,7 @@ void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex) // Update full texture or selected blocks. We only ever write to textures regions which have never been used before! // This backend choose to use tex->UpdateRect but you can use tex->Updates[] to upload individual regions. -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) WGPUTexelCopyTextureInfo dst_view = {}; #else WGPUImageCopyTexture dst_view = {}; @@ -616,7 +621,7 @@ void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex) dst_view.mipLevel = 0; dst_view.origin = { (uint32_t)upload_x, (uint32_t)upload_y, 0 }; dst_view.aspect = WGPUTextureAspect_All; -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) WGPUTexelCopyBufferLayout layout = {}; #else WGPUTextureDataLayout layout = {}; @@ -638,9 +643,10 @@ static void ImGui_ImplWGPU_CreateUniformBuffer() WGPUBufferDescriptor ub_desc = { nullptr, +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) + { "Dear ImGui Uniform buffer", WGPU_STRLEN, }, +#else "Dear ImGui Uniform buffer", -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) - WGPU_STRLEN, #endif WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform, MEMALIGN(sizeof(Uniforms), 16), @@ -753,7 +759,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects() // Create depth-stencil State WGPUDepthStencilState depth_stencil_state = {}; depth_stencil_state.format = bd->depthStencilFormat; -#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN) depth_stencil_state.depthWriteEnabled = WGPUOptionalBool_False; #else depth_stencil_state.depthWriteEnabled = false; @@ -835,14 +841,18 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info) // Setup backend capabilities flags ImGui_ImplWGPU_Data* bd = IM_NEW(ImGui_ImplWGPU_Data)(); io.BackendRendererUserData = (void*)bd; +#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) #if defined(__EMSCRIPTEN__) - io.BackendRendererName = "imgui_impl_webgpu_emscripten"; -#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) - io.BackendRendererName = "imgui_impl_webgpu_dawn"; -#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) - io.BackendRendererName = "imgui_impl_webgpu_wgpu"; + io.BackendRendererName = "imgui_impl_wgpu (Dawn, Emscripten)"; // compiled & linked using EMSCRIPTEN with "--use-port=emdawnwebgpu" flag #else - io.BackendRendererName = "imgui_impl_webgpu"; + io.BackendRendererName = "imgui_impl_wgpu (Dawn, Native)"; +#endif +#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#if defined(__EMSCRIPTEN__) + io.BackendRendererName = "imgui_impl_wgpu (WGPU, Emscripten)"; // linked using EMSCRIPTEN with "-sUSE_WEBGPU=1" flag, deprecated from EMSCRIPTEN 4.0.10 +#else + io.BackendRendererName = "imgui_impl_wgpu (WGPU, Native)"; +#endif #endif io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render. diff --git a/backends/imgui_impl_wgpu.h b/backends/imgui_impl_wgpu.h index 99630101b..d5b13ac65 100644 --- a/backends/imgui_impl_wgpu.h +++ b/backends/imgui_impl_wgpu.h @@ -1,11 +1,14 @@ // dear imgui: Renderer for WebGPU -// This needs to be used along with a Platform Binding (e.g. GLFW) -// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.) +// This needs to be used along with a Platform Binding (e.g. GLFW, SDL2, SDL3) +// (Please note that WebGPU is a recent API, may not be supported by all browser, and its ecosystem is generally a mess) -// Important note to dawn and/or wgpu users: when targeting native platforms (i.e. NOT emscripten), -// one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. +// When targeting native platforms: +// - One of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU *must* be provided. +// When targeting Emscripten: +// - We now defaults to IMGUI_IMPL_WEBGPU_BACKEND_DAWN is Emscripten version is 4.0.10+, which correspond to using Emscripten '--use-port=emdawnwebgpu'. +// - We can still define IMGUI_IMPL_WEBGPU_BACKEND_WGPU to use Emscripten '-s USE_WEBGPU=1' which is marked as obsolete by Emscripten. // Add #define to your imconfig.h file, or as a compilation flag in your build system. -// This requirement will be removed once WebGPU stabilizes and backends converge on a unified interface. +// This requirement may be removed once WebGPU stabilizes and backends converge on a unified interface. //#define IMGUI_IMPL_WEBGPU_BACKEND_DAWN //#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU @@ -29,6 +32,16 @@ #include "imgui.h" // IMGUI_IMPL_API #ifndef IMGUI_DISABLE +// Setup Emscripten default if not specified. +#if defined(__EMSCRIPTEN__) && !defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) && !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) +#include +#if (__EMSCRIPTEN_major__ >= 4) && (__EMSCRIPTEN_minor__ >= 0) && (__EMSCRIPTEN_tiny__ >= 10) +#define IMGUI_IMPL_WEBGPU_BACKEND_DAWN +#else +#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU +#endif +#endif + #include // Initialization data, for ImGui_ImplWGPU_Init() diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 34da19b52..f584079ef 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -39,6 +39,28 @@ HOW TO UPDATE? VERSION 1.92.5 WIP (In Progress) ----------------------------------------------------------------------- +Breaking Changes: + +Other Changes: + +- Tables: fixed a bug where nesting BeginTable()->Begin()->BeginTable() would + result in temporarily incorrect state, which would lead to bugs to side effects + in various locations, e.g. GetContentRegionAvail() calls or using clipper. (#9005) + EndTable() was mistakenly restoring a wrong current table. +- InputText: avoid continuously overwriting ownership of ImGuiKey_Enter/_KeypadEnter + keys in order to allow e.g. external Shortcut override behavior. (#9004) +- InputTextMultiline: fixed a crash when using ImGuiInputTextFlags_WordWrap and + resizing the parent window while keeping the multi-line field active (which is + most typically achieved when resizing programmatically or via a docking layout + reacting to a platform window resize). (#3237, #9007) [@anton-kl, @ocornut] +- Backends: Vulkan: added IMGUI_IMPL_VULKAN_VOLK_FILENAME to configure path to + Volk (default to "volk.h"). (#9008, #7722, #6582, #4854) [@mwlasiuk] +- Backends: WebGPU: update to compile with Dawn and Emscripten's 4.0.10+ + '--use-port=emdawnwebgpu' ports. (#8381, #8898) [@brutpitt, @trbabb] + When using Emscripten 4.0.10+, backend now defaults to IMGUI_IMPL_WEBGPU_BACKEND_DAWN + instead of IMGUI_IMPL_WEBGPU_BACKEND_WGPU, if neither are specified. + (note: examples application were not updated yet) + Docking+Viewports Branch: - Examples: SDL2+DX11, SDL3+DX11, Win32+DX10, Win32+DX11: fixed one resource diff --git a/examples/example_glfw_wgpu/Makefile.emscripten b/examples/example_glfw_wgpu/Makefile.emscripten index 8ee398bc8..545a50578 100644 --- a/examples/example_glfw_wgpu/Makefile.emscripten +++ b/examples/example_glfw_wgpu/Makefile.emscripten @@ -34,9 +34,16 @@ EMS = # ("EMS" options gets added to both CPPFLAGS and LDFLAGS, whereas some options are for linker only) # Note: For glfw, we use emscripten-glfw port (contrib.glfw3) instead of (-s USE_GLFW=3) to get a better support for High DPI displays. EMS += -s DISABLE_EXCEPTION_CATCHING=1 --use-port=contrib.glfw3 -LDFLAGS += -s USE_WEBGPU=1 LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1 +# (1) Using legacy WebGPU implementation (Emscripten < 4.0.10) +EMS += -DIMGUI_IMPL_WEBGPU_BACKEND_WGPU +LDFLAGS += -s USE_WEBGPU=1 + +# or (2) Using newer Dawn-based WebGPU port (Emscripten >= 4.0.10) (UNSUPPORTED YET) +#EMS += --use-port=emdawnwebgpu +#LDFLAGS += --use-port=emdawnwebgpu + # Build as single file (binary text encoded in .html file) #LDFLAGS += -sSINGLE_FILE diff --git a/examples/example_glfw_wgpu/main.cpp b/examples/example_glfw_wgpu/main.cpp index a4c884a54..ebc7884f1 100644 --- a/examples/example_glfw_wgpu/main.cpp +++ b/examples/example_glfw_wgpu/main.cpp @@ -27,17 +27,16 @@ #include // Data -static WGPUInstance wgpu_instance = nullptr; -static WGPUDevice wgpu_device = nullptr; -static WGPUSurface wgpu_surface = nullptr; -static WGPUTextureFormat wgpu_preferred_fmt = WGPUTextureFormat_RGBA8Unorm; -static WGPUSwapChain wgpu_swap_chain = nullptr; -static int wgpu_surface_width = 1280; -static int wgpu_surface_height = 800; +static WGPUInstance wgpu_instance = nullptr; +static WGPUDevice wgpu_device = nullptr; +static WGPUSurface wgpu_surface = nullptr; +static WGPUTextureFormat wgpu_preferred_fmt = WGPUTextureFormat_RGBA8Unorm; +static WGPUSwapChain wgpu_swap_chain = nullptr; +static int wgpu_surface_width = 1280; +static int wgpu_surface_height = 800; // Forward declarations static bool InitWGPU(GLFWwindow* window); -static void ResizeSurface(int width, int height); static void glfw_error_callback(int error, const char* description) { @@ -58,6 +57,21 @@ static void wgpu_error_callback(WGPUErrorType error_type, const char* message, v printf("%s error: %s\n", error_type_lbl, message); } +static void ResizeSurface(int width, int height) +{ + if (wgpu_swap_chain) + wgpuSwapChainRelease(wgpu_swap_chain); + wgpu_surface_width = width; + wgpu_surface_height = height; + WGPUSwapChainDescriptor swap_chain_desc = {}; + swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment; + swap_chain_desc.format = wgpu_preferred_fmt; + swap_chain_desc.width = width; + swap_chain_desc.height = height; + swap_chain_desc.presentMode = WGPUPresentMode_Fifo; + wgpu_swap_chain = wgpuDeviceCreateSwapChain(wgpu_device, wgpu_surface, &swap_chain_desc); +} + // Main code int main(int, char**) { @@ -167,7 +181,7 @@ int main(int, char**) glfwGetFramebufferSize((GLFWwindow*)window, &width, &height); if (width != wgpu_surface_width || height != wgpu_surface_height) { - ImGui_ImplWGPU_InvalidateDeviceObjects(); + ImGui_ImplWGPU_InvalidateDeviceObjects(); // FIXME-OPT: Why doing this? This seems unnecessary and unoptimal. ResizeSurface(width, height); ImGui_ImplWGPU_CreateDeviceObjects(); } @@ -276,21 +290,21 @@ static WGPUAdapter RequestAdapter(WGPUInstance instance) auto onAdapterRequestEnded = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, const char* message, void* pUserData) { if (status == WGPURequestAdapterStatus_Success) - *(WGPUAdapter*)(pUserData) = adapter; + *(WGPUAdapter*)pUserData = adapter; else printf("Could not get WebGPU adapter: %s\n", message); -}; + }; WGPUAdapter adapter; wgpuInstanceRequestAdapter(instance, nullptr, onAdapterRequestEnded, (void*)&adapter); return adapter; } -static WGPUDevice RequestDevice(WGPUAdapter& adapter) +static WGPUDevice RequestDevice(WGPUAdapter adapter) { auto onDeviceRequestEnded = [](WGPURequestDeviceStatus status, WGPUDevice device, const char* message, void* pUserData) { if (status == WGPURequestDeviceStatus_Success) - *(WGPUDevice*)(pUserData) = device; + *(WGPUDevice*)pUserData = device; else printf("Could not get WebGPU device: %s\n", message); }; @@ -308,14 +322,7 @@ static bool InitWGPU(GLFWwindow* window) wgpu_device = emscripten_webgpu_get_device(); if (!wgpu_device) return false; -#else - WGPUAdapter adapter = RequestAdapter(instance.Get()); - if (!adapter) - return false; - wgpu_device = RequestDevice(adapter); -#endif -#ifdef __EMSCRIPTEN__ wgpu::SurfaceDescriptorFromCanvasHTMLSelector canvas_desc = {}; canvas_desc.selector = "#canvas"; wgpu::SurfaceDescriptor surface_desc = {}; @@ -325,6 +332,11 @@ static bool InitWGPU(GLFWwindow* window) wgpu::Adapter adapter = {}; wgpu_preferred_fmt = (WGPUTextureFormat)surface.GetPreferredFormat(adapter); #else + WGPUAdapter adapter = RequestAdapter(instance.Get()); + if (!adapter) + return false; + wgpu_device = RequestDevice(adapter); + wgpu::Surface surface = wgpu::glfw::CreateSurfaceForWindow(instance, window); if (!surface) return false; @@ -336,21 +348,5 @@ static bool InitWGPU(GLFWwindow* window) wgpu_surface = surface.MoveToCHandle(); wgpuDeviceSetUncapturedErrorCallback(wgpu_device, wgpu_error_callback, nullptr); - return true; } - -static void ResizeSurface(int width, int height) -{ - if (wgpu_swap_chain) - wgpuSwapChainRelease(wgpu_swap_chain); - wgpu_surface_width = width; - wgpu_surface_height = height; - WGPUSwapChainDescriptor swap_chain_desc = {}; - swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment; - swap_chain_desc.format = wgpu_preferred_fmt; - swap_chain_desc.width = width; - swap_chain_desc.height = height; - swap_chain_desc.presentMode = WGPUPresentMode_Fifo; - wgpu_swap_chain = wgpuDeviceCreateSwapChain(wgpu_device, wgpu_surface, &swap_chain_desc); -} diff --git a/examples/example_sdl3_directx11/main.cpp b/examples/example_sdl3_directx11/main.cpp index cb761a679..f6d52601d 100644 --- a/examples/example_sdl3_directx11/main.cpp +++ b/examples/example_sdl3_directx11/main.cpp @@ -48,7 +48,7 @@ int main(int, char**) } SDL_PropertiesID props = SDL_GetWindowProperties(window); - HWND hwnd = (HWND)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); + HWND hwnd = (HWND)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr); // Initialize Direct3D if (!CreateDeviceD3D(hwnd)) diff --git a/imgui.cpp b/imgui.cpp index 0953f56ec..21b6b23e7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.4 +// dear imgui, v1.92.5 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index d0f071d2d..b918ec0aa 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.4 +// dear imgui, v1.92.5 WIP // (headers) // Help: @@ -28,8 +28,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.92.4" -#define IMGUI_VERSION_NUM 19240 +#define IMGUI_VERSION "1.92.5 WIP" +#define IMGUI_VERSION_NUM 19241 #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. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 9d2b42851..ce52f4b65 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.4 +// dear imgui, v1.92.5 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 908712a69..6ad75b2ab 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.4 +// dear imgui, v1.92.5 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index 64f691f47..c12e0173a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.92.4 +// dear imgui, v1.92.5 WIP // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. @@ -3278,6 +3278,7 @@ struct IMGUI_API ImGuiTable // sizeof() ~ 136 bytes. struct IMGUI_API ImGuiTableTempData { + ImGuiID WindowID; // Shortcut to g.Tables[TableIndex]->OuterWindow->ID. int TableIndex; // Index in g.Tables.Buf[] pool float LastTimeActive; // Last timestamp this structure was used float AngledHeadersExtraWidth; // Used in EndTable() diff --git a/imgui_tables.cpp b/imgui_tables.cpp index b4d4f891a..d79cfe435 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.4 +// dear imgui, v1.92.5 WIP // (tables and columns code) /* @@ -464,6 +464,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG table->HostIndentX = inner_window->DC.Indent.x; table->HostClipRect = inner_window->ClipRect; table->HostSkipItems = inner_window->SkipItems; + temp_data->WindowID = inner_window->ID; temp_data->HostBackupWorkRect = inner_window->WorkRect; temp_data->HostBackupParentWorkRect = inner_window->ParentWorkRect; temp_data->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset; @@ -1366,7 +1367,7 @@ void ImGui::EndTable() ImGuiWindow* inner_window = table->InnerWindow; ImGuiWindow* outer_window = table->OuterWindow; ImGuiTableTempData* temp_data = table->TempData; - IM_ASSERT(inner_window == g.CurrentWindow); + IM_ASSERT(inner_window == g.CurrentWindow && inner_window->ID == temp_data->WindowID); IM_ASSERT(outer_window == inner_window || outer_window == inner_window->ParentWindow); if (table->IsInsideRow) @@ -1559,7 +1560,7 @@ void ImGui::EndTable() IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table); IM_ASSERT(g.TablesTempDataStacked > 0); temp_data = (--g.TablesTempDataStacked > 0) ? &g.TablesTempData[g.TablesTempDataStacked - 1] : NULL; - g.CurrentTable = temp_data ? g.Tables.GetByIndex(temp_data->TableIndex) : NULL; + g.CurrentTable = temp_data && (temp_data->WindowID == outer_window->ID) ? g.Tables.GetByIndex(temp_data->TableIndex) : NULL; if (g.CurrentTable) { g.CurrentTable->TempData = temp_data; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index bd352a6ac..2961ab419 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.92.4 +// dear imgui, v1.92.5 WIP // (widgets code) /* @@ -4826,7 +4826,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ { // Declare some inputs, the other are registered and polled via Shortcut() routing system. // FIXME: The reason we don't use Shortcut() is we would need a routing flag to specify multiple mods, or to all mods combination into individual shortcuts. - const ImGuiKey always_owned_keys[] = { ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_Enter, ImGuiKey_KeypadEnter, ImGuiKey_Delete, ImGuiKey_Backspace, ImGuiKey_Home, ImGuiKey_End }; + const ImGuiKey always_owned_keys[] = { ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_Delete, ImGuiKey_Backspace, ImGuiKey_Home, ImGuiKey_End }; for (ImGuiKey key : always_owned_keys) SetKeyOwner(key, id); if (user_clicked) @@ -5034,7 +5034,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful. const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; - const bool is_enter_pressed = IsKeyPressed(ImGuiKey_Enter, true) || IsKeyPressed(ImGuiKey_KeypadEnter, true); + const bool is_enter = Shortcut(ImGuiKey_Enter, f_repeat, id) || Shortcut(ImGuiKey_KeypadEnter, f_repeat, id); + const bool is_ctrl_enter = Shortcut(ImGuiMod_Ctrl | ImGuiKey_Enter, f_repeat, id) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_KeypadEnter, f_repeat, id); const bool is_gamepad_validate = nav_gamepad_active && (IsKeyPressed(ImGuiKey_NavGamepadActivate, false) || IsKeyPressed(ImGuiKey_NavGamepadInput, false)); const bool is_cancel = Shortcut(ImGuiKey_Escape, f_repeat, id) || (nav_gamepad_active && Shortcut(ImGuiKey_NavGamepadCancel, f_repeat, id)); @@ -5069,11 +5070,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } - else if (is_enter_pressed || is_gamepad_validate) + else if (is_enter || is_ctrl_enter || is_gamepad_validate) { // Determine if we turn Enter into a \n character bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; - if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line != io.KeyCtrl)) + if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line != is_ctrl_enter)) { validated = true; if (io.ConfigInputTextEnterKeepActive && !is_multiline) @@ -5083,7 +5084,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } else if (!is_readonly) { - unsigned int c = '\n'; // Insert new line + // Insert new line + unsigned int c = '\n'; if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data)) state->OnCharPressed(c); } @@ -5407,7 +5409,12 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ line_index->Offsets.resize(0); int line_count = 1; if (is_multiline) - line_count = InputTextLineIndexBuild(flags, line_index, buf_display, buf_display_end, wrap_width, (render_cursor && state && state->CursorFollow) ? INT_MAX : line_visible_n1 + 1, buf_display_end ? NULL : &buf_display_end); + { + // If scrolling is expected to change build full index. + // FIXME-OPT: Could append to index when new value of line_visible_n1 becomes bigger, see second call to CalcClipRectVisibleItemsY() below. + bool will_scroll_y = state && ((state->CursorFollow && render_cursor) || (state->CursorCenterY && (render_cursor || render_selection))); + line_count = InputTextLineIndexBuild(flags, line_index, buf_display, buf_display_end, wrap_width, will_scroll_y ? INT_MAX : line_visible_n1 + 1, buf_display_end ? NULL : &buf_display_end); + } line_index->EndOffset = (int)(buf_display_end - buf_display); line_visible_n1 = ImMin(line_visible_n1, line_count);