LoginSignup
17

More than 5 years have passed since last update.

WPFデスクトップアプリでDirect2Dを使う

Last updated at Posted at 2015-12-27

はじめに

WPFのデスクトップアプリでDirect2D描画をしたいと思ったのですが、検索しても情報が古かったりいまいち良い方法が見当たりません。
割と新しめのは

  • Win2D: ユニバーサルアプリ前提なら
  • WPFDXInterop: pre-release(2015/12/27時点)。今後はこれが本命?

あたりですが、今回はデスクトップアプリで使いたかったのとSharpDXを試してみたい、ということでWPFコントロールを作ってみました。
(とはいえ大半のソースは古いSharpDX/SlimDXのWPF向けサンプルソースから持ってきてるので、今回の作業はDirectX11環境向けの調整とソースの整理、nugetパッケージ化くらいです)

この記事を書いているときに気づきましたが、SharpDXはDirectX12対応の3.0.0がリリースされたようです。
時間が出来たら今回作ったコントロールも対応させるかもしれません。

(2016/1/2追記)
SharpDXのバージョンを3.0.0に上げてリリース(D2dControl 1.1.5)しました。
とりあえずSharpDX側の名前空間変更を反映しただけで、Direct2Dの新機能(DrawGradientMeshとかDrawInkとか?)はよくわからないので未対応です…

動作確認環境

  • Windows10 / DirectX11
  • Visual Studio 2015
  • SharpDX 2.6.3

リンク

Github
Nuget

使い方

サンプルソースを見れば大体わかるかと思います。
基本的にはD2dControlを継承したクラスを作り、Render内でtargetに対してDirect2Dの描画関数を呼ぶだけです。
通常描画の前後でBeginDraw/EndDrawを呼ぶ必要がありますが、基底クラス側で呼んでいるのでここでは必要ありません。

    class TestControl : D2dControl.D2dControl {
        public override void Render( RenderTarget target ) {
            target.Clear( Color4.Black );
        }
    }

また、RenderTargetに依存するリソース(ブラシなど)を格納するためのリソースキャッシュも提供しています。
Render内でリソースの生成を行うと、これは毎フレーム呼ばれるのでパフォーマンス上よろしくないです。
だからと言ってメンバとして保持するとtargetが変わった際に例外で落ちます。
(実際Controlのリサイズ等でtargetは再生成されます)
というわけでresCahceRenderTargetを引数とするリソース生成用delegateを渡せばtarget更新時のリソース再生成などをやってくれるようになっています。

    class TestControl : D2dControl.D2dControl {
        public TestControl() {
            resCache.Add( "Brush", t => new SolidColorBrush( t, Color4.White ) );
        }

        public override void Render( RenderTarget target ) {
            var brush = resCache["Brush"] as Brush;
            target.DrawRectangle( new RectangleF( 10, 10, 10, 10 ), brush );
        }
    }

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17