Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_vulkan.cpp
#	docs/CHANGELOG.txt
This commit is contained in:
ocornut
2025-10-16 20:41:17 +02:00
15 changed files with 160 additions and 93 deletions

View File

@@ -29,6 +29,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (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-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*: 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*: 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. // 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.

View File

@@ -42,9 +42,14 @@
// If you have no idea what this is, leave it alone! // If you have no idea what this is, leave it alone!
//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES //#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().) // (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_USE_VOLK
//#define IMGUI_IMPL_VULKAN_VOLK_FILENAME <Volk/volk.h>
//#define IMGUI_IMPL_VULKAN_VOLK_FILENAME <volk.h> // Default
// Reminder: make those changes in your imconfig.h file, not here!
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES) #if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
#define VK_NO_PROTOTYPES #define VK_NO_PROTOTYPES
@@ -55,7 +60,11 @@
// Vulkan includes // Vulkan includes
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK #ifdef IMGUI_IMPL_VULKAN_USE_VOLK
#ifdef IMGUI_IMPL_VULKAN_VOLK_FILENAME
#include IMGUI_IMPL_VULKAN_VOLK_FILENAME
#else
#include <volk.h> #include <volk.h>
#endif
#else #else
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#endif #endif

View File

@@ -1,6 +1,6 @@
// dear imgui: Renderer for WebGPU // dear imgui: Renderer for WebGPU
// This needs to be used along with a Platform Binding (e.g. GLFW) // This needs to be used along with a Platform Binding (e.g. GLFW, SDL2, SDL3)
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.) // (Please note that WebGPU is a recent API, may not be supported by all browser, and its ecosystem is generally a mess)
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef! // [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef!
@@ -10,6 +10,8 @@
// Missing features or Issues: // Missing features or Issues:
// [ ] Renderer: Multi-viewport support (multiple windows), useful for desktop. // [ ] 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. // 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. // 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: // Learn about Dear ImGui:
@@ -20,6 +22,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (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-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
// 2025-06-12: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. (#8465) // 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. // 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" #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 #ifndef IMGUI_DISABLE
#include "imgui_impl_wgpu.h" #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 <limits.h> #include <limits.h>
#include <webgpu/webgpu.h> #include <webgpu/webgpu.h>
@@ -261,7 +264,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); 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 = {}; WGPUShaderSourceWGSL wgsl_desc = {};
wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL; wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL;
wgsl_desc.code = { wgsl_source, WGPU_STRLEN }; wgsl_desc.code = { wgsl_source, WGPU_STRLEN };
@@ -277,7 +280,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
WGPUProgrammableStageDescriptor stage_desc = {}; WGPUProgrammableStageDescriptor stage_desc = {};
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &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 }; stage_desc.entryPoint = { "main", WGPU_STRLEN };
#else #else
stage_desc.entryPoint = "main"; stage_desc.entryPoint = "main";
@@ -400,9 +403,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
WGPUBufferDescriptor vb_desc = WGPUBufferDescriptor vb_desc =
{ {
nullptr, nullptr,
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
{ "Dear ImGui Vertex buffer", WGPU_STRLEN, },
#else
"Dear ImGui Vertex buffer", "Dear ImGui Vertex buffer",
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
WGPU_STRLEN,
#endif #endif
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4), MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4),
@@ -427,9 +431,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
WGPUBufferDescriptor ib_desc = WGPUBufferDescriptor ib_desc =
{ {
nullptr, nullptr,
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
{ "Dear ImGui Index buffer", WGPU_STRLEN, },
#else
"Dear ImGui Index buffer", "Dear ImGui Index buffer",
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
WGPU_STRLEN,
#endif #endif
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4), MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4),
@@ -562,7 +567,7 @@ void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex)
// Create texture // Create texture
WGPUTextureDescriptor tex_desc = {}; 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 }; tex_desc.label = { "Dear ImGui Texture", WGPU_STRLEN };
#else #else
tex_desc.label = "Dear ImGui Texture"; 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! // 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. // 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 = {}; WGPUTexelCopyTextureInfo dst_view = {};
#else #else
WGPUImageCopyTexture dst_view = {}; WGPUImageCopyTexture dst_view = {};
@@ -616,7 +621,7 @@ void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex)
dst_view.mipLevel = 0; dst_view.mipLevel = 0;
dst_view.origin = { (uint32_t)upload_x, (uint32_t)upload_y, 0 }; dst_view.origin = { (uint32_t)upload_x, (uint32_t)upload_y, 0 };
dst_view.aspect = WGPUTextureAspect_All; 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 = {}; WGPUTexelCopyBufferLayout layout = {};
#else #else
WGPUTextureDataLayout layout = {}; WGPUTextureDataLayout layout = {};
@@ -638,9 +643,10 @@ static void ImGui_ImplWGPU_CreateUniformBuffer()
WGPUBufferDescriptor ub_desc = WGPUBufferDescriptor ub_desc =
{ {
nullptr, nullptr,
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU_EMSCRIPTEN)
{ "Dear ImGui Uniform buffer", WGPU_STRLEN, },
#else
"Dear ImGui Uniform buffer", "Dear ImGui Uniform buffer",
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
WGPU_STRLEN,
#endif #endif
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
MEMALIGN(sizeof(Uniforms), 16), MEMALIGN(sizeof(Uniforms), 16),
@@ -753,7 +759,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
// Create depth-stencil State // Create depth-stencil State
WGPUDepthStencilState depth_stencil_state = {}; WGPUDepthStencilState depth_stencil_state = {};
depth_stencil_state.format = bd->depthStencilFormat; 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; depth_stencil_state.depthWriteEnabled = WGPUOptionalBool_False;
#else #else
depth_stencil_state.depthWriteEnabled = false; depth_stencil_state.depthWriteEnabled = false;
@@ -835,14 +841,18 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
// Setup backend capabilities flags // Setup backend capabilities flags
ImGui_ImplWGPU_Data* bd = IM_NEW(ImGui_ImplWGPU_Data)(); ImGui_ImplWGPU_Data* bd = IM_NEW(ImGui_ImplWGPU_Data)();
io.BackendRendererUserData = (void*)bd; io.BackendRendererUserData = (void*)bd;
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
#if defined(__EMSCRIPTEN__) #if defined(__EMSCRIPTEN__)
io.BackendRendererName = "imgui_impl_webgpu_emscripten"; io.BackendRendererName = "imgui_impl_wgpu (Dawn, Emscripten)"; // compiled & linked using EMSCRIPTEN with "--use-port=emdawnwebgpu" flag
#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";
#else #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 #endif
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. 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. io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.

View File

@@ -1,11 +1,14 @@
// dear imgui: Renderer for WebGPU // dear imgui: Renderer for WebGPU
// This needs to be used along with a Platform Binding (e.g. GLFW) // This needs to be used along with a Platform Binding (e.g. GLFW, SDL2, SDL3)
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.) // (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), // When targeting native platforms:
// one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. // - 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. // 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_DAWN
//#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU //#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
@@ -29,6 +32,16 @@
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE #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 <emscripten/version.h>
#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 <webgpu/webgpu.h> #include <webgpu/webgpu.h>
// Initialization data, for ImGui_ImplWGPU_Init() // Initialization data, for ImGui_ImplWGPU_Init()

