Rick 的回答谈到了如果您不关心失去硬件加速可以使用的方法。我专注于如何使用大量的 GPU 加速来实现这一点。
为了保持渲染硬件加速并获得最佳性能,您将希望从 ID2DHwndRenderTarget 切换到使用更新的 ID2DDevice 和 ID2DDeviceContext 接口。老实说,它不会为您的代码添加更多逻辑,并且性能优势是巨大的。它也适用于带有平台更新的 Windows 7。总结一下过程:
- 在创建 D2D 工厂时创建 DXGI 工厂。
- 创建一个 D3D11 设备和一个 D2D 设备进行匹配。
- 使用 DXGI 工厂和 D3D 设备创建交换链。
- 向交换链请求其后台缓冲区并将其包装在 D2D 位图中。
- 在调用 BeginDraw() 和 EndDraw() 之间像以前一样渲染。请记住取消绑定后台缓冲区并销毁包装它的 D2D 位图!
- 在交换链上调用 Present() 以查看结果。
- 从 4 开始重复。
完成此操作后,您已经解锁了许多可能的解决方案。解决您的确切问题(交换颜色通道)的最简单和最有效的方法可能是使用颜色矩阵效果作为提到的其他答案之一。重要的是要认识到您需要使用更新的 ID2DDeviceContext 接口而不是 ID2DHwndRenderTarget 来获得它。如果您愿意,还有许多其他效果可以执行更复杂的操作。以下是一些对简单像素操作最有用的方法:
对于一般解决直接操作像素而不放弃硬件加速或进行大量复制的问题,有两种选择。首先是编写一个像素着色器并将其包装在一个完全自定义的 D2D 效果中。这不仅仅是在 CPU 上获取像素缓冲区并进行老式的位混搭,而是在 GPU 上完成所有这些工作要快得多。D2D 效果框架还使得将您的效果重用于其他目的、将其与其他效果组合等变得超级简单。
对于那些您绝对必须进行 CPU 像素操作但仍需要大幅加速的时候,您可以管理自己的可映射 D3D11 纹理。例如,如果您想从 CPU 异步操作纹理资源,则可以使用暂存纹理。还有另一个更详细的答案。有关详细信息,请参阅ID3D11Texture2D。