XNA Frameworkブログ
 

March, 2010

  • ひにけにXNA

    SpriteBatchとEffect

    • 2 Comments

    SpriteBatchにEffectを指定する

    前回の投稿ではXNA Framework 4.0で新しくなったSpriteBatch.Beginメソッドの紹介と、任意のレンダーステートを使ったものを例として紹介しました。今回はSpriteBatch.BeginメソッドにEffectを設定する方法を紹介します。

    前回も説明したとおり、Effectを設定する場合は以下の二通りのシナリオを考えて設計されています。

    1. 通常のスプライト描画で、主にピクセルシェーダーによってカスタマイズする
    2. View、Projectionなどを使用した3D効果

    1のシナリオでは、例えば画面全体をセピア色に変更したりする単純なカラー操作や、画像を波打たせるような効果を表現したいときに有効です。

    2のシナリオでは、スプライト自体を3Dの板として扱い、拡大縮小をはじめ、スプライトを任意の軸で傾けるといった効果を表現したいときなどがあります。

    Effectを使った2D描画

    SpriteBatch.Beginメソッドに指定した場合、SpriteBatchはスプライトの四角形の各頂点の生成は通常通り行いますが、2D描画用の行列計算は使用するEffect側で設定する必要があります。

    Reachプロファイルではシェーダーがサポートされていないので、CTP版ではピクセルシェーダーを使えませんが(HiDefのリリースまで待ってね)、ここではBasicEffectを使って2D描画する例を紹介します。

    // BasicEffectを生成し、必要なパラメーターを設定する
    effect = new BasicEffect(GraphicsDevice); effect.TextureEnabled = true; effect.VertexColorEnabled = true; Rectangle rc = GraphicsDevice.Viewport.Bounds; // 2D描画用のプロジェクション行列を計算する
    // XNA(DX9)のスクリーン座標は0.5ピクセルずれているので、
    // その調整をするのを忘れずに
    effect.Projection = Matrix.CreateTranslation( -0.5f, -0.5f, 0) * Matrix.CreateOrthographicOffCenter( rc.Left, rc.Right, rc.Bottom, rc.Top, 0, 100 ); effect.View = Matrix.Identity; effect.World = Matrix.Identity; spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, effect); spriteBatch.Draw(gridTex, new Vector2(150, 40), Color.White ); spriteBatch.End();

    2D描画用の行列計算をするのにMatrix.CreateOrthographicOffCenterメソッドに現在のViewportの矩形を指定しています。また、XNA(DX9)のスクリーン座標は0.5ピクセルずれているので���CreateOrthgraphicOffCenterメソッドで作った行列だけを指定すると、常にピクセルがずれた状態になります。この状態を防ぐためにMatrix.CreateTranslationを使って半ピクセル元に戻すようにしています。

    SpriteBatchで3D描画

    Effectを指定して3D描画する場合は、通常の3D描画と同様にView、Projection、そしてWorld行列を使用することができます。3D描画の場合、Vector2ではなくVector3を使いますがSpriteBatchを使用して描画した場合、各頂点のXとY座標はDrawメソッドに渡された座標を使い、Z値にはlayerDepthに渡された値を使います。

    ひとつ注意しないといけないのは、スクリーン座標と3D座標でY座標が上下反転しているということです。スクリーン座標ではY座標は画面の上の方がマイナスで下がプラスになっていますが、3D座標では画面の上の方がプラスで下がマイナスになります。ですから、普通に描画するとスプライトの上下が逆転してしまいます。結果的にポリゴンの描画方向が逆になるのでカリング対象になり、描画されていないように見えてしまいます。

    対処方法としてはゲームによって変わってきます。例えば2Dゲーム部分がメインで3D効果が少しの場合はスクリーン座標でコーディングして、3D効果の部分をスクリーン座標に合わせた行列を生成するようにするようにする手法を使います。逆に2Dゲームだけど3D効果を多用したい場合は、全てのスプライト描画をワールド座標で行ってしまうという手法があります。

    ここでは後者の方法を採用し、スプライトの描画はワールド座標で指定しています。また、描画方向逆転の問題は高さのパラメーターにマイナスの値を指定することで解決しています。

    // BasicEffectを生成し、3D描画に必要な行列を設定する
    effect = new BasicEffect(GraphicsDevice); effect.TextureEnabled = true; effect.VertexColorEnabled = true; effect.EnableDefaultLighting(); effect.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(45.0f), GraphicsDevice.Viewport.AspectRatio, 1.0f, 1000.0f); effect.View = Matrix.CreateLookAt(new Vector3(0, 0, 13), Vector3.Zero, Vector3.Up); effect.World = Matrix.CreateRotationX(MathHelper.ToRadians(-50.0f)); // エフェクトを指定して3D描画をする
    // 通常の3D描画として扱うのでDepthStencilState.Defaultを設定する
    spriteBatch.Begin(SpriteSortMode.Immediate, null, null, DepthStencilState.Default, null, effect); spriteBatch.Draw(texture, new Rectangle(-5, 5, 10, -10), // 高さがマイナスになっていることに注意 null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0 // layerDepth値はZ値として使われる ); spriteBatch.End();

    このコードを実行すると、以下の画像のようにスプライトを画面奥に向けて傾けて描画することができます。image

    また、SpriteBatch.Beginを呼んでからDrawメソッドをEffectのWorld行列を変更しながら描画することもできます。以前はSpriteSortMode.Immediateを指定してもテクスチャが同じ場合はSpriteBatch.Endメソッドが呼ばれたときにまとめて描画するようになっていましたが、4.0ではSpriteBatch.Being/End間でEffectのパラメーターを変更しながら描画するというシナリオに対応する為にSpriteSortMode.Immediateを指定した場合はDrawを呼ぶごとに実際に描画するようになりました。

    下の画面はGamefest 2010のデモ画面ですが、元のコードはプログラムで頂点バッファやインデックスバッファ、頂点宣言等を使用して3Dのポリゴンとして描画していました。ですが、ここでは3Dテキスト以外は全てSpriteBatchで描画するように変更しています。静止画だと判りづらいのですが、このシーンは複数の3Dのリング状に並んだ画像が回転しているものです。

    SpriteBatch3D また、Reachプロファイルでも使えるBasicEffectを使用しているので、まったく同じコードがWindows Phone 7 シリーズでも動作します。 SpriteBatch3D02

    まとめ

    以上のようにXNA Game Studio 4.0ではSpriteBatchのカスタム描画が容易となり、今までは難しかった3D効果もで容易にできるようになりました。

    で、以下はお約束の注意点です。

    • スクリーン座標とワールド座標ではY軸が逆になっている
    • 3D効果を使いたい場合は、使用する画像にミップマップを指定しないと、見た目が悪くなるのとパフォーマンス低下に繋がる場合があるので、できる限りミップマップを指定すること
    • ただし、Reachプロファイルではミップマップは2の乗数のサイズのテクスチャに限られていることに注意(実行時エラーとなる)。元の素材のサイズを変更するか、テクスチャプロセッサーのパラメーターで2のn乗のサイズに変更するように指定する
    • Effectに渡されるのは頂点座標とカラー、UV座標のみ。法線はEffectに渡されないのでライティング処理をする場合はシェーダー内で生成する必要がある(HiDefのみ)
  • ひにけにXNA

    SpriteBatchとレンダーステート

    • 0 Comments

    SpriteBatchをカスタマイズしたい

    SpriteBatchクラスはXNA Frameworkの中で最も使用頻度の高いクラスで、特に2Dゲームでは必須の機能です。私達がXNA GSE 1.0でSpriteBatchをデザインしたときには、一般的な2Dスプライト描画ができることが主な目的でした。確かにSpriteBatchは通常の2Dスプライトを描画するには非常に便利な機能ですが、いくつかの要望がありました。

    1. アルファブレンドをはじめとしたレンダーステートを自由に設定したい
    2. カスタムエフェクトと併用したい
    3. 3D効果が使いたい

    1についてですが、今までにSpriteBatch.Beginメソッドに指定できるSpriteBlendMode列挙には4つのブレンドモードしかなく、これ以外のブレンドモード、例えば色反転用のブレンドモードなどはサポートされていませんでした。

    2については特に独自のピクセルシェーダーを使いたいときなどにカスタムエフェクトは有効な手段ですが、オンラインドキュメントの「スプライトへのピクセルシェーダーの適用」にあるように、直感的ではないコードを書く必要がありました。

    3の3D効果についてですが今までのSpriteBatch.Beginメソッドには任意の行列を指定できるオーバーロードがありましたが、もともとは画面全体に対してスケーリングや回転などの処理をする時のために設計されたものなので、個々のスプライトを3D表示するのには向いていませんでした。

    刷新されたSpriteBatch.Beginメソッド

    これらの要望を解決するために4.0ではSpriteBatch.Beginメソッドを変更しました。以下は4.0のSpriteBatch.Beginメソッドです。

    SpriteBatch.Begin ()
    SpriteBatch.Begin (SpriteSortMode, BlendState)
    SpriteBatch.Begin (SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState)
    SpriteBatch.Begin (SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState, Effect)
    SpriteBatch.Begin (SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState, Effect, Matrix)

    以前あったSpriteBlendModeやSaveStateModeが消えた代わりに、レンダーステートオブジェクトと任意のEffectが指定できるようになりました。ちなみにSpriteSortModeとMatrix以外のパラメーターは全てnullを指定することでき、nullを指定した場合は規定値を設定するようになっています。

    引数の無いSpriteBatch.Beginメソッドを使用した場合、以下のコードと同様になります。

    // spriteBatch.Begin()を読んだ場合、以下のコードと同じ意味を持つ
    spriteBatch.Begin(
        SpriteSortMode.Deferred,
        BlendState.AlphaBlend,
        SamplerState.LinearClamp,
        DepthStencilState.None,
        RasterizerState.CullCounterClockwise
        );

    任意のレンダーステートを指定する

    このようにレンダーステートオブジェクトをSpriteBatch.Beginメソッドに直接指定できるようになったので、任意のブレンドステートを容易に指定できるようになりました。

    例えば色反転をするブレンドステートを使いたい場合は、以下のコードのようになります。

    // 普通にスプライトを二つ並べて描画する
    spriteBatch.Begin(); spriteBatch.Draw(tex, new Rectangle(0, 100, 400, 400), Color.White); spriteBatch.Draw(tex, new Rectangle(400, 100, 400, 400), Color.White); spriteBatch.End(); // 色反転用のブレンドステートを生成する
    BlendState invColorBlend = new BlendState { ColorBlendFunction = BlendFunction.Subtract, AlphaBlendFunction = BlendFunction.Subtract,
    ColorDestinationBlend = Blend.One, AlphaDestinationBlend = Blend.One, }; // 色反転用のブレンドステートを指定して、右側画像の色を反転する spriteBatch.Begin(SpriteSortMode.Deferred, invColorBlend); spriteBatch.Draw(whiteTex, new Rectangle(400, 100, 400, 400), Color.White); spriteBatch.End();

    いままでのようにSpriteSortMode.Immideateを指定して、Beginメソッドを読んだ後にレンダーステート設定するといった直感的でないコードを書く必要がなくなり、簡潔に書けるようになりました。

    このコードを実行すると、以下のような結果になります。 the-world

     SpriteBatchとレンダーステート

    今までと同じようにSpriteBatchはレンダーステートを変更します。今までは指定したSpriteBlendModeによって変更されるレンダーステートが変わったりするので、レンダーステートを手動で元に戻すのは面倒な作業でした。4.0ではレンダーステートオブジェクトのお陰でSpriteBatchによって変更されたレンダーステートを元に戻すのが容易になりました。

    SpriteBatchによって変更されたレンダーステートは以下の三行のコードで元に戻すことができます。

    GraphicsDevice.BlendState = BlendState.Opaque;
    GraphicsDevice.DepthStencilState = DepthStencilState.Default;
    GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

    なぜLinearClampなのか?

    通常、3Dモデルを表示する場合、テクスチャのアドレッシングモードはWrapを使用します。これはテクスチャを連続して並べるようにして表示することができからです。実際、SamplerStateの規定値はLinearWrapになっています。

    ではなぜSpriteBatchではLinearClampを設定しているのでしょうか?

    これはReachプロファイルで対応しているハードウェアの制限から来ています。Reachプロファイル対象となるGPUには2の乗数ではないサイズ(2,4,8,16,32,64,128,256,512…といったサイズ以外)のテクスチャにはWrapを指定できないという制約があります。

    タイトル画面の画像をはじめとして、SpriteBatchを使う場合は任意のサイズの画像を使用するケースが多くなります。もし、SpriteBatchで指定する規定値がLinearWrapになっていた場合、「タイトル画面は1280x720の画像を表示しよう」というときにReachプロファイルでは実行時にエラーとなってしまう問題があります。

    以上の理由からSpriteBatchのSamplerStateはLinearClampを指定するようになっています。

    次回は新しくなったSpriteBatchとカスタムエフェクトの使い方を紹介します。

  • ひにけにXNA

    消えたRenderState

    • 0 Comments

    カテゴリ分けされたレンダーステート

    XNA Game Studio 3.1では描画するときに欠かせないレンダーステート情報を変更するには、GraphicsDevice.RenderStateプロパティを介する必要がありました。プロパティ化したことにより、デバッガ上で即座にレンダーステートを確認できるというのはC++でDirectXを使っていた時よりも格段に使いやすくなっていました。

    ですが、RenderStateクラスには実に70近いプロパティがあり、中には複数のプロパティを正しく設定しないと思い通りに描画できないといった問題があったり、Visual Studio上で編集しているときでもインテリセンスに表示される候補が多すぎるという問題がありました。また、パフォーマンス的にも複数のレンダーステートを設定するのは時間が掛かってしまいます。さらにコードのメンテナンスしやすさの面から見ても、これだけの量のレンダーステートを人力で管理するのは難しく、かといって安易にStateBlockを使用すると更なるパフォーマンス低下の原因になってしまうという問題がありました。

    そこで、XNA Framework 4.0ではこれらの問題を解決する為に、レンダーステートを以下の4つのステートにカテゴリ分けしています。

    • BlendState
      • 半透明処理など、カラーブレンディングに関するステート
    • DepthStencilState
      • 深度バッファやステンシルバッファに関するステート
    • RasterizerState
      • ポリゴンのフィルモード、マルチサンプル設定などラスタライズ時に関するステート
    • SamplerState
      • テクスチャのサンプリングフィルターやアドレスモードなどのステート

    また、GraphicsDeviceにはBlendFactorプロパティがあり、BlendState.BlendFactorと同じものです。これはBlendFactorを使用するBlendStateを設定した後にBlendFactorの値だけを変えたい時の為に用意されています。GraphicsDevice.ReferenceStencilとDepthStencilState.ReferenceStecilの関係も同じものです。

    各ステートの初期化と設定方法

    それぞれのレンダーステートはあらかじめオブジェクトとして生成する必要があります。例えばBlendStateの場合は以下のように生成します。

    // 一般的な半透明ステートオブジェクトを生成する
    BlendState myState1 = new BlendState(); myState1.ColorSourceBlend = Blend.SourceAlpha; myState1.AlphaSourceBlend = Blend.SourceAlpha; myState1.ColorDestinationBlend = Blend.InverseSourceAlpha; myState1.AlphaDestinationBlend = Blend.InverseSourceAlpha;

    もしくは、C# 3.0から使えるようになったオブジェクト初期化子を使用して

    BlendState myState2 = new BlendState
    {
        ColorSourceBlend = Blend.SourceAlpha,
        AlphaSourceBlend = Blend.SourceAlpha,
        ColorDestinationBlend = Blend.InverseSourceAlpha,
        AlphaDestinationBlend = Blend.InverseSourceAlpha,
    };

    のように書くこともできます。この書き方のが一行ごとにオブジェクト名を書かなくて良いのですっきりとした感じになります。

    こうしてできたステートオブジェクトはGraphicsDeviceクラスのプロパティに設定することでレンダーステートを変更することができます。

    GraphicsDevice.BlendState = myState1;

    あらかじめ宣言されたステート

    このままだと、レンダーステートを設定する時にあらかじめ使用するステートオブジェクト作らないといけないので、それらを管理する手間が増えてしまいます。確かに、その方がパフォーマンス的には有利なのですが、良く使われるレンダーステートくらいは直ぐに使いたいと思う人が多いでしょう。

    そこで、それぞれのレンダーステートクラスには良く使われるステートの組み合わせが静的プロパティとしてあらかじめ用意されています。

    BlendStateであらかじめ宣言されているBlendStateプロパティ

    プロパティ名 意味 設定値
    Addtive 加算半透明用ブレンドステート ColorSourceBlend = Blend.SourceAlpha,
    AlphaSourceBlend = Blend.Blend.SourceAlpha,
    ColorDestinationBlend = Blend.One,
    AlphaDestinationBlend = Blend.One,
    AlphaBlend 半透明用ブレンドステート
    (アルファ値乗算済み)
    ColorSourceBlend = Blend.One,
    AlphaSourceBlend = Blend.One,
    ColorDestinationBlend = Blend.InverseSourceAlpha,
    AlphaDestinationBlend = Blend.InverseSourceAlpha,
    NonPremultiplied 半透明用ブレンドステート
    (一般的な半透明)
    ColorSourceBlend = Blend.SourceAlpha,
    AlphaSourceBlend = Blend.SourceAlpha,
    ColorDestinationBlend = Blend.InverseSourceAlpha,
    AlphaDestinationBlend = Blend.InverseSourceAlpha,
    Opaque 不透明用ブレンドステート(規定値) ColorSourceBlend = Blend.One,
    AlphaSourceBlend = Blend.One,
    ColorDestinationBlend = Blend.Zero,
    AlphaDestinationBlend = Blend.Zero,

    DepthStencilStateであらかじめ宣言されているDepthStencilStateプロパティ

    プロパティ名 意味 設定値
    Default 規定値、深度バッファの読み込み、更新あり DepthBufferEnable = true,
    DepthBufferWriteEnable = true,
    DepthRead 読み込みのみ
    深度バッファとの比較はするが、深度バッファの更新はしない。パーティクル等の半透明描画時に使用する
    DepthBufferEnable = true,
    DepthBufferWriteEnable = false,
    None 深度バッファを使用しない DepthBufferEnable = false, DepthBufferWriteEnable = false,

    RasterizerStateであらかじめ宣言されているRasterizerStateプロパティ

    プロパティ名 意味 設定値
    CullClockwise 時計方向回りのプリミティブをカリングする CullMode = CullMode.CullClockwiseFace,
    CullCounterClockwise 反時計方向回りのプリミティブをカリングする(規定値) CullMode = CullMode.CullCounterClockwiseFace,
    CullNoneNone カリングなし CullMode = CullMode.None,

    SamplerStateであらかじめ宣言されているSamplerStateプロパティ

    プロパティ名 意味 設定値
    AnisotropicClamp アニソトロピックフィルタリング(異方向性フィルタリング)、クランプ Filter = TextureFilter.Anisotropic,
    AddressU = TextureAddressMode.Clamp,
    AddressV = TextureAddressMode.Clamp,
    AddressW = TextureAddressMode.Clamp,
    AnisotropicWrap アニソトロピックフィルタリング(異方向性フィルタリング)、ラッピングあり Filter = TextureFilter.Anisotropic,
    AddressU = TextureAddressMode.Wrap,
    AddressV = TextureAddressMode.Wrap,
    AddressW = TextureAddressMode.Wrap,
    LinearClamp リニアフィルタリング、クランプ Filter = TextureFilter.Linear,
    AddressU = TextureAddressMode.Clamp,
    AddressV = TextureAddressMode.Clamp,
    AddressW = TextureAddressMode.Clamp,
    LinearWrap リニアフィルタリング、ラッピングあり(規定値) Filter = TextureFilter.Linear,
    AddressU = TextureAddressMode.Wrap,
    AddressV = TextureAddressMode.Wrap,
    AddressW = TextureAddressMode.Wrap,
    PointClamp ポイントフィルタリング、クランプ Filter = TextureFilter.Point,
    AddressU = TextureAddressMode.Clamp,
    AddressV = TextureAddressMode.Clamp,
    AddressW = TextureAddressMode.Clamp,
    PointWrap ポイントフィルタリング、ラッピングあり Filter = TextureFilter.Point, AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap, AddressW = TextureAddressMode.Wrap,

    レンダーステートの管理が簡単になった

    これら四種類のレンダーステートオブジェクトにカテゴリ分けと、あらかじめ用意されているステートの組み合わせを使用することでレンダーステートの管理がしやすくなりました。どれぐらい簡単になったかというと、例えば全てのレンダーステートを初期値に戻したいという場合があったとします(普段はあまりないけれど)。このケースの場合は以下の数行を書き加えるだけで実現することができます。

    // レンダーステートを初期値に戻す
    GraphicsDevice.BlendState = BlendState.Opaque; GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; // サンプラーステート数はReach、HiDefともに16個 for (int i = 0; i < 16; ++i) GraphicsDevice.SamplerStates[i] = SamplerState.LinearWrap;
  • ひにけにXNA

    XNA Game Studio 4.0、グラフィクスAPI・リファクタリング

    • 0 Comments

    XNA Frameworkの歴史

    XNAチームは発足当初から他のMicrosoftのプロダクトチームに比べると非常に少ない人数です。人数的に見て他のチームがXNAチームの10倍の規模なんていうのは普通にあることで、時には100倍の人数規模のチームと仕事をするなんてこともあります。

    私達がXNA Game Studio 1.0の時にFrameworkを設計したときにはXbox 360上で.Net CFを動くようになったのは最初のリリースの四ケ月程前でした。もちろん、たった四ケ月という期間と少ない人員でFrameworkの設計、実装、そしてテストをすることはできないので、Xbox 360上で.Net CFが動くまでの間に平行して他の作業を進めました。

    この時点で私達が設計、実装ができたのはWindows上のみだったので、自然とManaged DirectXの設計を参考にする機会が多くなり、どちらかというとDirectX 9.0のラッパーのようなものが多くなりました。

    この方針は設計期間を短くすることに繋がったのですが、後になってXbox 360とWindows上の動作に違い、例えばRenderTarget2Dの振る舞いの違いなどがあることに気づいた時には既にAPIの仕様を変更するには遅すぎる時期になってしまい、結局はXbox 360とWindowsの動作の違いはそのままにすることになってしまいました。

    また、追加してしまつた機能を削除するのは、新しく機能を追加するよりも遥かに難しいということを実感したのもXNA Game Studio Express 1.0をリリースした後になってからでした。

    一度追加してしまった機能は、使用頻度が少なくとも削ってしまうと、それまで動作していたゲームが動かないということになってしまいます。この使用頻度が低いAPIというのが厄介で、いかに使用頻度が低くてもAPIとして提供している以上はそのAPIが動作しているかどうか確認するためのテストをする必要があります。そして、前述のように人員の少ないXNAチームでは、このテストに掛かる時間が多くなってしまい、そのことで新機能を追加する時間が少なくなってしまうというのは問題です。

    将来を見越したリファクタリング

    XNA Game Studio 4.0でWindows Phone 7シリーズへの対応が決まった時、私達はこれがリファクタリングをするにはいい機会だと考えました。

    特にグラフィクスに関しては今までスマートフォーン向けのGPU用のDirectXドライバは存在せず、ドライバの設計はもちろん、ハードウェアベンダーとの話し合いからすることができた(しなければいけなかった)ので、XNAチーム側からの意見の多くが採用されました。

    ここで私達は今まで経験から、できるだけ長い間使えるAPIになるようにDirectX10 APIを元にしたAPIへとリファクタリングをすることにしました。と、言うと「ジオメトリシェーダーが使える!」と、考える人がいると思いますが、残念ですがXNA Game Studio 4.0の段階でDirectX 10特有の機能はサポートしていません。

    XNA Game Studio 4.0ではDirectX 9世代のGPUもサポートしているので、DirectX 10 APIをDirectX 9世代のGPU上で使用する、D3D10Level9と同等のことをしています。

    XNA Game Studio 4.0のグラフィクスではこの他にも以下のようなリファクタリングが施されています。

    • Capsメカニズムの廃止、Reach、HiDefのシンプルなフィーチャーレベルの採用
    • RenderStateを廃止し、BlendState、SampleState、DepthStencilState、そしてRasterizerStateとして分別
    • RenderTarget2DをTexture2Dから派生したクラスにし、深度バッファとの統合
    • アルファテスト関連のステートの廃止(代わりにAlpheTestEffectを使用)
    • トライアングルファン・プリミティブの廃止
    • ポイント・スプライトの廃止
    • VertexShader、PixelShaderなどの低レベルシェーダーAPIの廃止
    • BGRAフォーマットの廃止(Color構造体のバイトの並びがRGBAになった)
    • EffectPool、StateBlock、GammaRamp、ClipPlaneの廃止

    次回は新しくなったレンダーステートの紹介をします。

  • ひにけにXNA

    細分化されたXNA Game Studio 4.0アセンブリファイル

    • 0 Comments

    SilverlightからXNAフレームワークを使用する

    Windows Phone 7 シリーズでアプリケーションを作る場合は、SilverlightとXNA Frameworkを使うことができます。SilverlightはMicrosoft Expression Blendとの連携で簡単にUI構築ができるという利点があり、XNA Frameworkは3Dを筆頭に高パフォーマンスが求められるゲームアプリに向いています。

    Silverlightでアプリケーションを作っているときにXNA フレームワークの機能、特に追加されたばかりのダイナミックオーディオ機能や、GamerServices機能を使いたいというケースがあります。

    細分化されたアセンブリファイル

    このことを実現するために、4.0ではアセンブリファイルが機能ことに細分化され、それぞれが独立して機能するように変更が加えられています。

    XNA Game Studio 3.1までは実行時に必要なアセンブリファイルはMicrosoft.Xna.Framework.dllとMicrosoft.Xna.Framework.Game.dllの二つでしたが、4.0のReachプロファイルでは以下の様に各機能毎に分割されています。

    • Microsoft.Xna.Framework.dll
      • Math、オーディオ、メディア
    • Microsoft.Xna.Framework.Game.dll
      • Gameクラス関連
    • Microsoft.Xna.Framework.GamerServices.dll
      • GamerProfile、Achievement、Leaderboard等
    • Microsoft.Xna.Framework.Graphics.dll
      • グラフィクス関連
    • Microsoft.Xna.Framework.Input.Touch.dll
      • TouchPanelクラス

    これらのアセンブリファイルはMicrosoft.Xna.Framework.dllへの依存する以外はそれぞれ独立したアセンブリとして使用することができます。これで前述のように、SilverlightとXNA Frameworkの機能を組み合わせて使えるようになっています。同様にWindows上でもWPFやWinForm用のプロジェクトから、XNAのそれぞれのアセンブリを自由に使用することができるようになっています。

    このアセンブリの細分化を言い換えると、Microsoft.Xna.Framework.Graphics.dll以外のアセンブリはからグラフィクスへの依存がなくなったとも言えます。

    この副作用として、以前はTexture2DだったものがStreamを返すように変更されています。例えばGamerProfile.GamerPictureプロパティやメディアライブラリ内のPicture.GetTextureメソッドはGetImageメソッドに名称変更されているというようにです。

    ここで���されるStreamは.Netフレームワークで読み込むことのできる一般的な画像フォーマットファイルとなっているので、SilverlightやWPF上で簡単にDataBinding先として使用することができます。

    逆にこのストリームデータをゲーム内でテクスチャとして使うためにTexture2D.FromStreamメソッドが追加されています。

  • ひにけにXNA

    Windows Phone Developer Tools CTP版リリース

    • 0 Comments

    昨日のMIXのキーノート内で発表された通り、Windows Phone開発用ツールのCTP版がダウンロードできるようになりました。

    Windows Phone開発者用ページ
    http://developer.windowsphone.com/

    Windows Phone開発者用ツールCTP版ダウンロードページ
    http://www.microsoft.com/downloads/details.aspx?FamilyID=2338b5d1-79d8-46af-b828-380b0f854203&displaylang=en

    リリースノート
    http://download.microsoft.com/download/D/9/2/D926FB38-BB43-4D87-AE5A-1A3391279FAC/ReleaseNotes.htm

    このツール群の中にはXNA Game Studio 4.0 CTPを使うために必要な以下のものが含まれています。

    • XNA Game Studio 4.0 CTP
      • Visual Studio 2010 RC1とVisual Studio 2010 for Windows Phoneに対応
    • Visual Studio 2010 Express for Windows Phone
    • Windows Phone Emulator
      • GPUアクセラレーションを使用するにはDirectX 10に対応しているビデオカードが必要(対応していない場合はソフトウェア描画となる)

    XNA Game Studio 4.0として使う場合の注意点

    今回公開されたのはReach、HiDefのプロファイルのうちのReachプロファイル部分のみとなっていることに注意してください。これに加えて以下のことに注意する必要があります。

    • Reachプロファイルのみ対応
    • Xbox 360版は未対応(Reach版のコードは書くことはできる)
    • 自動スケーラー未対応
      • Windows Phone上では常に480x800のポートレート画面を使う必要がある。ランドスケープ にする場合はランドスケープ用のRenderTargetにゲーム画面を描画してから、最後にSpriteBatchを使って回転して描画する必要があります。
    • XNA Game Studio 3.0、3.1からのアップグレードウィザードは未完成
      • 新規にプロジェクトを生成し、元のプロジェクトから必要なものを追加する必要がある
    • ソリューション内で複数のプロジェクト(ゲームプロジェクトや、ゲームライブラリ等)から同じコンテントプロジェクトへの参照は不可(コンパイル時にエラーとなる)
    • XNA Game Studio 4.0では最終的にサポートする全てのプラットフォームで同一のAPIが使えるようになりますが、CTP版ではいくつかの違いがあります。
      • GamerServicesの実績やリーダーボードなどのAPIはWindows Phone版のみに存在する
      • プラットフォームによってEventHandlerとEventHandler<EventArgs>の違いが存在する

     

    XNA Game Studio 4.0 CTPを使ってみる

    Microsoft Visual Studio 2010 Express for Windows Phoneを起動して、プロジェクトの新規作成をすると以下の画面が表示されます。おなじみのWindows Game, Xbox 360 Gameのテンプレートがあるのはもちろん、Windows Phone Gameテンプレートが追加されています。

    GS40CTP01

    以前はゲームプロジェクトのサブプロジェクトとして存在していたコンテントプロジェクトが独立したプロジェクトとなりました。これにより、複数のプラットフォーム間でのコンテントの共有がしやすくなりました。

    下の画面はWindows Phone Emulator上で3Dモデルを読み込んで表示させたものです。Content.Load<Model>でモデルを読み込み、ModelMesh.Drawで描画するといった手法は今までどおり使えます。もちろん、MatrixやVector3といったMathライブラリはまったく同じ物を使うことができるので、この画面を表示するまでに数分しか掛かりませんでした。

    GS40CTP02

    アドバイス

    • Reachプロファイルのみのサポートとなるので、シェーダーを沢山使っているプロジェクトをテストするには向いていません。
    • Windows Phone EmulatorはOS自体もエミュレートしているので、起動に時間が掛かります。開発時間短縮の為にはWindows版でテストすることをお勧めします。

    次からは、XNA Game Studio 4.0になって変更された部分についての詳細を紹介していきます。

  • ひにけにXNA

    XNA Game Studio 4.0の新機能

    • 0 Comments

     

    最近、私の忙しさの尺度はこのブログの更新頻度に反比例しているということに気づきました。去年の秋あたりから忙しくなり、今年に入ってGamefest、GDC、そしてMIXへ向けての作業に追われる毎日でした。で、ちょっとだけひと段落したので、またいろいろと記事を書いていこう思っています。

    まず最初のニュースはXNA Game Studio 4.0についてです。XNA Game StudioはWindows、Xbox 360、そしてZuneと対応プラットフォームを増やしてきましたが、4.0ではWindows Phone 7シリーズへの対応が決まりました。

    Windows Phone 7シリーズでは要望の多かった3D APIが追加されています。ただし、Xbox 360やWindowsなどと比べると非力な携帯デバイスなので、複数のプラットフォームでゲームを作る場合にはプラットフォーム間のパフォーマンス差を考慮する必要があります。

    この労力を軽減するために4.0では、”Reach(リーチ)”と"HiDef(ハイデフ)”の二つのCapsを設けました。ReachはWindows Phone 7シリーズを含めたどのプラットフォームでも動作させることのできるAPI群からなり、HiDefはXbox 360やハイエンドWindowsマシン上で動作することを前提にしたAPI群からなります。HiDefではReachの全APIが使えるようになっています。

    以下はXNA Game Studio 4.0の主な新機能です。

    XNA Game Studio 4.0の新機能

    • Visual Studio 2010に対応
    • グラフィクスAPIを機能的に”Reach(リーチ)”と”HiDef(ハイデフ)”にカテゴリ分け
    • ダイナミックオーディオ
    • マイク
    • BasicEffectに加えて以下の基本的エフェクトクラスの追加
      • SkinnedEffect (スキンモデル用のエフェクト)
      • EnvironmentMapEffect (環境マップ用のエフェクト)
      • DualTextureEffect (デュアルテクスチャ用のエフェクト)
      • AlphaTestEffect (アルファテスト用のエフェクト)

    これらの詳細は今週開催されているGDC、そして来週開催されるMIXで公開される予定です。

    http://blogs.technet.com/microsoft_blog/archive/2010/03/09/game-developers-have-a-great-opportunity-with-windows-phone-7-series.aspx

    http://blogs.msdn.com/shawnhar/archive/2010/03/09/in-which-hints-become-facts-xna-game-studio-4-0.aspx#comments

    http://klucher.com/blog/achievement-unlocked-xna-game-studio-4-0-for-windows-phone/

Page 1 of 1 (7 items)