From 528b12eb7a30ba264ddcb4e33860e403bd133623 Mon Sep 17 00:00:00 2001 From: u3shit Date: Tue, 21 Apr 2020 02:13:06 +0200 Subject: [PATCH 01/14] Fix glClipControl(GL_UPPER_LEFT) handling in opengl3. --- docs/CHANGELOG.txt | 2 ++ examples/imgui_impl_opengl3.cpp | 21 +++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 81cb3bab..18cb9659 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -44,6 +44,8 @@ Other Changes: - TreeNode: Fixed bug where dragging a payload over a TreeNode() with either _OpenOnDoubleClick or _OpenOnArrow would open the node. (#143) - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) +- Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the + projection matrix top and bottom values. (#3143, #3146) [@u3shit] ----------------------------------------------------------------------- diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp index 40e531dd..bf8225d0 100644 --- a/examples/imgui_impl_opengl3.cpp +++ b/examples/imgui_impl_opengl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix. // 2020-04-12: OpenGL: Fixed context version check mistakenly testing for 4.0+ instead of 3.2+ to enable ImGuiBackendFlags_RendererHasVtxOffset. // 2020-03-24: OpenGL: Added support for glbinding 2.x OpenGL loader. // 2020-01-07: OpenGL: Added support for glbinding 3.x OpenGL loader. @@ -243,6 +244,14 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #endif + // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) + bool clip_origin_lower_left = true; +#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) + GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin); + if (current_clip_origin == GL_UPPER_LEFT) + clip_origin_lower_left = false; +#endif + // Setup viewport, orthographic projection matrix // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); @@ -250,6 +259,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float T = draw_data->DisplayPos.y; float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; + if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left const float ortho_projection[4][4] = { { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, @@ -318,12 +328,6 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - bool clip_origin_lower_left = true; -#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) - GLenum last_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) - if (last_clip_origin == GL_UPPER_LEFT) - clip_origin_lower_left = false; -#endif // Setup desired GL state // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts) @@ -371,10 +375,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) { // Apply scissor/clipping rectangle - if (clip_origin_lower_left) - glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); - else - glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) + glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); // Bind texture, Draw glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); From fd6d3155c07fb2292e7ef84f4d53d0fb8eb1196a Mon Sep 17 00:00:00 2001 From: Silent Date: Wed, 22 Apr 2020 10:13:20 +0200 Subject: [PATCH 02/14] Fix wrong comment in ImGuiCond_ (#3139) --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 5ac453c4..bdc241fa 100644 --- a/imgui.h +++ b/imgui.h @@ -1265,7 +1265,7 @@ enum ImGuiMouseCursor_ enum ImGuiCond_ { ImGuiCond_Always = 1 << 0, // Set the variable - ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) + ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call will succeed) ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the object/window has no persistently saved data (no entry in .ini file) ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time) }; From 223297b075a7c2c76f33356a3854e6dd8da2b49b Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 23 Apr 2020 16:30:37 +0200 Subject: [PATCH 03/14] Clarified comments about popups input blocking and ImGuiHoveredFlags_AllowWhenBlockedByPopup flag. (#3154) --- imgui.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/imgui.h b/imgui.h index bdc241fa..f2b1cd9d 100644 --- a/imgui.h +++ b/imgui.h @@ -591,13 +591,16 @@ namespace ImGui // Popups, Modals // The properties of popups windows are: - // - They block normal mouse hovering detection outside them. (*) + // - They block normal mouse hovering detection outside them. (*1) // - Unless modal, they can be closed by clicking anywhere outside them, or by pressing ESCAPE. - // - Their visibility state (~bool) is held internally by imgui instead of being held by the programmer as we are used to with regular Begin() calls. - // User can manipulate the visibility state by calling OpenPopup(). + // Because hovering detection is disabled outside the popup, when clicking outside the click will not be seen by underlying widgets! (*1) + // - Their visibility state (~bool) is held internally by Dear ImGui instead of being held by the programmer as we are used to with regular Begin() calls. + // User can manipulate the visibility state by calling OpenPopup(), CloseCurrentPopup() etc. // - We default to use the right mouse (ImGuiMouseButton_Right=1) for the Popup Context functions. - // (*) You can use IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) to bypass it and detect hovering even when normally blocked by a popup. - // Those three properties are connected. The library needs to hold their visibility state because it can close popups at any time. + // Those three properties are connected: we need to retain popup visibility state in the library because popups may be closed as any time. + // (*1) You can bypass that restriction and detect hovering even when normally blocked by a popup. + // To do this use the ImGuiHoveredFlags_AllowWhenBlockedByPopup when calling IsItemHovered() or IsWindowHovered(). + // This is what BeginPopupContextItem() and BeginPopupContextWindow() are doing already, allowing a right-click to reopen another popups without losing the click. IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returns true! IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! From 5ac5d3674fc79bfb41634df6ce412eb9bc098453 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 23 Apr 2020 15:30:30 +0200 Subject: [PATCH 04/14] Removed unncessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 1 + imgui.h | 15 ++++++++------- imgui_draw.cpp | 21 +++++++++------------ 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 18cb9659..ad309327 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -36,6 +36,9 @@ HOW TO UPDATE? Breaking Changes: +- Removed unncessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. Please + note that this is a Beta api and will likely be reworked to support multi-monitor multi-DPI. + Other Changes: - TreeNode: Fixed bug where BeginDragDropSource() failed when the _OpenOnDoubleClick flag is diff --git a/imgui.cpp b/imgui.cpp index 0d4d9780..f900a010 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -372,6 +372,7 @@ CODE When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2020/04/23 (1.77) - Removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular(). - 2020/01/22 (1.75) - ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius any more. - 2019/12/17 (1.75) - [undid this change in 1.76] made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead. - 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value. diff --git a/imgui.h b/imgui.h index f2b1cd9d..d3460d72 100644 --- a/imgui.h +++ b/imgui.h @@ -2150,13 +2150,13 @@ struct ImFontGlyphRangesBuilder // See ImFontAtlas::AddCustomRectXXX functions. struct ImFontAtlasCustomRect { - unsigned int ID; // Input // User ID. Use < 0x110000 to map into a font glyph, >= 0x110000 for other/internal/custom texture data. unsigned short Width, Height; // Input // Desired rectangle dimension unsigned short X, Y; // Output // Packed position in Atlas - float GlyphAdvanceX; // Input // For custom font glyphs only (ID < 0x110000): glyph xadvance - ImVec2 GlyphOffset; // Input // For custom font glyphs only (ID < 0x110000): glyph display offset - ImFont* Font; // Input // For custom font glyphs only (ID < 0x110000): target font - ImFontAtlasCustomRect() { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0,0); Font = NULL; } + unsigned int GlyphID; // Input // For custom font glyphs only (ID < 0x110000) + float GlyphAdvanceX; // Input // For custom font glyphs only: glyph xadvance + ImVec2 GlyphOffset; // Input // For custom font glyphs only: glyph display offset + ImFont* Font; // Input // For custom font glyphs only: target font + ImFontAtlasCustomRect() { Width = Height = 0; X = Y = 0xFFFF; GlyphID = 0; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0,0); Font = NULL; } bool IsPacked() const { return X != 0xFFFF; } }; @@ -2235,8 +2235,9 @@ struct ImFontAtlas // You can also request your rectangles to be mapped as font glyph (given a font + Unicode point), // so you can render e.g. custom colorful icons and use them as regular glyphs. // Read docs/FONTS.txt for more details about using colorful icons. - IMGUI_API int AddCustomRectRegular(unsigned int id, int width, int height); // Id needs to be >= 0x110000. Id >= 0x80000000 are reserved for ImGui and ImDrawList - IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0)); // Id needs to be < 0x110000 to register a rectangle to map into a specific font. + // Note: this API may be redesigned later in order to support multi-monitor varying DPI settings. + IMGUI_API int AddCustomRectRegular(int width, int height); + IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0)); const ImFontAtlasCustomRect*GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; } // [Internal] diff --git a/imgui_draw.cpp b/imgui_draw.cpp index d0d6a1e7..909949dc 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1543,7 +1543,6 @@ ImFontConfig::ImFontConfig() // The white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes. const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 108; const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; -const unsigned int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0x80000000; static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = { "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX- XX " @@ -1826,14 +1825,11 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed return font; } -int ImFontAtlas::AddCustomRectRegular(unsigned int id, int width, int height) +int ImFontAtlas::AddCustomRectRegular(int width, int height) { - // Breaking change on 2019/11/21 (1.74): ImFontAtlas::AddCustomRectRegular() now requires an ID >= 0x110000 (instead of >= 0x10000) - IM_ASSERT(id >= 0x110000); IM_ASSERT(width > 0 && width <= 0xFFFF); IM_ASSERT(height > 0 && height <= 0xFFFF); ImFontAtlasCustomRect r; - r.ID = id; r.Width = (unsigned short)width; r.Height = (unsigned short)height; CustomRects.push_back(r); @@ -1842,13 +1838,16 @@ int ImFontAtlas::AddCustomRectRegular(unsigned int id, int width, int height) int ImFontAtlas::AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset) { +#ifdef IMGUI_USE_WCHAR32 + IM_ASSERT(id <= IM_UNICODE_CODEPOINT_MAX); +#endif IM_ASSERT(font != NULL); IM_ASSERT(width > 0 && width <= 0xFFFF); IM_ASSERT(height > 0 && height <= 0xFFFF); ImFontAtlasCustomRect r; - r.ID = id; r.Width = (unsigned short)width; r.Height = (unsigned short)height; + r.GlyphID = id; r.GlyphAdvanceX = advance_x; r.GlyphOffset = offset; r.Font = font; @@ -1873,7 +1872,6 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou IM_ASSERT(CustomRectIds[0] != -1); ImFontAtlasCustomRect& r = CustomRects[CustomRectIds[0]]; - IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y); ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; *out_size = size; @@ -2208,9 +2206,9 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas) if (atlas->CustomRectIds[0] >= 0) return; if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) - atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); + atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); else - atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_ID, 2, 2); + atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(2, 2); } void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) @@ -2259,7 +2257,6 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) IM_ASSERT(atlas->CustomRectIds[0] >= 0); IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); ImFontAtlasCustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]]; - IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); IM_ASSERT(r.IsPacked()); const int w = atlas->TexWidth; @@ -2294,13 +2291,13 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas) for (int i = 0; i < atlas->CustomRects.Size; i++) { const ImFontAtlasCustomRect& r = atlas->CustomRects[i]; - if (r.Font == NULL || r.ID >= 0x110000) + if (r.Font == NULL || r.GlyphID == 0) continue; IM_ASSERT(r.Font->ContainerAtlas == atlas); ImVec2 uv0, uv1; atlas->CalcCustomRectUV(&r, &uv0, &uv1); - r.Font->AddGlyph((ImWchar)r.ID, r.GlyphOffset.x, r.GlyphOffset.y, r.GlyphOffset.x + r.Width, r.GlyphOffset.y + r.Height, uv0.x, uv0.y, uv1.x, uv1.y, r.GlyphAdvanceX); + r.Font->AddGlyph((ImWchar)r.GlyphID, r.GlyphOffset.x, r.GlyphOffset.y, r.GlyphOffset.x + r.Width, r.GlyphOffset.y + r.Height, uv0.x, uv0.y, uv1.x, uv1.y, r.GlyphAdvanceX); } // Build all fonts lookup tables From d3212482fe6e158db71999ae84de754f908ab8fd Mon Sep 17 00:00:00 2001 From: Matt Haynie Date: Thu, 23 Apr 2020 13:58:45 -0700 Subject: [PATCH 05/14] Fix multiple macro definitions of GLFW_INCLUDE_NONE (#3157) --- examples/imgui_impl_opengl3.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp index bf8225d0..c60df73d 100644 --- a/examples/imgui_impl_opengl3.cpp +++ b/examples/imgui_impl_opengl3.cpp @@ -121,12 +121,16 @@ #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #include // Needs to be initialized with gladLoadGL() in user's code. #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) +#ifndef GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#endif #include // Needs to be initialized with glbinding::Binding::initialize() in user's code. #include using namespace gl; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) +#ifndef GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#endif #include // Needs to be initialized with glbinding::initialize() in user's code. #include using namespace gl; From 73c30aa085d8432fcaa9288572b317a3c8951530 Mon Sep 17 00:00:00 2001 From: Chris Savoie Date: Thu, 4 Jul 2019 18:28:34 -0700 Subject: [PATCH 06/14] Backends: Vulkan: Don't skip drawing when there's no vertexes to ensure that user callbacks are still processed. --- docs/CHANGELOG.txt | 2 ++ examples/imgui_impl_vulkan.cpp | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ad309327..70480187 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,6 +49,8 @@ Other Changes: - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) - Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the projection matrix top and bottom values. (#3143, #3146) [@u3shit] +- Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData + structure didn't have any vertices. (#2697) [@kudaba] ----------------------------------------------------------------------- diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 095a7f26..72866dde 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2020-04-26: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData didn't have vertices. // 2019-08-01: Vulkan: Added support for specifying multisample count. Set ImGui_ImplVulkan_InitInfo::MSAASamples to one of the VkSampleCountFlagBits values to use, default is non-multisampled as before. // 2019-05-29: Vulkan: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-04-30: Vulkan: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. @@ -274,6 +275,7 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkCommandBu } // Bind Vertex And Index Buffer: + if (draw_data->TotalVtxCount > 0) { VkBuffer vertex_buffers[1] = { rb->VertexBuffer }; VkDeviceSize vertex_offset[1] = { 0 }; @@ -314,7 +316,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); - if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount == 0) + if (fb_width <= 0 || fb_height <= 0) return; ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo; @@ -343,6 +345,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm CreateOrResizeBuffer(rb->IndexBuffer, rb->IndexBufferMemory, rb->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); // Upload vertex/index data into a single contiguous GPU buffer + if (vertex_size > 0) { ImDrawVert* vtx_dst = NULL; ImDrawIdx* idx_dst = NULL; From 2593b6a1c86dcfc2fee95bbe55fbd9ae04d5991c Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Mon, 27 Apr 2020 12:01:59 +0300 Subject: [PATCH 07/14] Drag and Drop: Fix unintended fallback "..." tooltip during drag operation when drag source uses _SourceNoPreviewTooltip flags. (#3160) --- docs/CHANGELOG.txt | 4 +++- imgui.cpp | 2 +- imgui.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 70480187..11a9560c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,8 +49,10 @@ Other Changes: - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) - Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the projection matrix top and bottom values. (#3143, #3146) [@u3shit] -- Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData +- Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData structure didn't have any vertices. (#2697) [@kudaba] +- Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when + drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index f900a010..8e66bbed 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4216,7 +4216,7 @@ void ImGui::EndFrame() } // Drag and Drop: Fallback for source tooltip. This is not ideal but better than nothing. - if (g.DragDropActive && g.DragDropSourceFrameCount < g.FrameCount) + if (g.DragDropActive && g.DragDropSourceFrameCount < g.FrameCount && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) { g.DragDropWithinSource = true; SetTooltip("..."); diff --git a/imgui.h b/imgui.h index d3460d72..5420ac53 100644 --- a/imgui.h +++ b/imgui.h @@ -644,6 +644,7 @@ namespace ImGui // Drag and Drop // - [BETA API] API may evolve! + // - If you stop calling BeginDragDropSource() the payload is preserved however it won't have a preview tooltip (we currently display a fallback "..." tooltip as replacement) IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond = 0); // type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! From 8cbff5ccb23675f5b3eaa1080a79bb2ae575fc33 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Fri, 24 Apr 2020 15:50:27 -0500 Subject: [PATCH 08/14] Fix various typos. (#3161) (found by Debian's lintian on a package that uses imgui.) (found by codespell.) --- imgui.cpp | 12 ++++++------ imgui.h | 4 ++-- imgui_demo.cpp | 10 +++++----- imgui_draw.cpp | 14 +++++++------- imgui_widgets.cpp | 10 +++++----- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 8e66bbed..8ce07618 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -900,7 +900,7 @@ static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f; // Time // Window resizing from edges (when io.ConfigWindowsResizeFromEdges = true and ImGuiBackendFlags_HasMouseCursors is set in io.BackendFlags by back-end) static const float WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS = 4.0f; // Extend outside and inside windows. Affect FindHoveredWindow(). static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time. -static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certaint time, unless mouse moved. +static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certain time, unless mouse moved. //------------------------------------------------------------------------- // [SECTION] FORWARD DECLARATIONS @@ -4231,7 +4231,7 @@ void ImGui::EndFrame() UpdateMouseMovingWindowEndFrame(); // Sort the window list so that all child windows are after their parent - // We cannot do that on FocusWindow() because childs may not exist yet + // We cannot do that on FocusWindow() because children may not exist yet g.WindowsTempSortBuffer.resize(0); g.WindowsTempSortBuffer.reserve(g.Windows.Size); for (int i = 0; i != g.Windows.Size; i++) @@ -4331,7 +4331,7 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex } // Find window given position, search front-to-back -// FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programatically +// FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically // with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is // called, aka before the next Begin(). Moving window isn't affected. static void FindHoveredWindow() @@ -6360,7 +6360,7 @@ bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) } // Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext) -// Note that NoNavFocus makes the window not reachable with CTRL+TAB but it can still be focused with mouse or programmaticaly. +// Note that NoNavFocus makes the window not reachable with CTRL+TAB but it can still be focused with mouse or programmatically. // If you want a window to never be focused, you may use the e.g. NoInputs flag. bool ImGui::IsWindowNavFocusable(ImGuiWindow* window) { @@ -6814,7 +6814,7 @@ static void ImGui::ErrorCheckEndFrameSanityChecks() { ImGuiContext& g = *GImGui; - // Verify that io.KeyXXX fields haven't been tampered with. Key mods shoudl not be modified between NewFrame() and EndFrame() + // Verify that io.KeyXXX fields haven't been tampered with. Key mods should not be modified between NewFrame() and EndFrame() const ImGuiKeyModFlags expected_key_mod_flags = GetMergedKeyModFlags(); IM_ASSERT(g.IO.KeyMods == expected_key_mod_flags && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); IM_UNUSED(expected_key_mod_flags); @@ -7811,7 +7811,7 @@ void ImGui::EndPopup() // Make all menus and popups wrap around for now, may need to expose that policy. NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_LoopY); - // Child-popups don't need to be layed out + // Child-popups don't need to be laid out IM_ASSERT(g.WithinEndChild == false); if (window->Flags & ImGuiWindowFlags_ChildWindow) g.WithinEndChild = true; diff --git a/imgui.h b/imgui.h index 5420ac53..3dfdc39c 100644 --- a/imgui.h +++ b/imgui.h @@ -371,7 +371,7 @@ namespace ImGui // Cursor / Layout // - By "cursor" we mean the current output position. // - The typical widget behavior is to output themselves at the current cursor position, then move the cursor one line down. - // - You can call SameLine() between widgets to undo the last carriage return and output at the right of the preceeding widget. + // - You can call SameLine() between widgets to undo the last carriage return and output at the right of the preceding widget. // - Attention! We currently have inconsistencies between window-local and absolute positions we will aim to fix with future API: // Window-local coordinates: SameLine(), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), GetContentRegionMax(), GetWindowContentRegion*(), PushTextWrapPos() // Absolute coordinate: GetCursorScreenPos(), SetCursorScreenPos(), all ImDrawList:: functions. @@ -2299,7 +2299,7 @@ struct ImFont float Scale; // 4 // in // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetWindowFontScale() float Ascent, Descent; // 4+4 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] int MetricsTotalSurface;// 4 // out // // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs) - ImU8 Used4kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/4096/8]; // 2 bytes if ImWchar=ImWchar16, 34 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations accross all used codepoints. + ImU8 Used4kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/4096/8]; // 2 bytes if ImWchar=ImWchar16, 34 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints. // Methods IMGUI_API ImFont(); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index e9652ef7..a052205c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -644,7 +644,7 @@ static void ShowDemoWindowWidgets() static bool test_drag_and_drop = false; ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnArrow); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be layed out after the node."); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node."); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanFullWidth); ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position); ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop); @@ -994,7 +994,7 @@ static void ShowDemoWindowWidgets() } if (ImGui::TreeNode("Alignment")) { - HelpMarker("By default, Selectables uses style.SelectableTextAlign but it can be overriden on a per-item basis using PushStyleVar(). You'll probably want to always keep your default situation to left-align otherwise it becomes difficult to layout multiple items on a same line"); + HelpMarker("By default, Selectables uses style.SelectableTextAlign but it can be overridden on a per-item basis using PushStyleVar(). You'll probably want to always keep your default situation to left-align otherwise it becomes difficult to layout multiple items on a same line"); static bool selected[3*3] = { true, false, true, false, true, false, true, false, true }; for (int y = 0; y < 3; y++) { @@ -1065,7 +1065,7 @@ static void ShowDemoWindowWidgets() if (ImGui::TreeNode("Resize Callback")) { // To wire InputText() with std::string or any other custom string type, - // you can use the ImGuiInputTextFlags_CallbackResize flag + create a custom ImGui::InputText() wrapper using your prefered type. + // you can use the ImGuiInputTextFlags_CallbackResize flag + create a custom ImGui::InputText() wrapper using your preferred type. // See misc/cpp/imgui_stdlib.h for an implementation of this using std::string. HelpMarker("Demonstrate using ImGuiInputTextFlags_CallbackResize to wire your resizable string type to InputText().\n\nSee misc/cpp/imgui_stdlib.h for an implementation of this for std::string."); struct Funcs @@ -1082,7 +1082,7 @@ static void ShowDemoWindowWidgets() return 0; } - // Tip: Because ImGui:: is a namespace you would typicall add your own function into the namespace in your own source files. + // Tip: Because ImGui:: is a namespace you would typically add your own function into the namespace in your own source files. // For example, you may add a function called ImGui::InputText(const char* label, MyString* my_str). static bool MyInputTextMultiline(const char* label, ImVector* my_str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0) { @@ -3865,7 +3865,7 @@ struct ExampleAppConsole AddLog("Unknown command: '%s'\n", command_line); } - // On commad input, we scroll to bottom even if AutoScroll==false + // On command input, we scroll to bottom even if AutoScroll==false ScrollToBottom = true; } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 909949dc..954c5536 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -615,7 +615,7 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c _IdxWritePtr += 6; } -// On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superflous function calls to optimize debug/non-inlined builds. +// On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superfluous function calls to optimize debug/non-inlined builds. // Those macros expects l-values. #define IM_NORMALIZE2F_OVER_ZERO(VX,VY) do { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = 1.0f / ImSqrt(d2); VX *= inv_len; VY *= inv_len; } } while (0) #define IM_FIXNORMAL2F(VX,VY) do { float d2 = VX*VX + VY*VY; if (d2 < 0.5f) d2 = 0.5f; float inv_lensq = 1.0f / d2; VX *= inv_lensq; VY *= inv_lensq; } while (0) @@ -684,7 +684,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 dm_x *= AA_SIZE; dm_y *= AA_SIZE; - // Add temporary vertexes + // Add temporary vertices ImVec2* out_vtx = &temp_points[i2*2]; out_vtx[0].x = points[i2].x + dm_x; out_vtx[0].y = points[i2].y + dm_y; @@ -701,7 +701,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 idx1 = idx2; } - // Add vertexes + // Add vertices for (int i = 0; i < points_count; i++) { _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; @@ -741,7 +741,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 float dm_in_x = dm_x * half_inner_thickness; float dm_in_y = dm_y * half_inner_thickness; - // Add temporary vertexes + // Add temporary vertices ImVec2* out_vtx = &temp_points[i2*4]; out_vtx[0].x = points[i2].x + dm_out_x; out_vtx[0].y = points[i2].y + dm_out_y; @@ -764,7 +764,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 idx1 = idx2; } - // Add vertexes + // Add vertices for (int i = 0; i < points_count; i++) { _VtxWritePtr[0].pos = temp_points[i*4+0]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col_trans; @@ -2307,7 +2307,7 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas) // Ellipsis character is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis). // However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character. - // FIXME: Also note that 0x2026 is currently seldomly included in our font ranges. Because of this we are more likely to use three individual dots. + // FIXME: Also note that 0x2026 is currently seldom included in our font ranges. Because of this we are more likely to use three individual dots. for (int i = 0; i < atlas->Fonts.size(); i++) { ImFont* font = atlas->Fonts[i]; @@ -3329,7 +3329,7 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im // Helper for ColorPicker4() // NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that. -// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding alltogether. +// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether. // FIXME: uses ImGui::GetColorU32 void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, int rounding_corners_flags) { diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 02ac3cd5..e58c8aea 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2345,7 +2345,7 @@ float ImGui::SliderCalcRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_m return (float)((FLOATTYPE)(v_clamped - v_min) / (FLOATTYPE)(v_max - v_min)); } -// FIXME: Move some of the code into SliderBehavior(). Current responsability is larger than what the equivalent DragBehaviorT<> does, we also do some rendering, etc. +// FIXME: Move some of the code into SliderBehavior(). Current responsibility is larger than what the equivalent DragBehaviorT<> does, we also do some rendering, etc. template bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb) { @@ -2942,7 +2942,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data if ((flags & (ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific)) == 0) flags |= ImGuiInputTextFlags_CharsDecimal; flags |= ImGuiInputTextFlags_AutoSelectAll; - flags |= ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselve by comparing the actual data rather than the string. + flags |= ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string. if (p_step != NULL) { @@ -3360,7 +3360,7 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons if (!is_resizable) return; - // Contrary to STB_TEXTEDIT_INSERTCHARS() this is working in the UTF8 buffer, hence the midly similar code (until we remove the U16 buffer alltogether!) + // Contrary to STB_TEXTEDIT_INSERTCHARS() this is working in the UTF8 buffer, hence the mildly similar code (until we remove the U16 buffer altogether!) ImGuiContext& g = *GImGui; ImGuiInputTextState* edit_state = &g.InputTextState; IM_ASSERT(edit_state->ID != 0 && g.ActiveId == edit_state->ID); @@ -4745,7 +4745,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (flags & ImGuiColorEditFlags_DisplayRGB || (flags & ImGuiColorEditFlags__DisplayMask) == 0) if (ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_DisplayRGB)) { - // FIXME: Hackily differenciating using the DragInt (ActiveId != 0 && !ActiveIdAllowOverlap) vs. using the InputText or DropTarget. + // FIXME: Hackily differentiating using the DragInt (ActiveId != 0 && !ActiveIdAllowOverlap) vs. using the InputText or DropTarget. // For the later we don't want to run the hue-wrap canceling code. If you are well versed in HSV picker please provide your input! (See #2050) value_changed_fix_hue_wrap = (g.ActiveId != 0 && !g.ActiveIdAllowOverlap); value_changed = true; @@ -6249,7 +6249,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu, - // However the final position is going to be different! It is choosen by FindBestWindowPosForPopup(). + // However the final position is going to be different! It is chosen by FindBestWindowPosForPopup(). // e.g. Menus tend to overlap each other horizontally to amplify relative Z-ordering. ImVec2 popup_pos, pos = window->DC.CursorPos; if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) From a2454f2a45ea016443411fcf69a971e9b1d650f6 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Tue, 28 Apr 2020 15:15:00 +0100 Subject: [PATCH 09/14] Use __NEWLIB__ instead of __SWITCH__ and __CYGWIN__ for alloca.h-detection (#3070) Cygwin uses newlib, so it's covered by the __NEWLIB__ check. You can see how it defines __NEWLIB__ here: https://cygwin.com/git/?p=newlib-cygwin.git;a=blob;f=newlib/configure.in#l453 --- imgui_draw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 954c5536..1df83d12 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -36,7 +36,7 @@ Index of this file: #include // vsnprintf, sscanf, printf #if !defined(alloca) -#if defined(__GLIBC__) || defined(__sun) || defined(__CYGWIN__) || defined(__APPLE__) || defined(__SWITCH__) +#if defined(__GLIBC__) || defined(__sun) || defined(__APPLE__) || defined(__NEWLIB__) #include // alloca (glibc uses . Note that Cygwin may have _WIN32 defined, so the order matters here) #elif defined(_WIN32) #include // alloca From d5ce3b43aeff58e31966903f23e8ed3dea6f11af Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 4 May 2020 11:03:05 +0200 Subject: [PATCH 10/14] Backends: Vulkan: Fixed error in if initial frame has no vertices. (#3177) --- docs/CHANGELOG.txt | 3 ++- examples/imgui_impl_vulkan.cpp | 25 ++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 11a9560c..039a67ad 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,7 +49,8 @@ Other Changes: - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) - Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the projection matrix top and bottom values. (#3143, #3146) [@u3shit] -- Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData +- Backends: Vulkan: Fixed error in if initial frame has no vertices. (#3177) +- Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData structure didn't have any vertices. (#2697) [@kudaba] - Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 72866dde..652476c7 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2020-05-04: Vulkan: Fixed crash if initial frame has no vertices. // 2020-04-26: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData didn't have vertices. // 2019-08-01: Vulkan: Added support for specifying multisample count. Set ImGui_ImplVulkan_InitInfo::MSAASamples to one of the VkSampleCountFlagBits values to use, default is non-multisampled as before. // 2019-05-29: Vulkan: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. @@ -334,22 +335,20 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm wrb->Index = (wrb->Index + 1) % wrb->Count; ImGui_ImplVulkanH_FrameRenderBuffers* rb = &wrb->FrameRenderBuffers[wrb->Index]; - VkResult err; - - // Create or resize the vertex/index buffers - size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); - size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx); - if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size) - CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); - if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size) - CreateOrResizeBuffer(rb->IndexBuffer, rb->IndexBufferMemory, rb->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); - - // Upload vertex/index data into a single contiguous GPU buffer - if (vertex_size > 0) + if (draw_data->TotalVtxCount > 0) { + // Create or resize the vertex/index buffers + size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); + size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx); + if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size) + CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size) + CreateOrResizeBuffer(rb->IndexBuffer, rb->IndexBufferMemory, rb->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); + + // Upload vertex/index data into a single contiguous GPU buffer ImDrawVert* vtx_dst = NULL; ImDrawIdx* idx_dst = NULL; - err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst)); + VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, vertex_size, 0, (void**)(&vtx_dst)); check_vk_result(err); err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)(&idx_dst)); check_vk_result(err); From 794bf7a28d80caffb423b1ede77ca993c3efa387 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Wed, 29 Apr 2020 13:32:16 +0300 Subject: [PATCH 11/14] CI: Implement builds with IMGUI_DISABLE_WIN32_FUNCTIONS, IMGUI_DISABLE_FILE_FUNCTIONS, IMGUI_USE_BGRA_PACKED_COLOR IM_VEC2_CLASS_EXTRA, IM_VEC4_CLASS_EXTRA and building library as a DLL. --- .github/workflows/build.yml | 55 +++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b089bfb4..03641749 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,6 +59,29 @@ jobs: echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp + - name: Build example_null (with IMGUI_DISABLE_WIN32_FUNCTIONS) + shell: bash + run: | + echo '#define IMGUI_DISABLE_WIN32_FUNCTIONS' > example_single_file.cpp + echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp + echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp + echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp + g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp + + - name: Build example_null (as DLL) + shell: cmd + run: | + "%VS_PATH%\VC\Auxiliary\Build\vcvarsall.bat" x64 + echo '#ifdef _EXPORT' > example_single_file.cpp + echo '# define IMGUI_API __declspec(dllexport)' >> example_single_file.cpp + echo '#else' >> example_single_file.cpp + echo '# define IMGUI_API __declspec(dllimport)' >> example_single_file.cpp + echo '#endif' >> example_single_file.cpp + echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp + echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp + cl.exe /D_USRDLL /D_WINDLL /D_EXPORT /I. example_single_file.cpp /LD /FeImGui.dll /link + cl.exe /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp + - name: Build Win32 example_glfw_opengl2 shell: cmd run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release' @@ -233,6 +256,38 @@ jobs: echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp + - name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS) + run: | + echo '#define IMGUI_DISABLE_FILE_FUNCTIONS' > example_single_file.cpp + echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp + echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp + echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp + g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp + + - name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR) + run: | + echo '#define IMGUI_USE_BGRA_PACKED_COLOR' > example_single_file.cpp + echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp + echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp + echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp + g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp + + - name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA) + run: | + echo 'struct MyVec2 { float x; float y; MyVec2(float x, float y) : x(x), y(y) { } };' > example_single_file.cpp + echo 'struct MyVec4 { float x; float y; float z; float w;' >> example_single_file.cpp + echo 'MyVec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { } };' >> example_single_file.cpp + echo '#define IM_VEC2_CLASS_EXTRA \' >> example_single_file.cpp + echo ' ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \' >> example_single_file.cpp + echo ' operator MyVec2() const { return MyVec2(x, y); }' >> example_single_file.cpp + echo '#define IM_VEC4_CLASS_EXTRA \' >> example_single_file.cpp + echo ' ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \' >> example_single_file.cpp + echo ' operator MyVec4() const { return MyVec4(x, y, z, w); }' >> example_single_file.cpp + echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp + echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp + echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp + g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp + - name: Build example_glfw_opengl2 run: make -C examples/example_glfw_opengl2 From 1e9abf60d1b6c71a738c96ef9c123ab358608bf8 Mon Sep 17 00:00:00 2001 From: Silent Date: Tue, 28 Apr 2020 21:53:46 +0200 Subject: [PATCH 12/14] Backends: Keep shader blobs as local variables. (#3176) --- examples/imgui_impl_dx10.cpp | 33 ++++++++++++++++++++------------- examples/imgui_impl_dx11.cpp | 33 ++++++++++++++++++++------------- examples/imgui_impl_dx12.cpp | 30 ++++++++++++++++++------------ 3 files changed, 58 insertions(+), 38 deletions(-) diff --git a/examples/imgui_impl_dx10.cpp b/examples/imgui_impl_dx10.cpp index 7eb4e5af..ffaa7707 100644 --- a/examples/imgui_impl_dx10.cpp +++ b/examples/imgui_impl_dx10.cpp @@ -41,11 +41,9 @@ static ID3D10Device* g_pd3dDevice = NULL; static IDXGIFactory* g_pFactory = NULL; static ID3D10Buffer* g_pVB = NULL; static ID3D10Buffer* g_pIB = NULL; -static ID3D10Blob* g_pVertexShaderBlob = NULL; static ID3D10VertexShader* g_pVertexShader = NULL; static ID3D10InputLayout* g_pInputLayout = NULL; static ID3D10Buffer* g_pVertexConstantBuffer = NULL; -static ID3D10Blob* g_pPixelShaderBlob = NULL; static ID3D10PixelShader* g_pPixelShader = NULL; static ID3D10SamplerState* g_pFontSampler = NULL; static ID3D10ShaderResourceView*g_pFontTextureView = NULL; @@ -369,11 +367,14 @@ bool ImGui_ImplDX10_CreateDeviceObjects() return output;\ }"; - D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, NULL); - if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return false; - if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pVertexShader) != S_OK) + ID3DBlob* vertexShaderBlob; + if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL))) + return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + if (g_pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_pVertexShader) != S_OK) + { + vertexShaderBlob->Release(); return false; + } // Create the input layout D3D10_INPUT_ELEMENT_DESC local_layout[] = @@ -382,8 +383,12 @@ bool ImGui_ImplDX10_CreateDeviceObjects() { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D10_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; - if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) + if (g_pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) + { + vertexShaderBlob->Release(); return false; + } + vertexShaderBlob->Release(); // Create the constant buffer { @@ -415,11 +420,15 @@ bool ImGui_ImplDX10_CreateDeviceObjects() return out_col; \ }"; - D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, NULL); - if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return false; - if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), &g_pPixelShader) != S_OK) + ID3DBlob* pixelShaderBlob; + if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL))) + return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + if (g_pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), &g_pPixelShader) != S_OK) + { + pixelShaderBlob->Release(); return false; + } + pixelShaderBlob->Release(); } // Create the blending setup @@ -482,11 +491,9 @@ void ImGui_ImplDX10_InvalidateDeviceObjects() if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; } if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } - if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; } if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; } if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; } - if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } } bool ImGui_ImplDX10_Init(ID3D10Device* device) diff --git a/examples/imgui_impl_dx11.cpp b/examples/imgui_impl_dx11.cpp index 97e17ff1..5aa09f9b 100644 --- a/examples/imgui_impl_dx11.cpp +++ b/examples/imgui_impl_dx11.cpp @@ -42,11 +42,9 @@ static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; static IDXGIFactory* g_pFactory = NULL; static ID3D11Buffer* g_pVB = NULL; static ID3D11Buffer* g_pIB = NULL; -static ID3D10Blob* g_pVertexShaderBlob = NULL; static ID3D11VertexShader* g_pVertexShader = NULL; static ID3D11InputLayout* g_pInputLayout = NULL; static ID3D11Buffer* g_pVertexConstantBuffer = NULL; -static ID3D10Blob* g_pPixelShaderBlob = NULL; static ID3D11PixelShader* g_pPixelShader = NULL; static ID3D11SamplerState* g_pFontSampler = NULL; static ID3D11ShaderResourceView*g_pFontTextureView = NULL; @@ -381,11 +379,14 @@ bool ImGui_ImplDX11_CreateDeviceObjects() return output;\ }"; - D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &g_pVertexShaderBlob, NULL); - if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return false; - if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK) + ID3DBlob* vertexShaderBlob; + if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL))) + return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + if (g_pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK) + { + vertexShaderBlob->Release(); return false; + } // Create the input layout D3D11_INPUT_ELEMENT_DESC local_layout[] = @@ -394,8 +395,12 @@ bool ImGui_ImplDX11_CreateDeviceObjects() { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; - if (g_pd3dDevice->CreateInputLayout(local_layout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) + if (g_pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) + { + vertexShaderBlob->Release(); return false; + } + vertexShaderBlob->Release(); // Create the constant buffer { @@ -427,11 +432,15 @@ bool ImGui_ImplDX11_CreateDeviceObjects() return out_col; \ }"; - D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &g_pPixelShaderBlob, NULL); - if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return false; - if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK) + ID3DBlob* pixelShaderBlob; + if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL))) + return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + if (g_pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK) + { + pixelShaderBlob->Release(); return false; + } + pixelShaderBlob->Release(); } // Create the blending setup @@ -494,11 +503,9 @@ void ImGui_ImplDX11_InvalidateDeviceObjects() if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; } if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; } if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; } - if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; } if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; } if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; } - if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } } bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) diff --git a/examples/imgui_impl_dx12.cpp b/examples/imgui_impl_dx12.cpp index e7bb5e9c..a2913613 100644 --- a/examples/imgui_impl_dx12.cpp +++ b/examples/imgui_impl_dx12.cpp @@ -37,8 +37,6 @@ // DirectX data static ID3D12Device* g_pd3dDevice = NULL; -static ID3D10Blob* g_pVertexShaderBlob = NULL; -static ID3D10Blob* g_pPixelShaderBlob = NULL; static ID3D12RootSignature* g_pRootSignature = NULL; static ID3D12PipelineState* g_pPipelineState = NULL; static DXGI_FORMAT g_RTVFormat = DXGI_FORMAT_UNKNOWN; @@ -473,6 +471,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects() psoDesc.SampleDesc.Count = 1; psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + ID3DBlob* vertexShaderBlob; + ID3DBlob* pixelShaderBlob; + // Create the vertex shader { static const char* vertexShader = @@ -503,10 +504,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects() return output;\ }"; - D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &g_pVertexShaderBlob, NULL); - if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return false; - psoDesc.VS = { g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize() }; + if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vertexShaderBlob, NULL))) + return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + psoDesc.VS = { vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize() }; // Create the input layout static D3D12_INPUT_ELEMENT_DESC local_layout[] = { @@ -535,10 +535,12 @@ bool ImGui_ImplDX12_CreateDeviceObjects() return out_col; \ }"; - D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &g_pPixelShaderBlob, NULL); - if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return false; - psoDesc.PS = { g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize() }; + if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &pixelShaderBlob, NULL))) + { + vertexShaderBlob->Release(); + return false; // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + } + psoDesc.PS = { pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize() }; } // Create the blending setup @@ -584,7 +586,13 @@ bool ImGui_ImplDX12_CreateDeviceObjects() } if (g_pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&g_pPipelineState)) != S_OK) + { + vertexShaderBlob->Release(); + pixelShaderBlob->Release(); return false; + } + vertexShaderBlob->Release(); + pixelShaderBlob->Release(); ImGui_ImplDX12_CreateFontsTexture(); @@ -596,8 +604,6 @@ void ImGui_ImplDX12_InvalidateDeviceObjects() if (!g_pd3dDevice) return; - SafeRelease(g_pVertexShaderBlob); - SafeRelease(g_pPixelShaderBlob); SafeRelease(g_pRootSignature); SafeRelease(g_pPipelineState); SafeRelease(g_pFontTextureResource); From 099091280f055c1267bf75dc390a8d95665e8c3f Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 4 May 2020 11:32:58 +0200 Subject: [PATCH 13/14] Backends: DX10/DX11: Minor tweaks. --- examples/imgui_impl_dx10.cpp | 30 +++++++++++++++--------------- examples/imgui_impl_dx11.cpp | 30 +++++++++++++++--------------- examples/imgui_impl_dx12.cpp | 9 +++------ 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/examples/imgui_impl_dx10.cpp b/examples/imgui_impl_dx10.cpp index ffaa7707..23ade277 100644 --- a/examples/imgui_impl_dx10.cpp +++ b/examples/imgui_impl_dx10.cpp @@ -342,29 +342,29 @@ bool ImGui_ImplDX10_CreateDeviceObjects() static const char* vertexShader = "cbuffer vertexBuffer : register(b0) \ {\ - float4x4 ProjectionMatrix; \ + float4x4 ProjectionMatrix; \ };\ struct VS_INPUT\ {\ - float2 pos : POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ + float2 pos : POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ };\ \ struct PS_INPUT\ {\ - float4 pos : SV_POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ };\ \ PS_INPUT main(VS_INPUT input)\ {\ - PS_INPUT output;\ - output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ - output.col = input.col;\ - output.uv = input.uv;\ - return output;\ + PS_INPUT output;\ + output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ + output.col = input.col;\ + output.uv = input.uv;\ + return output;\ }"; ID3DBlob* vertexShaderBlob; @@ -379,9 +379,9 @@ bool ImGui_ImplDX10_CreateDeviceObjects() // Create the input layout D3D10_INPUT_ELEMENT_DESC local_layout[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D10_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D10_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "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 }, }; if (g_pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) { diff --git a/examples/imgui_impl_dx11.cpp b/examples/imgui_impl_dx11.cpp index 5aa09f9b..26eb407f 100644 --- a/examples/imgui_impl_dx11.cpp +++ b/examples/imgui_impl_dx11.cpp @@ -354,29 +354,29 @@ bool ImGui_ImplDX11_CreateDeviceObjects() static const char* vertexShader = "cbuffer vertexBuffer : register(b0) \ {\ - float4x4 ProjectionMatrix; \ + float4x4 ProjectionMatrix; \ };\ struct VS_INPUT\ {\ - float2 pos : POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ + float2 pos : POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ };\ \ struct PS_INPUT\ {\ - float4 pos : SV_POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ };\ \ PS_INPUT main(VS_INPUT input)\ {\ - PS_INPUT output;\ - output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ - output.col = input.col;\ - output.uv = input.uv;\ - return output;\ + PS_INPUT output;\ + output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ + output.col = input.col;\ + output.uv = input.uv;\ + return output;\ }"; ID3DBlob* vertexShaderBlob; @@ -391,9 +391,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects() // Create the input layout D3D11_INPUT_ELEMENT_DESC local_layout[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "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 }, }; if (g_pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) { diff --git a/examples/imgui_impl_dx12.cpp b/examples/imgui_impl_dx12.cpp index a2913613..167a189b 100644 --- a/examples/imgui_impl_dx12.cpp +++ b/examples/imgui_impl_dx12.cpp @@ -585,14 +585,11 @@ bool ImGui_ImplDX12_CreateDeviceObjects() desc.BackFace = desc.FrontFace; } - if (g_pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&g_pPipelineState)) != S_OK) - { - vertexShaderBlob->Release(); - pixelShaderBlob->Release(); - return false; - } + HRESULT result_pipeline_state = g_pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&g_pPipelineState)); vertexShaderBlob->Release(); pixelShaderBlob->Release(); + if (result_pipeline_state != S_OK) + return false; ImGui_ImplDX12_CreateFontsTexture(); From b4dd28ffbbe4d382d38ef6de742db93388b5482f Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 4 May 2020 14:58:21 +0200 Subject: [PATCH 14/14] Style: Added style.TabMinWidthForUnselectedCloseButton settings. Set to 0.0f (default) to always make a close button appear on hover (same as Chrome, VS). Set to FLT_MAX to only display a close button when selected (merely hovering is not enough). Set to an intermediary value to toggle behavior based on width (same as Firefox). --- docs/CHANGELOG.txt | 4 ++++ imgui.cpp | 3 +++ imgui.h | 1 + imgui_internal.h | 2 +- imgui_widgets.cpp | 23 +++++++++++++++++++---- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 039a67ad..819abbec 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -46,6 +46,10 @@ Other Changes: flag was also set, and _OpenOnArrow is frequently set along with _OpenOnDoubleClick). - TreeNode: Fixed bug where dragging a payload over a TreeNode() with either _OpenOnDoubleClick or _OpenOnArrow would open the node. (#143) +- Style: Added style.TabMinWidthForUnselectedCloseButton settings. + Set to 0.0f (default) to always make a close button appear on hover (same as Chrome, VS). + Set to FLT_MAX to only display a close button when selected (merely hovering is not enough). + Set to an intermediary value to toggle behavior based on width (same as Firefox). - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) - Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the projection matrix top and bottom values. (#3143, #3146) [@u3shit] diff --git a/imgui.cpp b/imgui.cpp index 8ce07618..680a3289 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1028,6 +1028,7 @@ ImGuiStyle::ImGuiStyle() GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. TabBorderSize = 0.0f; // Thickness of border around tabs. + TabMinWidthForUnselectedCloseButton = 0.0f; // Minimum width for close button to appears on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. @@ -1064,6 +1065,8 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor) GrabMinSize = ImFloor(GrabMinSize * scale_factor); GrabRounding = ImFloor(GrabRounding * scale_factor); TabRounding = ImFloor(TabRounding * scale_factor); + if (TabMinWidthForUnselectedCloseButton != FLT_MAX) + TabMinWidthForUnselectedCloseButton = ImFloor(TabMinWidthForUnselectedCloseButton * scale_factor); DisplayWindowPadding = ImFloor(DisplayWindowPadding * scale_factor); DisplaySafeAreaPadding = ImFloor(DisplaySafeAreaPadding * scale_factor); MouseCursorScale = ImFloor(MouseCursorScale * scale_factor); diff --git a/imgui.h b/imgui.h index 3dfdc39c..9c85e97b 100644 --- a/imgui.h +++ b/imgui.h @@ -1393,6 +1393,7 @@ struct ImGuiStyle float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. float TabBorderSize; // Thickness of border around tabs. + float TabMinWidthForUnselectedCloseButton; // Minimum width for close button to appears on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered). ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. diff --git a/imgui_internal.h b/imgui_internal.h index d6ef765d..46cca946 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1827,7 +1827,7 @@ namespace ImGui IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags); IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button); IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col); - IMGUI_API bool TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id); + IMGUI_API bool TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id, bool is_contents_visible); // Render helpers // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index e58c8aea..200c43e4 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7090,6 +7090,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, tab_bar->NextSelectedTabId = id; // Lock visibility + // (Note: tab_contents_visible != tab_selected... because CTRL+TAB operations may preview some tabs without selecting them!) bool tab_contents_visible = (tab_bar->VisibleTabId == id); if (tab_contents_visible) tab_bar->VisibleTabWasSubmitted = true; @@ -7195,7 +7196,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, // Render tab label, process close button const ImGuiID close_button_id = p_open ? window->GetID((void*)((intptr_t)id + 1)) : 0; - bool just_closed = TabItemLabelAndCloseButton(display_draw_list, bb, flags, tab_bar->FramePadding, label, id, close_button_id); + bool just_closed = TabItemLabelAndCloseButton(display_draw_list, bb, flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible); if (just_closed && p_open != NULL) { *p_open = false; @@ -7270,13 +7271,21 @@ void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabI // Render text label (with custom clipping) + Unsaved Document marker + Close Button logic // We tend to lock style.FramePadding for a given tab-bar, hence the 'frame_padding' parameter. -bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id) +bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id, bool is_contents_visible) { ImGuiContext& g = *GImGui; ImVec2 label_size = CalcTextSize(label, NULL, true); if (bb.GetWidth() <= 1.0f) return false; + // In Style V2 we'll have full override of all colors per state (e.g. focused, selected) + // But right now if you want to alter text color of tabs this is what you need to do. +#if 0 + const float backup_alpha = g.Style.Alpha; + if (!is_contents_visible) + g.Style.Alpha *= 0.7f; +#endif + // Render text label (with clipping + alpha gradient) + unsaved marker const char* TAB_UNSAVED_MARKER = "*"; ImRect text_pixel_clip_bb(bb.Min.x + frame_padding.x, bb.Min.y + frame_padding.y, bb.Max.x - frame_padding.x, bb.Max.y); @@ -7296,8 +7305,9 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, bool close_button_pressed = false; bool close_button_visible = false; if (close_button_id != 0) - if (g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == close_button_id) - close_button_visible = true; + if (is_contents_visible || bb.GetWidth() >= g.Style.TabMinWidthForUnselectedCloseButton) + if (g.HoveredId == tab_id || g.HoveredId == close_button_id || g.ActiveId == close_button_id) + close_button_visible = true; if (close_button_visible) { ImGuiItemHoveredDataBackup last_item_backup; @@ -7318,6 +7328,11 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, float ellipsis_max_x = close_button_visible ? text_pixel_clip_bb.Max.x : bb.Max.x - 1.0f; RenderTextEllipsis(draw_list, text_ellipsis_clip_bb.Min, text_ellipsis_clip_bb.Max, text_pixel_clip_bb.Max.x, ellipsis_max_x, label, NULL, &label_size); +#if 0 + if (!is_contents_visible) + g.Style.Alpha = backup_alpha; +#endif + return close_button_pressed; }