我想向整个 Windows 桌面添加动态视频效果。
我希望能够将屏幕变成灰色,将边缘倾斜并添加一些扫描线,使其看起来像旧的 CRT 屏幕,或者使屏幕出现故障,就像他们在不懂技术的电影中展示被黑客入侵的系统一样, ETC。
影响本身超出了这个问题的范围。这个问题是如何应用它们,即如何获取 Windows 生成的桌面图像,应用我的效果并将结果呈现在同一显示器上。
我知道几种可能有效的方法。
- 挂钩绘制内容的 WinAPI 调用。
- 创建一个假的辅助显示器,使其成为主要显示设备,从中获取视频流,应用我的效果,并在真实显示器上呈现
- 创建应用效果的自定义显示驱动程序。
所有这些都有缺点:复杂性、驱动程序签名要求、复杂的设置。有更好的方法来实现我想要的吗?
1 非常难,不同的 API 太多。
2 困难的部分是制作假显示器。如果您购买名为“HDMI 虚拟插头”的 10 美元设备,它将变得相对简单,并且具有 100% 记录的 API。使用桌面复制API获取显示器1的纹理,应用你想要的任何效果并在显示器2上显示。如果你想要良好的性能,你最好完全在GPU上实现处理,例如使用自定义像素着色器渲染四边形。
3 可以,但是很难做到。
还有另一种方法。实现和使用未记录的 API 很棘手,但根据我的经验相当可靠,至少在 Windows 7 上是如此。编写一个将自身注入到 dwm.exe 中的 DLL。这是一个 Windows 进程“桌面窗口管理器”,它组成了桌面上可见的所有内容。 DLL注入后,创建一个新线程,在该线程中调用D3D11CreateDeviceAndSwapChain,然后使用例如MinHook https://github.com/TsudaKageyu/minhook拦截Present
,并且理想情况下还ResizeBuffers
的方法IDXGISwapChain
界面。如果成功,dwm.exe 将在每次呈现框架或桌面分辨率更改时调用 DLL 中的函数。然后,在当前的功能中,您可以做您的事情,例如添加另一个渲染通道来实现您的效果,然后调用原始实现以实际将结果呈现到桌面。
这在理论上很容易,但在实践中实施起来却相当棘手。例如。调试 dwm.exe 很困难,您必须依赖日志记录,或者可能使用带有远程调试器的虚拟机。此外,这也不能跨 Windows 版本移植。另一个限制是,它不适用于视频游戏等全屏应用程序,它们会绕过 dwm.exe。对于视频游戏,仅适用于游戏中的“无边框全屏窗口”设置。
Update:另一种方法,简单得多。创建一个具有每像素透明度的最顶层全屏窗口。操作系统支持它们数十年,设置WS_EX_LAYERED
and WS_EX_TRANSPARENT
扩展样式位。你将无法进行灰度处理,因为你只能覆盖你的东西,而不能读取下面的内容,但边缘、扫描线和毛刺是完全可行的。为了获得最佳性能,请使用一些以 GPU 为中心的 API 来渲染该窗口,例如C++ 中的 Direct2D 或 D3D。调试起来也更容易,可以使用 2 个显示器,也可以放置透明窗口,使其占据角落的一个矩形,为 IDE 留下足够的屏幕空间。这是一个例子 https://github.com/DmitrySikorsky/StarryNight(不是我的)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)