Win2D 官方文章系列翻译 - 与 Direct2D 互操作
本文为个人博客备份文章,原文地址:
http://validvoid.net/win2d-interop-with-direct2d/
Win2D 作为 Direct2D 的上层实现,支持与其进行双向互操作。如果你有一个 Win2D 对象,你可以访问到用以实现它的原生 Direct2D 对象;而如果你有一个 Direct2D 对象,只要包装该 Direct2D 对象的 Win2D 对象存在,你也能查找到此 Win2D 对象,或者,当 Win2D 包装对象不存在时,你也可以手动创建一个新的包装器。
互操作使你能够混合搭配使用 Win2D 与 DirectX API。你可以编写一个 Win2D应用,而部分使用原生 DirectX —— 以调用某些需要原生接口的 API 或第三方组件。你也可以编写一个原生的 DirectX 应用,在某些特定位置转而使用 Win2D,以享受其便利性或者 C# 支持。
互操作 API
要在 Win2D 与原生 Direct2D 接口之间进行互操作,需使用 C++/CX 互操作 API 定义于头文件 Microsoft.Graphics.Canvas.native.h 中:
#include <Microsoft.Graphics.Canvas.native.h> using namespace Microsoft::Graphics::Canvas;
获得 Win2D 对象包装的原生 Direct2D 对象:
template<typename T, typename U>
Microsoft::WRL::ComPtr<T> GetWrappedResource(U^ wrapper); template<typename T, typename U>
Microsoft::WRL::ComPtr<T> GetWrappedResource(CanvasDevice^ device, U^ wrapper); template<typename T, typename U>
Microsoft::WRL::ComPtr<T> GetWrappedResource(CanvasDevice^ device, U^ wrapper, float dpi);
对多数类型而言,调用 GetWrappedResource 方法仅需传入一个 Win2D 包装器对象作为参数即可。对部分类型(见下文附表)则必须同时传入一个设备和/或 DPI 值作为方法参数。对于那些无需传入设备和 DPI 值的类型,在调用 GetWrappedResource 方法时传入这两个参数也没有问题。
获得包装原生 Direct2D 对象的 Win2D 对象:
template<typename WRAPPER>
WRAPPER^ GetOrCreate(IUnknown* resource); template<typename WRAPPER>
WRAPPER^ GetOrCreate(CanvasDevice^ device, IUnknown* resource); template<typename WRAPPER>
WRAPPER^ GetOrCreate(ID2D1Device1* device, IUnknown* resource); template<typename WRAPPER>
WRAPPER^ GetOrCreate(CanvasDevice^ device, IUnknown* resource, float dpi); template<typename WRAPPER>
WRAPPER^ GetOrCreate(ID2D1Device1* device, IUnknown* resource, float dpi);
如果一个包装器实例已经存在,GetOrCreate 方法会返回该实例,否则会创建一个新实例。只要该包装器实例持续存在,对同一个原生对象反复调用该方法每次都会返回相同的包装器实例。如果对该包装器实例的全部引用都被释放,从而使其引用计数归零,实例销毁,则之后的所有 GetOrCreate 调用都会创建新的包装器。
对于某些类型而言,调用 GetOrCreate 方法时秩序传入一个 Direct2D 资源对象作为参数,而对于其它类型,则调用时必须同时传入一个设备和 DPI 值。在非必要情况下调用 GetOrCreate 方法时也传入以上两个参数也没有问题。如果一个 Win2D 包装器已经存在,对于那些要求传入设备和 DPI 值参数的类型,调用方法时亦可省略这两个参数,因为这两个参数仅用于创建新的包装器实例。
GetOrCreate 方法能够解析继承层次并总是生成最合适的派生包装器类型。例如调用 GetOrCreate<CanvasBitmap>(ID2D1Bitmap1*),传入的 ID2D1Bitmap1 带有 D2D1_BITMAP_OPTIONS_TARGET 标志,则方法返回的包装器实例实际上会是一个 CanvasRenderTarget (派生自 CanvasBitmap)。反之,如果调用 GetOrCreate<CanvasRenderTarget>(ID2D1Bitmap1*),ID2D1Bitmap1 不带 D2D1_BITMAP_OPTIONS_TARGET 标志,则会抛出一个无效转换异常。
更极端一些,像 GetOrCreate<Object>(IUnknown*) 和 GetWrappedResource<IUnknown>(Object^) 这样的调用也是可以的。
支持互操作的类型
|
Win2D 类型 |
Direct2D 类型 |
GetOrCreate 参数 |
GetWrappedResource 参数 |
|---|---|---|---|
| CanvasBitmap | ID2D1Bitmap1 不带 D2D1_BITMAP_OPTIONS_TARGET | 设备 | - |
| CanvasCachedGeometry | ID2D1GeometryRealization | 设备 | - |
| CanvasCommandList | ID2D1CommandList | 设备 | - |
| CanvasDevice | ID2D1Device1 | - | - |
| CanvasDrawingSession | ID2D1DeviceContext1 | - | - |
| CanvasGeometry | ID2D1Geometry,或其任一派生接口ID2D1PathGeometry,ID2D1RectangleGeometry,ID2D1RoundedRectangleGeometry,ID2D1EllipseGeometry,ID2D1TransformedGeometry, orID2D1GeometryGroup | 设备 | - |
| CanvasGradientMesh | ID2D1GradientMesh | 设备 | - |
| CanvasImageBrush | ID2D1BitmapBrush1 (当图像是一个 CanvasBitmap 并且 SourceRectangle 为 null)或者ID2D1ImageBrush(当图像是 ICanvasImage 的其它派生类型,或当已设置 SourceRectangle 属性) | 设备 | 可选 DPI(1) |
| CanvasLinearGradientBrush | ID2D1LinearGradientBrush | 设备 | - |
| CanvasRadialGradientBrush | ID2D1RadialGradientBrush | 设备 | - |
| CanvasRenderTarget | ID2D1Bitmap1 带 D2D1_BITMAP_OPTIONS_TARGET | 设备 | - |
| CanvasSolidColorBrush | ID2D1SolidColorBrush | 设备 | - |
| CanvasStrokeStyle | ID2D1StrokeStyle1 | - | 设备 |
| CanvasSwapChain | IDXGISwapChain1 | 设备, DPI | - |
| CanvasTextFormat | IDWriteTextFormat1 | - | - |
| CanvasTextLayout | IDWriteTextLayout2 | 设备 | - |
| Microsoft.Graphics.Canvas.Effects.* (多个 Win2D 类映射到相同的 D2D 类型) | ID2D1Effect 带合适的 D2D1_PROPERTY_TYPE_CLSID | 设备 | 设备,可选 DPI(1) |
| CanvasTextRenderingParameters | IDWriteRenderingParams2 | - | - |
(1) 可选 DPI 意味着对此类型调用 GetWrappedResource 时可以不指定 DPI,而如果手动指定了 DPI, Win2D 则可通过舍弃冗余的 DPI 补偿节点来增进配置效果图的效率。这适用于对一个特效类型调用 GetWrappedResource 方法的情况。 而当一个 CanvasImageBrush 以其源图像作为特效时,调用 GetWrappedResource 方法亦适用此技巧。
示例
#include <Microsoft.Graphics.Canvas.native.h>
#include <d2d1_2.h> using namespace Microsoft::Graphics::Canvas;
using namespace Microsoft::WRL; // 互操作 Win2D -> Direct2D.
CanvasDevice^ canvasDevice = ...;
CanvasBitmap^ canvasBitmap = ...; ComPtr<ID2D1Device> nativeDevice = GetWrappedResource<ID2D1Device>(canvasDevice);
ComPtr<ID2D1Bitmap1> nativeBitmap = GetWrappedResource<ID2D1Bitmap1>(canvasBitmap); // 互操作 Direct2D -> Win2D.
canvasDevice = GetOrCreate<CanvasDevice>(nativeDevice.Get());
bitmap = GetOrCreate<CanvasBitmap>(canvasDevice, nativeBitmap.Get());
Win2D 官方文章系列翻译 - 与 Direct2D 互操作的更多相关文章
- Win2D 官方文章系列翻译 - 像素格式
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-pixel-formats/ DirectXPixelFormat 枚举 包含了 Direct3D 和 DXG ...
- Win2D 官方文章系列翻译 - 处理设备丢失
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-handling-device-lost/ “设备丢失”是指 GPU 设备失效无法继续进行渲染的情况.GPU ...
- Win2D 官方文章系列翻译 - DPI (每英寸点数)和 DIPs(设备独立像素)
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-dpi-dips/ 本文旨在解释物理像素与设备独立像素(DIPs, device independent pi ...
- Win2D 官方文章系列翻译 - 避免内存泄漏
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-avoiding-memory-leaks/ 在托管 XAML 应用中使用 Win2D 控件时,必须谨慎处理对 ...
- Win2D 官方文章系列翻译 - 幕后绘制
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-offscreen-drawing/ 应用有时需要将图形绘制到并不立即显示的目标上.此类绘制动作被称作“幕后绘 ...
- Win2D 官方文章系列翻译 - 预乘 Alpha
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-premultiplied-alpha/ 在计算机绘图中有两种表示颜色值不透明度的方法.Win2D 中两种方法 ...
- Win2D 官方文章系列翻译 - 调整控件分辨率
本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-choosing-control-resolution/ 本文旨在讲解如何配置 Win2D XAML 控件使用 ...
- NLog文章系列——如何配置NLog(转)
NLog使用方法 作者:Jaros?aw Kowalski <> 翻译:CrazyCoder(由衷感谢他的热心!!) 原文:http://www.nlog-project.org/conf ...
- AngularJS系列-翻译官网
公司之前一直用的Web前台框架是Knockout,我们通常直接叫ko,有看过汤姆大叔的KO系列,也有在用,发现有时候用得不太顺手.本人是会WPF的,所以MVVM也是比较熟悉的,学ko也是很快就把汤姆大 ...
随机推荐
- Android6的Logger日志系统
版权声明:本文为博主原创文章,未经博主允许不得转载. Android2.x中Logger日志系统采用了字符设备驱动来支持,到了Android6.0已经找不到kernel/goldfish/driver ...
- 加快 hive 查询的 5 种方法
1. 使用 Tez set hive.execution.engine=tez; 2. 使用 ORCFILE.当有多个表 join 时,使用 ORCFile 进行存储,会显著地提高速度. CREATE ...
- C语言字符串操作
1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1) 附加字符串 strncat(p, p1, n) 附加指定长度 ...
- poj2409(polya 定理模板)
题目链接:http://poj.org/problem?id=2409 题意:输入 m, n 表示有 m 种颜色,要构造一个长度为 n 的手环,旋转和对称的只算一种,问能组成多少个不同的手环. 思路: ...
- 青橙 A1280. 最长双回文串
A1280. 最长双回文串 时间限制:2.0s 内存限制:512.0MB 总提交次数: AC次数: 平均分: 将本题分享到: 查看未格式化的试题 提交 试题讨 ...
- P4559 [JSOI2018]列队
\(\color{#0066ff}{ 题目描述 }\) 作为一名大学生,九条可怜在去年参加了她人生中的最后一次军训. 军训中的一个重要项目是练习列队,为了训练学生,教官给每一个学生分配了一个休息位置. ...
- redhat7查看系统版本 修改主机名
在CentOS或RHEL中,有三种定义的主机名:静态的(static),瞬态的(transient),以及灵活的(pretty).“静态”主机名也称为内核主机名,是系统在启动时从 /etc/hostn ...
- Arcgis Server for JavaScript API之自定义InfoWindow
各位看到这个标题不要嫌烦,因为本人最近一直在研究相关的问题,所以相关文章也只能是这些,同时希望看过我的文章的朋友,我的文章能够给你帮助. 在前面的两篇相关的文章里面,实现InfoWindow是通过di ...
- office word使用技巧汇总
1.用MathType编辑的公式放在Word中有时会显示不全,仅显示其中一部分. 以下教程介绍解决Word中MathType公式显示不全的方法. 在Word中粘贴完公式后,选中该公式,在工具栏里选择“ ...
- Python条件与循环
1.条件语句: 形式: if 判断语句 : 执行语句1elif 判断语句2: 执行语句2elif 判断语句3: 执行语句3#...else: 执行语句4 占位符 pass 2.循环语句 1.wh ...