View File

@@ -39,6 +39,28 @@ HOW TO UPDATE?
VERSION 1.92.5 WIP (In Progress) 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: Docking+Viewports Branch:
- Examples: SDL2+DX11, SDL3+DX11, Win32+DX10, Win32+DX11: fixed one resource - Examples: SDL2+DX11, SDL3+DX11, Win32+DX10, Win32+DX11: fixed one resource

View File

@@ -34,9 +34,16 @@ EMS =
# ("EMS" options gets added to both CPPFLAGS and LDFLAGS, whereas some options are for linker only) # ("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. # 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 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 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) # Build as single file (binary text encoded in .html file)
#LDFLAGS += -sSINGLE_FILE #LDFLAGS += -sSINGLE_FILE

View File

@@ -37,7 +37,6 @@ static int wgpu_surface_height = 800;
// Forward declarations // Forward declarations
static bool InitWGPU(GLFWwindow* window); static bool InitWGPU(GLFWwindow* window);
static void ResizeSurface(int width, int height);
static void glfw_error_callback(int error, const char* description) 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); 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 // Main code
int main(int, char**) int main(int, char**)
{ {
@@ -167,7 +181,7 @@ int main(int, char**)
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height); glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
if (width != wgpu_surface_width || height != wgpu_surface_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); ResizeSurface(width, height);
ImGui_ImplWGPU_CreateDeviceObjects(); ImGui_ImplWGPU_CreateDeviceObjects();
} }
@@ -276,7 +290,7 @@ static WGPUAdapter RequestAdapter(WGPUInstance instance)
auto onAdapterRequestEnded = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, const char* message, void* pUserData) auto onAdapterRequestEnded = [](WGPURequestAdapterStatus status, WGPUAdapter adapter, const char* message, void* pUserData)
{ {
if (status == WGPURequestAdapterStatus_Success) if (status == WGPURequestAdapterStatus_Success)
*(WGPUAdapter*)(pUserData) = adapter; *(WGPUAdapter*)pUserData = adapter;
else else
printf("Could not get WebGPU adapter: %s\n", message); printf("Could not get WebGPU adapter: %s\n", message);
}; };
@@ -285,12 +299,12 @@ static WGPUAdapter RequestAdapter(WGPUInstance instance)
return adapter; return adapter;
} }
static WGPUDevice RequestDevice(WGPUAdapter& adapter) static WGPUDevice RequestDevice(WGPUAdapter adapter)
{ {
auto onDeviceRequestEnded = [](WGPURequestDeviceStatus status, WGPUDevice device, const char* message, void* pUserData) auto onDeviceRequestEnded = [](WGPURequestDeviceStatus status, WGPUDevice device, const char* message, void* pUserData)
{ {
if (status == WGPURequestDeviceStatus_Success) if (status == WGPURequestDeviceStatus_Success)
*(WGPUDevice*)(pUserData) = device; *(WGPUDevice*)pUserData = device;
else else
printf("Could not get WebGPU device: %s\n", message); printf("Could not get WebGPU device: %s\n", message);
}; };
@@ -308,14 +322,7 @@ static bool InitWGPU(GLFWwindow* window)
wgpu_device = emscripten_webgpu_get_device(); wgpu_device = emscripten_webgpu_get_device();
if (!wgpu_device) if (!wgpu_device)
return false; return false;
#else
WGPUAdapter adapter = RequestAdapter(instance.Get());
if (!adapter)
return false;
wgpu_device = RequestDevice(adapter);
#endif
#ifdef __EMSCRIPTEN__
wgpu::SurfaceDescriptorFromCanvasHTMLSelector canvas_desc = {}; wgpu::SurfaceDescriptorFromCanvasHTMLSelector canvas_desc = {};
canvas_desc.selector = "#canvas"; canvas_desc.selector = "#canvas";
wgpu::SurfaceDescriptor surface_desc = {}; wgpu::SurfaceDescriptor surface_desc = {};
@@ -325,6 +332,11 @@ static bool InitWGPU(GLFWwindow* window)
wgpu::Adapter adapter = {}; wgpu::Adapter adapter = {};
wgpu_preferred_fmt = (WGPUTextureFormat)surface.GetPreferredFormat(adapter); wgpu_preferred_fmt = (WGPUTextureFormat)surface.GetPreferredFormat(adapter);
#else #else
WGPUAdapter adapter = RequestAdapter(instance.Get());
if (!adapter)
return false;
wgpu_device = RequestDevice(adapter);
wgpu::Surface surface = wgpu::glfw::CreateSurfaceForWindow(instance, window); wgpu::Surface surface = wgpu::glfw::CreateSurfaceForWindow(instance, window);
if (!surface) if (!surface)
return false; return false;
@@ -336,21 +348,5 @@ static bool InitWGPU(GLFWwindow* window)
wgpu_surface = surface.MoveToCHandle(); wgpu_surface = surface.MoveToCHandle();
wgpuDeviceSetUncapturedErrorCallback(wgpu_device, wgpu_error_callback, nullptr); wgpuDeviceSetUncapturedErrorCallback(wgpu_device, wgpu_error_callback, nullptr);
return true; 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);
}

