当前位置: 首页 > news >正文

使用 Direct3D11 的 OpenSharedResource 方法渲染来自其他进程/设备的共享资源(SharedHandle)

如果你得到了一个来自于其他进程或者其他模块的 Direct3D11 的共享资源,即 SharedHandle 句柄,那么可以使用本文提到的方法将其转换成 Direct3D11 的设备和纹理,这样你可以进行后续的其他处理。


本文内容

    • SharpDX
    • SharedHandle
    • OpenSharedResource
    • 后续操作
      • 获取 Texture2D
      • 获取 Texture2DDescription
      • 获取 Surface

SharpDX

本文的代码会使用到 SharpDX 库,因此,你需要在你的项目当中安装这些 NuGet 包:

<!-- 基础,必装 -->
<PackageReference Include="SharpDX" Version="4.2.0" />
<PackageReference Include="SharpDX.D3DCompiler" Version="4.2.0" />
<PackageReference Include="SharpDX.DXGI" Version="4.2.0" />
<PackageReference Include="SharpDX.Mathematics" Version="4.2.0" />
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />

<!-- 其他,可选 -->
<PackageReference Include="SharpDX.Direct2D1" Version="4.2.0" />
<PackageReference Include="SharpDX.Direct3D9" Version="4.2.0" />

SharedHandle

Direct3D 支持在不同的 Direct3D 设备之间共享资源。需要设置 ResourceOptionFlagsShared 的纹理才可以支持共享,当然这不是本文要说的重点。

本文要说的是,如果你拿到了一个来自于其他模块的共享资源句柄的时候,你可以如何使用它。

你的使用可能类似于这样:

public void OnAcceleratedPaint(IntPtr sharedHandle, Int32Rect dirtyRect)
{
    // 通过 sharedHandle 进行后续的处理。
}

OpenSharedResource

DirectX 中用来表示 Direct3D11 的设备类型是 ID3D11Device,它有一个 OpenSharedResource 方法可以用来打开来自于其他设备的共享资源。

对应到 SharpDX 中,用来表示 Direct3D11 的设备的类型是 SharpDX.Direct3D11.Device,其有一个 OpenSharedResource<T> 方法来打开来自于其他设备的共享资源。

我们必须要创建一个自己的 Direct3D11 设备,因为设备是不共享的,代码如下:

var device = new SharpDX.Direct3D11.Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport);
var resource = device.OpenSharedResource<SharpDX.Direct3D11.Resource>(sharedHandle);

后续操作

在得到此共享资源之后,我们可以获得更多关于此资源的描述,以及有限地使用此资源的方法。

获取 Texture2D

可以通过 QueryInterface 获取某个资源相关的 COM 对象的引用。我们拿到的共享资源是 2D 纹理的话,我们可以使用 QueryInterface 获取 SharpDX.Direct3D11.Texture2D COM 对象的引用。

var texture = resource.QueryInterface<SharpDX.Direct3D11.Texture2D>();

获取 Texture2DDescription

可以从 Texture2D 的实例中获取到 Texture2DDescription,这是用来描述此 2D 纹理创建时的各种信息。

// 在 DirectX 的传统代码中,通常使用 desc 来作为 Texture2DDescription 实例命名的后缀。
// 不过 C# 代码通常不这么干,这是 C++ 代码的习惯。在这里这么写是为了在得到 C++ 搜索结果的时候可以与本文所述的 C# 代码对应起来。
var desc = texture.Description;

获取 Surface

或者,我们可以获取到 2D 图面,用于做渲染、绘制等操作。当然,是否能真正进行这些操作取决于 Texture2DDescription 中是否允许相关的操作。

var surface = texture2D.QueryInterface<SharpDX.DXGI.Surface>();

在获取到 SharpDX.DXGI.Surface 的 COM 组件引用之后,可以在内存中映射位图用于调试,可以参见:

  • 将 Direct3D11 在 GPU 中的纹理(Texture2D)导出到内存或导出成图片文件

参考资料

  • c++ - Direct3D11: Sharing a texture between devices: black texture - Stack Overflow
  • ID3D11Device::OpenSharedResource (d3d11.h) - Microsoft Docs
  • IDXGIResource interface (Windows)
  • IDXGIResource (dxgi.h) - Microsoft Docs
  • IUnknown::QueryInterface(Q,) - Microsoft Docs

我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • 将 Direct3D11 在 GPU 中的纹理(Texture2D)导出到内存(Map)或导出成图片文件
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • C#/.NET 当我们在写事件 += 和 -= 的时候,方法是如何转换成事件处理器的
  • 清理 git 仓库太繁琐?试试 bfg!删除敏感信息删除大文件一句命令搞定(比官方文档还详细的使用说明)
  • 可集成到文件管理器,一句 PowerShell 脚本发布某个版本的所有 NuGet 包
  • Windows 系统的默认字体是什么?应用的默认字体是什么?
  • C# 8.0 的可空引用类型,不止是加个问号哦!你还有很多种不同的可空玩法
  • 一个简单的方法:截取子类名称中不包含基类后缀的部分
  • 使用 MSBuild Target 复制文件的时候如何保持文件夹结构不变
  • 如何在 MSBuild 中正确使用 % 来引用每一个项(Item)中的元数据
  • 如何将一个 .NET 对象序列化为 HTTP GET 的请求字符串
  • 屏幕边缘上有趣的 1 个像素,看不见、摸不到
  • 在 MSBuild 编译过程中操作文件和文件夹(检查存在/创建文件夹/读写文件/移动文件/复制文件/删除文件夹)
  • 在 WPF 程序中应用 Windows 10 真•亚克力效果
  • 推荐 .NET/C# 开发者安装的几款代码分析插件或对应的代码分析 NuGet 包
  • ES6语法详解(一)
  • java2019面试题北京
  • MySQL数据库运维之数据恢复
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • sessionStorage和localStorage
  • SpiderData 2019年2月13日 DApp数据排行榜
  • SQLServer插入数据
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 好的网址,关于.net 4.0 ,vs 2010
  • 近期前端发展计划
  • 聊一聊前端的监控
  • 设计模式 开闭原则
  • 突破自己的技术思维
  • 我看到的前端
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • ${factoryList }后面有空格不影响
  • (2)(2.10) LTM telemetry
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (剑指Offer)面试题34:丑数
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (一)基于IDEA的JAVA基础12
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • *2 echo、printf、mkdir命令的应用
  • .gitignore文件—git忽略文件
  • .NET Core 中插件式开发实现
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • .Net中ListT 泛型转成DataTable、DataSet
  • @configuration注解_2w字长文给你讲透了配置类为什么要添加 @Configuration注解
  • @EnableAsync和@Async开始异步任务支持
  • @RestControllerAdvice异常统一处理类失效原因
  • [AIGC] MySQL存储引擎详解
  • [C# 基础知识系列]专题十六:Linq介绍