Windowsストアアプリ入門 vol78:SharpDXのサンプルを実行するまで

日曜日 , 21, 10月 2012 Leave a comment

 なんだか入門を外れたタイトルですが「私が入門編レベルしか紹介できない」というレベルで入門です。

 (今作っているアプリで必要なスキルなんですが・・・)

 

 SharpDxはDirectXをC#から利用できるというライブラリです。

 今回はサンプルを実行して仕組みを眺めて見るところまで行きます。

 

 

 

導入

 

 SharpDxページからサンプルをダウンロードします。

 ダウンロードページに移動してSharpDX-Full-2.3.1.exe(2012年10月21日時点)をダウンロードします。

 

うまく解凍できない場合

 

 私の環境だとダウンロードディレクトリだとうまく解凍できないことがあったので、ディレクトリを移動して解凍しました。

 

 以下のようなエラーがでる(出ないでただ解凍できないこともある)場合は、exeを右クリック→「プロパティ」から「ブロックの解除」を行います。

 

 

サンプルを実行する

 

 解凍したディレクトリのSamplesディレクトリを開きます。

 

 

 SharpDXWin8Samples.slnをVisualStudioで開きます。

 以下のようなプロジェクト構成が見られます。

 CommonDxディレクトリが共有のライブラリでそれ以外が実行可能なサンプルプロジェクトです。

 

 

 実行した場合は、そのプロジェクトを「スタートアップ」に設定します。

 プロジェクトを右クリックして下の画像のように「スタートアッププロジェクトに設定」に指定します。

 

 

 MinCubeBrushXamlを実行します。

 

 

 XAML+DirectXという面白いサンプルが実行されました。

 

仕組みを眺めてみる

 

 このサンプルはどのような仕組みで実行されているんのでしょう?

 MainPage.xamlを見ると以下のような簡単な構図です。

 

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Canvas x:Name="d3dCanvas" HorizontalAlignment="Left" Height="401.27" Margin="207.611,85.365,0,0" VerticalAlignment="Top" Width="398.778" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto">
        	<Canvas.RenderTransform>
        		<CompositeTransform Rotation="30"/>
        	</Canvas.RenderTransform>
        	<TextBlock x:Name="textBlock" Text="SharpDX
Direct3D11-XAML
Brush Interop!" FontFamily="Verdana" FontSize="26.667" FontStyle="Italic" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center" Height="109.088" Width="332" Canvas.Left="33.342" Canvas.Top="10"/>
        	<Rectangle x:Name="d3dRectangle"  Height="267.182" Canvas.Left="33.342" Stroke="Black" Canvas.Top="124.088" Width="332"/>
        </Canvas>
        <Canvas x:Name="d2dCanvas" HorizontalAlignment="Left" Height="401.27" Margin="734.111,194.865,0,0" VerticalAlignment="Top" Width="398.778" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto">
            <Canvas.RenderTransform>
                <CompositeTransform Rotation="30"/>
            </Canvas.RenderTransform>
            <TextBlock x:Name="textBlock1" Text="SharpDX
Direct2D-XAML
Brush Interop!" FontFamily="Verdana" FontSize="26.667" FontStyle="Italic" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center" Height="109.088" Width="332" Canvas.Left="33.342" Canvas.Top="10"/>
            <Rectangle x:Name="d2dRectangle" Height="267.182" Canvas.Left="33.342" Stroke="Black" Canvas.Top="124.088" Width="332"/>
        </Canvas>

 

 傾けたCanvasコントロールの中にRectangleが一つずつ配置されています。

 このRectangleがDirectXの描画領域になります。

 

C#コード

 

 続いてMainPage.xaml.csコードを見てみます。

 こちらはちょっと簡単とはいえません。

 

            d3dDragHandler = new DragHandler(d3dCanvas) { CursorOver = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeAll, 1) };
            d2dDragHandler = new DragHandler(d2dCanvas) { CursorOver = new Windows.UI.Core.CoreCursor(Windows.UI.Core.CoreCursorType.SizeAll, 1) };

 

 CommonDXディレクトリにあるDragHandlerを利用することでドラッグ操作とその場合のカーソルの変更を可能にします。

 

 

DeviceManagerクラス

 

deviceManager = new DeviceManager();

 

 デバイスへのアクセスを供給するマネージャークラスです。

 OnInitializeイベントハンドラーで初期化されたDeviceManagerへのアクセスを提供します。

 

            deviceManager.OnInitialize += d3dTarget.Initialize;
            deviceManager.OnInitialize += d2dTarget.Initialize;
            deviceManager.OnInitialize += cubeRenderer.Initialize;
            deviceManager.OnInitialize += shapeRenderer.Initialize;

 

SurfaceImageSourceTargetクラス

 

 XAMLにDirectX映像を描画するにはSurfaceImageSourceTargetクラスを利用します。

 

            // Use CoreWindowTarget as the rendering target (Initialize SwapChain, RenderTargetView, DepthStencilView, BitmapTarget)
            d3dTarget = new SurfaceImageSourceTarget(pixelWidth, pixelHeight);
            d3dBrush.ImageSource = d3dTarget.ImageSource;

 

 ImageBrushのImageSourceとして描画を渡す感じですね。

 SurfaceImageSourceTargetのOnRenderを次々と呼び出すことで画面がアニメーション表示されます。

 

            // Render the cube within the CoreWindow
            d3dTarget.OnRender += cubeRenderer.Render;
            d2dTarget.OnRender += shapeRenderer.Render;

 

CubeRendererクラス

 

 立方体を描画する仕組みです。

 DeviceManagerのOnInitializeイベントでInitializeが実行され、

 SurfaceImageSourceTargetのOnRenderイベントでRenderメソッドが実行されます。

 ここまではシンプルですね。

 

 ここから先もまぁ簡単なサンプルなのでコードはシンプルなんですが以下の部分が問題・・・

 

            // Loads vertex shader bytecode
            var vertexShaderByteCode = NativeFile.ReadAllBytes(path + "\\MiniCube_VS.fxo");
            vertexShader = new VertexShader(d3dDevice, vertexShaderByteCode);

            // Loads pixel shader bytecode
            pixelShader = new PixelShader(d3dDevice, NativeFile.ReadAllBytes(path + "\\MiniCube_PS.fxo"));

 

 「ちょうてんしぇだー」と「ぴくせるしぇーだー」を「えふえっくすおー形式(.fxo)」というバイナリ化されたフィルで指定しています。

 (ひらがな表記は理解力をあらわしています)

 この辺がよくわからない、今後の調査が必要という感じなんですが。fxoファイルを使わないでコードで描画しているサンプルないかなぁ。

 

 以下のようにBufferで色々なデータを処理しているのも型がわからず理解が難しいですね。慣れの問題かな・・・。

 

            vertexBufferBinding = new VertexBufferBinding(vertices, Utilities.SizeOf<Vector4>() * 2, 0);

            // Create Constant Buffer
            constantBuffer = ToDispose(new SharpDX.Direct3D11.Buffer(d3dDevice, Utilities.SizeOf<Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0)

 

 この辺がちゃんと理解できたら入門編その2を書こうかなと思いますが、ちょっと先の話になりそうです。

 

 というわけで、入り口までのご案内を終了します。

 


Please give us your valuable comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です