Windows 10 特刊 2015

第 30 卷,第 11 期

本文章是由機器翻譯。

圖形與動畫 - Windows 程式撰寫已升級到 10

Kenny Kerr |Windows 2015

否則會做為桌面視窗管理員 (DWM)、 Windows 撰寫引擎取得新應用程式開發介面的 Windows 10。DirectComposition 已轉譯緩衝處理的主要介面但為傳統 COM API 無法平均的應用程式開發人員多半存取。新的 Windows 撰寫應用程式開發介面根據 Windows 執行階段 (WinRT) 並提供高效能轉譯由混用的 Direct2D 和 Direct3D 所提供的大幅改良了動畫和效果功能現在可支援的保留視覺化樹狀結構的即時模式圖形世界的基礎。

我第一次撰寫有關 DWM 年代 2006 beta 中的 Windows Vista 時 (goo.gl/19jCyR)。它可讓您控制指定視窗的柔邊效果的範圍以及建立混合好好與桌面的自訂色彩。[圖 1 說明在 Windows 7 中此項成就的高度。無法產生 Direct3D 和 Direct2D 建立令人讚嘆的視覺效果應用程式的硬體加速呈現方式 (goo.gl/IufcN1)。您甚至可以混合與 DWM 的 GDI 和使用者控制項的舊世界 (goo.gl/9ITISE)。還是,任何急著做任何的觀察器無法告訴 DWM 有提供更多功能 — 很多。Windows 7 的 Windows Flip 3D 功能已說服證明。

Aero Windows
[圖 1] Windows Aero

Windows 8 引進了新的應用程式開發介面 DWM 呼叫 DirectComposition,DirectX 系列的啟發其設計的傳統 COM Api 提供尾曲其名稱。DirectComposition 開始讓開發人員的 DWM 為何這麼做能夠更清楚的圖片。它也提供改良的術語。DWM 其實 Windows 撰寫引擎,而且它能夠產生 Windows Vista 和 Windows 7 中這些超炫的效果,因為它根本的改變桌面視窗所呈現的方式。根據預設,組合引擎會建立用於每個最上層視窗的重新導向介面。我這詳細說明在 2014 年 6 月的專欄 (goo.gl/oMlVa4)。這些重新導向表面構成視覺化樹狀結構的一部分且 DirectComposition 允許都利用相同的應用程式技術提供輕量的保留模式 API 提供高效能的圖形。DirectComposition 提供視覺化樹狀結構和介面允許卸載組合引擎的動畫效果的實際執行應用程式的管理。這些功能述我年 8 月 (goo.gl/CNwnWR) 和 2014 年 9 月資料行 (goo.gl/y7ZMLL)。我甚至會產生與 DirectComposition pluralsight 的高效能轉譯的課程 (goo.gl/fgg0XN)。

Windows 8 聯邦 DirectComposition,與以及其他 Api 的 DirectX 系列令人印象深刻的增強功能,但它也 kerensky 新紀元中 Windows api 可能會永久變更開發人員看看 OS 的方式。簡介 Windows 執行階段執行的所有一切。Microsoft 承諾的全新的新方式來建置應用程式和存取拼寫所謂有長久以來一直主控項的方式建置應用程式以及與作業系統互動的 Win32 API 最終淘汰的作業系統服務。Windows 8 有 rocky 啟動、 Windows 8.1 修正大量問題但 Windows 10 現在提供更完整的 API 將滿足許多更多開發人員建置第一級的應用程式、 雅倫、 嚴重的應用程式、 windows 感興趣。

Windows 10 隨附於 2015 年 7 月中的新組合還未準備好開始生產的 API 預覽。它是仍有可能變更並因此無法在提交到 Windows 市集的通用 Windows 應用程式中使用。這也是因為組合現已供實際執行的應用程式開發介面都有變更本質上,更美好。此 Windows 10 更新也是第一次相同的複合應用程式開發介面所提供的所有的外型規格可以進一步提供 credence 通用 Windows 平台的通用部分。組合的作用相同不論是否您的目標程式多顯示桌面製作公司或小型 smartphone 帶著走。

當然,每個人都喜歡 Windows 執行階段的相關重點是它最後會傳遞承諾的 common language runtime 上適用於 Windows。如果您想要在 C# 中的程式碼,您可以使用 Windows 執行階段直接透過內建於 Microsoft.NET Framework 的支援。如果就我想要使用 c + + Windows 執行階段使用沒有中繼或成本的抽象概念。Windows 執行階段建置 COM 而非.NET 和這類最適合 c + + 耗用量。我將使用現代 c + + Windows 執行階段 (moderncpp.com)、 標準 c + + 語言投影中,但是您可以跟隨您偏好的語言應用程式開發介面都相同,無論。我甚至還會提供 C# 來說明如何完美 Windows 執行階段可支援不同的語言中的某些範例。

Windows 撰寫應用程式開發介面 distances 本身從自己的 DirectX 根目錄。雖然 DirectComposition 提供呈現之後 Direct3D 和 Direct2D 裝置的裝置物件的新 Windows 撰寫應用程式開發介面會以複合開始。它不過,會提供相同的用途,做為撰寫資源的 factory。除此之外,是非常類似於 DirectComposition Windows 組合。沒有代表視窗和其視覺化樹狀結構之間的關聯性的組合目標。差異變得更清楚看到您仔細看視覺效果。Visual DirectComposition 必須提供某種形式的點陣圖的內容屬性。點陣圖就是一種三件事: 撰寫介面、 DXGI 交換鏈結或另一個視窗的重新導向介面。典型的 DirectComposition 應用程式所組成的視覺效果和呈現介面做為內容或不同的視覺效果的點陣圖。如上圖中 [圖 2, ,撰寫視覺化樹狀結構會稍有不同的怪獸。新的視覺物件沒有內容的屬性並改為轉譯組合筆刷。這原來是更具彈性的抽象概念。雖然筆刷之前可以非常有效率的方式建立簡單的單色筆刷和更複雜的筆刷可定義,至少在概念上,可以呈現為點陣圖方式跟如何 Direct2D 會提供可視為映像的效果。右邊的抽象層可讓所有的差異。

Windows 撰寫視覺化樹狀結構
[圖 2 Windows 撰寫視覺化樹狀結構

讓我們逐步說明這全部是如何運作並提供您一窺可行的一些實用的範例。同樣地,您可以挑選您最愛的 WinRT 語言投影。您可以建立複合現代 c + +,,如下所示:

using namespace Windows::UI::Composition;
Compositor compositor;

同樣地,您可以執行相同的 C#:

using Windows.UI.Composition;
Compositor compositor = new Compositor();

您甚至可以使用更 flamboyant 語法提供的 C + + /CX:

using namespace Windows::UI::Composition;
Compositor ^ compositor = ref new Compositor();

這些是所有從應用程式開發介面的觀點而言相當的只是反映在語言投影中的差異。基本上有兩種方式可以在其中您可以立即寫入通用 Windows 應用程式。也許最常見的方法是使用作業系統的 Windows.UI.Xaml 命名空間。如果 XAML 不到您的應用程式的重要,您也可以直接與不會相依於 XAML 中使用基礎的應用程式模型。我在 2013 年 8 月專欄中所述的 WinRT 應用程式模型 (goo.gl/GI3OKP)。使用這個方法,您只需要最少的 IFrameworkView 和 IFrameworkViewSource 介面的實作一切就得了。[圖 3 提供以 C# 可讓您開始著手的基本大綱。Windows 組合也會提供與 XAML、 緊密整合但舉個簡單的 XAML 釋放應用程式因為它提供了更簡單遊樂場要深入了解組合。我會得到 xaml 有點稍後在本文中。

[圖 3 中 C# Windows 執行階段應用程式模型

using Windows.ApplicationModel.Core;
using Windows.UI.Core;
class View : IFrameworkView, IFrameworkViewSource
{
  static void Main()
  {
    CoreApplication.Run(new View());
  }
  public IFrameworkView CreateView()
  {
     return this;
  }
  public void SetWindow(CoreWindow window)
  {
    // Prepare composition resources here...
  }
  public void Run()
  {
    CoreWindow window = CoreWindow.GetForCurrentThread();
    window.Activate();
    window.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessUntilQuit);
  }
  public void Initialize(CoreApplicationView applicationView) { }
  public void Load(string entryPoint) { }
  public void Uninitialize() { }
}

它是在應用程式的 SetWindow 方法 (請參閱 [圖 3) 應該建構複合項。事實上,這就是最早的點可能是因為複合項相依於該視窗的發送器而且這的點的視窗和發送器最後的應用程式的生命週期中是否存在。複合應用程式檢視之間的關聯性接著可以建立藉由建立複合目標:

CompositionTarget m_target = nullptr;
// ...
m_target = compositor.CreateTargetForCurrentView();

很重要應用程式保持組合目標運作,因此請務必讓 IFrameworkView 實作的成員變數。我之前有提到,組合目標表示視窗或檢視和視覺化樹狀結構之間的關聯性。只要使用組合的目標是將根目錄設定為視覺化。通常這會是視覺化的容器:

ContainerVisual root = compositor.CreateContainerVisual();
m_target.Root(root);

我在此處使用 c + +,缺少語言支援的屬性,所以根屬性投影成存取子方法。C# 是加上的屬性語法非常類似:

ContainerVisual root = compositor.CreateContainerVisual();
m_target.Root = root;

DirectComposition 提供一種視覺化表示點陣圖內容支援不同種類的介面。Windows 組合提供了代表不同種類的視覺效果、 筆刷和動畫的小型類別階層但沒有一種介面和只能建立使用 c + +,因為它是 Windows 撰寫 interop API 適用於 XAML 和更複雜的應用程式開發人員等架構的一部分。

Visual 類別階層所示 [圖 4。CompositionObject 是複合項所支援的資源。組合的所有物件可能會都可能動畫顯示其屬性。視覺效果提供許多屬性來控制多方面的視覺效果的相對位置、 外觀、 裁剪和轉譯選項。它包含轉換矩陣屬性為小數位數和旋轉的快速鍵。這是功能強大的基底類別。相較之下,ContainerVisual 是相當簡單的類別,只是將子系的屬性。雖然您可以直接建立容器視覺效果、 SpriteVisual 加入關聯如此視覺圖形可以實際呈現它自己的像素的筆刷的能力。

複合視覺效果
[圖 4 複合視覺效果

指定根容器視覺效果,我可以建立任意數目的子視覺效果:

VisualCollection children = root.Children();

這些也可以是容器視覺效果,但他們應該更可能 sprite 視覺效果。我可以新增三個視覺效果做為子系的根 visual 使用 c + + 中的迴圈:

using namespace Windows::Foundation::Numerics;
for (unsigned i = 0; i != 3; ++i)
{
  SpriteVisual visual = compositor.CreateSpriteVisual();
  visual.Size(Vector2{ 300.0f, 200.0f });
  visual.Offset(Vector3{ 50 + 20.0f * i, 50 + 20.0f * i });
  children.InsertAtTop(visual);
}

您可以輕鬆地想像中的應用程式視窗 [圖 5, ,和尚未這段程式碼不會因為沒有筆刷所呈現這些視覺元件相關聯的任何項目。筆刷類別階層架構所示 [圖 6。CompositionBrush 是只要筆刷的基底類別,並不提供它自己的任何功能。CompositionColorBrush 是供應項目只用於呈現純色視覺效果的色彩屬性的最簡單的種類。這不聽起來可能很令人興奮,但別忘了您可以連接至該色彩屬性動畫。CompositionEffectBrush 和 CompositionSurfaceBrush 類別相關的但是更複雜的筆刷因為它們由其他資源。CompositionSurfaceBrush 會呈現任何附加的視覺效果用撰寫介面。它有各種不同屬性的繪圖,例如插補、 對齊和伸展,更別提介面本身該控制項點陣圖。CompositionEffectBrush 接受數目之介面的筆刷來產生不同的效果。

子視窗的視覺效果
[圖 5] 視窗中的子系視覺效果

組合筆刷
[圖 6 組合筆刷

建立和套用色彩的筆刷很簡單。以下是在 C# 中的範例:

using Windows.UI;
CompositionColorBrush brush = compositor.CreateColorBrush();
brush.Color = Color.FromArgb(0xDC, 0x5B, 0x9B, 0xD5);
visual.Brush = brush;

色彩結構來自受 Windows.UI 命名空間和運動 alpha、 紅色、 綠色和藍色做為 8 位元色彩值離開浮點色彩值的 DirectComposition 和 Direct2D 喜好設定。這種視覺效果和筆刷不錯的功能是隨時都可以變更色彩屬性和任何參考相同的筆刷的視覺效果會自動更新。其實我已經提示過了前,如色彩屬性甚至可以使用動畫。那麼要如何運作的? 這會帶我們動畫類別。

動畫類別階層架構所示 [圖 7。CompositionAnimation 基底類別提供儲存運算式搭配使用的具名的值的能力。我會詳細討論有關運算式很快。KeyFrameAnimation 提供持續時間、 反覆項目和停止行為像一般的主要畫面式動畫屬性。不同的主要畫面格動畫類別提供特定類型的方法來插入主要畫面格,以及特定型別的動畫屬性。例如,ColorKeyFrameAnimation 可讓您插入主要畫面格的色彩值和屬性來控制主要畫面格之間的變化的色彩空間。

組合的動畫
[圖 7 組合動畫

建立動畫物件並將該動畫套用到特定組合物件是出乎意料的簡單。假設我想要建立視覺效果的不透明度動畫。我可以將視覺效果的不透明度設定為直接與 c + + 的純量值的 50%,如下所示:

visual.Opacity(0.5f);

或者,我可以建立純量的動畫物件和主要畫面格來產生介於 0.0 到 1.0 之間的動畫變數代表 0%到 100%不透明:

ScalarKeyFrameAnimation animation =
  compositor.CreateScalarKeyFrameAnimation();
animation.InsertKeyFrame(0.0f, 0.0f); // Optional
animation.InsertKeyFrame(1.0f, 1.0f);

InsertKeyFrame 的第一個參數為相對位移的動畫 (0.0) 開始的動畫 (1.0) 結尾。第二個參數是在該點動畫時間軸中的動畫變數的值。因此這個動畫順暢地將轉換的值從 0.0 到 1.0 動畫的持續期間。我接著可以設定此動畫整體持續期間如下:

using namespace Windows::Foundation;
animation.Duration(TimeSpan::FromSeconds(1));

準備就緒動畫與我只需要連接至組合物件和我所選的屬性:

visual.StartAnimation(L"Opacity", animation);

StartAnimation 方法實際上會繼承自 CompositionObject 基底類別,這表示您可以動畫顯示各種不同類別的屬性。這是另一個離開 DirectComposition、 提供每個製成動畫的屬性為純量值及動畫物件的多載。Windows 組合提供更豐富屬性系統開啟大門一些非常有趣的功能。特別是,它支援的功能撰寫減少必須撰寫更有趣的動畫及效果的程式碼數量的文字運算式。這些運算式會在執行階段編譯和有效率地執行 Windows 撰寫引擎所剖析。

假設您需要為旋轉沿著 Y 軸的視覺效果並為它提供深度的外觀。因為可以將不會產生包含檢視方塊的轉換以弧度為單位的視覺效果的 RotationAngle 屬性都是不夠的。為視覺效果旋轉,人們的眼睛最接近的邊緣應該看起來更大,雖然相反的邊緣應該看起來比較小。[圖 8 顯示旋轉說明這項行為的視覺效果的數目。

旋轉的視覺效果
[圖 8 旋轉視覺效果

您要如何完成這種動畫的效果? 嗯,現在讓我們著手的旋轉角度的純量的主要畫面格動畫:

ScalarKeyFrameAnimation animation = compositor.CreateScalarKeyFrameAnimation();
animation.InsertKeyFrame(1.0f, 2.0f * Math::Pi,
  compositor.CreateLinearEasingFunction());
animation.Duration(TimeSpan::FromSeconds(2));
animation.IterationBehavior(AnimationIterationBehavior::Forever);

線性 easing 函式會覆寫預設加速或減速函式來產生連續的旋轉動作。我要定義自訂物件與我可以從參考運算式內的屬性時。複合項提供針對這個用途的屬性:

CompositionPropertySet rotation = compositor.CreatePropertySet();
rotation.InsertScalar(L"Angle", 0.0f);

因此我可以使用 StartAnimation 方法來輕鬆地為任何內建屬性建立我的自訂屬性的動畫屬性集也是撰寫物件:

rotation.StartAnimation(L"Angle", animation);

我現在有其角度屬性是在影片中的物件。現在我需要定義轉換矩陣以同時委派至本身的旋轉角度的這個動畫屬性產生想要的效果。輸入運算式:

ExpressionAnimation expression =
  compositor.CreateExpressionAnimation(
    L"pre * Matrix4x4.CreateFromAxisAngle(axis, rotation.Angle) * post");

運算式動畫不是主要畫面格動畫物件是沒有相對的主要畫面格的位移動畫變數可能會變更 (根據某些插補函式)。請改為運算式只是參考可能會自行建立動畫在傳統意義上的參數。儘管如此,它是由我決定來定義哪些"pre"、"軸,""旋轉"和"post"是。現在讓我們著手軸參數:

expression.SetVector3Parameter(L"axis", Vector3{ 0.0f, 1.0f, 0.0f });

在運算式內的 CreateFromAxisAngle 方法預期軸旋轉和這樣會定義沿著 Y 軸軸。它也會預期我們可以延後至旋轉屬性集,而且動畫 」 角度"屬性的角度和旋轉的:

expression.SetReferenceParameter(L"rotation", rotation);

若要確保旋轉會透過中央的視覺效果而非左邊的緣,我需要預先相乘旋轉矩陣 CreateFromAxisAngle 由邏輯上會轉移至旋轉點的軸的翻譯:

expression.SetMatrix4x4Parameter(
  L"pre", Matrix4x4::Translation(-width / 2.0f, -height / 2.0f, 0.0f));

請記住 pre 和 post 矩陣實際上就只是讓並非交換,矩陣相乘。最後,我可以旋轉矩陣之後加入一些檢視方塊,然後還原至其原始位置的視覺效果:

expression.SetMatrix4x4Parameter(
  L"post", Matrix4x4::PerspectiveProjection(width * 2.0f) *
    Matrix4x4::Translation(width / 2.0f, height / 2.0f, 0.0f));

這就符合運算式所參考的所有參數和我現在可以直接使用運算式動畫來製作動畫的視覺物件使用其 TransformMatrix 屬性:

visual.StartAnimation(L"TransformMatrix", expression);

因此我探討了各種方式來建立、 填滿和建立視覺效果,但如果需要直接呈現視覺效果的動畫嗎? DirectComposition 提供預先配置介面和沒有嚴密配置呼叫所配置的虛擬介面隨選與也可調整大小的點陣圖。Windows 組合看似提供沒有建立介面的能力。沒有 CompositionDrawingSurface 類別,但是沒有辦法建立不含向外尋求協助。答案是來自 Windows 撰寫 interop API。WinRT 類別可以實作其他的 COM 介面直接顯示如果您只是元件的 Windows 中繼資料。假設這些隱匿介面的知識,您可以輕鬆地查詢它們在 c + +。當然,這會為您正在逐步執行 Windows 撰寫應用程式開發介面為主流的開發人員提供很棒的抽象概念之外的更多工作。我要做的第一件事就是建立轉譯裝置和我要使用 Direct3D 11,因為 Windows 組合還不能支援 Direct3D 12:

ComPtr<ID3D11Device> direct3dDevice;

我接著會準備裝置建立旗標:

unsigned flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT |
                 D3D11_CREATE_DEVICE_SINGLETHREADED;
#ifdef _DEBUG
flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

BGRA 支援可讓我呈現更容易實行的 Direct2D 應用程式開發介面使用此裝置,並接著 D3D11CreateDevice 函式會建立本身的硬體裝置:

check(D3D11CreateDevice(nullptr, // Adapter
                        D3D_DRIVER_TYPE_HARDWARE,
                        nullptr, // Module
                        flags,
                        nullptr, 0, // Highest available feature level
                        D3D11_SDK_VERSION,
                        set(direct3dDevice),
                        nullptr, // Actual feature level
                        nullptr)); // Device context

我接著需要查詢裝置的 DXGI 介面,因為那是我需要建立 Direct2D 裝置:

ComPtr<IDXGIDevice3> dxgiDevice = direct3dDevice.As<IDXGIDevice3>();

現在就可以開始建立 Direct2D 裝置本身:

ComPtr<ID2D1Device> direct2dDevice;

在這裡,同樣地,我將啟用進一步診斷的偵錯層:

D2D1_CREATION_PROPERTIES properties = {};
#ifdef _DEBUG
properties.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
#endif

我可以先建立 Direct2D factory 來建立裝置。那就是我需要建立與裝置無關的任何資源時相當實用。在此我將使用 D2D1CreateDevice 函式所提供的快速鍵:

check(D2D1CreateDevice(get(dxgiDevice), properties, set(direct2dDevice)));

轉譯裝置已就緒。我有我可以用來呈現任何我可以想像 Direct2D 裝置。現在我必須告訴 Windows 撰寫引擎此轉譯裝置相關。這是其中的隱匿進到介面。假設我使用了在整個的複合,我可以查詢 ICompositorInterop 介面:

namespace abi = ABI::Windows::UI::Composition;
ComPtr<abi::ICompositorInterop> compositorInterop;
check(compositor->QueryInterface(set(compositorInterop)));

ICompositorInterop 提供用於建立方法撰寫介面從 DXGI 介面,的確很方便如果您想要撰寫視覺化樹狀結構中包含現有的交換鏈結,但是它會提供其他更有趣的是能夠。其 CreateGraphicsDevice 方法會建立提供轉譯裝置 CompositionGraphicsDevice 物件。CompositionGraphicsDevice 類別 Windows 組合 API 中的一般類別而不是偽裝的介面,但是因此您需要使用 c + + 和 ICompositorInterop 介面來建立它不會提供建構函式:

CompositionGraphicsDevice device = nullptr;
check(compositorInterop->CreateGraphicsDevice(get(direct2dDevice), set(device)));

因為 CompositionGraphicsDevice WinRT 型別,我可以再次使用現代 c + + 中,而不是指標和手動錯誤處理。而它是最後讓我建立撰寫介面 CompositionGraphicsDevice:

using namespace Windows::Graphics::DirectX;
CompositionDrawingSurface surface =
  compositionDevice.CreateDrawingSurface(Size{ 100, 100 },
    DirectXPixelFormat::B8G8R8A8UIntNormalized,
    CompositionAlphaMode::Premultiplied);

我在此建立綜合介面 100 x 100 像素的大小。請注意這代表實體的像素而不是邏輯 DPI 感知協調的假設和 Windows 組合的其餘部分所提供。介面也提供 Direct2D 所支援的 32 位元 alpha 混色轉譯。當然 Direct3D 和 Direct2D 不會還提供透過 Windows 執行階段回到隱匿介面實際上繪製此介面是:

ComPtr<abi::ICompositionDrawingSurfaceInterop> surfaceInterop;
check(surface->QueryInterface(set(surfaceInterop)));

更像之前 DirectComposition,Windows 複合功能所提供上列示的 ICompositionDrawingSurfaceInterop 介面經過相同名稱的 Direct2D 方法呼叫的典型呼叫取代 BeginDraw 和 EndDraw 方法:

ComPtr<ID2D1DeviceContext> dc;
POINT offset = {};
check(surfaceInterop->BeginDraw(nullptr, // Update rect
                                __uuidof(dc),
                                reinterpret_cast<void **>(set(dc)),
                                &offset));

Windows 組合會將原始的轉譯裝置提供時間撰寫裝置建立和使用它來建立裝置內容或呈現目標。我可以選擇性地提供在實際的像素的裁剪矩形但是這裡我要只選擇呈現介面的無限制存取。BeginDraw 也會傳回位移再次中實體的像素表示預期的繪圖介面的來源。這不一定會呈現目標的左上角和必須小心調整或轉換以適當地配合此位移任何繪製命令。同樣地,不要呼叫 BeginDraw 呈現目標上為您已經完成的 Windows 組合。此呈現目標以邏輯方式撰寫應用程式開發介面所擁有而且必須小心不必為了 EndDraw 呼叫它。呈現目標現在已準備就緒,但並不知道檢視的邏輯或有效 DPI。我可以使用 Windows::Graphics::Display 命名空間來取得邏輯 DPI 為目前的檢視和設定將用於 Direct2D 所呈現的 DPI:

using namespace Windows::Graphics::Display;
DisplayInformation display = DisplayInformation::GetForCurrentView();
float const dpi = display.LogicalDpi();
dc->SetDpi(dpi, dpi);

轉譯可以開始之前的最後一個步驟是以某種方式處理組合的位移。一個簡單的辦法是使用以產生轉換矩陣的位移。只要記住 Direct2D 往來邏輯像素,因此我需要使用而不是只是位移、 將新建立的 DPI 值:

dc->SetTransform(D2D1::Matrix3x2F::Translation(offset.x * 96.0f / dpi,
                                               offset.y * 96.0f / dpi));

此時您可以繪製您喜歡的內容之前呼叫 EndDraw 方法以確保任何批次的 Direct2D 介面 interop 介面上繪製命令的處理以及到介面的變更會反映在撰寫視覺化樹狀結構:

check(surfaceInterop->EndDraw());

當然,我還沒有視覺效果與尚未相關聯的介面,and 前面提過,視覺效果不再提供內容屬性必須使用筆刷來呈現。幸好複合項將會建立用來代表預先存在的表面筆刷:

CompositionSurfaceBrush brush = compositor.CreateSurfaceBrush(surface);

然後可以建立一般 sprite 筆刷及使用這個筆刷將帶入光線的視覺效果:

SpriteVisual visual = compositor.CreateSpriteVisual();
visual.Brush(brush);
visual.Size(Vector2{ ... });

如果不足夠讓您的互通性,甚至可以採取 XAML 項目並擷取基礎複合視覺效果。以下是在 C# 中的範例:

using Windows.UI.Xaml.Hosting;
Visual visual = ElementCompositionPreview.GetElementVisual(button);

儘管其看似暫存狀態 ElementCompositionPreview 事實上是適合用於生產環境和提交到 Windows 市集應用程式可能使用。假設任何 UI 項目,靜態 GetElementVisual 方法會從基礎組合的視覺化樹狀結構中傳回視覺效果。請注意它會傳回視覺效果而非 ContainerVisual 或 SpriteVisual,因此您無法直接使用視覺化子系或套用筆刷,但是您可以調整 Windows 組合所提供的許多視覺屬性。ElementCompositionPreview 協助程式類別提供一些額外的靜態方法來加入子視覺效果中受控制的方式。您可以變更視覺效果的位移和之類 UI 點擊測試將會繼續在 XAML 層級工作。您甚至可以套用動畫直接與 Windows 撰寫而不會破壞它的基礎建置而成的 XAML 基礎結構。讓我們來建立簡單的純量動畫來旋轉] 按鈕。我需要複合項擷取視覺效果,然後建立之前動畫物件當做:

Compositor compositor = visual.Compositor;
ScalarKeyFrameAnimation animation = compositor.CreateScalarKeyFrameAnimation();

讓我們來建置簡單的動畫緩慢旋轉按鈕不限次數的線性 easing 函式:

animation.InsertKeyFrame(1.0f, (float) (2 * Math.PI),
  compositor.CreateLinearEasingFunction());

我接著可以指出單一旋轉應該採取 3 秒並繼續不限次數:

animation.Duration = TimeSpan.FromSeconds(3);
animation.IterationBehavior = AnimationIterationBehavior.Forever;

最後,我只是可以連接動畫 XAML 指示複合引擎以動畫顯示其 RotationAngle 屬性所提供的視覺效果到:

visual.StartAnimation("RotationAngle", animation);

雖然您可能會拉開這與 XAML 單獨,Windows 撰寫引擎提供更多的威力和彈性假設它位於較低層的抽象層級而且一定可以提供較佳的效能。另一個範例 Windows 組合會提供目前不支援 XAML 四元數動畫。

還有很多談到 Windows 撰寫引擎。在我的淺見,這會是最具突破 WinRT API 的日期。手上的電源量讓人充滿驚喜和但不同於很多其他大型 UI 和圖形 Api,它沒有採用具有效能權衡取捨或甚至是高昂的學習曲線。在許多方面,Windows 組合會是代表所有良好且令人興奮的相關 Windows 平台。

您可以在 Twitter 上找到 Windows 組合小組: @WinComposition


Kenny Kerr是電腦程式設計人員在加拿大和作者基礎 Pluralsight 和 Microsoft MVP。他的部落格網址 kennykerr.ca 以及您可以在 Twitter 上追隨他: @kennykerr

感謝以下的微軟技術專家對本文的審閱: Mark Aldham、 James 耶、 John Serna、 Jeffrey Stall 和 Nick Waggoner