mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-01 03:19:12 +08:00
Viewport: per-viewport overlay draw list created on demand. With this pattern it'll be easier to consider adding more (e.g. background draw list). (#545)
This commit is contained in:
parent
83bd3595a4
commit
8be6f40ae1
65
imgui.cpp
65
imgui.cpp
@ -2717,17 +2717,32 @@ int ImGui::GetFrameCount()
|
||||
return GImGui->FrameCount;
|
||||
}
|
||||
|
||||
ImDrawList* ImGui::GetOverlayDrawList(ImGuiWindow* window)
|
||||
ImDrawList* ImGui::GetOverlayDrawList(ImGuiViewportP* viewport)
|
||||
{
|
||||
IM_ASSERT(window && window->Viewport);
|
||||
return window->Viewport->OverlayDrawList;
|
||||
// Create the draw list on demand, because it is not frequently used for all viewports
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (viewport->OverlayDrawList == NULL)
|
||||
{
|
||||
viewport->OverlayDrawList = IM_NEW(ImDrawList)(&g.DrawListSharedData);
|
||||
viewport->OverlayDrawList->_OwnerName = "##Overlay";
|
||||
}
|
||||
|
||||
// Our ImDrawList system requires that there is always a command
|
||||
if (viewport->LastFrameOverlayDrawList != g.FrameCount)
|
||||
{
|
||||
viewport->OverlayDrawList->Clear();
|
||||
viewport->OverlayDrawList->PushTextureID(g.IO.Fonts->TexID);
|
||||
viewport->OverlayDrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false);
|
||||
viewport->OverlayDrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0);
|
||||
viewport->LastFrameOverlayDrawList = g.FrameCount;
|
||||
}
|
||||
return viewport->OverlayDrawList;
|
||||
}
|
||||
|
||||
ImDrawList* ImGui::GetOverlayDrawList()
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
IM_ASSERT(window && window->Viewport);
|
||||
return window->Viewport->OverlayDrawList;
|
||||
return GetOverlayDrawList(window->Viewport);
|
||||
}
|
||||
|
||||
ImDrawListSharedData* ImGui::GetDrawListSharedData()
|
||||
@ -3633,15 +3648,6 @@ void ImGui::RenderPlatformWindowsDefault(void* platform_render_arg, void* render
|
||||
}
|
||||
}
|
||||
|
||||
static void SetupOverlayDrawList(ImDrawList* draw_list, ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
draw_list->Clear();
|
||||
draw_list->PushTextureID(g.IO.Fonts->TexID);
|
||||
draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false);
|
||||
draw_list->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0);
|
||||
}
|
||||
|
||||
static void NewFrameUpdateMouseInputs()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -3832,7 +3838,6 @@ void ImGui::NewFrame()
|
||||
ImGuiViewportP* viewport = g.Viewports[n];
|
||||
viewport->DrawData = NULL;
|
||||
viewport->DrawDataP.Clear();
|
||||
SetupOverlayDrawList(viewport->OverlayDrawList, viewport);
|
||||
}
|
||||
|
||||
// Clear reference to active widget if the widget isn't alive anymore
|
||||
@ -4051,7 +4056,7 @@ void ImGui::Initialize(ImGuiContext* context)
|
||||
g.SettingsHandlers.push_front(ini_handler);
|
||||
|
||||
// Create default viewport
|
||||
ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)(&g.DrawListSharedData);
|
||||
ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)();
|
||||
viewport->ID = IMGUI_VIEWPORT_DEFAULT_ID;
|
||||
viewport->Idx = 0;
|
||||
g.Viewports.push_back(viewport);
|
||||
@ -4563,7 +4568,7 @@ void ImGui::Render()
|
||||
ImVec2 pos = (g.MousePosViewport == viewport) ? main_pos : ConvertPlatformPosToViewportPos(ConvertViewportPosToPlatformPos(main_pos, g.MousePosViewport), viewport);
|
||||
if (viewport->GetRect().Overlaps(ImRect(pos, pos + ImVec2(2,2)*sc + size * sc)))
|
||||
{
|
||||
ImDrawList* draw_list = viewport->OverlayDrawList;
|
||||
ImDrawList* draw_list = GetOverlayDrawList(viewport);
|
||||
draw_list->PushTextureID(tex_id);
|
||||
draw_list->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
|
||||
draw_list->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
|
||||
@ -4580,7 +4585,8 @@ void ImGui::Render()
|
||||
{
|
||||
ImGuiViewportP* viewport = g.Viewports[n];
|
||||
viewport->DrawDataBuilder.FlattenIntoSingleLayer();
|
||||
AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], viewport->OverlayDrawList);
|
||||
if (viewport->OverlayDrawList != NULL)
|
||||
AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetOverlayDrawList(viewport));
|
||||
SetupViewportDrawData(viewport, &viewport->DrawDataBuilder.Layers[0]);
|
||||
g.IO.MetricsRenderVertices += viewport->DrawData->TotalVtxCount;
|
||||
g.IO.MetricsRenderIndices += viewport->DrawData->TotalIdxCount;
|
||||
@ -4683,7 +4689,7 @@ ImGuiViewportP* ImGui::Viewport(ImGuiWindow* window, ImGuiID id, ImGuiViewportFl
|
||||
else
|
||||
{
|
||||
// New viewport
|
||||
viewport = IM_NEW(ImGuiViewportP)(&g.DrawListSharedData);
|
||||
viewport = IM_NEW(ImGuiViewportP)();
|
||||
viewport->ID = id;
|
||||
viewport->Idx = g.Viewports.Size;
|
||||
viewport->Pos = ImVec2(g.Viewports.back()->GetNextX(), 0.0f);
|
||||
@ -4691,11 +4697,9 @@ ImGuiViewportP* ImGui::Viewport(ImGuiWindow* window, ImGuiID id, ImGuiViewportFl
|
||||
g.Viewports.push_back(viewport);
|
||||
|
||||
// We normally setup for all viewports in NewFrame() but here need to handle the mid-frame creation of a new viewport.
|
||||
// 1. We need to extend the fullscreen clip rect so the OverlayDrawList clip is correct for that the first frame
|
||||
// 2. Our ImDrawList system requires that there is always a command, SetupOverlayDrawList() effectively does that by setting up texture and clip rect
|
||||
// We need to extend the fullscreen clip rect so the OverlayDrawList clip is correct for that the first frame
|
||||
g.DrawListSharedData.ClipRectFullscreen.z = ImMax(g.DrawListSharedData.ClipRectFullscreen.z, viewport->Pos.x + viewport->Size.x);
|
||||
g.DrawListSharedData.ClipRectFullscreen.w = ImMax(g.DrawListSharedData.ClipRectFullscreen.w, viewport->Pos.y + viewport->Size.y);
|
||||
SetupOverlayDrawList(viewport->OverlayDrawList, viewport);
|
||||
}
|
||||
|
||||
IM_ASSERT(viewport->Pos.y == 0.0f);
|
||||
@ -6699,12 +6703,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
|
||||
// Draw modal window background (darkens what is behind them, all viewports)
|
||||
if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow() && window->HiddenFrames <= 0)
|
||||
{
|
||||
window->DrawList->AddRectFilled(viewport_rect.Min, viewport_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio));
|
||||
for (int viewport_n = 0; viewport_n < g.Viewports.Size; viewport_n++)
|
||||
if (g.Viewports[viewport_n] != window->Viewport)
|
||||
g.Viewports[viewport_n]->OverlayDrawList->AddRectFilled(g.Viewports[viewport_n]->Pos, g.Viewports[viewport_n]->Pos + g.Viewports[viewport_n]->Size, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio));
|
||||
}
|
||||
{
|
||||
ImGuiViewportP* viewport = g.Viewports[viewport_n];
|
||||
ImDrawList* draw_list = (viewport == window->Viewport) ? window->DrawList : GetOverlayDrawList(viewport);
|
||||
draw_list->AddRectFilled(viewport->Pos, viewport->Pos + viewport->Size, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio));
|
||||
}
|
||||
|
||||
// Draw navigation selection/windowing rectangle background
|
||||
if (g.NavWindowingTarget == window)
|
||||
@ -14060,7 +14064,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
return;
|
||||
}
|
||||
|
||||
ImDrawList* overlay_draw_list = viewport->OverlayDrawList; // Render additional visuals into the top-most draw list
|
||||
ImDrawList* overlay_draw_list = GetOverlayDrawList(viewport); // Render additional visuals into the top-most draw list
|
||||
if (window && ImGui::IsItemHovered())
|
||||
overlay_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255));
|
||||
if (!node_open)
|
||||
@ -14245,8 +14249,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
char buf[32];
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "%d", window->BeginOrderWithinContext);
|
||||
float font_size = ImGui::GetFontSize() * 2;
|
||||
window->Viewport->OverlayDrawList->AddRectFilled(window->PosFloat, window->PosFloat + ImVec2(font_size, font_size), IM_COL32(200, 100, 100, 255));
|
||||
window->Viewport->OverlayDrawList->AddText(NULL, font_size, window->PosFloat, IM_COL32(255, 255, 255, 255), buf);
|
||||
ImDrawList* overlay_draw_list = GetOverlayDrawList(window->Viewport);
|
||||
overlay_draw_list->AddRectFilled(window->PosFloat, window->PosFloat + ImVec2(font_size, font_size), IM_COL32(200, 100, 100, 255));
|
||||
overlay_draw_list->AddText(NULL, font_size, window->PosFloat, IM_COL32(255, 255, 255, 255), buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -516,6 +516,7 @@ struct ImGuiViewportP : public ImGuiViewport
|
||||
int Idx;
|
||||
int LastFrameActive; // Last frame number this viewport was activated by a window
|
||||
int LastFrameAsRefViewport; // Last frame number this viewport was io.MouseViewportRef
|
||||
int LastFrameOverlayDrawList;
|
||||
ImGuiID LastNameHash;
|
||||
float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent)
|
||||
float LastAlpha;
|
||||
@ -525,8 +526,8 @@ struct ImGuiViewportP : public ImGuiViewport
|
||||
ImDrawDataBuilder DrawDataBuilder;
|
||||
ImVec2 RendererLastSize;
|
||||
|
||||
ImGuiViewportP(ImDrawListSharedData* draw_list_shared_data) { Idx = 1; LastFrameActive = LastFrameAsRefViewport = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; Window = NULL; OverlayDrawList = IM_NEW(ImDrawList)(draw_list_shared_data); OverlayDrawList->_OwnerName = "##Overlay"; RendererLastSize = ImVec2(-1.0f,-1.0f); }
|
||||
~ImGuiViewportP() { IM_DELETE(OverlayDrawList); }
|
||||
ImGuiViewportP() { Idx = 1; LastFrameActive = LastFrameAsRefViewport = LastFrameOverlayDrawList = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; Window = NULL; OverlayDrawList = NULL; RendererLastSize = ImVec2(-1.0f,-1.0f); }
|
||||
~ImGuiViewportP() { if (OverlayDrawList) IM_DELETE(OverlayDrawList); }
|
||||
ImRect GetRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
|
||||
float GetNextX() const { const float SPACING = 4.0f; return Pos.x + Size.x + SPACING; }
|
||||
};
|
||||
@ -1099,7 +1100,8 @@ namespace ImGui
|
||||
IMGUI_API void PopItemFlag();
|
||||
|
||||
IMGUI_API void SetCurrentFont(ImFont* font);
|
||||
IMGUI_API ImDrawList* GetOverlayDrawList(ImGuiWindow* window);
|
||||
IMGUI_API ImDrawList* GetOverlayDrawList(ImGuiViewportP* viewport);
|
||||
inline ImDrawList* GetOverlayDrawList(ImGuiWindow* window) { return GetOverlayDrawList(window->Viewport); }
|
||||
|
||||
IMGUI_API void OpenPopupEx(ImGuiID id);
|
||||
IMGUI_API void ClosePopup(ImGuiID id);
|
||||
|
Loading…
Reference in New Issue
Block a user