如何使用IDXGISwapChain和ID3D11Device/ID3D11DeviceContext呈现到不同的窗口



以前,当我构建工具时,我使用了D3D版本9,其中对Present()的调用可以接受目标窗口和矩形,因此您可以从单个设备绘制到许多不同的窗口。当使用D3D加速桌面应用程序和/或构建工具而不是游戏时,这是非常棒的!

我之前也用D3D11构建了一个游戏渲染器,这也很棒,因为状态管理和线程接口设计得很好,你甚至可以瞄准D3D 9级硬件,这在市面上仍然很常见(与D3D 10相反,它只能瞄准10级或更高)。

然而,现在我想用D3D11构建一个工具。不幸的是,从D3D11CreateDeviceAndSwapChain()返回的IDXGISwapChain似乎"记住"它的HWND,并且只想呈现给该窗口。这是非常不方便的,因为我可能有大量的窗口,每个窗口都需要绘制相当简单的图形,并且只能响应WM_PAINT(再次说明,这是用于工具,而不是游戏)。

我想做的是保存回缓冲内存。具体来说,我曾经能够创建一个单一的后台缓冲区,桌面大小,我知道它可以覆盖所有渲染需求,然后这将是分配的单个副本。即使有10个重叠的窗口,它们都通过相同的后端缓冲区呈现,所以除了初始分配之外不会浪费内存。我可以创建不是交换链的纹理,并将它们用作"渲染目标",但我找不到一种很好的方法来呈现任意客户端窗口的任意矩形,而不读取位图并将其复制到DIBSection中,这将是非常低效的。此外,没有办法创建许多交换链,并让它们共享相同的回缓冲区。

我能做的最好的事情是为每个窗口创建一个交换链,并将每个交换链的后缓冲调整到非常小的大小,除非我渲染到交换链,此时我调整它的大小以匹配窗口。然而,这似乎效率低下,因为调整目标大小并不是一个"自由"的操作。那么,有没有更好的办法呢?

我最终得到的答案是为每个单独的显示区域创建一个后缓冲区,而不是将其大小设置为后缓冲区。我想,在一个桌面构图和透明度可以在我背后"为所欲为"的世界里,这可能对系统有帮助。学会爱上VVM系统,我猜:-)(VVM for Virtual Video Memory)

最新更新