Mango Teapot ① Silverlight と XNA によるグラフィックス デバイスの共有

Windows Phone "Mango" では、Silverlight と XNA でグラフィックス デバイス(GPU サーフェイス)の共有が可能になっており、両方の API を使って同じ画面の描画ができるようになりました。また、カメラやコンパスや加速度計などさまざまなセンサーもアプリケーションから利用できるようになりました。

先日の「Windows Phone "Mango" 開発支援セミナー」用に、これらを活用したAR(Argument Reality)サンプル Mango Teapot を作成したので、その内容を数回に分けて解説します。

Mango Teapot は Windows Phone 7.5 の AR アプリケーション サンプルです。ソースコードは mangoteapot.codeplex.com で公開しています。ビルドするには Windows Phone SDK 7.1 Beta 2 が必要です。エミュレータでも動作しますが、実機での動作には Windows Phone “Mango” が必要ですので、もう少しお待ちください。

  1. Silverlight と XNA によるグラフィックス デバイスの共有
  2. Teapot クラス
  3. 加速度センサーと モーション
  4. カメラ

 

 Mango Teapot

 

Silverlight と XNA によるグラフィックス デバイスの共有

これまで Windows Phone 7 では Silverlight アプリケーションは PhoneApplicationPage の派生クラスで作成し、XNA アプリケーションは Game クラスの派生クラスで作成していたため、Silverlight と XNA の両方を使ってグラフィックス デバイスを共有することはできませんでした。つまり、一つの画面にXNA のコンテンツと Silverlight のメニューを混在させることができませんでした。

“Mango” では PhoneApplicationPage の派生クラスでの XNA の描画が可能になっています。これによって、高速な直接モードのグラフィックス(特に3D)とXAMLやUIコントロールによる容易なUIデザインとの良いとこ取りが可能になりました。そのカギとなっているのは以下の4つのクラスです。

GameTimer

GameTimer は、Game 派生クラスと同じ様に、Update メソッドと Draw メソッドが定期的に(通常30ミリ秒)で呼び出されるようにするタイマー クラスです。

timer = new GameTimer();

timer.UpdateInterval = TimeSpan.FromTicks(333333);

timer.Update += OnUpdate;

timer.Draw += OnDraw;

ContentManager

XNA では、Content プロジェクトに画像やサウンドや 3D データのようなコンテンツを登録し、ゲーム プロジェクトからロードします。ContentManager は PhoneApplicationPage 派生クラスから Content プロジェクトのコンテンツをロードするためのクラスです。

ContentManager content = (Application.Current as App).Content;

SoundEffect plink = content.Load<SoundEffect>("plink");

Texture2D t_GreenGem = content.Load<Texture2D>("GreenGem");

SharedGraphicsDeviceManager

XNA と Silverlight で共有するグラフィックス デバイスを管理するクラスです。SetSharingMode メソッドの引数を true にすると共有可能になります。

GraphicsDevice device =
SharedGraphicsDeviceManager.Current.GraphicsDevice;

device.SetSharingMode(true);

 

UIElementRenderer

XNA のDrawメソッド内で、XAML などで定義した Silverlight のコンテンツから XNA のテクスチャを生成するクラスです。生成したテクスチャをスプライト バッチで描画します。

UIElementRenderer elementRenderer = new UIElementRenderer
(this, device.Viewport.Width, device.Viewport.Height);

private void OnDraw(object sender, GameTimerEventArgs e)

{

  // Silverlight UI をテクスチャに描画

  elementRenderer.Render();

  // デバイスのクリーンアップ

  SharedGraphicsDeviceManager.Current.GraphicsDevice.
Clear(Color.CornflowerBlue);

 

  // Silverlight UI 要素の描画

  spriteBatch.Begin();

  spriteBatch.Draw(elementRenderer.Texture,
Vector2.Zero, Color.White);

  spriteBatch.End();

 

  // Teapot の描画

  teapot.Draw(SharedGraphicsDeviceManager.
Current.GraphicsDevice);

}

次回は Teapot クラスを解説します。