From 3f26a07ee1813cecaa87253436149e28fc11dc4e Mon Sep 17 00:00:00 2001 From: Giovanni Funchal Date: Thu, 21 May 2020 12:49:06 +0100 Subject: [PATCH 01/12] Backends: OpenGL: Fixed loader auto-detection to not interfere with ES2/ES3 defines. (#3246) --- docs/CHANGELOG.txt | 1 + examples/imgui_impl_opengl3.cpp | 20 ------------ examples/imgui_impl_opengl3.h | 57 ++++++++++++++++++++------------- 3 files changed, 36 insertions(+), 42 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index dff65283..96d439be 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -66,6 +66,7 @@ Other Changes: - 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: OpenGL: On OSX, if unspecified by app, made default GLSL version 150. (#3199) [@albertvaka] +- Backends: OpenGL: Fixed loader auto-detection to not interfere with ES2/ES3 defines. (#3246) [@funchal] - 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] diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp index 61131eb6..3ad04a41 100644 --- a/examples/imgui_impl_opengl3.cpp +++ b/examples/imgui_impl_opengl3.cpp @@ -79,27 +79,7 @@ #else #include // intptr_t #endif -#if defined(__APPLE__) -#include "TargetConditionals.h" -#endif -// Auto-enable GLES on matching platforms -#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) -#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) -#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" -#elif defined(__EMSCRIPTEN__) -#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" -#endif -#endif - -#if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3) -#undef IMGUI_IMPL_OPENGL_LOADER_GL3W -#undef IMGUI_IMPL_OPENGL_LOADER_GLEW -#undef IMGUI_IMPL_OPENGL_LOADER_GLAD -#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING2 -#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING3 -#undef IMGUI_IMPL_OPENGL_LOADER_CUSTOM -#endif // GL includes #if defined(IMGUI_IMPL_OPENGL_ES2) diff --git a/examples/imgui_impl_opengl3.h b/examples/imgui_impl_opengl3.h index d55935a1..07d35219 100644 --- a/examples/imgui_impl_opengl3.h +++ b/examples/imgui_impl_opengl3.h @@ -12,7 +12,7 @@ // https://github.com/ocornut/imgui // About Desktop OpenGL function loaders: -// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. +// Modern Desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. @@ -36,36 +36,49 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture(); IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); -// Specific OpenGL versions +// Specific OpenGL ES versions //#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten //#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android -// Desktop OpenGL: attempt to detect default GL loader based on available header files. +// Attempt to auto-detect the default Desktop GL loader based on available header files. // If auto-detection fails or doesn't select the same GL loader file as used by your application, // you are likely to get a crash in ImGui_ImplOpenGL3_Init(). -// You can explicitly select a loader by using '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line. -#if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \ +// You can explicitly select a loader by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line. +#if !defined(IMGUI_IMPL_OPENGL_ES2) \ + && !defined(IMGUI_IMPL_OPENGL_ES3) \ + && !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) - #if defined(__has_include) - #if __has_include() - #define IMGUI_IMPL_OPENGL_LOADER_GLEW - #elif __has_include() - #define IMGUI_IMPL_OPENGL_LOADER_GLAD - #elif __has_include() - #define IMGUI_IMPL_OPENGL_LOADER_GL3W - #elif __has_include() - #define IMGUI_IMPL_OPENGL_LOADER_GLBINDING3 - #elif __has_include() - #define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2 - #else - #error "Cannot detect OpenGL loader!" - #endif - #else - #define IMGUI_IMPL_OPENGL_LOADER_GL3W // Default to GL3W - #endif + +// Try to detect GLES on matching platforms +#if defined(__APPLE__) +#include "TargetConditionals.h" +#endif +#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) +#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" +#elif defined(__EMSCRIPTEN__) +#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" + +// Otherwise try to detect supported Desktop OpenGL loaders.. +#elif defined(__has_include) +#if __has_include() + #define IMGUI_IMPL_OPENGL_LOADER_GLEW +#elif __has_include() + #define IMGUI_IMPL_OPENGL_LOADER_GLAD +#elif __has_include() + #define IMGUI_IMPL_OPENGL_LOADER_GL3W +#elif __has_include() + #define IMGUI_IMPL_OPENGL_LOADER_GLBINDING3 +#elif __has_include() + #define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2 +#else + #error "Cannot detect OpenGL loader!" +#endif +#else + #define IMGUI_IMPL_OPENGL_LOADER_GL3W // Default to GL3W embedded in our repository #endif +#endif From 41e8837f5948fae98f5fb1892f0e408aa806a2f2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 2 Jun 2020 18:13:54 +0200 Subject: [PATCH 02/12] Comments, adding some spacing in ImVec2() constructors. --- imgui.cpp | 10 +++++----- imgui.h | 35 ++++++++++++++++++----------------- imgui_demo.cpp | 8 ++++---- imgui_draw.cpp | 2 +- imgui_internal.h | 6 +++--- imgui_widgets.cpp | 10 +++++----- 6 files changed, 36 insertions(+), 35 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 68b50827..82de5dfb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -505,7 +505,7 @@ CODE - 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton(). - 2017/08/08 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu. - changed prototype of 'ColorEdit4(const char* label, float col[4], bool show_alpha = true)' to 'ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)', where passing flags = 0x01 is a safe no-op (hello dodgy backward compatibility!). - check and run the demo window, under "Color/Picker Widgets", to understand the various new options. - - changed prototype of rarely used 'ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)' to 'ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0))' + - changed prototype of rarely used 'ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)' to 'ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0, 0))' - 2017/07/20 (1.51) - removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse - 2017/05/26 (1.50) - removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. - 2017/05/01 (1.50) - renamed ImDrawList::PathFill() (rarely used directly) to ImDrawList::PathFillConvex() for clarity. @@ -5083,10 +5083,10 @@ static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_ { ImRect rect = window->Rect(); if (thickness == 0.0f) rect.Max -= ImVec2(1,1); - if (border_n == 0) return ImRect(rect.Min.x + perp_padding, rect.Min.y - thickness, rect.Max.x - perp_padding, rect.Min.y + thickness); // Top - if (border_n == 1) return ImRect(rect.Max.x - thickness, rect.Min.y + perp_padding, rect.Max.x + thickness, rect.Max.y - perp_padding); // Right - if (border_n == 2) return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness, rect.Max.x - perp_padding, rect.Max.y + thickness); // Bottom - if (border_n == 3) return ImRect(rect.Min.x - thickness, rect.Min.y + perp_padding, rect.Min.x + thickness, rect.Max.y - perp_padding); // Left + if (border_n == 0) { return ImRect(rect.Min.x + perp_padding, rect.Min.y - thickness, rect.Max.x - perp_padding, rect.Min.y + thickness); } // Top + if (border_n == 1) { return ImRect(rect.Max.x - thickness, rect.Min.y + perp_padding, rect.Max.x + thickness, rect.Max.y - perp_padding); } // Right + if (border_n == 2) { return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness, rect.Max.x - perp_padding, rect.Max.y + thickness); } // Bottom + if (border_n == 3) { return ImRect(rect.Min.x - thickness, rect.Min.y + perp_padding, rect.Min.x + thickness, rect.Max.y - perp_padding); } // Left IM_ASSERT(0); return ImRect(); } diff --git a/imgui.h b/imgui.h index 1a8d7a40..824c98de 100644 --- a/imgui.h +++ b/imgui.h @@ -268,9 +268,10 @@ namespace ImGui // Windows // - Begin() = push window to the stack and start appending to it. End() = pop window from the stack. - // - You may append multiple times to the same window during the same frame. // - Passing 'bool* p_open != NULL' shows a window-closing widget in the upper-right corner of the window, // which clicking will set the boolean to false when clicked. + // - You may append multiple times to the same window during the same frame by calling Begin()/End() pairs multiple times. + // Some information such as 'flags' or 'p_open' will only be considered by the first call to Begin(). // - Begin() return false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting // anything to the window. Always call a matching End() for each Begin() call, regardless of its return value! // [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu, @@ -285,8 +286,8 @@ namespace ImGui // - For each independent axis of 'size': ==0.0f: use remaining host window size / >0.0f: fixed size / <0.0f: use remaining window size minus abs(size) / Each axis can use a different mode, e.g. ImVec2(0,400). // - BeginChild() returns false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting anything to the window. // Always call a matching EndChild() for each BeginChild() call, regardless of its return value [as with Begin: this is due to legacy reason and inconsistent with most BeginXXX functions apart from the regular Begin() which behaves like BeginChild().] - IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0); - IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0); + IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0); + IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0); IMGUI_API void EndChild(); // Windows Utilities @@ -302,7 +303,7 @@ namespace ImGui IMGUI_API float GetWindowHeight(); // get current window height (shortcut for GetWindowSize().y) // Prefer using SetNextXXX functions (before Begin) rather that SetXXX functions (after Begin). - IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. + IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0, 0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Sizes will be rounded down. Use callback to apply non-trivial programmatic constraints. IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ scrollable client area, which enforce the range of scrollbars). Not including window decorations (title bar, menu bar, etc.) nor WindowPadding. set an axis to 0.0f to leave it automatic. call before Begin() @@ -310,7 +311,7 @@ namespace ImGui IMGUI_API void SetNextWindowFocus(); // set next window to be focused / top-most. call before Begin() IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily override the Alpha component of ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground. IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. - IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. + IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0, 0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed(). IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / top-most. prefer using SetNextWindowFocus(). IMGUI_API void SetWindowFontScale(float scale); // set font scale. Adjust IO.FontGlobalScale if you want to scale all windows. This is an old API! For correct scaling, prefer to reload font + rebuild ImFontAtlas + call style.ScaleAllSizes(). @@ -433,17 +434,17 @@ namespace ImGui // Widgets: Main // - Most widgets return true when the value has been changed or when pressed/selected // - You may also use one of the many IsItemXXX functions (e.g. IsItemActive, IsItemHovered, etc.) to query widget state. - IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button + IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0, 0)); // button IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.) IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); // square button with an arrow shape - IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); - IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding + IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); + IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding IMGUI_API bool Checkbox(const char* label, bool* v); IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); IMGUI_API bool RadioButton(const char* label, bool active); // use with e.g. if (RadioButton("one", my_value==1)) { my_value = 1; } IMGUI_API bool RadioButton(const char* label, int* v, int v_button); // shortcut to handle the above pattern when value is an integer - IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1,0), const char* overlay = NULL); + IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1, 0), const char* overlay = NULL); IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses // Widgets: Combo Box @@ -498,7 +499,7 @@ namespace ImGui // - If you want to use InputText() with std::string or any custom dynamic string type, see misc/cpp/imgui_stdlib.h and comments in imgui_demo.cpp. // - Most of the ImGuiInputTextFlags flags are only useful for InputText() and not for InputFloatX, InputIntX, InputDouble etc. IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); - IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags flags = 0); IMGUI_API bool InputFloat2(const char* label, float v[2], const char* format = "%.3f", ImGuiInputTextFlags flags = 0); @@ -519,7 +520,7 @@ namespace ImGui IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL); - IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0)); // display a colored square/button, hover for details, return true when pressed. + IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0, 0)); // display a colored square/button, hover for details, return true when pressed. IMGUI_API void SetColorEditOptions(ImGuiColorEditFlags flags); // initialize current options (generally on application startup) if you want to select a default format, picker type, etc. User will be able to change many settings, unless you pass the _NoOptions flag to your calls. // Widgets: Trees @@ -545,14 +546,14 @@ namespace ImGui // Widgets: Selectables // - A selectable highlights when hovered, and can display another color when selected. // - Neighbors selectable extend their highlight bounds in order to leave no gap between them. This is so a series of selected Selectable appear contiguous. - IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // "bool selected" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height - IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper. + IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool selected" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height + IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper. // Widgets: List Boxes // - FIXME: To be consistent with all the newer API, ListBoxHeader/ListBoxFooter should in reality be called BeginListBox/EndListBox. Will rename them. IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); - IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. if the function return true, you can output elements then call ListBoxFooter() afterwards. + IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)); // use if you want to reimplement ListBox() will custom data or interactions. if the function return true, you can output elements then call ListBoxFooter() afterwards. IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // " IMGUI_API void ListBoxFooter(); // terminate the scrolling region. only call ListBoxFooter() if ListBoxHeader() returned true! @@ -1487,7 +1488,7 @@ struct ImGuiIO // Input - Fill before calling NewFrame() //------------------------------------------------------------------ - ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) + ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.) bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. @@ -2158,7 +2159,7 @@ struct ImFontAtlasCustomRect 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; } + ImFontAtlasCustomRect() { Width = Height = 0; X = Y = 0xFFFF; GlyphID = 0; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0, 0); Font = NULL; } bool IsPacked() const { return X != 0xFFFF; } }; @@ -2239,7 +2240,7 @@ struct ImFontAtlas // Read docs/FONTS.txt for more details about using colorful icons. // 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)); + 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_demo.cpp b/imgui_demo.cpp index 42f0844a..8cece7be 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2676,7 +2676,7 @@ static void ShowDemoWindowLayout() } if (show_child) { - ImGui::BeginChild("child", ImVec2(0,0), true); + ImGui::BeginChild("child", ImVec2(0, 0), true); ImGui::EndChild(); } ImGui::End(); @@ -4373,7 +4373,7 @@ struct ExampleAppLog Filter.Draw("Filter", -100.0f); ImGui::Separator(); - ImGui::BeginChild("scrolling", ImVec2(0,0), false, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::BeginChild("scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar); if (clear) Clear(); @@ -4646,7 +4646,7 @@ static void ShowExampleAppLongText(bool* p_open) case 1: { // Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper. - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); ImGuiListClipper clipper(lines); while (clipper.Step()) for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) @@ -4656,7 +4656,7 @@ static void ShowExampleAppLongText(bool* p_open) } case 2: // Multiple calls to Text(), not clipped (slow) - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); for (int i = 0; i < lines; i++) ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); ImGui::PopStyleVar(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 2dfccf07..057ddb65 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2873,7 +2873,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons const float line_height = size; const float scale = size / FontSize; - ImVec2 text_size = ImVec2(0,0); + ImVec2 text_size = ImVec2(0, 0); float line_width = 0.0f; const bool word_wrap_enabled = (wrap_width > 0.0f); diff --git a/imgui_internal.h b/imgui_internal.h index 2802f519..96e7b19e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1597,7 +1597,7 @@ struct IMGUI_API ImGuiWindow ImGuiCond SetWindowSizeAllowFlags; // store acceptable condition flags for SetNextWindowSize() use. ImGuiCond SetWindowCollapsedAllowFlags; // store acceptable condition flags for SetNextWindowCollapsed() use. ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size) - ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right. + ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0, 0) when positioning from top-left corner; ImVec2(0.5f, 0.5f) for centering; ImVec2(1, 1) for bottom right. ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack. (In theory this should be in the TempData structure) ImGuiWindowTempData DC; // Temporary per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the "DC" variable name. @@ -1920,7 +1920,7 @@ namespace ImGui // NB: All position are in absolute pixels coordinates (we are never using window coordinates internally) IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); - IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL); + IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL); IMGUI_API void RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL); IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end, const ImVec2* text_size_if_known); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); @@ -1946,7 +1946,7 @@ namespace ImGui // Widgets IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0); - IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0); + IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos); IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos); IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index e509c039..07be3b36 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1225,7 +1225,7 @@ void ImGui::Spacing() ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return; - ItemSize(ImVec2(0,0)); + ItemSize(ImVec2(0, 0)); } void ImGui::Dummy(const ImVec2& size) @@ -1249,7 +1249,7 @@ void ImGui::NewLine() const ImGuiLayoutType backup_layout_type = window->DC.LayoutType; window->DC.LayoutType = ImGuiLayoutType_Vertical; if (window->DC.CurrLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. - ItemSize(ImVec2(0,0)); + ItemSize(ImVec2(0, 0)); else ItemSize(ImVec2(0.0f, g.FontSize)); window->DC.LayoutType = backup_layout_type; @@ -1611,7 +1611,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi // The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here. if (popup_max_height_in_items != -1 && !(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint)) - SetNextWindowSizeConstraints(ImVec2(0,0), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); + SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); if (!BeginCombo(label, preview_value, ImGuiComboFlags_None)) return false; @@ -3182,7 +3182,7 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() - return InputTextEx(label, NULL, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); + return InputTextEx(label, NULL, buf, (int)buf_size, ImVec2(0, 0), flags, callback, user_data); } bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) @@ -3217,7 +3217,7 @@ static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* t const float line_height = g.FontSize; const float scale = line_height / font->FontSize; - ImVec2 text_size = ImVec2(0,0); + ImVec2 text_size = ImVec2(0, 0); float line_width = 0.0f; const ImWchar* s = text_begin; From 5e976e9b0584878b5503fd86e81795c14981d1de Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Jun 2020 22:04:14 +0200 Subject: [PATCH 03/12] Title capitalization (#3280) --- docs/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index e8fa16f1..5536c5bc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,8 @@ -dear imgui +Dear ImGui ===== [![Build Status](https://github.com/ocornut/imgui/workflows/build/badge.svg)](https://github.com/ocornut/imgui/actions?workflow=build) -(This library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using dear imgui, please consider reaching out.) +(This library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using Dear ImGui, please consider reaching out.) Businesses: support continued development via invoiced technical support, maintenance, sponsoring contracts:
  _E-mail: contact @ dearimgui dot org_ @@ -86,7 +86,7 @@ Dear ImGui allows you to **create elaborate tools** as well as very short-lived Check out the Wiki's [About the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#About-the-IMGUI-paradigm) section if you want to understand the core principles behind the IMGUI paradigm. An IMGUI tries to minimize superfluous state duplication, state synchronization and state retention from the user's point of view. It is less error prone (less code and less bugs) than traditional retained-mode interfaces, and lends itself to create dynamic user interfaces. -Dear ImGui outputs vertex buffers and command lists that you can easily render in your application. The number of draw calls and state changes required to render them is fairly small. Because Dear ImGui doesn't know or touch graphics state directly, you can call its functions anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate dear imgui with your existing codebase. +Dear ImGui outputs vertex buffers and command lists that you can easily render in your application. The number of draw calls and state changes required to render them is fairly small. Because Dear ImGui doesn't know or touch graphics state directly, you can call its functions anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate Dear ImGui with your existing codebase. _A common misunderstanding is to mistake immediate mode gui for immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes as the gui functions are called. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._ @@ -178,7 +178,7 @@ How to help **How can I help financing further development of Dear ImGui?** -Your contributions are keeping this project alive. The library is available under a free and permissive license, but continued maintenance and development are a full-time endeavor and I would like to grow the team. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using dear imgui, please consider reaching out for invoiced technical support and maintenance contracts. Thank you! +Your contributions are keeping this project alive. The library is available under a free and permissive license, but continued maintenance and development are a full-time endeavor and I would like to grow the team. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using Dear ImGui, please consider reaching out for invoiced technical support and maintenance contracts. Thank you! Businesses: support continued development via invoiced technical support, maintenance, sponsoring contracts:
  _E-mail: contact @ dearimgui dot org_ From 53dfccbe4b047539ed4a173fbfd95bf2f5856ea2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 4 Jun 2020 17:53:41 +0200 Subject: [PATCH 04/12] imgui_freetype: Fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails. (#618) --- docs/CHANGELOG.txt | 1 + misc/freetype/imgui_freetype.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 96d439be..e7ff09d7 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -56,6 +56,7 @@ Other Changes: BeginMenu()/EndMenu() or BeginPopup/EndPopup(). (#3223, #1207) [@rokups] - Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] +- Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails. - CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups, static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns). Fixed a static contructor which led to this dependency on some compiler setups (unclear which). diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index 69108e3e..20a3be0e 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -13,6 +13,7 @@ // - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding. // - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions(). // - v0.62: (2019/02/09) added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!) +// - v0.63: (2020/06/04) fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails. // Gamma Correct Blending: // FreeType assumes blending in linear space rather than gamma space. @@ -467,7 +468,6 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i]; const FT_Glyph_Metrics* metrics = src_tmp.Font.LoadGlyph(src_glyph.Codepoint); - IM_ASSERT(metrics != NULL); if (metrics == NULL) continue; @@ -559,6 +559,8 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i]; stbrp_rect& pack_rect = src_tmp.Rects[glyph_i]; IM_ASSERT(pack_rect.was_packed); + if (pack_rect.w == 0 && pack_rect.h == 0) + continue; GlyphInfo& info = src_glyph.Info; IM_ASSERT(info.Width + padding <= pack_rect.w); From 79fbab543d229c8526d4d05078028f7fa0656c7b Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 4 Jun 2020 18:59:04 +0200 Subject: [PATCH 05/12] Minor fix to avoid undefined behavior sanitizer triggering (#3276) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 82de5dfb..b74f44cf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3516,7 +3516,7 @@ static void ImGui::UpdateMouseInputs() ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f); if (ImLengthSqr(delta_from_click_pos) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist) g.IO.MouseDoubleClicked[i] = true; - g.IO.MouseClickedTime[i] = -DBL_MAX; // so the third click isn't turned into a double-click + g.IO.MouseClickedTime[i] = -g.IO.MouseDoubleClickTime * 2.0f; // Mark as "old enough" so the third click isn't turned into a double-click } else { From 6eb66fbef3f6c65b9612170fae2ea150b6082b7a Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Fri, 5 Jun 2020 01:23:18 +0200 Subject: [PATCH 06/12] Backends: Win32: Cache the result of a windows version check. (#3283) This is not expected to change while the application is running :) --- examples/imgui_impl_win32.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index ae18eb6e..57d6e3ed 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -417,7 +417,8 @@ void ImGui_ImplWin32_EnableDpiAwareness() float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) { UINT xdpi = 96, ydpi = 96; - if (IsWindows8Point1OrGreater()) + static BOOL bIsWindows8Point1OrGreater = IsWindows8Point1OrGreater(); + if (bIsWindows8Point1OrGreater) { static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor")) From dc49b14e2983547a165e5dc43edcee0e51b496c8 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Fri, 5 Jun 2020 14:47:49 +0300 Subject: [PATCH 07/12] Misc: Fix examples of using other OpenGL3 bindings in Makefiles. --- examples/example_glfw_opengl3/Makefile | 9 ++++++--- examples/example_sdl_opengl3/Makefile | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/example_glfw_opengl3/Makefile b/examples/example_glfw_opengl3/Makefile index 7696eaae..3bc72b6f 100644 --- a/examples/example_glfw_opengl3/Makefile +++ b/examples/example_glfw_opengl3/Makefile @@ -35,7 +35,8 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W ## Using OpenGL loader: glew ## (This assumes a system-wide installation) -# CXXFLAGS += -lGLEW -DIMGUI_IMPL_OPENGL_LOADER_GLEW +# CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLEW +# LIBS += -lGLEW ## Using OpenGL loader: glad # SOURCES += ../libs/glad/src/glad.c @@ -44,9 +45,11 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W ## Using OpenGL loader: glbinding ## This assumes a system-wide installation ## of either version 3.0.0 (or newer) -# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING3 +# CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING3 +# LIBS += -lglbinding ## or the older version 2.x -# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2 +# CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2 +# LIBS += -lglbinding ##--------------------------------------------------------------------- ## BUILD FLAGS PER PLATFORM diff --git a/examples/example_sdl_opengl3/Makefile b/examples/example_sdl_opengl3/Makefile index e8b2f566..41826741 100644 --- a/examples/example_sdl_opengl3/Makefile +++ b/examples/example_sdl_opengl3/Makefile @@ -35,7 +35,8 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W ## Using OpenGL loader: glew ## (This assumes a system-wide installation) -# CXXFLAGS += -lGLEW -DIMGUI_IMPL_OPENGL_LOADER_GLEW +# CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLEW +# LIBS += -lGLEW ## Using OpenGL loader: glad # SOURCES += ../libs/glad/src/glad.c @@ -44,9 +45,11 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W ## Using OpenGL loader: glbinding ## This assumes a system-wide installation ## of either version 3.0.0 (or newer) -# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING3 +# CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING3 +# LIBS += -lglbinding ## or the older version 2.x -# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2 +# CXXFLAGS += -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2 +# LIBS += -lglbinding ##--------------------------------------------------------------------- ## BUILD FLAGS PER PLATFORM From 5af8a8c7e83e735a1640d9347aa31c94d10e71fa Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Fri, 5 Jun 2020 13:04:55 +0300 Subject: [PATCH 08/12] CI: Extra warnings for builds with Clang. Backends: OpenGL3: Fix sign conversion warnings. --- examples/example_null/Makefile | 7 +++++-- examples/imgui_impl_opengl3.cpp | 26 +++++++++++++------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/examples/example_null/Makefile b/examples/example_null/Makefile index 0ccee11b..15c547a5 100644 --- a/examples/example_null/Makefile +++ b/examples/example_null/Makefile @@ -40,7 +40,10 @@ endif ifeq ($(UNAME_S), Linux) #LINUX ECHO_MESSAGE = "Linux" ifneq ($(WITH_EXTRA_WARNINGS), 0) - CXXFLAGS += -Wextra -pedantic + CXXFLAGS += -Wextra -Wpedantic + ifeq ($(shell $(CXX) -v 2>&1 | grep -c "clang version"), 1) + CXXFLAGS += -Wshadow -Wsign-conversion + endif endif CFLAGS = $(CXXFLAGS) endif @@ -56,7 +59,7 @@ endif ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) ECHO_MESSAGE = "MinGW" ifneq ($(WITH_EXTRA_WARNINGS), 0) - CXXFLAGS += -Wextra -pedantic + CXXFLAGS += -Wextra -Wpedantic endif CFLAGS = $(CXXFLAGS) endif diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp index 3ad04a41..028a704b 100644 --- a/examples/imgui_impl_opengl3.cpp +++ b/examples/imgui_impl_opengl3.cpp @@ -132,8 +132,8 @@ static GLuint g_GlVersion = 0; // Extracted at runtime usin static char g_GlslVersionString[32] = ""; // Specified by user or detected based on compile time GL settings. static GLuint g_FontTexture = 0; static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; -static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location -static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location +static GLint g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location +static GLuint g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; // Functions @@ -144,7 +144,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) GLint major, minor; glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor); - g_GlVersion = major * 100 + minor * 10; + g_GlVersion = (GLuint)(major * 100 + minor * 10); #else g_GlVersion = 200; // GLES 2 #endif @@ -292,14 +292,14 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) // Backup GL state GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture); glActiveTexture(GL_TEXTURE0); - GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program); + GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture); #ifdef GL_SAMPLER_BINDING - GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); + GLuint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); #endif - GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); #ifndef IMGUI_IMPL_OPENGL_ES2 - GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object); + GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object); #endif #ifdef GL_POLYGON_MODE GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); @@ -336,8 +336,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) const ImDrawList* cmd_list = draw_data->CmdLists[n]; // Upload vertex/index buffers - glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { @@ -643,9 +643,9 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects() g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); - g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position"); - g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV"); - g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color"); + g_AttribLocationVtxPos = (GLuint)glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationVtxUV = (GLuint)glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationVtxColor = (GLuint)glGetAttribLocation(g_ShaderHandle, "Color"); // Create buffers glGenBuffers(1, &g_VboHandle); From 78d5ccfb9012bdf9e25317aa11fc79e7e639c8fb Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 6 Jun 2020 16:44:31 +0200 Subject: [PATCH 09/12] ImDrawList: PushColumnsBackground(): Fixed incorrect assert. (#3163) --- imgui_widgets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 07be3b36..2ba7c6b4 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7553,7 +7553,7 @@ void ImGui::PushColumnsBackground() int cmd_size = window->DrawList->CmdBuffer.Size; PushClipRect(columns->HostClipRect.Min, columns->HostClipRect.Max, false); IM_UNUSED(cmd_size); - IM_ASSERT(cmd_size == window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd + IM_ASSERT(cmd_size >= window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd } void ImGui::PopColumnsBackground() From e22e3f300af3b913e3209bde2a9dff91ed637807 Mon Sep 17 00:00:00 2001 From: thedmd Date: Sat, 6 Jun 2020 16:37:07 +0200 Subject: [PATCH 10/12] ImDrawList: Fixed an issue when draw command merging or cancelling while crossing the VtxOffset boundary would lead to draw command being emitted with wrong VtxOffset value. (#3129, #3163, #3232) --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 2 +- imgui_draw.cpp | 32 ++++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e7ff09d7..54e5a113 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -56,6 +56,9 @@ Other Changes: BeginMenu()/EndMenu() or BeginPopup/EndPopup(). (#3223, #1207) [@rokups] - Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] +- ImDrawList: Fixed an issue when draw command merging or cancelling while crossing the VtxOffset + boundary would lead to draw command being emitted with wrong VtxOffset value. (#3129, #3163, #3232) + [@thedmd, @Shironekoben, @sergeyn, @ocornut] - Misc, Freetype: Fix for rare case where FT_Get_Char_Index() succeed but FT_Load_Glyph() fails. - CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups, static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns). diff --git a/imgui.cpp b/imgui.cpp index b74f44cf..0c2156d5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10267,7 +10267,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; char buf[300]; - ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd: %4d triangles, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)", + ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd:%5d triangles, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)", pcmd->ElemCount/3, (void*)(intptr_t)pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 057ddb65..0e56b3f4 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -460,11 +460,17 @@ void ImDrawList::UpdateClipRect() } // Try to merge with previous command if it matches, else use current command - ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; - if (curr_cmd->ElemCount == 0 && prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL) - CmdBuffer.pop_back(); - else - curr_cmd->ClipRect = curr_clip_rect; + if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1) + { + ImDrawCmd* prev_cmd = curr_cmd - 1; + if (memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->VtxOffset == _VtxCurrentOffset && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL) + { + CmdBuffer.pop_back(); + return; + } + } + + curr_cmd->ClipRect = curr_clip_rect; } void ImDrawList::UpdateTextureID() @@ -479,11 +485,17 @@ void ImDrawList::UpdateTextureID() } // Try to merge with previous command if it matches, else use current command - ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; - if (curr_cmd->ElemCount == 0 && prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL) - CmdBuffer.pop_back(); - else - curr_cmd->TextureId = curr_texture_id; + if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1) + { + ImDrawCmd* prev_cmd = curr_cmd - 1; + if (prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->VtxOffset == _VtxCurrentOffset && prev_cmd->UserCallback == NULL) + { + CmdBuffer.pop_back(); + return; + } + } + + curr_cmd->TextureId = curr_texture_id; } #undef GetCurrentClipRect From 003153b3acbbb0022d35ea7fba4155c6706d801e Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 6 Jun 2020 19:52:41 +0200 Subject: [PATCH 11/12] ImDrawList: Tweaks to make style consistent (using pointers, same local names). Added comments. Should be no-op. --- imgui.cpp | 8 ++++---- imgui.h | 20 ++++++++++---------- imgui_draw.cpp | 22 +++++++++++----------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0c2156d5..01ceafe9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4077,15 +4077,15 @@ static void AddWindowToSortBuffer(ImVector* out_sorted_windows, Im static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* draw_list) { - if (draw_list->CmdBuffer.empty()) + if (draw_list->CmdBuffer.Size == 0) return; // Remove trailing command if unused - ImDrawCmd& last_cmd = draw_list->CmdBuffer.back(); - if (last_cmd.ElemCount == 0 && last_cmd.UserCallback == NULL) + ImDrawCmd* curr_cmd = &draw_list->CmdBuffer.back(); + if (curr_cmd->ElemCount == 0 && curr_cmd->UserCallback == NULL) { draw_list->CmdBuffer.pop_back(); - if (draw_list->CmdBuffer.empty()) + if (draw_list->CmdBuffer.Size == 0) return; } diff --git a/imgui.h b/imgui.h index 824c98de..ebad93cb 100644 --- a/imgui.h +++ b/imgui.h @@ -1878,13 +1878,13 @@ typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* c // is enabled, those fields allow us to render meshes larger than 64K vertices while keeping 16-bit indices. struct ImDrawCmd { - unsigned int ElemCount; // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. - ImVec4 ClipRect; // Clipping rectangle (x1, y1, x2, y2). Subtract ImDrawData->DisplayPos to get clipping rectangle in "viewport" coordinates - ImTextureID TextureId; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas. - unsigned int VtxOffset; // Start offset in vertex buffer. Pre-1.71 or without ImGuiBackendFlags_RendererHasVtxOffset: always 0. With ImGuiBackendFlags_RendererHasVtxOffset: may be >0 to support meshes larger than 64K vertices with 16-bit indices. - unsigned int IdxOffset; // Start offset in index buffer. Always equal to sum of ElemCount drawn so far. - ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. - void* UserCallbackData; // The draw callback code can access this. + unsigned int ElemCount; // 4 // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. + ImVec4 ClipRect; // 4*4 // Clipping rectangle (x1, y1, x2, y2). Subtract ImDrawData->DisplayPos to get clipping rectangle in "viewport" coordinates + ImTextureID TextureId; // 4-8 // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas. + unsigned int VtxOffset; // 4 // Start offset in vertex buffer. Pre-1.71 or without ImGuiBackendFlags_RendererHasVtxOffset: always 0. With ImGuiBackendFlags_RendererHasVtxOffset: may be >0 to support meshes larger than 64K vertices with 16-bit indices. + unsigned int IdxOffset; // 4 // Start offset in index buffer. Always equal to sum of ElemCount drawn so far. + ImDrawCallback UserCallback; // 4-8 // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. + void* UserCallbackData; // 4-8 // The draw callback code can access this. ImDrawCmd() { ElemCount = 0; TextureId = (ImTextureID)NULL; VtxOffset = IdxOffset = 0; UserCallback = NULL; UserCallbackData = NULL; } }; @@ -1984,7 +1984,7 @@ struct ImDrawList ImVector _ClipRectStack; // [Internal] ImVector _TextureIdStack; // [Internal] ImVector _Path; // [Internal] current path building - ImDrawListSplitter _Splitter; // [Internal] for channels api + ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!) // If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui) ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); } @@ -2048,13 +2048,13 @@ struct ImDrawList // - Use to split render into layers. By switching channels to can render out-of-order (e.g. submit FG primitives before BG primitives) // - Use to minimize draw calls (e.g. if going back-and-forth between multiple clipping rectangles, prefer to append into separate channels then merge at the end) // - FIXME-OBSOLETE: This API shouldn't have been in ImDrawList in the first place! - // Prefer using your own persistent copy of ImDrawListSplitter as you can stack them. + // Prefer using your own persistent instance of ImDrawListSplitter as you can stack them. // Using the ImDrawList::ChannelsXXXX you cannot stack a split over another. inline void ChannelsSplit(int count) { _Splitter.Split(this, count); } inline void ChannelsMerge() { _Splitter.Merge(this); } inline void ChannelsSetCurrent(int n) { _Splitter.SetCurrentChannel(this, n); } - // Internal helpers + // [Internal helpers] // NB: all primitives needs to be reserved via PrimReserve() beforehand! IMGUI_API void Clear(); IMGUI_API void ClearFreeMemory(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 0e56b3f4..91de2ae6 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -434,14 +434,14 @@ void ImDrawList::AddDrawCmd() void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) { - ImDrawCmd* current_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; - if (!current_cmd || current_cmd->ElemCount != 0 || current_cmd->UserCallback != NULL) + ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size - 1] : NULL; + if (!curr_cmd || curr_cmd->ElemCount != 0 || curr_cmd->UserCallback != NULL) { AddDrawCmd(); - current_cmd = &CmdBuffer.back(); + curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; } - current_cmd->UserCallback = callback; - current_cmd->UserCallbackData = callback_data; + curr_cmd->UserCallback = callback; + curr_cmd->UserCallbackData = callback_data; AddDrawCmd(); // Force a new command after us (see comment below) } @@ -452,7 +452,7 @@ void ImDrawList::UpdateClipRect() { // If current command is used with different settings we need to add a new command const ImVec4 curr_clip_rect = GetCurrentClipRect(); - ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size-1] : NULL; + ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size - 1] : NULL; if (!curr_cmd || (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) != 0) || curr_cmd->UserCallback != NULL) { AddDrawCmd(); @@ -477,7 +477,7 @@ void ImDrawList::UpdateTextureID() { // If current command is used with different settings we need to add a new command const ImTextureID curr_texture_id = GetCurrentTextureId(); - ImDrawCmd* curr_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; + ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size - 1] : NULL; if (!curr_cmd || (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != curr_texture_id) || curr_cmd->UserCallback != NULL) { AddDrawCmd(); @@ -559,8 +559,8 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count) AddDrawCmd(); } - ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size - 1]; - draw_cmd.ElemCount += idx_count; + ImDrawCmd* draw_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + draw_cmd->ElemCount += idx_count; int vtx_buffer_old_size = VtxBuffer.Size; VtxBuffer.resize(vtx_buffer_old_size + vtx_count); @@ -576,8 +576,8 @@ void ImDrawList::PrimUnreserve(int idx_count, int vtx_count) { IM_ASSERT_PARANOID(idx_count >= 0 && vtx_count >= 0); - ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size - 1]; - draw_cmd.ElemCount -= idx_count; + ImDrawCmd* draw_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + draw_cmd->ElemCount -= idx_count; VtxBuffer.shrink(VtxBuffer.Size - vtx_count); IdxBuffer.shrink(IdxBuffer.Size - idx_count); } From 0320e7257babeac02337771e1249317b44664a85 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sat, 6 Jun 2020 20:25:56 +0200 Subject: [PATCH 12/12] ImDrawList: Small refactor to create empty command when beginning the frame, allowing to simplify some functions. + Missing clearing two fields in ClearFreeMemory() (was hamrless) --- imgui.cpp | 6 +++--- imgui.h | 5 +++-- imgui_draw.cpp | 18 +++++++++++------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 01ceafe9..07a832c4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3777,11 +3777,11 @@ void ImGui::NewFrame() if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset; - g.BackgroundDrawList.Clear(); + g.BackgroundDrawList.ResetForNewFrame(); g.BackgroundDrawList.PushTextureID(g.IO.Fonts->TexID); g.BackgroundDrawList.PushClipRectFullScreen(); - g.ForegroundDrawList.Clear(); + g.ForegroundDrawList.ResetForNewFrame(); g.ForegroundDrawList.PushTextureID(g.IO.Fonts->TexID); g.ForegroundDrawList.PushClipRectFullScreen(); @@ -5860,7 +5860,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // DRAWING // Setup draw list and outer clipping rectangle - window->DrawList->Clear(); + window->DrawList->ResetForNewFrame(); window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); PushClipRect(host_rect.Min, host_rect.Max, false); diff --git a/imgui.h b/imgui.h index ebad93cb..7906ae07 100644 --- a/imgui.h +++ b/imgui.h @@ -1987,7 +1987,8 @@ struct ImDrawList ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!) // If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui) - ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); } + ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; Flags = ImDrawListFlags_None; _VtxCurrentOffset = _VtxCurrentIdx = 0; _VtxWritePtr = NULL; _IdxWritePtr = NULL; _OwnerName = NULL; } + ~ImDrawList() { ClearFreeMemory(); } IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) IMGUI_API void PushClipRectFullScreen(); @@ -2056,7 +2057,7 @@ struct ImDrawList // [Internal helpers] // NB: all primitives needs to be reserved via PrimReserve() beforehand! - IMGUI_API void Clear(); + IMGUI_API void ResetForNewFrame(); IMGUI_API void ClearFreeMemory(); IMGUI_API void PrimReserve(int idx_count, int vtx_count); IMGUI_API void PrimUnreserve(int idx_count, int vtx_count); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 91de2ae6..d5844dbe 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -376,12 +376,13 @@ void ImDrawListSharedData::SetCircleSegmentMaxError(float max_error) } } -void ImDrawList::Clear() +// Initialize before use in a new frame. We always have a command ready in the buffer. +void ImDrawList::ResetForNewFrame() { CmdBuffer.resize(0); IdxBuffer.resize(0); VtxBuffer.resize(0); - Flags = _Data ? _Data->InitialFlags : ImDrawListFlags_None; + Flags = _Data->InitialFlags; _VtxCurrentOffset = 0; _VtxCurrentIdx = 0; _VtxWritePtr = NULL; @@ -390,6 +391,7 @@ void ImDrawList::Clear() _TextureIdStack.resize(0); _Path.resize(0); _Splitter.Clear(); + CmdBuffer.push_back(ImDrawCmd()); } void ImDrawList::ClearFreeMemory() @@ -397,6 +399,8 @@ void ImDrawList::ClearFreeMemory() CmdBuffer.clear(); IdxBuffer.clear(); VtxBuffer.clear(); + Flags = ImDrawListFlags_None; + _VtxCurrentOffset = 0; _VtxCurrentIdx = 0; _VtxWritePtr = NULL; _IdxWritePtr = NULL; @@ -434,8 +438,8 @@ void ImDrawList::AddDrawCmd() void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) { - ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size - 1] : NULL; - if (!curr_cmd || curr_cmd->ElemCount != 0 || curr_cmd->UserCallback != NULL) + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + if (curr_cmd->ElemCount != 0 || curr_cmd->UserCallback != NULL) { AddDrawCmd(); curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; @@ -452,8 +456,8 @@ void ImDrawList::UpdateClipRect() { // If current command is used with different settings we need to add a new command const ImVec4 curr_clip_rect = GetCurrentClipRect(); - ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size - 1] : NULL; - if (!curr_cmd || (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) != 0) || curr_cmd->UserCallback != NULL) + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + if ((curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) != 0) || curr_cmd->UserCallback != NULL) { AddDrawCmd(); return; @@ -477,7 +481,7 @@ void ImDrawList::UpdateTextureID() { // If current command is used with different settings we need to add a new command const ImTextureID curr_texture_id = GetCurrentTextureId(); - ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size - 1] : NULL; + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; if (!curr_cmd || (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != curr_texture_id) || curr_cmd->UserCallback != NULL) { AddDrawCmd();