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のデバッグもできます!
次回は、WPFでメニューを作成して、Direct3Dのレンダリングを制御してみましょう。
つづく