diff --git a/backends/imgui_impl_allegro5.cpp b/backends/imgui_impl_allegro5.cpp index 3d98636ea..1264e8d04 100644 --- a/backends/imgui_impl_allegro5.cpp +++ b/backends/imgui_impl_allegro5.cpp @@ -439,9 +439,9 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display) // We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion. ALLEGRO_VERTEX_ELEMENT elems[] = { - { ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, pos) }, - { ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, uv) }, - { ALLEGRO_PRIM_COLOR_ATTR, 0, IM_OFFSETOF(ImDrawVertAllegro, col) }, + { ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, pos) }, + { ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, uv) }, + { ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ImDrawVertAllegro, col) }, { 0, 0, 0 } }; bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro)); diff --git a/backends/imgui_impl_dx10.cpp b/backends/imgui_impl_dx10.cpp index 2d53e182f..75c546700 100644 --- a/backends/imgui_impl_dx10.cpp +++ b/backends/imgui_impl_dx10.cpp @@ -420,9 +420,9 @@ bool ImGui_ImplDX10_CreateDeviceObjects() // Create the input layout D3D10_INPUT_ELEMENT_DESC local_layout[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D10_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D10_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK) { diff --git a/backends/imgui_impl_dx11.cpp b/backends/imgui_impl_dx11.cpp index f2b20e4a4..7b0263656 100644 --- a/backends/imgui_impl_dx11.cpp +++ b/backends/imgui_impl_dx11.cpp @@ -432,9 +432,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects() // Create the input layout D3D11_INPUT_ELEMENT_DESC local_layout[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK) { diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index 22261a1db..428e47ee0 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -667,9 +667,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects() // Create the input layout static D3D12_INPUT_ELEMENT_DESC local_layout[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, }; psoDesc.InputLayout = { local_layout, 3 }; } diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index 55af1b1e3..20754d650 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -707,13 +707,13 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows() } MTLVertexDescriptor* vertexDescriptor = [MTLVertexDescriptor vertexDescriptor]; - vertexDescriptor.attributes[0].offset = IM_OFFSETOF(ImDrawVert, pos); + vertexDescriptor.attributes[0].offset = offsetof(ImDrawVert, pos); vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; // position vertexDescriptor.attributes[0].bufferIndex = 0; - vertexDescriptor.attributes[1].offset = IM_OFFSETOF(ImDrawVert, uv); + vertexDescriptor.attributes[1].offset = offsetof(ImDrawVert, uv); vertexDescriptor.attributes[1].format = MTLVertexFormatFloat2; // texCoords vertexDescriptor.attributes[1].bufferIndex = 0; - vertexDescriptor.attributes[2].offset = IM_OFFSETOF(ImDrawVert, col); + vertexDescriptor.attributes[2].offset = offsetof(ImDrawVert, col); vertexDescriptor.attributes[2].format = MTLVertexFormatUChar4; // color vertexDescriptor.attributes[2].bufferIndex = 0; vertexDescriptor.layouts[0].stepRate = 1; diff --git a/backends/imgui_impl_opengl2.cpp b/backends/imgui_impl_opengl2.cpp index 8defd84ba..3a21c0913 100644 --- a/backends/imgui_impl_opengl2.cpp +++ b/backends/imgui_impl_opengl2.cpp @@ -203,9 +203,9 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data) const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col))); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp index 6aa49ea3d..f93cda161 100644 --- a/backends/imgui_impl_opengl3.cpp +++ b/backends/imgui_impl_opengl3.cpp @@ -24,6 +24,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2023-11-08: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead of "libGL.so.1", accomodating for NetBSD systems having only "libGL.so.3" available. (#6983) // 2023-10-05: OpenGL: Rename symbols in our internal loader so that LTO compilation with another copy of gl3w is possible. (#6875, #6668, #4445) // 2023-06-20: OpenGL: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333) // 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375) @@ -472,9 +473,9 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxPos)); GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxUV)); GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxColor)); - GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos))); - GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv))); - GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col))); + GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, pos))); + GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, uv))); + GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col))); } // OpenGL3 Render function. diff --git a/backends/imgui_impl_opengl3_loader.h b/backends/imgui_impl_opengl3_loader.h index a077751c9..9fb8ffb32 100644 --- a/backends/imgui_impl_opengl3_loader.h +++ b/backends/imgui_impl_opengl3_loader.h @@ -118,7 +118,7 @@ extern "C" { ** included as . ** ** glcorearb.h includes only APIs in the latest OpenGL core profile -** implementation together with APIs in newer ARB extensions which +** implementation together with APIs in newer ARB extensions which ** can be supported by the core profile. It does not, and never will ** include functionality removed from the core profile, such as ** fixed-function vertex and fragment processing. @@ -666,7 +666,8 @@ static GL3WglProc (*glx_get_proc_address)(const GLubyte *); static int open_libgl(void) { - libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL); + // While most systems use libGL.so.1, NetBSD seems to use that libGL.so.3. See https://github.com/ocornut/imgui/issues/6983 + libgl = dlopen("libGL.so", RTLD_LAZY | RTLD_LOCAL); if (!libgl) return GL3W_ERROR_LIBRARY_OPEN; *(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB"); diff --git a/backends/imgui_impl_sdlrenderer2.cpp b/backends/imgui_impl_sdlrenderer2.cpp index affa13950..4c90492e7 100644 --- a/backends/imgui_impl_sdlrenderer2.cpp +++ b/backends/imgui_impl_sdlrenderer2.cpp @@ -183,12 +183,12 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data) SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) }; SDL_RenderSetClipRect(bd->SDLRenderer, &r); - const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, pos)); - const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, uv)); + const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos)); + const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv)); #if SDL_VERSION_ATLEAST(2,0,19) - const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.19+ + const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+ #else - const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18 + const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18 #endif // Bind texture, Draw diff --git a/backends/imgui_impl_sdlrenderer3.cpp b/backends/imgui_impl_sdlrenderer3.cpp index 2deb6075b..29671be0d 100644 --- a/backends/imgui_impl_sdlrenderer3.cpp +++ b/backends/imgui_impl_sdlrenderer3.cpp @@ -178,12 +178,12 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data) SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) }; SDL_SetRenderClipRect(bd->SDLRenderer, &r); - const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, pos)); - const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, uv)); + const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos)); + const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv)); #if SDL_VERSION_ATLEAST(2,0,19) - const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.19+ + const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+ #else - const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18 + const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18 #endif // Bind texture, Draw diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index c75ceb3aa..7099bf331 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -35,6 +35,11 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2023-11-10: *BREAKING CHANGE*: Removed parameter from ImGui_ImplVulkan_CreateFontsTexture(): backend now creates its own command-buffer to upload fonts. +// *BREAKING CHANGE*: Removed ImGui_ImplVulkan_DestroyFontUploadObjects() which is now unecessary as we create and destroy those objects in the backend. +// ImGui_ImplVulkan_CreateFontsTexture() is automatically called by NewFrame() the first time. +// You can call ImGui_ImplVulkan_CreateFontsTexture() again to recreate the font atlas texture. +// Added ImGui_ImplVulkan_DestroyFontsTexture() but you probably never need to call this. // 2023-07-04: Vulkan: Added optional support for VK_KHR_dynamic_rendering. User needs to set init_info->UseDynamicRendering = true and init_info->ColorAttachmentFormat. // 2023-01-02: Vulkan: Fixed sampler passed to ImGui_ImplVulkan_AddTexture() not being honored + removed a bunch of duplicate code. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. @@ -134,8 +139,8 @@ struct ImGui_ImplVulkan_Data VkImage FontImage; VkImageView FontView; VkDescriptorSet FontDescriptorSet; - VkDeviceMemory UploadBufferMemory; - VkBuffer UploadBuffer; + VkCommandPool FontCommandPool; + VkCommandBuffer FontCommandBuffer; // Render buffers for main window ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers; @@ -619,19 +624,55 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm vkCmdSetScissor(command_buffer, 0, 1, &scissor); } -bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) +bool ImGui_ImplVulkan_CreateFontsTexture() { ImGuiIO& io = ImGui::GetIO(); ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + VkResult err; + + // Destroy existing texture (if any) + if (bd->FontView || bd->FontImage || bd->FontMemory || bd->FontDescriptorSet) + { + vkQueueWaitIdle(v->Queue); + ImGui_ImplVulkan_DestroyFontsTexture(); + } + + // Create command pool/buffer + if (bd->FontCommandPool == VK_NULL_HANDLE) + { + VkCommandPoolCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + info.queueFamilyIndex = v->QueueFamily; + vkCreateCommandPool(v->Device, &info, nullptr, &bd->FontCommandPool); + } + if (bd->FontCommandBuffer == VK_NULL_HANDLE) + { + VkCommandBufferAllocateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + info.commandPool = bd->FontCommandPool; + info.commandBufferCount = 1; + err = vkAllocateCommandBuffers(v->Device, &info, &bd->FontCommandBuffer); + check_vk_result(err); + } + + // Start command buffer + { + err = vkResetCommandPool(v->Device, bd->FontCommandPool, 0); + check_vk_result(err); + VkCommandBufferBeginInfo begin_info = {}; + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + err = vkBeginCommandBuffer(bd->FontCommandBuffer, &begin_info); + check_vk_result(err); + } unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); size_t upload_size = width * height * 4 * sizeof(char); - VkResult err; - // Create the Image: { VkImageCreateInfo info = {}; @@ -680,40 +721,42 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) bd->FontDescriptorSet = (VkDescriptorSet)ImGui_ImplVulkan_AddTexture(bd->FontSampler, bd->FontView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); // Create the Upload Buffer: + VkDeviceMemory upload_buffer_memory; + VkBuffer upload_buffer; { VkBufferCreateInfo buffer_info = {}; buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_info.size = upload_size; buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &bd->UploadBuffer); + err = vkCreateBuffer(v->Device, &buffer_info, v->Allocator, &upload_buffer); check_vk_result(err); VkMemoryRequirements req; - vkGetBufferMemoryRequirements(v->Device, bd->UploadBuffer, &req); + vkGetBufferMemoryRequirements(v->Device, upload_buffer, &req); bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment; VkMemoryAllocateInfo alloc_info = {}; alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; alloc_info.allocationSize = req.size; alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits); - err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &bd->UploadBufferMemory); + err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &upload_buffer_memory); check_vk_result(err); - err = vkBindBufferMemory(v->Device, bd->UploadBuffer, bd->UploadBufferMemory, 0); + err = vkBindBufferMemory(v->Device, upload_buffer, upload_buffer_memory, 0); check_vk_result(err); } // Upload to Buffer: { char* map = nullptr; - err = vkMapMemory(v->Device, bd->UploadBufferMemory, 0, upload_size, 0, (void**)(&map)); + err = vkMapMemory(v->Device, upload_buffer_memory, 0, upload_size, 0, (void**)(&map)); check_vk_result(err); memcpy(map, pixels, upload_size); VkMappedMemoryRange range[1] = {}; range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - range[0].memory = bd->UploadBufferMemory; + range[0].memory = upload_buffer_memory; range[0].size = upload_size; err = vkFlushMappedMemoryRanges(v->Device, 1, range); check_vk_result(err); - vkUnmapMemory(v->Device, bd->UploadBufferMemory); + vkUnmapMemory(v->Device, upload_buffer_memory); } // Copy to Image: @@ -729,7 +772,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copy_barrier[0].subresourceRange.levelCount = 1; copy_barrier[0].subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, copy_barrier); + vkCmdPipelineBarrier(bd->FontCommandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, copy_barrier); VkBufferImageCopy region = {}; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -737,7 +780,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) region.imageExtent.width = width; region.imageExtent.height = height; region.imageExtent.depth = 1; - vkCmdCopyBufferToImage(command_buffer, bd->UploadBuffer, bd->FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + vkCmdCopyBufferToImage(bd->FontCommandBuffer, upload_buffer, bd->FontImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); VkImageMemoryBarrier use_barrier[1] = {}; use_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -751,15 +794,50 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer) use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; use_barrier[0].subresourceRange.levelCount = 1; use_barrier[0].subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, use_barrier); + vkCmdPipelineBarrier(bd->FontCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, use_barrier); } // Store our identifier io.Fonts->SetTexID((ImTextureID)bd->FontDescriptorSet); + // End command buffer + VkSubmitInfo end_info = {}; + end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + end_info.commandBufferCount = 1; + end_info.pCommandBuffers = &bd->FontCommandBuffer; + err = vkEndCommandBuffer(bd->FontCommandBuffer); + check_vk_result(err); + err = vkQueueSubmit(v->Queue, 1, &end_info, VK_NULL_HANDLE); + check_vk_result(err); + + err = vkDeviceWaitIdle(v->Device); + check_vk_result(err); + + vkDestroyBuffer(v->Device, upload_buffer, v->Allocator); + vkFreeMemory(v->Device, upload_buffer_memory, v->Allocator); + return true; } +// You probably never need to call this, as it is called by ImGui_ImplVulkan_CreateFontsTexture() and ImGui_ImplVulkan_Shutdown(). +void ImGui_ImplVulkan_DestroyFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + + if (bd->FontDescriptorSet) + { + ImGui_ImplVulkan_RemoveTexture(bd->FontDescriptorSet); + bd->FontDescriptorSet = VK_NULL_HANDLE; + io.Fonts->SetTexID(0); + } + + if (bd->FontView) { vkDestroyImageView(v->Device, bd->FontView, v->Allocator); bd->FontView = VK_NULL_HANDLE; } + if (bd->FontImage) { vkDestroyImage(v->Device, bd->FontImage, v->Allocator); bd->FontImage = VK_NULL_HANDLE; } + if (bd->FontMemory) { vkFreeMemory(v->Device, bd->FontMemory, v->Allocator); bd->FontMemory = VK_NULL_HANDLE; } +} + static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAllocationCallbacks* allocator) { // Create the shader modules @@ -807,15 +885,15 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC attribute_desc[0].location = 0; attribute_desc[0].binding = binding_desc[0].binding; attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT; - attribute_desc[0].offset = IM_OFFSETOF(ImDrawVert, pos); + attribute_desc[0].offset = offsetof(ImDrawVert, pos); attribute_desc[1].location = 1; attribute_desc[1].binding = binding_desc[0].binding; attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT; - attribute_desc[1].offset = IM_OFFSETOF(ImDrawVert, uv); + attribute_desc[1].offset = offsetof(ImDrawVert, uv); attribute_desc[2].location = 2; attribute_desc[2].binding = binding_desc[0].binding; attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM; - attribute_desc[2].offset = IM_OFFSETOF(ImDrawVert, col); + attribute_desc[2].offset = offsetof(ImDrawVert, col); VkPipelineVertexInputStateCreateInfo vertex_info = {}; vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; @@ -962,34 +1040,16 @@ bool ImGui_ImplVulkan_CreateDeviceObjects() return true; } -void ImGui_ImplVulkan_DestroyFontUploadObjects() -{ - ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); - ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; - if (bd->UploadBuffer) - { - vkDestroyBuffer(v->Device, bd->UploadBuffer, v->Allocator); - bd->UploadBuffer = VK_NULL_HANDLE; - } - if (bd->UploadBufferMemory) - { - vkFreeMemory(v->Device, bd->UploadBufferMemory, v->Allocator); - bd->UploadBufferMemory = VK_NULL_HANDLE; - } -} - void ImGui_ImplVulkan_DestroyDeviceObjects() { ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator); - ImGui_ImplVulkan_DestroyFontUploadObjects(); + ImGui_ImplVulkan_DestroyFontsTexture(); + if (bd->FontCommandPool) { vkDestroyCommandPool(v->Device, bd->FontCommandPool, v->Allocator); bd->FontCommandPool = VK_NULL_HANDLE; } if (bd->ShaderModuleVert) { vkDestroyShaderModule(v->Device, bd->ShaderModuleVert, v->Allocator); bd->ShaderModuleVert = VK_NULL_HANDLE; } if (bd->ShaderModuleFrag) { vkDestroyShaderModule(v->Device, bd->ShaderModuleFrag, v->Allocator); bd->ShaderModuleFrag = VK_NULL_HANDLE; } - if (bd->FontView) { vkDestroyImageView(v->Device, bd->FontView, v->Allocator); bd->FontView = VK_NULL_HANDLE; } - if (bd->FontImage) { vkDestroyImage(v->Device, bd->FontImage, v->Allocator); bd->FontImage = VK_NULL_HANDLE; } - if (bd->FontMemory) { vkFreeMemory(v->Device, bd->FontMemory, v->Allocator); bd->FontMemory = VK_NULL_HANDLE; } if (bd->FontSampler) { vkDestroySampler(v->Device, bd->FontSampler, v->Allocator); bd->FontSampler = VK_NULL_HANDLE; } if (bd->DescriptorSetLayout) { vkDestroyDescriptorSetLayout(v->Device, bd->DescriptorSetLayout, v->Allocator); bd->DescriptorSetLayout = VK_NULL_HANDLE; } if (bd->PipelineLayout) { vkDestroyPipelineLayout(v->Device, bd->PipelineLayout, v->Allocator); bd->PipelineLayout = VK_NULL_HANDLE; } @@ -1106,7 +1166,9 @@ void ImGui_ImplVulkan_NewFrame() { ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplVulkan_Init()?"); - IM_UNUSED(bd); + + if (!bd->FontDescriptorSet) + ImGui_ImplVulkan_CreateFontsTexture(); } void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count) diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index 53388c81d..45a1627a5 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -79,8 +79,8 @@ IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* inf IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown(); IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame(); IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE); -IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer); -IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects(); +IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(); +IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture(); IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated) // Register a texture (VkDescriptorSet == ImTextureID) diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index d6f886b56..0e0c77b7c 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -603,9 +603,9 @@ bool ImGui_ImplWGPU_CreateDeviceObjects() // Vertex input configuration WGPUVertexAttribute attribute_desc[] = { - { WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, pos), 0 }, - { WGPUVertexFormat_Float32x2, (uint64_t)IM_OFFSETOF(ImDrawVert, uv), 1 }, - { WGPUVertexFormat_Unorm8x4, (uint64_t)IM_OFFSETOF(ImDrawVert, col), 2 }, + { WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 }, + { WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 }, + { WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 }, }; WGPUVertexBufferLayout buffer_layouts[1]; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 1796b92e4..938f011bf 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -68,6 +68,8 @@ Breaking changes: as earlier name was misleading. Kept inline redirection function. (#4631) - IO: Removed io.MetricsActiveAllocations introduced in 1.63, was displayed in Metrics and unlikely to be accessed by end-user. Value still visible in the UI and easily to recompute from a delta. + - Defining IMGUI_DISABLE_OBSOLETE_FUNCTIONS now automaticaly define IMGUI_DISABLE_OBSOLETE_KEYIO. (#4921) + - Removed IM_OFFSETOF() macro in favor of using offsetof() available in C++11. Kept redirection define. (#4537) - ListBox, Combo: Changed signature of "name getter" callback in old one-liner ListBox()/Combo() apis. Before: getter type: bool (*getter)(void* user_data, int idx, const char** out_text) @@ -86,6 +88,11 @@ Breaking changes: - Commented out runtime support for hardcoded ~0 or 0x01..0x0F rounding flags values for AddRect()/AddRectFilled()/PathRect()/AddImageRounded(). -> Use ImDrawFlags_RoundCornersXXX flags. Read 1.82 Changelog for details. + - Backends: Vulkan: Removed parameter from ImGui_ImplVulkan_CreateFontsTexture(): backend now creates its own + command-buffer to upload fonts. Removed ImGui_ImplVulkan_DestroyFontUploadObjects() which is now unecessary. + No need to call ImGui_ImplVulkan_CreateFontsTexture() as it is done automatically in NewFrame(). + You can call ImGui_ImplVulkan_CreateFontsTexture() manually if you need to reload the font atlas texture. + (#6943, #6715, #6327, #3743, #4618) Other changes: @@ -208,6 +215,13 @@ Other changes: - Demo: Added "Drag and Drop -> Tooltip at target location" demo. - Demo: Added "Layout -> Child Windows -> Manual-resize" demo. (#1710) - Demo: Added "Layout -> Child Windows -> Auto-resize with constraints" demo. (#1666, #1395, #1496, #1710) +- Backends: Vulkan: Removed parameter from ImGui_ImplVulkan_CreateFontsTexture(): backend now creates its own + command-buffer to upload fonts. Removed ImGui_ImplVulkan_DestroyFontUploadObjects() which is now unecessary. + No need to call ImGui_ImplVulkan_CreateFontsTexture() as it is done automatically in NewFrame(). + You can call ImGui_ImplVulkan_CreateFontsTexture() manually if you need to reload font atlas texture. + Fixed leaks, and added ImGui_ImplVulkan_DestroyFontsTexture() (probably no need to call this directly). + (#6943, #6715, #6327, #3743, #4618) + [@helynranta, @thomasherzog, @guybrush77, @albin-johansson, @MiroKaku, @benbatya-fb, @ocornut] - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] - Backends: GLFW: Added support for F13 to F24 function keys. (#6891) - Backends: SDL2, SDL3: Added support for F13 to F24 function keys, AppBack, AppForward. (#6891) @@ -218,7 +232,10 @@ Other changes: doesn't emit it (same behavior as GLFW/SDL). (#6859) [@thedmd, @SuperWangKai] - Backends: OpenGL3: rename symbols in our internal loader so that LTO compilation with another copy of gl3w becomes possible. (#6875, #6668, #4445) [@nicolasnoble] +- Backends: OpenGL3: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead + of "libGL.so.1", accomodating for NetBSD systems having only "libGL.so.3" available. (#6983) - Backends: OSX: Added support for F13 to F20 function keys. Support mapping F13 to PrintScreen. (#6891) +- Examples: GLFW+Vulkan, SDL+Vulkan: Extracted font upload code into a UploadFonts() function. - Internals: Renamed ImFloor() to ImTrunc(). Renamed ImFloorSigned() to ImFloor(). (#6861) Docking+Viewports Branch: diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 7d0a05fb2..5fb86739c 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -470,36 +470,6 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != nullptr); - // Upload Fonts - { - // Use any command queue - VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool; - VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer; - - err = vkResetCommandPool(g_Device, command_pool, 0); - check_vk_result(err); - VkCommandBufferBeginInfo begin_info = {}; - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - err = vkBeginCommandBuffer(command_buffer, &begin_info); - check_vk_result(err); - - ImGui_ImplVulkan_CreateFontsTexture(command_buffer); - - VkSubmitInfo end_info = {}; - end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - end_info.commandBufferCount = 1; - end_info.pCommandBuffers = &command_buffer; - err = vkEndCommandBuffer(command_buffer); - check_vk_result(err); - err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE); - check_vk_result(err); - - err = vkDeviceWaitIdle(g_Device); - check_vk_result(err); - ImGui_ImplVulkan_DestroyFontUploadObjects(); - } - // Our state bool show_demo_window = true; bool show_another_window = false; diff --git a/examples/example_sdl2_vulkan/main.cpp b/examples/example_sdl2_vulkan/main.cpp index 7d353d46d..cbaa34bc4 100644 --- a/examples/example_sdl2_vulkan/main.cpp +++ b/examples/example_sdl2_vulkan/main.cpp @@ -465,36 +465,6 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese()); //IM_ASSERT(font != nullptr); - // Upload Fonts - { - // Use any command queue - VkCommandPool command_pool = wd->Frames[wd->FrameIndex].CommandPool; - VkCommandBuffer command_buffer = wd->Frames[wd->FrameIndex].CommandBuffer; - - err = vkResetCommandPool(g_Device, command_pool, 0); - check_vk_result(err); - VkCommandBufferBeginInfo begin_info = {}; - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - err = vkBeginCommandBuffer(command_buffer, &begin_info); - check_vk_result(err); - - ImGui_ImplVulkan_CreateFontsTexture(command_buffer); - - VkSubmitInfo end_info = {}; - end_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - end_info.commandBufferCount = 1; - end_info.pCommandBuffers = &command_buffer; - err = vkEndCommandBuffer(command_buffer); - check_vk_result(err); - err = vkQueueSubmit(g_Queue, 1, &end_info, VK_NULL_HANDLE); - check_vk_result(err); - - err = vkDeviceWaitIdle(g_Device); - check_vk_result(err); - ImGui_ImplVulkan_DestroyFontUploadObjects(); - } - // Our state bool show_demo_window = true; bool show_another_window = false; diff --git a/imconfig.h b/imconfig.h index bac7661f0..e09dff036 100644 --- a/imconfig.h +++ b/imconfig.h @@ -28,7 +28,7 @@ //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names. //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS -//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions. +//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS. //---- Disable all of Dear ImGui or don't implement standard windows/tools. // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. diff --git a/imgui.cpp b/imgui.cpp index 4a06ef9dc..338a2410e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -432,6 +432,7 @@ CODE - likewise io.MousePos and GetMousePos() will use OS coordinates. If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos. + - 2023/11/09 (1.90.0) - removed IM_OFFSETOF() macro in favor of using offsetof() available in C++11. Kept redirection define (will obsolete). - 2023/11/07 (1.90.0) - removed BeginChildFrame()/EndChildFrame() in favor of using BeginChild() with the ImGuiChildFlags_FrameStyle flag. kept inline redirection function (will obsolete). those functions were merely PushStyle/PopStyle helpers, the removal isn't so much motivated by needing to add the feature in BeginChild(), but by the necessity to avoid BeginChildFrame() signature mismatching BeginChild() signature and features. - 2023/11/02 (1.90.0) - BeginChild: upgraded 'bool border = true' parameter to 'ImGuiChildFlags flags' type, added ImGuiChildFlags_Border equivalent. As with our prior "bool-to-flags" API updates, the ImGuiChildFlags_Border value is guaranteed to be == true forever to ensure a smoother transition, meaning all existing calls will still work. @@ -3185,36 +3186,36 @@ static const ImGuiCol GWindowDockStyleColors[ImGuiWindowDockStyleCol_COUNT] = static const ImGuiDataVarInfo GStyleVarInfo[] = { - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, CellPadding) }, // ImGuiStyleVar_CellPadding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextBorderSize) },// ImGuiStyleVar_SeparatorTextBorderSize - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign - { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding - { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, DockingSeparatorSize) }, // ImGuiStyleVar_DockingSeparatorSize + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, CellPadding) }, // ImGuiStyleVar_CellPadding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize) },// ImGuiStyleVar_SeparatorTextBorderSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DockingSeparatorSize) }, // ImGuiStyleVar_DockingSeparatorSize }; const ImGuiDataVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx) diff --git a/imgui.h b/imgui.h index 3e6dad87d..d4952f816 100644 --- a/imgui.h +++ b/imgui.h @@ -87,7 +87,6 @@ Index of this file: #endif #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers! #define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds. -#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) // Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions. @@ -1490,6 +1489,11 @@ enum ImGuiSortDirection_ ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc. }; +// Since 1.90, defining IMGUI_DISABLE_OBSOLETE_FUNCTIONS automatically defines IMGUI_DISABLE_OBSOLETE_KEYIO as well. +#if defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) && !defined(IMGUI_DISABLE_OBSOLETE_KEYIO) +#define IMGUI_DISABLE_OBSOLETE_KEYIO +#endif + // A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value): can represent Keyboard, Mouse and Gamepad values. // All our named keys are >= 512. Keys value 0 to 511 are left unused as legacy native/opaque key values (< 1.87). // Since >= 1.89 we increased typing (went from int to enum), some legacy code may need a cast to ImGuiKey. @@ -3505,6 +3509,8 @@ enum ImGuiModFlags_ { ImGuiModFlags_None = 0, ImGuiModFlags_Ctrl = ImGuiMod_Ctrl //typedef ImGuiKeyChord ImGuiKeyModFlags; // == int //enum ImGuiKeyModFlags_ { ImGuiKeyModFlags_None = 0, ImGuiKeyModFlags_Ctrl = ImGuiMod_Ctrl, ImGuiKeyModFlags_Shift = ImGuiMod_Shift, ImGuiKeyModFlags_Alt = ImGuiMod_Alt, ImGuiKeyModFlags_Super = ImGuiMod_Super }; +#define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // OBSOLETED IN 1.90 (now using C++11 standard version) + #endif // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // RENAMED IMGUI_DISABLE_METRICS_WINDOW > IMGUI_DISABLE_DEBUG_TOOLS in 1.88 (from June 2022) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 9a7a89b10..20e68a0d0 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -392,9 +392,9 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error) void ImDrawList::_ResetForNewFrame() { // Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory. - IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0); - IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4)); - IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID)); + IM_STATIC_ASSERT(offsetof(ImDrawCmd, ClipRect) == 0); + IM_STATIC_ASSERT(offsetof(ImDrawCmd, TextureId) == sizeof(ImVec4)); + IM_STATIC_ASSERT(offsetof(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID)); if (_Splitter._Count > 1) _Splitter.Merge(this); @@ -481,7 +481,7 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) } // Compare ClipRect, TextureId and VtxOffset with a single memcmp() -#define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int)) +#define ImDrawCmd_HeaderSize (offsetof(ImDrawCmd, VtxOffset) + sizeof(unsigned int)) #define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset #define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset #define ImDrawCmd_AreSequentialIdxOffset(CMD_0, CMD_1) (CMD_0->IdxOffset + CMD_0->ElemCount == CMD_1->IdxOffset) diff --git a/imgui_internal.h b/imgui_internal.h index 209353637..dfb450336 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3035,6 +3035,7 @@ struct IMGUI_API ImGuiTable bool IsSortSpecsDirty; bool IsUsingHeaders; // Set when the first row had the ImGuiTableRowFlags_Headers flag. bool IsContextPopupOpen; // Set when default context menu is open (also see: ContextPopupColumn, InstanceInteracted). + bool DisableDefaultContextMenu; // Disable default context menu contents. You may submit your own using TableBeginContextMenuPopup()/EndPopup() bool IsSettingsRequestLoad; bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSetttings data. bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1) @@ -3513,7 +3514,7 @@ namespace ImGui IMGUI_API void TableUpdateBorders(ImGuiTable* table); IMGUI_API void TableUpdateColumnsWeightFromWidth(ImGuiTable* table); IMGUI_API void TableDrawBorders(ImGuiTable* table); - IMGUI_API void TableDrawContextMenu(ImGuiTable* table); + IMGUI_API void TableDrawDefaultContextMenu(ImGuiTable* table, ImGuiTableFlags flags_for_section_to_display); IMGUI_API bool TableBeginContextMenuPopup(ImGuiTable* table); IMGUI_API void TableMergeDrawChannels(ImGuiTable* table); inline ImGuiTableInstanceData* TableGetInstanceData(ImGuiTable* table, int instance_no) { if (instance_no == 0) return &table->InstanceDataFirst; return &table->InstanceDataExtra[instance_no - 1]; } diff --git a/imgui_tables.cpp b/imgui_tables.cpp index bc54546e2..c9ea4544e 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -48,7 +48,8 @@ Index of this file: // - TableUpdateLayout() [Internal] followup to BeginTable(): setup everything: widths, columns positions, clipping rectangles. Automatically called by the FIRST call to TableNextRow() or TableHeadersRow(). // | TableSetupDrawChannels() - setup ImDrawList channels // | TableUpdateBorders() - detect hovering columns for resize, ahead of contents submission -// | TableDrawContextMenu() - draw right-click context menu +// | TableBeginContextMenuPopup() +// | - TableDrawDefaultContextMenu() - draw right-click context menu contents //----------------------------------------------------------------------------- // - TableHeadersRow() or TableHeader() user submit a headers row (optional) // | TableSortSpecsClickColumn() - when left-clicked: alter sort order and sort direction @@ -1190,10 +1191,14 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) if (g.ActiveId == 0 || (table->IsActiveIdInTable || g.DragDropActive)) table->HighlightColumnHeader = table->HoveredColumnBody; - // [Part 11] Context menu - if (TableBeginContextMenuPopup(table)) + // [Part 11] Default context menu + // - To append to this menu: you can call TableBeginContextMenuPopup()/.../EndPopup(). + // - To modify or replace this: set table->IsContextPopupNoDefaultContents = true, then call TableBeginContextMenuPopup()/.../EndPopup(). + // - You may call TableDrawDefaultContextMenu() with selected flags to display specific sections of the default menu, + // e.g. TableDrawDefaultContextMenu(table, table->Flags & ~ImGuiTableFlags_Hideable) will display everything EXCEPT columns visibility options. + if (table->DisableDefaultContextMenu == false && TableBeginContextMenuPopup(table)) { - TableDrawContextMenu(table); + TableDrawDefaultContextMenu(table, table->Flags); EndPopup(); } @@ -3257,7 +3262,8 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width) // [SECTION] Tables: Context Menu //------------------------------------------------------------------------- // - TableOpenContextMenu() [Internal] -// - TableDrawContextMenu() [Internal] +// - TableBeginContextMenuPopup() [Internal] +// - TableDrawDefaultContextMenu() [Internal] //------------------------------------------------------------------------- // Use -1 to open menu not specific to a given column. @@ -3293,7 +3299,13 @@ bool ImGui::TableBeginContextMenuPopup(ImGuiTable* table) // Output context menu into current window (generally a popup) // FIXME-TABLE: Ideally this should be writable by the user. Full programmatic access to that data? -void ImGui::TableDrawContextMenu(ImGuiTable* table) +// Sections to display are pulled from 'flags_for_section_to_display', which is typically == table->Flags. +// - ImGuiTableFlags_Resizable -> display Sizing menu items +// - ImGuiTableFlags_Reorderable -> display "Reset Order" +////- ImGuiTableFlags_Sortable -> display sorting options (disabled) +// - ImGuiTableFlags_Hideable -> display columns visibility menu items +// It means if you have a custom context menus you can call this section and omit some sections, and add your own. +void ImGui::TableDrawDefaultContextMenu(ImGuiTable* table, ImGuiTableFlags flags_for_section_to_display) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -3305,7 +3317,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table) ImGuiTableColumn* column = (column_n != -1) ? &table->Columns[column_n] : NULL; // Sizing - if (table->Flags & ImGuiTableFlags_Resizable) + if (flags_for_section_to_display & ImGuiTableFlags_Resizable) { if (column != NULL) { @@ -3325,7 +3337,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table) } // Ordering - if (table->Flags & ImGuiTableFlags_Reorderable) + if (flags_for_section_to_display & ImGuiTableFlags_Reorderable) { if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableResetOrder), NULL, false, !table->IsDefaultDisplayOrder)) table->IsResetDisplayOrderRequest = true; @@ -3339,7 +3351,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table) // Sorting // (modify TableOpenContextMenu() to add _Sortable flag if enabling this) #if 0 - if ((table->Flags & ImGuiTableFlags_Sortable) && column != NULL && (column->Flags & ImGuiTableColumnFlags_NoSort) == 0) + if ((flags_for_section_to_display & ImGuiTableFlags_Sortable) && column != NULL && (column->Flags & ImGuiTableColumnFlags_NoSort) == 0) { if (want_separator) Separator(); @@ -3354,7 +3366,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table) #endif // Hiding / Visibility - if (table->Flags & ImGuiTableFlags_Hideable) + if (flags_for_section_to_display & ImGuiTableFlags_Hideable) { if (want_separator) Separator();