View File

@@ -48,7 +48,7 @@ int main(int, char**)
} }
SDL_PropertiesID props = SDL_GetWindowProperties(window); 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 // Initialize Direct3D
if (!CreateDeviceD3D(hwnd)) if (!CreateDeviceD3D(hwnd))

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.4 // dear imgui, v1.92.5 WIP
// (main code and documentation) // (main code and documentation)
// Help: // Help:

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.4 // dear imgui, v1.92.5 WIP
// (headers) // (headers)
// Help: // Help:
@@ -28,8 +28,8 @@
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') // (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 "1.92.5 WIP"
#define IMGUI_VERSION_NUM 19240 #define IMGUI_VERSION_NUM 19241
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #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_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch. #define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.4 // dear imgui, v1.92.5 WIP
// (demo code) // (demo code)
// Help: // Help:

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.4 // dear imgui, v1.92.5 WIP
// (drawing and font code) // (drawing and font code)
/* /*

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.4 // dear imgui, v1.92.5 WIP
// (internal structures/api) // (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. // 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. // sizeof() ~ 136 bytes.
struct IMGUI_API ImGuiTableTempData struct IMGUI_API ImGuiTableTempData
{ {
ImGuiID WindowID; // Shortcut to g.Tables[TableIndex]->OuterWindow->ID.
int TableIndex; // Index in g.Tables.Buf[] pool int TableIndex; // Index in g.Tables.Buf[] pool
float LastTimeActive; // Last timestamp this structure was used float LastTimeActive; // Last timestamp this structure was used
float AngledHeadersExtraWidth; // Used in EndTable() float AngledHeadersExtraWidth; // Used in EndTable()

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.4 // dear imgui, v1.92.5 WIP
// (tables and columns code) // (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->HostIndentX = inner_window->DC.Indent.x;
table->HostClipRect = inner_window->ClipRect; table->HostClipRect = inner_window->ClipRect;
table->HostSkipItems = inner_window->SkipItems; table->HostSkipItems = inner_window->SkipItems;
temp_data->WindowID = inner_window->ID;
temp_data->HostBackupWorkRect = inner_window->WorkRect; temp_data->HostBackupWorkRect = inner_window->WorkRect;
temp_data->HostBackupParentWorkRect = inner_window->ParentWorkRect; temp_data->HostBackupParentWorkRect = inner_window->ParentWorkRect;
temp_data->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset; temp_data->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset;
@@ -1366,7 +1367,7 @@ void ImGui::EndTable()
ImGuiWindow* inner_window = table->InnerWindow; ImGuiWindow* inner_window = table->InnerWindow;
ImGuiWindow* outer_window = table->OuterWindow; ImGuiWindow* outer_window = table->OuterWindow;
ImGuiTableTempData* temp_data = table->TempData; 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); IM_ASSERT(outer_window == inner_window || outer_window == inner_window->ParentWindow);
if (table->IsInsideRow) if (table->IsInsideRow)
@@ -1559,7 +1560,7 @@ void ImGui::EndTable()
IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table); IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table);
IM_ASSERT(g.TablesTempDataStacked > 0); IM_ASSERT(g.TablesTempDataStacked > 0);
temp_data = (--g.TablesTempDataStacked > 0) ? &g.TablesTempData[g.TablesTempDataStacked - 1] : NULL; 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) if (g.CurrentTable)
{ {
g.CurrentTable->TempData = temp_data; g.CurrentTable->TempData = temp_data;

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.92.4 // dear imgui, v1.92.5 WIP
// (widgets code) // (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. // 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. // 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) for (ImGuiKey key : always_owned_keys)
SetKeyOwner(key, id); SetKeyOwner(key, id);
if (user_clicked) 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. // 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 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_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)); 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); 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 // Determine if we turn Enter into a \n character
bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; 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; validated = true;
if (io.ConfigInputTextEnterKeepActive && !is_multiline) 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) 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)) if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
state->OnCharPressed(c); 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); line_index->Offsets.resize(0);
int line_count = 1; int line_count = 1;
if (is_multiline) 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_index->EndOffset = (int)(buf_display_end - buf_display);
line_visible_n1 = ImMin(line_visible_n1, line_count); line_visible_n1 = ImMin(line_visible_n1, line_count);