なんだか入門を外れたタイトルですが「私が入門編レベルしか紹介できない」というレベルで入門です。
(今作っているアプリで必要なスキルなんですが・・・)
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の描画領域になります。
続いて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 = new DeviceManager();
デバイスへのアクセスを供給するマネージャークラスです。
OnInitializeイベントハンドラーで初期化されたDeviceManagerへのアクセスを提供します。
deviceManager.OnInitialize += d3dTarget.Initialize; deviceManager.OnInitialize += d2dTarget.Initialize; deviceManager.OnInitialize += cubeRenderer.Initialize; deviceManager.OnInitialize += shapeRenderer.Initialize;
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;
立方体を描画する仕組みです。
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