zoukankan      html  css  js  c++  java
  • Win2D 官方文章系列翻译

    本文为个人博客备份文章,原文地址:

    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());  
  • 相关阅读:
    奥赛-欧几里得算法-最大公约数
    dbForge Studio for MySQL 中文乱码问题
    【C++】纯C++实现http打开网页下载内容的功能
    【C++】C++string类总结
    【C++】C++中的string类的用法总结
    【网络编程/C++】修改本机ip地址
    MFC控件的SubclassDlgItem
    MFC 不让程序显示在任务栏上
    MFC中无边框窗口的拖动
    MFC 获取图像的大小
  • 原文地址:https://www.cnblogs.com/validvoid/p/win2d-interop-with-direct2d.html
Copyright © 2011-2022 走看看