我想创建一个 Direct2D GUI,以 DLL 的形式运行,并使用注入到其中的应用程序的 Direct3D 进行渲染。
我知道可以使用
ID2D1Factory::CreateDxgiSurfaceRenderTarget
创建一个 DXGI 表面,并将其用作 D2D 渲染目标,但这需要在 Direct3D 设备上开启 D3D11_CREATE_DEVICE_BGRA_SUPPORT
标志。
问题是应用程序创建设备时没有启用此标志,因此 ID2D1Factory::CreateDxgiSurfaceRenderTarget
会失败。
我正在尝试找到另一种方法,在应用程序窗口中进行绘制(内部或外部窗口的渲染目标),并且如果该窗口处于全屏状态,也能正常工作。
迄今为止,我尝试了以下替代方案:
1. 使用 ID2D1Factory::CreateDCRenderTarget
创建 D2D 渲染目标。这个方法可以工作,但是我渲染的部分会闪烁/快速显示和隐藏。我已经在 ID2D1RenderTarget::BeginDraw
之前调用了 ID2D1DCRenderTarget::BindDC
,但它仍然会闪烁,虽然比原来好一些。
2. 创建一个新窗口,始终位于所有其他窗口顶部,并在此窗口中进行 D2D 渲染,但是,如果应用程序进入全屏状态,则此窗口不会显示在屏幕上。
3. 使用启用了 D3D11_CREATE_DEVICE_BGRA_SUPPORT
标志的第二个 D3D 设备,并在窗口设备和自己之间共享 ID3D11Texture2D
资源,但我无法使其工作......没有多少关于如何做这件事的示例。我的想法是创建第二个设备,在该设备上使用 D2D 进行绘制,然后同步 2 个 D3D 设备-我遵循了 这个示例(使用 direct11)。
4. 创建一个 D2D 设备并共享 d2d 设备的数据与 d3d 设备, 但是当调用 ID2D1Factory1::CreateDevice
创建设备时它会失败,因为创建 D3D 设备时未启用 D3D11_CREATE_DEVICE_BGRA_SUPPORT
标志。我从 这个示例 开始。
我听说过硬件叠加,但它只适用于某些显卡,我认为我会遇到问题。参考链接:https://learn.microsoft.com/el-gr/windows/win32/medfound/hardware-overlay-support
目前我已经陷入了僵局,不知道该怎么办。有没有人有什么想法可以帮助我?
也许有一种方法可以在屏幕上绘图并工作,即使窗口是全屏状态下的?
D3D11CreateDeviceAndSwapChain
这样的 Windows 实现的 API 函数挂钩并不是很容易被检测到,因为微软正在使用 Windows 更新替换实现。在现代 Windows 中,微软甚至可以将实现移动到 DLL 中,而不会破坏使用 API 的程序的二进制兼容性。 - SoontsD3D11_RESOURCE_MISC_SHARED_NTHANDLE
标志。微软公司建议相反,但我记得使用NT句柄时会有兼容性问题。 - Soonts