网站博客自媒体轻松,化妆品网站推广策划书,新浪 sae wordpress,wordpress膘桴霜最ImGui 的主窗口是平台窗口#xff0c;默认是可见的#xff0c;这会影响视觉效果。那么怎么隐藏 ImGui 的主窗口呢#xff1f;
这很简单#xff0c;但是需要针对后端做一些修改。
本文仅介绍在 glfwopengl3 和 win32dx11 两种实现上如何修改。
在 win32dx11 实现上#…ImGui 的主窗口是平台窗口默认是可见的这会影响视觉效果。那么怎么隐藏 ImGui 的主窗口呢
这很简单但是需要针对后端做一些修改。
本文仅介绍在 glfwopengl3 和 win32dx11 两种实现上如何修改。
在 win32dx11 实现上隐藏主窗口首先需要找到 issues 中关于窗口背景透明度的临时解决方案实施这些方案。我们最好在窗口透明的基础上隐藏平台窗口。
你可以参考
Add support for transparent backbuffers to GLFW contexts (OpenGL3 and Vulkan) by SageMade · Pull Request #2766 · ocornut/imgui
为 DX12 后端添加 DirectComposition 用于透明度 作者 Soreepeong ·拉取请求 #7462 ·奥科努特/IMGUI
然后我们现在可以为 Viewports 开启混合透明每像素透明度。然后设置 clear_color 的Alpha 通道数值为0也就是完全透明。
这样主视口ID: 0x11111111上面将不会渲染任何颜色。
1隐藏主视口的平台窗口
随后我们将 Win32 窗口的设置进行调整主要是消除任务栏图标、窗口边框、标题栏、以及使得窗口不遮挡任何屏幕内容。
你可能会觉得使用 WS_EX_TRANSPATENT 有用其实它只在使用分层透明度时候比较合适而分层透明的效率没有混合透明高所以我没采用。
然后我们在平台窗口创建时候指定 WS_POPUP WS_EX_TOOLWINDOW 以便于不在任务栏显示平台窗口的图标。
设置窗口位置大小为 pos (0,0) , size (1,1)矩形大小不能为 0为 0 会导致 Imgui 的一些异常状态最终导致界面无法响应。
其实到这里已经实现了隐藏主视口的平台窗口了。但是有一些细节仍需要处理。
接下来在 ImGuiWindow 结构中添加一个字段 bool WindowInitFocused。在 imgui_internal.h 中添加声明
IMGUI_API void FocusRootPlatformWindow(ImGuiWindow* window);
然后在 imgui.cpp 的最后添加实现
void FocusRootPlatformWindow(ImGuiWindow* window)
{ImGuiContext g *GImGui;ImGuiWindow* rootWnd window-RootWindow;if (!rootWnd-WindowInitFocused) // I dont know why the status was overwritten{// Before updating the platform window data for the first frame, // PlatformUserData may be nullptr, and no actual processing should be performed at this time.if (rootWnd-Viewport-PlatformUserData nullptr) return;g.PlatformIO.Platform_SetWindowFocus(rootWnd-Viewport);rootWnd-WindowInitFocused true;}
}
这样在 每次 ImGui::Begin() 后都可以调用一次
ImGui::FocusRootPlatformWindow(ImGui::GetCurrentWindow());
来触发平台窗口的焦点获取ImGui 在获取焦点时候才会去检查更新 Viewport 和 Window 的关系。任务栏不显示图标的原因就在这里面但我还没有具体确定具体原因。强制平台窗口获取焦点暂时解决了任务栏不显示图标的问题。
当前的 WindowSelectViewport(window) 调用未来可能被重写会将 ImGui 窗口移动到新的 Viewport。不过存在一个 bug即使用 Imgui 窗口的 id, pos 和 size 作为 viewport 的相应参数这会导致什么呢平台窗口的边框和标题栏占据空间使得 imgui 窗口不对齐。
WindowSelectViewport(window);
SetCurrentViewport(window, window-Viewport);
window-FontDpiScale (g.IO.ConfigFlags ImGuiConfigFlags_DpiEnableScaleFonts) ? window-Viewport-DpiScale : 1.0f;
SetCurrentWindow(window);
目前一种方法是修复 WindowSelectViewport 中的 AddUpdateViewport 的最后一个参数由默认标识符改为 NoDecoration 即无平台窗口装饰。 WindowSelectViewport 修复 其实也不能说这里有错其实并没有错只是我们在使用的时候需要注意
需要在 WindowSelectViewport 调用之后为 Viewport 添加 ImGuiViewportFlags_NoDecoration 这个标识符来正确去除平台窗口的装饰而不是自己去调用 SetWindowLongPtr 这样的 api
WindowSelectViewport(window);
window-Viewport-Flags | ImGuiViewportFlags_NoDecoration;
另一种隐藏平台窗口的实现是使用分层透明这里我也介绍一下就是在 Win32 窗口创建时使用纯色画刷然后使用 SetLayeredWindowAttribute 将背景色去除将平台窗口设置为无边框全屏窗口注意不是独占显示器的窗口然后给窗口添加 WS_EX_TRANSPARENT 样式这将允许在窗口完全透明的位置穿透鼠标、键盘消息。看上去就像没有窗口了一般。
diff --git a/examples/example_win32_directx11/main.cpp b/examples/example_win32_directx11/main.cpp
index fe462e74..b73f127a 100644
--- a/examples/example_win32_directx11/main.cppb/examples/example_win32_directx11/main.cpp-28,7 28,7 int main(int, char**)// Create application windowWNDCLASSEX wc { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T(ImGui Example), NULL };::RegisterClassEx(wc);
- HWND hwnd ::CreateWindow(wc.lpszClassName, _T(Dear ImGui DirectX11 Example), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);HWND hwnd ::CreateWindowEx(WS_EX_LAYERED, wc.lpszClassName, _T(Dear ImGui DirectX11 Example), WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, wc.hInstance, NULL);// Initialize Direct3Dif (!CreateDeviceD3D(hwnd))-75,7 75,7 int main(int, char**)// Our statebool show_demo_window true;bool show_another_window false;
- ImVec4 clear_color ImVec4(0.45f, 0.55f, 0.60f, 1.00f);float clear_color[] { 0, 0, 0, 0 };// Main loopMSG msg;-115,7 115,7 int main(int, char**)ImGui::Checkbox(Another Window, show_another_window);ImGui::SliderFloat(float, f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
- ImGui::ColorEdit3(clear color, (float*)clear_color); // Edit 3 floats representing a colorImGui::ColorEdit3(clear color, clear_color); // Edit 3 floats representing a colorif (ImGui::Button(Button)) // Buttons return true when clicked (most widgets return true when edited/activated)counter;-139,11 139,28 int main(int, char**)// RenderingImGui::Render();g_pd3dDeviceContext-OMSetRenderTargets(1, g_mainRenderTargetView, NULL);
- g_pd3dDeviceContext-ClearRenderTargetView(g_mainRenderTargetView, (float*)clear_color);g_pd3dDeviceContext-ClearRenderTargetView(g_mainRenderTargetView, clear_color);ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());BLENDFUNCTION blend { AC_SRC_OVER, 0, 0, AC_SRC_ALPHA };POINT pt { 0, 0 };SIZE sz { 0, 0 };IDXGISurface1 *pSurface NULL;HDC hDC NULL;g_pSwapChain-Present(1, 0); // Present with vsync//g_pSwapChain-Present(0, 0); // Present without vsyncg_pSwapChain-GetBuffer(0, IID_PPV_ARGS(pSurface));DXGI_SURFACE_DESC desc;pSurface-GetDesc(desc);sz.cx desc.Width;sz.cy desc.Height;pSurface-GetDC(FALSE, hDC);::UpdateLayeredWindow(hwnd, nullptr, nullptr, sz, hDC, pt, 0, blend, ULW_COLORKEY);pSurface-ReleaseDC(nullptr);pSurface-Release();}// Cleanup-162,16 179,18 int main(int, char**)bool CreateDeviceD3D(HWND hWnd){RECT rcWnd;GetWindowRect(hWnd, rcWnd);// Setup swap chainDXGI_SWAP_CHAIN_DESC sd;ZeroMemory(sd, sizeof(sd));sd.BufferCount 2;
- sd.BufferDesc.Width 0;
- sd.BufferDesc.Height 0;
- sd.BufferDesc.Format DXGI_FORMAT_R8G8B8A8_UNORM;sd.BufferDesc.Width rcWnd.right - rcWnd.left;sd.BufferDesc.Height rcWnd.bottom - rcWnd.top;sd.BufferDesc.Format DXGI_FORMAT_B8G8R8A8_UNORM;sd.BufferDesc.RefreshRate.Numerator 60;sd.BufferDesc.RefreshRate.Denominator 1;
- sd.Flags DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;sd.Flags DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;sd.BufferUsage DXGI_USAGE_RENDER_TARGET_OUTPUT;sd.OutputWindow hWnd;sd.SampleDesc.Count 1; glfwopengl3 实现上
使用 ImGui 的 docking 分支需要 Multi Viewports 功能官方描述Multi-viewports is the feature allowing you to seamlessly extract Dear ImGui windows out of your main rendering context.
然后使用 glfw 创建一个 offscreen context 即在创建窗口前加入以下代码即可。
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // 设置 offscreen context 的标志位// 需要在创建窗口前设置标志
// Create window with graphics context
GLFWwindow* window glfwCreateWindow(200, 1, Dear ImGui GLFWOpenGL3 example, NULL, NULL);
同时记得检查代码中的这一部分内容检查有没有启动 docking 和 viewport 支持假如这一段编译错误说明还没有切换到 docking 分支。
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO io ImGui::GetIO();
(void)io; // 避免 unused 变量的警告
io.ConfigFlags | ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags | ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
io.ConfigFlags | ImGuiConfigFlags_DockingEnable; // !!! 启用 docking 功能的支持
io.ConfigFlags | ImGuiConfigFlags_ViewportsEnable; // !!! 启用 viewport 功能的支持
io.ConfigViewportsNoAutoMerge true; // 参考评论建议加上这行
//io.ConfigViewportsNoTaskBarIcon true;
效果图 glfwopengl3 实现 此方法来源https://www.zhihu.com/question/336183356/answer/1948292375。
最后貌似还有一种折中的办法就是把 ImGui Main Window 的大小绘制得和平台窗口一样大即可并且去除平台窗口的边框装饰将平台窗口改成背景透明使得拖动时候不会“穿帮”。
例如 dx11 的实现
主要通过移除 imgui 窗口标题栏并使其填充整个 DirectX11 窗口将两个窗口“融合”在一起。
要实现此操作只需在 ImGui::Begin()中将 ImGuiWindowFlags_NoTitleBar 标志传递给 ImGui 窗口根据需要可能还需要 ImGuiWindowFlags_NoMove 和 ImGuiWindowFlags_NoResize
在 ImGui::Begin()之前添加 ImGui::SetNextWindowPos()和 ImGui::SetNextWindowSize()指令将 imgui 窗口放置在左上角并调整其大小以适应 DirectX11 窗口
最终你应该有类似下面的东西
ImGuiWindowFlags window_flags 0;
window_flags | ImGuiWindowFlags_NoTitleBar;
window_flags | ImGuiWindowFlags_NoMove;
window_flags | ImGuiWindowFlags_NoResize;while(...) {...ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f)); // place the next window in the top left corner (0,0)ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize); // make the next window fullscreenImGui::Begin(imgui window, NULL, window_flags) // create a window...
}
该方法来自
https://stackoverflow.com/questions/74954814/remove-the-parent-default-window-in-imgui。
2实现遍历窗口列表新增窗口关闭检测模仿 raylib
添加下面代码函数名也可以叫 GetWin32WindowShouldClose() / GetXXWindowShouldClose()。glfw 里面有一个叫 glfwSetWindowShouldClose 的实现来着。
namespace ImGui {ImVectorImGuiWindow* GetImGuiWindowList(){ImGuiContext g *GImGui;return g.Windows;}bool WindowCanShutdownNow(bool* p_open_main){bool window_has_active false;if (!p_open_main || !(*p_open_main)){ImVectorImGuiWindow* windows GetImGuiWindowList();if (!windows.size()){return false;}for (const auto window : windows){// The Debug##Default window ImGui creates internally in NewFrame()// It is hidden and has no owner Viewport.if (window-Name !stricmp(window-Name, Debug##Default))continue;//if (window-Active window-ViewportOwned)if (window-Active !window-Hidden){window_has_active true;break;}}}else{return false;}return !window_has_active;}
}
GetImGuiWindowList 在 imgui_internal.h 中声明WindowCanShutdownNow 在 imgui.h 中声明。
窗口关闭检测怎么使用
在消息循环中添加这样的代码
while (!done)
{// Poll and handle messages (inputs, window resize, etc.)// See the WndProc() function below for our to dispatch events to the Win32 backend.// 轮询和处理消息输入、窗口大小调整等// 请参阅位于此页下方的 WndProc() 函数了解如何将事件调度到 Win32 后端。MSG msg;while (::PeekMessage(msg, nullptr, 0U, 0U, PM_REMOVE)){::TranslateMessage(msg);::DispatchMessage(msg);if (msg.message WM_QUIT)done true;}if (done)break;// 下面是添加的窗口关闭检测当所有 Imgui 窗口被关闭时自动关闭平台窗口并使得消息循环得以正常结束。if (ImGui::WindowCanShutdownNow(show_main_window))PostMessageW(hwnd, WM_CLOSE, NULL, NULL);......
}
最终的效果 实现的多视口隐藏主视口背景窗口 本文出处链接https://blog.csdn.net/qq_59075481/article/details/145773493。 文章转载自: http://www.morning.ychoise.com.gov.cn.ychoise.com http://www.morning.dmzqd.cn.gov.cn.dmzqd.cn http://www.morning.wljzr.cn.gov.cn.wljzr.cn http://www.morning.wmsgt.cn.gov.cn.wmsgt.cn http://www.morning.kpcdc.cn.gov.cn.kpcdc.cn http://www.morning.jcrfm.cn.gov.cn.jcrfm.cn http://www.morning.dqxph.cn.gov.cn.dqxph.cn http://www.morning.sfnr.cn.gov.cn.sfnr.cn http://www.morning.pzwfw.cn.gov.cn.pzwfw.cn http://www.morning.wphzr.cn.gov.cn.wphzr.cn http://www.morning.pqkyx.cn.gov.cn.pqkyx.cn http://www.morning.pqhfx.cn.gov.cn.pqhfx.cn http://www.morning.jqhrk.cn.gov.cn.jqhrk.cn http://www.morning.trtxt.cn.gov.cn.trtxt.cn http://www.morning.ndpzm.cn.gov.cn.ndpzm.cn http://www.morning.mzydm.cn.gov.cn.mzydm.cn http://www.morning.srrzb.cn.gov.cn.srrzb.cn http://www.morning.rszyf.cn.gov.cn.rszyf.cn http://www.morning.pmlgr.cn.gov.cn.pmlgr.cn http://www.morning.grjh.cn.gov.cn.grjh.cn http://www.morning.pcbfl.cn.gov.cn.pcbfl.cn http://www.morning.plznfnh.cn.gov.cn.plznfnh.cn http://www.morning.yhwmg.cn.gov.cn.yhwmg.cn http://www.morning.easiuse.com.gov.cn.easiuse.com http://www.morning.mdpcz.cn.gov.cn.mdpcz.cn http://www.morning.rxhn.cn.gov.cn.rxhn.cn http://www.morning.hpprx.cn.gov.cn.hpprx.cn http://www.morning.pmghz.cn.gov.cn.pmghz.cn http://www.morning.tqdlk.cn.gov.cn.tqdlk.cn http://www.morning.pbsfq.cn.gov.cn.pbsfq.cn http://www.morning.twmp.cn.gov.cn.twmp.cn http://www.morning.jrpmf.cn.gov.cn.jrpmf.cn http://www.morning.mdwtm.cn.gov.cn.mdwtm.cn http://www.morning.wcyr.cn.gov.cn.wcyr.cn http://www.morning.snygg.cn.gov.cn.snygg.cn http://www.morning.mmhaoma.com.gov.cn.mmhaoma.com http://www.morning.jngdh.cn.gov.cn.jngdh.cn http://www.morning.plqsz.cn.gov.cn.plqsz.cn http://www.morning.mhnrx.cn.gov.cn.mhnrx.cn http://www.morning.c7501.cn.gov.cn.c7501.cn http://www.morning.wdlyt.cn.gov.cn.wdlyt.cn http://www.morning.brsgw.cn.gov.cn.brsgw.cn http://www.morning.blznh.cn.gov.cn.blznh.cn http://www.morning.qsctt.cn.gov.cn.qsctt.cn http://www.morning.rfyk.cn.gov.cn.rfyk.cn http://www.morning.qtfss.cn.gov.cn.qtfss.cn http://www.morning.zwhtr.cn.gov.cn.zwhtr.cn http://www.morning.ztmnr.cn.gov.cn.ztmnr.cn http://www.morning.dnzyx.cn.gov.cn.dnzyx.cn http://www.morning.mbrbg.cn.gov.cn.mbrbg.cn http://www.morning.ktlxk.cn.gov.cn.ktlxk.cn http://www.morning.wtxdp.cn.gov.cn.wtxdp.cn http://www.morning.brnwc.cn.gov.cn.brnwc.cn http://www.morning.nmtyx.cn.gov.cn.nmtyx.cn http://www.morning.sfwd.cn.gov.cn.sfwd.cn http://www.morning.djgrg.cn.gov.cn.djgrg.cn http://www.morning.kwhrq.cn.gov.cn.kwhrq.cn http://www.morning.fbmrz.cn.gov.cn.fbmrz.cn http://www.morning.zdydj.cn.gov.cn.zdydj.cn http://www.morning.mlwpr.cn.gov.cn.mlwpr.cn http://www.morning.jlnlr.cn.gov.cn.jlnlr.cn http://www.morning.txmlg.cn.gov.cn.txmlg.cn http://www.morning.bswnf.cn.gov.cn.bswnf.cn http://www.morning.rkypb.cn.gov.cn.rkypb.cn http://www.morning.mnnxt.cn.gov.cn.mnnxt.cn http://www.morning.zyslyq.cn.gov.cn.zyslyq.cn http://www.morning.lsmnn.cn.gov.cn.lsmnn.cn http://www.morning.zcqbx.cn.gov.cn.zcqbx.cn http://www.morning.hsdhr.cn.gov.cn.hsdhr.cn http://www.morning.wcrcy.cn.gov.cn.wcrcy.cn http://www.morning.mhnr.cn.gov.cn.mhnr.cn http://www.morning.hgscb.cn.gov.cn.hgscb.cn http://www.morning.txfxy.cn.gov.cn.txfxy.cn http://www.morning.qhrdx.cn.gov.cn.qhrdx.cn http://www.morning.dpppx.cn.gov.cn.dpppx.cn http://www.morning.kyctc.cn.gov.cn.kyctc.cn http://www.morning.spqbp.cn.gov.cn.spqbp.cn http://www.morning.yhwmg.cn.gov.cn.yhwmg.cn http://www.morning.lcplz.cn.gov.cn.lcplz.cn http://www.morning.ryfq.cn.gov.cn.ryfq.cn