Direct2D与Direct3D互操作方案求助:无BGRA支持标志下全屏D2D绘制
可行实现方案
方案1:Hook目标应用的D3D设备创建流程(优先选择)
直接Hook目标应用调用的D3D11CreateDevice或D3D11CreateDeviceAndSwapChain函数,在传入的创建标志位中额外或上D3D11_CREATE_DEVICE_BGRA_SUPPORT。
- 该标志仅用于支持DXGI表面与GDI/D2D的互操作,不会对原应用的D3D渲染逻辑产生负面影响,99%以上的常规应用添加该标志后可正常运行
- 补全标志后即可直接用
ID2D1Factory::CreateDxgiSurfaceRenderTarget创建绑定到目标应用后备缓冲的D2D渲染目标,绘制无闪烁,天然支持窗口/全屏独占模式
方案2:跨设备共享纹理修正方案(无法Hook设备创建时选择)
之前尝试的共享纹理方案失败大概率是参数配置问题,按以下步骤调整即可正常运行:
- 枚举目标D3D设备所属的显卡适配器,在同一块适配器上创建你的专属D3D11设备,创建时添加
D3D11_CREATE_DEVICE_BGRA_SUPPORT标志 - 创建
ID3D11Texture2D共享纹理时,必须添加D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX标志,格式固定为DXGI_FORMAT_B8G8R8A8_UNORM,分辨率与目标窗口分辨率一致 - 在你自己的设备上用D2D绘制内容到共享纹理,完成后通过关键区互斥锁释放纹理所有权
- Hook目标应用的
Present调用,在其执行 Present 前,用目标设备打开共享纹理,将纹理内容绘制到目标应用的后备缓冲上
- 该方案无需修改原设备的任何属性,兼容性强,支持所有窗口/全屏场景
方案3:后备兼容方案(适配低版本D3D目标)
如果目标应用使用D3D9等更低版本的D3D接口:
- 调用
IDirect3DDevice9::GetBackBuffer拿到目标应用的后备缓冲 - 创建D2D WIC位图渲染目标,在内存中完成所有D2D绘制
- 将绘制完成的像素数据拷贝到D3D纹理,再绘制到目标后备缓冲
- 性能略低于前两种方案,但无闪烁问题,兼容所有场景
注意事项
- 所有绘制逻辑必须放在目标应用渲染线程的
Present调用前执行,不要单独开线程绘制,避免画面不同步导致的闪烁或撕裂 - 目标应用切换窗口/全屏模式时,需要同步销毁重建你的渲染目标、共享纹理等资源,避免资源失效
- 共享纹理方案中,两个D3D设备的特性等级需要保持兼容,避免纹理打开失败
内容的提问来源于stack exchange,提问作者mod Zz
相关产品推荐
相关产品推荐

