To debug running programs Silverlight5 with XNA

Summary

初めて Silverlight5 で XNA を使用したプログラムをデバッグ実行したときに何も表示されず、どうすれば動くのかわからなかったという人も少なからずいるかと思います。ここでは Silverlight で XNA のプログラムを動かす時の手順について説明します。

この記事では XNA のプログラムを動作させるための手順について説明したものであるため、XNA のプログラム自体については特に説明していませんのでご注意ください。

Operating environment

Silverlight Silverlight5
Visual Studio
  • Visual Studio 2010
  • Visual Studio 2012
  • Visual Studio 2013

Tested environment

Silverlight Silverlight5
Visual Studio Visual Studio Professional 2013

Content

プロジェクトの作成から順番に説明していますので、分かる部分は読み飛ばしてください。

最初に Silverlight アプリケーションを作成します。Visual Studio のメニューから「ファイル」「新規作成」「プロジェクト」を選択します。

プロジェクトの新規作成

「Silverlight アプリケーション」を選択します。

Silverlight アプリケーションを選択

Web サイトのホストについてですが、必ずホストするサイトを指定してください。Silverlight 単体でデバッグ実行したときに自動生成されるテストページでは GPU を使用した XNA のプログラムを動かすことはできません。(ただし、手動でテストページを作成する場合はこの限りではありません)

ホストする Web サイトの作成

プロジェクトが作成されたら Silverlight アプリケーションの「参照設定」を右クリックして「参照の追加」を選択します。

参照の追加

左のメニューから「アセンブリ」「フレームワーク」を選択して以下の項目にチェックを入れます。(まだ OK ボタンは押さないでください)

  • Microsoft.Xna.Framework
  • Microsoft.Xna.Framework.Graphics
  • System.Windows.Xna

参照するアセンブリを選択

続いて左のメニューから「拡張」を選択し、以下の項目にチェックをいれて OK ボタンを押します。

  • Microsoft.Xna.Framework.Graphics.Extensions
  • Microsoft.Xna.Framework.Math

XNA のプログラムを動作させるのに最低限必要なものを選んでいますので、必要に応じて参照するアセンブリを選択してください。

参照するアセンブリを選択

アセンブリの参照が追加されます。

参照一覧

次にコードに手を加えていきます。今回は XNA のプログラムが正常に動作したかが最低限わかるものだけを記載しています。

Silverlight アプリケーションから「MainPage.xaml」を開き以下のコードを追加します。

<Grid x:Name="LayoutRoot" Background="White">
  <!-- 追加ここから -->
  <DrawingSurface Draw="DrawingSurface_Draw" />
  <TextBlock x:Name="textBlockMessage"/>
  <!-- 追加ここまで -->
</Grid>

DrawingSurface は XNA のプログラムでの描画対象エリアになります。実行すると繰り返し Draw イベントが発生するのでそこに描画処理を記述します。今回は正常に動作しているかがわかるように背景色だけを描画するようにします。

textBlockMessage は XNA のプログラムが正常に動作しているかしていないかをテキストで表示するためのものです。今回はそれを確認するための入れているので、実際のリリースではいりません。

次に「MainPage.xaml.cs」ファイルを開きます。最初に using の個所を整理ます。Silverlight アプリケーション向けの名前空間が指定されているので、XNA 用に変更します。実際に作るときはアプリケーションに合わせて定義してください。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
//using System.Windows.Input;
//using System.Windows.Media;
//using System.Windows.Media.Animation;
//using System.Windows.Shapes;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Windows.Graphics;

次に、起動したとき現在の描画モードと描画ができなかった時の理由をテキストで表示するようにします。Silverlight アプリケーションが起動された時に分かるのでコンストラクタに書いています。

public MainPage()
{
  InitializeComponent();

  textBlockMessage.Text
    = string.Format("RenderMode:{0}\r\nRenderModeReason:{1}",
                    GraphicsDeviceManager.Current.RenderMode.ToString(),
                    GraphicsDeviceManager.Current.RenderModeReason);
}

描画処理を書きます。今回は描画イベントが発生したときに XNA Framework で背景を描画するだけにしています。

private void DrawingSurface_Draw(object sender, DrawEventArgs e)
{
  GraphicsDeviceManager.Current.GraphicsDevice.Clear(new Color(0x64, 0x95, 0xED));
}

ではデバッグ実行してみましょう。

デバッグ実行。

実行すると図のように表示されます。RenderMode:Unavailable でハードウェアによる描画が利用できない、RenderModeReason:GPUAccelerationDisabled で GPU による描画が無効となっています。これはサーバー側の問題であるため、まずはこれを有効にする必要があります。

描画ができない

Silverlight の実行でホストされている ASP.NET プロジェクトから「<プロジェクト名>TestPage.aspx」ファイルを開きます。

TestPage.aspx を開く

object のパラメータに「EnableGPUAcceleration」を追加し、値を「true」にします。こうするとサーバー側でこの Silverlight アプリケーションは GPU を使用しますよ、という許可を出したことになります。(実際にはクライアントの処理で解決されるものなのですが、HTML を出力するのはサーバーなのでサーバー側の問題ということにしています)

<body>
  <form id="form1" runat="server" style="height:100%">
    <div id="silverlightControlHost">
      <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
        <param name="source" value="ClientBin/DebugXna.xap"/>
        <param name="onError" value="onSilverlightError" />
        <param name="background" value="white" />
        <param name="minRuntimeVersion" value="5.0.61118.0" />
        <param name="autoUpgrade" value="true" />
        <!-- 追加ここから -->
        <param name="EnableGPUAcceleration" value="true" />
        <!-- 追加ここまで -->
        <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration:none">
          <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Microsoft Silverlight の取得" style="border-style:none"/>
        </a>
      </object>
      <iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe>
    </div>
  </form>
</body>

これで実行してみると図のようになります。RenderModeReason が SecurityBlocked になりました。これは GPU による描画がセキュリティを考慮して既定で許可されていないためです。これはクライアントの問題なのでデバッグ実行に加えて実際にリリースした場合もユーザーに次の手順を実行してもらい、GPU による描画を許可してもらう必要があります。

RenderModeReason が SecurityBlocked に変化

GPU による描画を許可するには、Silverlight アプリケーションを右クリックしてメニューから「Silverlight」を選択します。

Silverlight を選択

ダイアログが開くので「アクセス許可」のタブを選択し、該当するサイトを選択した後「許可」ボタンをクリックします。

アクセス許可

アクセス許可が「許可」になったら OK ボタンをクリックします。

アクセス許可が「許可」に代わる

デバッグ実行中の場合はブラウザを更新しても有効にならないので、いったんブラウザを閉じ再度実行すると、RenderMode がハードウェア描画になり、XNA による背景描画も有効になることがわかります。これで思う存分 XNA のプログラムを作ることができるようになりました。

ハードウェアによる描画が有効

Download