From 19c4fa8dd5671a751275c7389deffa029a61b294 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 28 Nov 2018 15:41:17 +0100 Subject: [PATCH 1/4] Examples: DX12: Fixed compilation of imgui_impl_dx12.cpp in viewport branch. Multi-viewport is still not functional. --- examples/example_win32_directx12/main.cpp | 4 ++-- examples/imgui_impl_dx12.cpp | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/example_win32_directx12/main.cpp b/examples/example_win32_directx12/main.cpp index 70e9ea937..e8ceae3d3 100644 --- a/examples/example_win32_directx12/main.cpp +++ b/examples/example_win32_directx12/main.cpp @@ -38,9 +38,9 @@ static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFER void CreateRenderTarget() { - ID3D12Resource* pBackBuffer; for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) { + ID3D12Resource* pBackBuffer = NULL; g_pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer)); g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, g_mainRenderTargetDescriptor[i]); g_mainRenderTargetResource[i] = pBackBuffer; @@ -415,7 +415,7 @@ int main(int, char**) if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); + ImGui::RenderPlatformWindowsDefault(NULL, (void*)g_pd3dCommandList); } g_pSwapChain->Present(1, 0); // Present with vsync diff --git a/examples/imgui_impl_dx12.cpp b/examples/imgui_impl_dx12.cpp index 821b14991..eca42f650 100644 --- a/examples/imgui_impl_dx12.cpp +++ b/examples/imgui_impl_dx12.cpp @@ -731,18 +731,22 @@ static void ImGui_ImplDX12_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) */ } -static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*) +// arg = ID3D12GraphicsCommandList* +static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void* renderer_arg) { ImGuiViewportDataDx12* data = (ImGuiViewportDataDx12*)viewport->RendererUserData; IM_ASSERT(0); (void)data; + + ID3D12GraphicsCommandList* command_list = (ID3D12GraphicsCommandList*)renderer_arg; + /* ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); g_pd3dDeviceContext->OMSetRenderTargets(1, &data->RTView, NULL); if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear)) g_pd3dDeviceContext->ClearRenderTargetView(data->RTView, (float*)&clear_color); */ - ImGui_ImplDX12_RenderDrawData(viewport->DrawData); + ImGui_ImplDX12_RenderDrawData(viewport->DrawData, command_list); } static void ImGui_ImplDX12_SwapBuffers(ImGuiViewport* viewport, void*) From 01f940dc9a71985f0da92eb43266fe4c1309c59b Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 28 Nov 2018 22:50:37 +0100 Subject: [PATCH 2/4] Viewport: imgui_impl_sdl2: Added support for PlatformIO Platform_SetWindowAlpha. --- examples/imgui_impl_sdl.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/imgui_impl_sdl.cpp b/examples/imgui_impl_sdl.cpp index af0291421..ea5886cc8 100644 --- a/examples/imgui_impl_sdl.cpp +++ b/examples/imgui_impl_sdl.cpp @@ -46,7 +46,7 @@ #include #define SDL_HAS_WARP_MOUSE_GLOBAL SDL_VERSION_ATLEAST(2,0,4) #define SDL_HAS_CAPTURE_MOUSE SDL_VERSION_ATLEAST(2,0,4) -#define SDL_HAS_WINDOW_OPACITY SDL_VERSION_ATLEAST(2,0,5) +#define SDL_HAS_WINDOW_ALPHA SDL_VERSION_ATLEAST(2,0,5) #define SDL_HAS_ALWAYS_ON_TOP SDL_VERSION_ATLEAST(2,0,5) #define SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_VERSION_ATLEAST(2,0,5) #define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2,0,4) @@ -463,6 +463,14 @@ static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const char* t SDL_SetWindowTitle(data->Window, title); } +#if SDL_HAS_WINDOW_ALPHA +static void ImGui_ImplSDL2_SetWindowAlpha(ImGuiViewport* viewport, float alpha) +{ + ImGuiViewportDataSDL2* data = (ImGuiViewportDataSDL2*)viewport->PlatformUserData; + SDL_SetWindowOpacity(data->Window, alpha); +} +#endif + static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport* viewport) { ImGuiViewportDataSDL2* data = (ImGuiViewportDataSDL2*)viewport->PlatformUserData; @@ -556,6 +564,9 @@ static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_g platform_io.Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle; platform_io.Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow; platform_io.Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers; +#if SDL_HAS_WINDOW_ALPHA + platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL2_SetWindowAlpha; +#endif #if SDL_HAS_VULKAN platform_io.Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface; #endif From 36cbe1e5211be295d7cf0ccefd144deb85753cd8 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 29 Nov 2018 21:16:45 +0100 Subject: [PATCH 3/4] Viewport: Misc renaming. --- imgui.cpp | 24 ++++++++++++------------ imgui_internal.h | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a3480ef27..19ddfc1d7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7187,7 +7187,7 @@ static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window) static bool ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport) { ImGuiContext& g = *GImGui; - if (!(viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) || window->Viewport == viewport || viewport->PlatformIsMinimized) + if (!(viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) || window->Viewport == viewport || viewport->PlatformWindowMinimized) return false; if (!viewport->GetRect().Contains(window->Rect())) return false; @@ -7242,7 +7242,7 @@ static ImGuiViewportP* FindViewportHoveredFromPlatformWindowStack(const ImVec2 m for (int n = 0; n < g.Viewports.Size; n++) { ImGuiViewportP* viewport = g.Viewports[n]; - if (!(viewport->Flags & ImGuiViewportFlags_NoInputs) && !viewport->PlatformIsMinimized && viewport->GetRect().Contains(mouse_platform_pos)) + if (!(viewport->Flags & ImGuiViewportFlags_NoInputs) && !viewport->PlatformWindowMinimized && viewport->GetRect().Contains(mouse_platform_pos)) if (best_candidate == NULL || best_candidate->LastFrontMostStampCount < viewport->LastFrontMostStampCount) best_candidate = viewport; } @@ -7294,12 +7294,12 @@ static void ImGui::UpdateViewports() if ((g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)) { - if (g.PlatformIO.Platform_GetWindowMinimized && (n == 0 || viewport->CreatedPlatformWindow)) - viewport->PlatformIsMinimized = g.PlatformIO.Platform_GetWindowMinimized(viewport); + if (g.PlatformIO.Platform_GetWindowMinimized && (n == 0 || viewport->PlatformWindowCreated)) + viewport->PlatformWindowMinimized = g.PlatformIO.Platform_GetWindowMinimized(viewport); // Apply Position and Size (from Platform Window to ImGui) if requested. // We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities. - if (!viewport->PlatformIsMinimized) + if (!viewport->PlatformWindowMinimized) { if (viewport->PlatformRequestMove) viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport); @@ -7387,14 +7387,14 @@ static void ImGui::UpdateViewports() const bool is_mouse_dragging_with_an_expected_destination = g.DragDropActive; if (is_mouse_dragging_with_an_expected_destination && viewport_hovered == NULL) viewport_hovered = g.MouseLastHoveredViewport; - if (is_mouse_dragging_with_an_expected_destination || g.ActiveId == 0 || !ImGui::IsAnyMouseDown()) + if (is_mouse_dragging_with_an_expected_destination || g.ActiveId == 0 || !IsAnyMouseDown()) if (viewport_hovered != NULL && viewport_hovered != g.MouseViewport && !(viewport_hovered->Flags & ImGuiViewportFlags_NoInputs)) g.MouseViewport = viewport_hovered; IM_ASSERT(g.MouseViewport != NULL); } -// FIXME: We should ideally refactor the system to call this everyframe (we currently don't) +// FIXME: We should ideally refactor the system to call this every frame (we currently don't) ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const ImVec2& pos, const ImVec2& size, ImGuiViewportFlags flags) { ImGuiContext& g = *GImGui; @@ -7601,7 +7601,7 @@ void ImGui::UpdatePlatformWindows() } // Create window - bool is_new_window = (viewport->CreatedPlatformWindow == false); + bool is_new_window = (viewport->PlatformWindowCreated == false); if (is_new_window) { g.PlatformIO.Platform_CreateWindow(viewport); @@ -7610,7 +7610,7 @@ void ImGui::UpdatePlatformWindows() viewport->LastNameHash = 0; viewport->LastPlatformPos = viewport->LastPlatformSize = ImVec2(FLT_MAX, FLT_MAX); // By clearing those we'll enforce a call to Platform_SetWindowPos/Platform_SetWindowSize before Platform_ShowWindow viewport->LastRendererSize = viewport->Size; - viewport->CreatedPlatformWindow = true; + viewport->PlatformWindowCreated = true; } // Apply Position and Size (from ImGui to Platform/Renderer back-ends) @@ -7757,7 +7757,7 @@ void ImGui::DestroyPlatformWindow(ImGuiViewportP* viewport) IM_ASSERT(viewport->PlatformUserData == NULL); viewport->PlatformHandle = NULL; viewport->RendererUserData = viewport->PlatformHandle = NULL; - viewport->CreatedPlatformWindow = false; + viewport->PlatformWindowCreated = false; } void ImGui::DestroyPlatformWindows() @@ -9897,7 +9897,7 @@ static void RenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewp ImVec2 scale = bb.GetSize() / viewport->Size; ImVec2 off = bb.Min - viewport->Pos * scale; - float alpha_mul = viewport->PlatformIsMinimized ? 0.30f : 1.00f; + float alpha_mul = viewport->PlatformWindowMinimized ? 0.30f : 1.00f; window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul * 0.40f)); for (int i = 0; i != g.Windows.Size; i++) { @@ -10104,7 +10104,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::BulletText("Flags: 0x%04X =%s%s%s%s%s%s", viewport->Flags, (flags & ImGuiViewportFlags_CanHostOtherWindows) ? " CanHostOtherWindows" : "", (flags & ImGuiViewportFlags_NoDecoration) ? " NoDecoration" : "", (flags & ImGuiViewportFlags_NoFocusOnAppearing) ? " NoFocusOnAppearing" : "", (flags & ImGuiViewportFlags_NoInputs) ? " NoInputs" : "", - (flags & ImGuiViewportFlags_NoRendererClear) ? " NoRendererClear" : "", viewport->PlatformIsMinimized ? ", PlatformIsMinimized" : ""); + (flags & ImGuiViewportFlags_NoRendererClear) ? " NoRendererClear" : "", viewport->PlatformWindowMinimized ? ", PlatformWindowMinimized" : ""); for (int layer_i = 0; layer_i < IM_ARRAYSIZE(viewport->DrawDataBuilder.Layers); layer_i++) for (int draw_list_i = 0; draw_list_i < viewport->DrawDataBuilder.Layers[layer_i].Size; draw_list_i++) Funcs::NodeDrawList(NULL, viewport, viewport->DrawDataBuilder.Layers[layer_i][draw_list_i], "DrawList"); diff --git a/imgui_internal.h b/imgui_internal.h index 78b8bab68..65d3a5738 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -627,11 +627,11 @@ struct ImGuiViewportP : public ImGuiViewport int LastFrontMostStampCount; // Last stamp number from when a window hosted by this viewport was made front-most (by comparing this value between two viewport we have an implicit viewport z-order ImGuiID LastNameHash; ImVec2 LastPos; - bool CreatedPlatformWindow; float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent) float LastAlpha; int PlatformMonitor; - bool PlatformIsMinimized; + bool PlatformWindowCreated; + bool PlatformWindowMinimized; ImGuiWindow* Window; ImDrawList* OverlayDrawList; // For convenience, a draw list we can render to that's always rendered last (we use it to draw software mouse cursor when io.MouseDrawCursor is set) ImDrawData DrawDataP; @@ -640,7 +640,7 @@ struct ImGuiViewportP : public ImGuiViewport ImVec2 LastPlatformSize; ImVec2 LastRendererSize; - ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameOverlayDrawList = LastFrontMostStampCount = -1; LastNameHash = 0; CreatedPlatformWindow = false; Alpha = LastAlpha = 1.0f; PlatformMonitor = INT_MIN; PlatformIsMinimized = false; Window = NULL; OverlayDrawList = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } + ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameOverlayDrawList = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = INT_MIN; PlatformWindowCreated = PlatformWindowMinimized = false; Window = NULL; OverlayDrawList = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } ~ImGuiViewportP() { if (OverlayDrawList) IM_DELETE(OverlayDrawList); } ImRect GetRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } ImVec2 GetCenter() const{ return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); } From 2fbbcaa339f46c1f87dcd9cb044374a480afba3f Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 29 Nov 2018 21:28:47 +0100 Subject: [PATCH 4/4] Viewport: Avoid calling platform functions when window is not created (apart from Platform_GetWindowDpiScale, documented as such). Main viewport situation is still ambiguous. (#1542) --- imgui.cpp | 19 ++++++++++++------- imgui.h | 4 ++-- imgui_internal.h | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 19ddfc1d7..28e34cec2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3681,7 +3681,7 @@ void ImGui::EndFrame() IM_ASSERT(g.FrameScopeActive && "Forgot to call ImGui::NewFrame()"); // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) - if (g.PlatformIO.Platform_SetImeInputPos && g.PlatformImePosViewport != NULL && ImLengthSqr(g.PlatformImePos - g.PlatformImeLastPos) > 0.0001f) + if (g.PlatformIO.Platform_SetImeInputPos && ImLengthSqr(g.PlatformImePos - g.PlatformImeLastPos) > 0.0001f && g.PlatformImePosViewport && g.PlatformImePosViewport->PlatformWindowCreated) { g.PlatformIO.Platform_SetImeInputPos(g.PlatformImePosViewport, g.PlatformImePos); g.PlatformImeLastPos = g.PlatformImePos; @@ -7292,14 +7292,15 @@ static void ImGui::UpdateViewports() continue; } + const bool platform_funcs_available = (n == 0 || viewport->PlatformWindowCreated); if ((g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)) { - if (g.PlatformIO.Platform_GetWindowMinimized && (n == 0 || viewport->PlatformWindowCreated)) + if (g.PlatformIO.Platform_GetWindowMinimized && platform_funcs_available) viewport->PlatformWindowMinimized = g.PlatformIO.Platform_GetWindowMinimized(viewport); // Apply Position and Size (from Platform Window to ImGui) if requested. // We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities. - if (!viewport->PlatformWindowMinimized) + if (!viewport->PlatformWindowMinimized && platform_funcs_available) { if (viewport->PlatformRequestMove) viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport); @@ -7665,10 +7666,13 @@ void ImGui::UpdatePlatformWindows() if (g.PlatformIO.Platform_GetWindowFocus != NULL) { ImGuiViewportP* focused_viewport = NULL; - for (int i = 0; i < g.Viewports.Size && focused_viewport == NULL; i++) - if (g.Viewports[i]->PlatformUserData != NULL || g.Viewports[i]->PlatformHandle != NULL) - if (g.PlatformIO.Platform_GetWindowFocus(g.Viewports[i])) - focused_viewport = g.Viewports[i]; + for (int n = 0; n < g.Viewports.Size && focused_viewport == NULL; n++) + { + ImGuiViewportP* viewport = g.Viewports[n]; + if (n == 0 || viewport->PlatformWindowCreated) + if (g.PlatformIO.Platform_GetWindowFocus(viewport)) + focused_viewport = viewport; + } if (focused_viewport && g.PlatformLastFocusedViewport != focused_viewport->ID) { if (focused_viewport->LastFrontMostStampCount != g.WindowsFrontMostStampCount) @@ -7758,6 +7762,7 @@ void ImGui::DestroyPlatformWindow(ImGuiViewportP* viewport) viewport->PlatformHandle = NULL; viewport->RendererUserData = viewport->PlatformHandle = NULL; viewport->PlatformWindowCreated = false; + viewport->PlatformRequestClose = viewport->PlatformRequestMove = viewport->PlatformRequestResize = false; } void ImGui::DestroyPlatformWindows() diff --git a/imgui.h b/imgui.h index f77943a6f..1d9cdb763 100644 --- a/imgui.h +++ b/imgui.h @@ -2107,8 +2107,8 @@ struct ImGuiPlatformIO void (*Platform_SetWindowAlpha)(ImGuiViewport* vp, float alpha); // (Optional) Setup window transparency void (*Platform_RenderWindow)(ImGuiViewport* vp, void* render_arg); // (Optional) Setup for render (platform side) void (*Platform_SwapBuffers)(ImGuiViewport* vp, void* render_arg); // (Optional) Call Present/SwapBuffers (platform side) - float (*Platform_GetWindowDpiScale)(ImGuiViewport* vp); // (Optional) DPI handling: Return DPI scale for this viewport. 1.0f = 96 DPI. (FIXME-DPI) - void (*Platform_OnChangedViewport)(ImGuiViewport* vp); // (Optional) DPI handling: Called during Begin() every time the viewport we are outputting into changes, so back-end has a chance to swap fonts to adjust style. + float (*Platform_GetWindowDpiScale)(ImGuiViewport* vp); // (Optional) [BETA] (FIXME-DPI) DPI handling: Return DPI scale for this viewport. 1.0f = 96 DPI. IMPORTANT: this will be called _before_ the window is created, in which case the implementation is expected to use the viewport->Pos/Size fields to estimate DPI value. + void (*Platform_OnChangedViewport)(ImGuiViewport* vp); // (Optional) [BETA] (FIXME-DPI) DPI handling: Called during Begin() every time the viewport we are outputting into changes, so back-end has a chance to swap fonts to adjust style. void (*Platform_SetImeInputPos)(ImGuiViewport* vp, ImVec2 pos); // (Optional) Set IME (Input Method Editor, e.g. for Asian languages) input position, so text preview appears over the imgui input box. int (*Platform_CreateVkSurface)(ImGuiViewport* vp, ImU64 vk_inst, const void* vk_allocators, ImU64* out_vk_surface); // (Optional) For Renderer to call into Platform code diff --git a/imgui_internal.h b/imgui_internal.h index 65d3a5738..aff91eb19 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -848,7 +848,7 @@ struct ImGuiContext // Platform support ImVec2 PlatformImePos, PlatformImeLastPos; // Cursor position request & last passed to the OS Input Method Editor - ImGuiViewport* PlatformImePosViewport; + ImGuiViewportP* PlatformImePosViewport; // Settings bool SettingsLoaded;