Compartilhar via


D3DImage チュートリアル ⑥ C#の編集

コードビハインドでは、D3DWrapper.cppで実装したD3DWrapperクラスをコンストラクトして、Initialize(およびInitGeometry), Render, Cleanupを呼び出すメソッドを実装します。

StartDXRenderingメソッドはInitialize(およびInitGeometry)を呼び出し、D3DImageとD3DSurfaceとを対応付け、レンダリング用のイベントハンドラーを定義します。

private readonly D3DWrapper myD3DScene = new D3DWrapper();

private void StartDXRendering()
{
  if (!myD3DImage.IsFrontBufferAvailable)
    return;

  IntPtr scene =
myD3DScene.Initialize(
new WindowInteropHelper(this).Handle);
  myD3DScene.InitGeometry();
  myD3DImage.Lock();
  myD3DImage.SetBackBuffer(
D3DResourceType.IDirect3DSurface9, scene);
  myD3DImage.Unlock();

  CompositionTarget.Rendering +=
new EventHandler(OnRendering);
}

StopRenderingメソッドはCleanupを呼び出し、StartDXRenderingで定義したイベントハンドラーを削除します。

private void StopDXRendering()
{
  CompositionTarget.Rendering -= OnRendering;
  myD3DScene.Cleanup();
}

OnRenderメソッドはD3DImageをロックし、Renderを呼び出し、D3DImage.AddDirtyRectを呼び出してから(書き込む範囲を決める)、ロック解除します。このメソッドはレンダリング可能な時いつも呼び出されます。

void OnRendering(object sender, EventArgs e)
{
  if (!myD3DImage.IsFrontBufferAvailable)
    return;

  myD3DImage.Lock();
  int width = 0, height = 0;
  myD3DScene.Render(ref width, ref height);
  myD3DImage.AddDirtyRect(new Int32Rect(0, 0, width, height));
  myD3DImage.Unlock();
}

残りは、XAMLで宣言したイベントハンドラーのコールバックを実装するだけです。Load時にはStartDXRenderingを呼び出し、フロントバッファの状態が変化したときは、IsFrontBufferAvailableをチェックして、StartDXRenderingかStopDXRenderingを呼び出します。

private void Window_Loaded(object sender,RoutedEventArgs e)
{
  StartDXRendering();
}

 

private void myD3DImage_IsFrontBufferAvailableChanged(
object sender, DependencyPropertyChangedEventArgs e)
{
  if (myD3DImage.IsFrontBufferAvailable)
  {
    StartDXRendering();
  }
  else
  {
    StopDXRendering();
  }
}

これでひとまず完成です。F5キーを押してデバッグ実行してください。以下のようにSample Browserからインストールした同じトラが回転しているはずです。D3DRenderer.cppのRenderメソッドにブレークポイントを追加すれば、ネイティブCPPのデバッグもできます!

image

次回は、WPFでメニューを作成して、Direct3Dのレンダリングを制御してみましょう。

つづく