From ee770af72c93172ff6f0feafd22c6f7f6db28be9 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 4 Mar 2018 16:06:43 +0100 Subject: [PATCH 1/9] Columns: Adding per-window display in Metrics. Tidying up, removing old code/comments. (#125, #1499, #1656) --- imgui.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4195a8c5..8d9611bf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12384,7 +12384,7 @@ static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning. ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. + IM_ASSERT(column_index > 0); // We are not supposed to drag column 0. IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + GetColumnsRectHalfWidth() - window->Pos.x; @@ -12405,16 +12405,6 @@ float ImGui::GetColumnOffset(int column_index) column_index = columns->Current; IM_ASSERT(column_index < columns->Columns.Size); - /* - if (g.ActiveId) - { - ImGuiContext& g = *GImGui; - const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index); - if (g.ActiveId == column_id) - return GetDraggedColumnOffset(columns, column_index); - } - */ - const float t = columns->Columns[column_index].OffsetNorm; const float x_offset = ImLerp(columns->MinX, columns->MaxX, t); return x_offset; @@ -12524,7 +12514,6 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag // Set state for first column const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range - //column->MaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; columns->MaxX = content_region_width - window->Scroll.x; columns->StartPosY = window->DC.CursorPos.y; columns->StartMaxPosX = window->DC.CursorMaxPos.x; @@ -12640,7 +12629,7 @@ void ImGui::EndColumns() window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); } -// [2017/12: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing] +// [2018-03: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing] void ImGui::Columns(int columns_count, const char* id, bool border) { ImGuiWindow* window = GetCurrentWindow(); @@ -13237,6 +13226,21 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::BulletText("NavRectRel[0]: "); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); + if (window->ColumnsStorage.Size > 0 && ImGui::TreeNode("Columns", "Columns sets (%d)", window->ColumnsStorage.Size)) + { + for (int n = 0; n < window->ColumnsStorage.Size; n++) + { + const ImGuiColumnsSet* columns = &window->ColumnsStorage[n]; + if (ImGui::TreeNode((void*)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) + { + ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX); + for (int column_n = 0; column_n < columns->Columns.Size; column_n++) + ImGui::BulletText("Column %02d: OffsetNorm %.3f (= %.1f px)", column_n, columns->Columns[column_n].OffsetNorm, OffsetNormToPixels(columns, columns->Columns[column_n].OffsetNorm)); + ImGui::TreePop(); + } + } + ImGui::TreePop(); + } ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); ImGui::TreePop(); } From 968a8d2a3fecc3bf870a20f3e6a2f10dbe2cddab Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 4 Mar 2018 16:57:44 +0100 Subject: [PATCH 2/9] Columns: Clamping MaxX above MinX. This shouldn't have much of a benefit / affect, but the internal values are more sane this way. (#125) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 8d9611bf..27a82075 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12514,7 +12514,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag // Set state for first column const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range - columns->MaxX = content_region_width - window->Scroll.x; + columns->MaxX = ImMax(content_region_width - window->Scroll.x, columns->MinX + 1.0f); columns->StartPosY = window->DC.CursorPos.y; columns->StartMaxPosX = window->DC.CursorMaxPos.x; columns->CellMinY = columns->CellMaxY = window->DC.CursorPos.y; From bf7481eba01252f3e53590c7c592b86b318bcd52 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 4 Mar 2018 17:44:17 +0100 Subject: [PATCH 3/9] Columns: Extent stop at the right-most clipped pixel. The right-most column might appear a little wider but it's usable space matches the others. (#125). +9 Internal: Store InnerClipRect. --- imgui.cpp | 19 +++++++++---------- imgui_internal.h | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 27a82075..d9991336 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6131,21 +6131,20 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y - window->WindowBorderSize; //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); + // Inner clipping rectangle + // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); + window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y); + window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); + window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y); + // After Begin() we fill the last item / hovered data using the title bar data. Make that a standard behavior (to allow usage of context menus on title bar only, etc.). window->DC.LastItemId = window->MoveId; window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0; window->DC.LastItemRect = title_bar_rect; } - // Inner clipping rectangle - // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. - const float border_size = window->WindowBorderSize; - ImRect clip_rect; - clip_rect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - border_size))); - clip_rect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y); - clip_rect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - border_size))); - clip_rect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y); - PushClipRect(clip_rect.Min, clip_rect.Max, true); + PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true); // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) if (first_begin_of_the_frame) @@ -12512,7 +12511,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag window->DC.ColumnsSet = columns; // Set state for first column - const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); + const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->InnerClipRect.Max.x - window->Pos.x); columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range columns->MaxX = ImMax(content_region_width - window->Scroll.x, columns->MinX + 1.0f); columns->StartPosY = window->DC.CursorPos.y; diff --git a/imgui_internal.h b/imgui_internal.h index dd0e08ad..79fc4d95 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -944,7 +944,7 @@ struct IMGUI_API ImGuiWindow ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window. - ImRect InnerRect; + ImRect InnerRect, InnerClipRect; int LastFrameActive; float ItemWidthDefault; ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items From 5ed45d0aec76ffae27e8089024c8b4531c7214e0 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 4 Mar 2018 17:55:59 +0100 Subject: [PATCH 4/9] Columns: Fixed destructive small resize. (#1656). The OffsetNorm clamp introduced by #913 was ok as it didn't write back into the storage, which #1499 started doing making it destructive. Right now I don't think the clamp is needed at all. It had uses (eg: hide the issue fixed by bf7481eba01252f3e53590c7c592b86b318bcd52). --- imgui.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d9991336..bfbac41f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12537,19 +12537,10 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag } } - for (int n = 0; n < columns_count + 1; n++) + for (int n = 0; n < columns_count; n++) { - // Clamp position - ImGuiColumnData* column = &columns->Columns[n]; - float t = column->OffsetNorm; - if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) - t = ImMin(t, PixelsToOffsetNorm(columns, (columns->MaxX - columns->MinX) - g.Style.ColumnsMinSpacing * (columns->Count - n))); - column->OffsetNorm = t; - - if (n == columns_count) - continue; - // Compute clipping rectangle + ImGuiColumnData* column = &columns->Columns[n]; float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n) - 1.0f); float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n + 1) - 1.0f); column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); From 0ec356eb6e5471178ea543d02c28b59bb97d659a Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 5 Mar 2018 11:30:23 +0100 Subject: [PATCH 5/9] Comments, FAQ update. --- README.md | 7 +++---- imgui.cpp | 53 +++++++++++++++++++++++--------------------------- imgui.h | 11 ++++++----- imgui_draw.cpp | 2 +- 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index da797963..b5f43563 100644 --- a/README.md +++ b/README.md @@ -231,18 +231,17 @@ See the [Software using dear imgui page](https://github.com/ocornut/imgui/wiki/S The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations. -How can I help? +How can I tell whether to dispatch mouse/keyboard to imgui or to my application?
How can I display an image? What is ImTextureID, how does it works?
How can I have multiple widgets with the same label, or without any label? (Yes). A primer on labels and ID stack. -
How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?
How can I load a different font than the default?
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? -
How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables)
How can I use the drawing facilities without an Dear ImGui window? (using ImDrawList API)
I integrated Dear ImGui in my engine and the text or lines are blurry..
I integrated Dear ImGui in my engine and some elements are disappearing when I move windows around.. +
How can I help? See the FAQ in imgui.cpp for answers. @@ -250,7 +249,7 @@ See the FAQ in imgui.cpp for answers. You can control Dear ImGui with a gamepad, see the explanation in imgui.cpp about how to use the navigation feature (short version: map your gamepad inputs into the `io.NavInputs[]` array and set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad`). -You can share your computer mouse seamlessy with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the prefered solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui). +You can share your computer mouse seamlessy with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the prefered solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC using Synergy 1.x. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui). For touch inputs, you can increase the hit box of widgets (via the _style.TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse or gamepad to allow optimising for screen real-estate and precision. diff --git a/imgui.cpp b/imgui.cpp index bfbac41f..64c2f4f9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -23,18 +23,17 @@ - API BREAKING CHANGES (read me when you update!) - ISSUES & TODO LIST - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - - How can I help? + - How can I tell whether to dispatch mouse/keyboard to imgui or to my application? - How can I display an image? What is ImTextureID, how does it works? - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels and the ID stack. - - How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? - How can I load a different font than the default? - How can I easily use icons in my application? - How can I load multiple fonts? - How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? - - How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables) - How can I use the drawing facilities without an ImGui window? (using ImDrawList API) - I integrated Dear ImGui in my engine and the text or lines are blurry.. - I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. + - How can I help? - ISSUES & TODO-LIST - CODE @@ -234,7 +233,7 @@ Please reach out if you think the game vs navigation input sharing could be improved. - Mouse: - PS4 users: Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback. - - Consoles/Tablet/Phone users: Consider using Synergy host (on your computer) + uSynergy.c (in your console/tablet/phone app) to use your PC mouse/keyboard. + - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + uSynergy.c (in your console/tablet/phone app) to share your PC mouse/keyboard. - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavMoveMouse flag. Enabling ImGuiConfigFlags_NavMoveMouse instructs dear imgui to move your mouse cursor along with navigation movements. When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantMoveMouse' to notify you that it wants the mouse cursor to be moved. @@ -405,13 +404,18 @@ FREQUENTLY ASKED QUESTIONS (FAQ), TIPS ====================================== - Q: How can I help? - A: - If you are experienced with Dear ImGui and C++, look at the github issues, or TODO.txt and see how you want/can help! - - Convince your company to fund development time! Individual users: you can also become a Patron (patreon.com/imgui) or donate on PayPal! See README. - - Disclose your usage of dear imgui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. - You may post screenshot or links in the gallery threads (github.com/ocornut/imgui/issues/1269). Visuals are ideal as they inspire other programmers. - But even without visuals, disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions. - - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on github or privately). + Q: How can I tell whether to dispatch mouse/keyboard to imgui or to my application? + A: You can read the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags from the ImGuiIO structure. + - When 'io.WantCaptureMouse' is set, imgui wants to use your mouse state, and you may want to discard/hide the inputs from the rest of your application. + - When 'io.WantCaptureKeyboard' is set, imgui wants to use your keyboard state, and you may want to discard/hide the inputs from the rest of your application. + - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console OS). + The 'io.WantCaptureMouse' is more accurate that any attempt to "check if the mouse is hovering a window" (don't do that!). + It handle mouse dragging correctly (both dragging that started over your application or over an imgui window) and handle e.g. modal windows blocking inputs. + Those flags are updated by ImGui::NewFrame(). Preferably read the flags after calling NewFrame() if you can afford it, but reading them before is also + perfectly fine, as the bool toggle fairly rarely. + (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically + have 'io.WantCaptureKeyboard=false'. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs + were for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.) Q: How can I display an image? What is ImTextureID, how does it works? A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function. @@ -521,18 +525,6 @@ e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! - Q: How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? - A: You can read the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'ioWantTextInput' flags from the ImGuiIO structure. - - When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. - - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console OS). - Preferably read the flags after calling ImGui::NewFrame() to avoid them lagging by one frame. But reading those flags before calling NewFrame() is - also generally ok, as the bool toggles fairly rarely and you don't generally expect to interact with either Dear ImGui or your application during - the same frame when that transition occurs. Dear ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, - so 'io.WantCaptureMouse' is more accurate and correct than checking if a window is hovered. - (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically - have 'io.WantCaptureKeyboard=false'. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs - were for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.) - Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) A: Use the font atlas to load the TTF/OTF file you want: ImGuiIO& io = ImGui::GetIO(); @@ -599,13 +591,9 @@ For languages using IME, on Windows you can copy the Hwnd of your application to io.ImeWindowHandle. The default implementation of io.ImeSetInputScreenPosFn() on Windows will set your IME position correctly. - Q: How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables) - A: Create your own context 'ctx = CreateContext()' + 'SetCurrentContext(ctx)' and your own font atlas 'ctx->GetIO().Fonts = new ImFontAtlas()' - so you don't rely on the default globals. - Q: How can I use the drawing facilities without an ImGui window? (using ImDrawList API) - A: - You can create a dummy window. Call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flag, - push a ImGuiCol_WindowBg with zero alpha, then retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. + A: - You can create a dummy window. Call SetNextWindowBgAlpha(0.0f), call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flags. + Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. - You can call ImGui::GetOverlayDrawList() and use this draw list to display contents over every other imgui windows. - You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create your own ImDrawListSharedData. @@ -617,6 +605,13 @@ A: You are probably mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1=left,y1=top,x2=right,y2=bottom) and NOT as (x1,y1,width,height). + Q: How can I help? + A: - If you are experienced with Dear ImGui and C++, look at the github issues, or TODO.txt and see how you want/can help! + - Convince your company to fund development time! Individual users: you can also become a Patron (patreon.com/imgui) or donate on PayPal! See README. + - Disclose your usage of dear imgui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. + You may post screenshot or links in the gallery threads (github.com/ocornut/imgui/issues/1269). Visuals are ideal as they inspire other programmers. + But even without visuals, disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions. + - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on github or privately). - tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. this is also useful to set yourself in the context of another window (to get/set other settings) diff --git a/imgui.h b/imgui.h index e6b3fe39..11110142 100644 --- a/imgui.h +++ b/imgui.h @@ -487,7 +487,7 @@ namespace ImGui IMGUI_API ImVec2 GetItemRectSize(); // get size of last item, in screen space IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags = 0); // is current window focused? or its root/child, depending on flags. see flags for options. - IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. + IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. NB: If you are trying to check whether your mouse should be dispatched to imgui or to your app, you should use the 'io.WantCaptureMouse' boolean for that! Please read the FAQ! IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API float GetTime(); @@ -656,6 +656,7 @@ enum ImGuiFocusedFlags_ }; // Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() +// Note: If you are trying to check whether your mouse should be dispatched to imgui or to your app, you should use the 'io.WantCaptureMouse' boolean for that. Please read the FAQ! enum ImGuiHoveredFlags_ { ImGuiHoveredFlags_Default = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. @@ -1665,10 +1666,10 @@ struct ImFontAtlas IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after Build(). Set font_cfg->FontDataOwnedByAtlas to false to keep ownership. IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp. IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter. - IMGUI_API void ClearTexData(); // Clear the CPU-side texture data. Saves RAM once the texture has been copied to graphics memory. - IMGUI_API void ClearInputData(); // Clear the input TTF data (inc sizes, glyph ranges) - IMGUI_API void ClearFonts(); // Clear the ImGui-side font data (glyphs storage, UV coordinates) - IMGUI_API void Clear(); // Clear all + IMGUI_API void ClearInputData(); // Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts. + IMGUI_API void ClearTexData(); // Clear output texture data (CPU side). Saves RAM once the texture has been copied to graphics memory. + IMGUI_API void ClearFonts(); // Clear output font data (glyphs storage, UV coordinates). + IMGUI_API void Clear(); // Clear all input and output. // Build atlas, retrieve pixel data. // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID(). diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c939733d..1a15a140 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1391,7 +1391,7 @@ void ImFontAtlas::ClearInputData() ConfigData[i].FontData = NULL; } - // When clearing this we lose access to the font name and other information used to build the font. + // When clearing this we lose access to the font name and other information used to build the font. for (int i = 0; i < Fonts.Size; i++) if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size) { From 51afaf7117b9835376ac6f242453c492dc8843cb Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 5 Mar 2018 13:15:15 +0100 Subject: [PATCH 6/9] Fixed type cast warning. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 64c2f4f9..31e7ff9e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13216,7 +13216,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) for (int n = 0; n < window->ColumnsStorage.Size; n++) { const ImGuiColumnsSet* columns = &window->ColumnsStorage[n]; - if (ImGui::TreeNode((void*)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) + if (ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) { ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX); for (int column_n = 0; column_n < columns->Columns.Size; column_n++) From 945f4d1ecd5806268de9674c3753feb7911fb935 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 5 Mar 2018 16:16:27 +0100 Subject: [PATCH 7/9] Removed redundant semi colons. (#1653) --- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index fe6d208c..713a929d 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2239,7 +2239,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) { ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size.x + cell_spacing), base_pos.y + (n / 16) * (cell_size.y + cell_spacing)); ImVec2 cell_p2(cell_p1.x + cell_size.x, cell_p1.y + cell_size.y); - const ImFontGlyph* glyph = font->FindGlyph((ImWchar)(base+n));; + const ImFontGlyph* glyph = font->FindGlyph((ImWchar)(base+n)); draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255,255,255,100) : IM_COL32(255,255,255,50)); font->RenderChar(draw_list, cell_size.x, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2)) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1a15a140..53f8160b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2056,7 +2056,7 @@ const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() // Unpack int codepoint = 0x4e00; memcpy(full_ranges, base_ranges, sizeof(base_ranges)); - ImWchar* dst = full_ranges + IM_ARRAYSIZE(base_ranges);; + ImWchar* dst = full_ranges + IM_ARRAYSIZE(base_ranges); for (int n = 0; n < IM_ARRAYSIZE(offsets_from_0x4E00); n++, dst += 2) dst[0] = dst[1] = (ImWchar)(codepoint += (offsets_from_0x4E00[n] + 1)); dst[0] = 0; From cea7492babfbd561589a41858159b14f0ca2373e Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 5 Mar 2018 22:47:53 +0100 Subject: [PATCH 8/9] Render: Removed the code that disable render if style.Alpha is 0.0f, it is both incorrect (as style Alpha can be modified mid-frame), not really necessary (just tested that full Alpha = 0 will lead to empty draw lists!) and misleading (bulk of the work was already done). --- imgui.cpp | 83 ++++++++++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 31e7ff9e..775d61e3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4028,52 +4028,47 @@ void ImGui::Render() ImGui::EndFrame(); g.FrameCountRendered = g.FrameCount; - // Skip render altogether if alpha is 0.0 - // Note that vertex buffers have been created and are wasted, so it is best practice that you don't create windows in the first place, or consistently respond to Begin() returning false. - if (g.Style.Alpha > 0.0f) - { - // Gather windows to render - g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; - g.DrawDataBuilder.Clear(); - ImGuiWindow* window_to_render_front_most = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget : NULL; - for (int n = 0; n != g.Windows.Size; n++) - { - ImGuiWindow* window = g.Windows[n]; - if (window->Active && window->HiddenFrames <= 0 && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0 && window != window_to_render_front_most) - AddWindowToDrawDataSelectLayer(window); - } - if (window_to_render_front_most && window_to_render_front_most->Active && window_to_render_front_most->HiddenFrames <= 0) // NavWindowingTarget is always temporarily displayed as the front-most window - AddWindowToDrawDataSelectLayer(window_to_render_front_most); - g.DrawDataBuilder.FlattenIntoSingleLayer(); - - // Draw software mouse cursor if requested - ImVec2 offset, size, uv[4]; - if (g.IO.MouseDrawCursor && g.IO.Fonts->GetMouseCursorTexData(g.MouseCursor, &offset, &size, &uv[0], &uv[2])) - { - const ImVec2 pos = g.IO.MousePos - offset; - const ImTextureID tex_id = g.IO.Fonts->TexID; - const float sc = g.Style.MouseCursorScale; - g.OverlayDrawList.PushTextureID(tex_id); - g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(1,0)*sc, pos+ImVec2(1,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(2,0)*sc, pos+ImVec2(2,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[2], uv[3], IM_COL32(0,0,0,255)); // Black border - g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[0], uv[1], IM_COL32(255,255,255,255)); // White fill - g.OverlayDrawList.PopTextureID(); - } - if (!g.OverlayDrawList.VtxBuffer.empty()) - AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); - - // Setup ImDrawData structure for end-user - SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData); - g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount; - g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; - - // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() + // Gather windows to render + g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; + g.DrawDataBuilder.Clear(); + ImGuiWindow* window_to_render_front_most = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget : NULL; + for (int n = 0; n != g.Windows.Size; n++) + { + ImGuiWindow* window = g.Windows[n]; + if (window->Active && window->HiddenFrames <= 0 && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != window_to_render_front_most) + AddWindowToDrawDataSelectLayer(window); + } + if (window_to_render_front_most && window_to_render_front_most->Active && window_to_render_front_most->HiddenFrames <= 0) // NavWindowingTarget is always temporarily displayed as the front-most window + AddWindowToDrawDataSelectLayer(window_to_render_front_most); + g.DrawDataBuilder.FlattenIntoSingleLayer(); + + // Draw software mouse cursor if requested + ImVec2 offset, size, uv[4]; + if (g.IO.MouseDrawCursor && g.IO.Fonts->GetMouseCursorTexData(g.MouseCursor, &offset, &size, &uv[0], &uv[2])) + { + const ImVec2 pos = g.IO.MousePos - offset; + const ImTextureID tex_id = g.IO.Fonts->TexID; + const float sc = g.Style.MouseCursorScale; + g.OverlayDrawList.PushTextureID(tex_id); + g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(1,0)*sc, pos+ImVec2(1,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(2,0)*sc, pos+ImVec2(2,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[2], uv[3], IM_COL32(0,0,0,255)); // Black border + g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[0], uv[1], IM_COL32(255,255,255,255)); // White fill + g.OverlayDrawList.PopTextureID(); + } + if (!g.OverlayDrawList.VtxBuffer.empty()) + AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); + + // Setup ImDrawData structure for end-user + SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData); + g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount; + g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; + + // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) - g.IO.RenderDrawListsFn(&g.DrawData); + if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) + g.IO.RenderDrawListsFn(&g.DrawData); #endif - } } const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) From a2ed3ee2cfdf3a763bc97e9eaf2d43b1be87364d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 6 Mar 2018 19:48:30 +0100 Subject: [PATCH 9/9] Examples: OpenGL3: Added a way to override the glsl version number through the Init call. (#1667, #1466) --- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 29 ++++++++++++++----- .../opengl3_example/imgui_impl_glfw_gl3.h | 2 +- .../imgui_impl_sdl_gl3.cpp | 24 +++++++++++---- .../sdl_opengl3_example/imgui_impl_sdl_gl3.h | 2 +- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index e7571942..8a8b8ed9 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-03-06: OpenGL: Added const char* glsl_version parameter to ImGui_ImplGlfwGL3_Init() so user can override the GLSL version e.g. "#version 150". // 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL3 in their name. @@ -31,6 +32,10 @@ // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. // 2016-04-30: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + #include "imgui.h" #include "imgui_impl_glfw_gl3.h" @@ -51,6 +56,7 @@ static bool g_MouseJustPressed[3] = { false, false, false }; static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; // OpenGL3 data +static char g_GlslVersion[32] = "#version 150"; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; @@ -258,8 +264,7 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - const GLchar *vertex_shader = - "#version 150\n" + const GLchar* vertex_shader = "uniform mat4 ProjMtx;\n" "in vec2 Position;\n" "in vec2 UV;\n" @@ -274,7 +279,6 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() "}\n"; const GLchar* fragment_shader = - "#version 150\n" "uniform sampler2D Texture;\n" "in vec2 Frag_UV;\n" "in vec4 Frag_Color;\n" @@ -284,11 +288,14 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" "}\n"; + const GLchar* vertex_shader_with_version[2] = { g_GlslVersion, vertex_shader }; + const GLchar* fragment_shader_with_version[2] = { g_GlslVersion, fragment_shader }; + g_ShaderHandle = glCreateProgram(); g_VertHandle = glCreateShader(GL_VERTEX_SHADER); g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_VertHandle, 1, &vertex_shader, 0); - glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL); + glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL); glCompileShader(g_VertHandle); glCompileShader(g_FragHandle); glAttachShader(g_ShaderHandle, g_VertHandle); @@ -347,12 +354,20 @@ static void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); } -bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) +bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks, const char* glsl_version) { g_Window = window; + // Store GL version string so we can refer to it later in case we recreate shaders. + if (glsl_version == NULL) + glsl_version = "#version 150"; + IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersion)); + strcpy(g_GlslVersion, glsl_version); + strcat(g_GlslVersion, "\n"); + + // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. ImGuiIO& io = ImGui::GetIO(); - io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.h b/examples/opengl3_example/imgui_impl_glfw_gl3.h index 6cbbe4a5..33b5329d 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.h +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.h @@ -13,7 +13,7 @@ struct GLFWwindow; -IMGUI_API bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks, const char* glsl_version = NULL); IMGUI_API void ImGui_ImplGlfwGL3_Shutdown(); IMGUI_API void ImGui_ImplGlfwGL3_NewFrame(); IMGUI_API void ImGui_ImplGlfwGL3_RenderDrawData(ImDrawData* draw_data); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index a0ca7e62..995948d0 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -12,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-03-06: OpenGL: Added const char* glsl_version parameter to ImGui_ImplSdlGL3_Init() so user can override the GLSL version e.g. "#version 150". // 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. // 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself. @@ -31,6 +32,10 @@ // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. // 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + #include "imgui.h" #include "imgui_impl_sdl_gl3.h" @@ -45,6 +50,7 @@ static bool g_MousePressed[3] = { false, false, false }; static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; // OpenGL data +static char g_GlslVersion[32] = "#version 150"; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; @@ -261,7 +267,6 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); const GLchar *vertex_shader = - "#version 150\n" "uniform mat4 ProjMtx;\n" "in vec2 Position;\n" "in vec2 UV;\n" @@ -276,7 +281,6 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() "}\n"; const GLchar* fragment_shader = - "#version 150\n" "uniform sampler2D Texture;\n" "in vec2 Frag_UV;\n" "in vec4 Frag_Color;\n" @@ -286,11 +290,14 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" "}\n"; + const GLchar* vertex_shader_with_version[2] = { g_GlslVersion, vertex_shader }; + const GLchar* fragment_shader_with_version[2] = { g_GlslVersion, fragment_shader }; + g_ShaderHandle = glCreateProgram(); g_VertHandle = glCreateShader(GL_VERTEX_SHADER); g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_VertHandle, 1, &vertex_shader, 0); - glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL); + glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL); glCompileShader(g_VertHandle); glCompileShader(g_FragHandle); glAttachShader(g_ShaderHandle, g_VertHandle); @@ -341,8 +348,15 @@ void ImGui_ImplSdlGL3_InvalidateDeviceObjects() } } -bool ImGui_ImplSdlGL3_Init(SDL_Window* window) +bool ImGui_ImplSdlGL3_Init(SDL_Window* window, const char* glsl_version) { + // Store GL version string so we can refer to it later in case we recreate shaders. + if (glsl_version == NULL) + glsl_version = "#version 150"; + IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersion)); + strcpy(g_GlslVersion, glsl_version); + strcat(g_GlslVersion, "\n"); + // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. ImGuiIO& io = ImGui::GetIO(); io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB; diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h index fa111a17..3aa00c3d 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h @@ -13,7 +13,7 @@ struct SDL_Window; typedef union SDL_Event SDL_Event; -IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window* window, const char* glsl_version = NULL); IMGUI_API void ImGui_ImplSdlGL3_Shutdown(); IMGUI_API void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window); IMGUI_API void ImGui_ImplSdlGL3_RenderDrawData(ImDrawData* draw_data);