Spacewar の3Dモデルを描画する

XNA で Spacewar の3Dモデル(p1_wedge.fbx) を回転しながら描画します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. XNA で Spacewar の3Dモデル(p1_wedge.fbx) を回転しながら描画します。
    XNA Game Studio 2.0 のサンプルプログラム Spacewar を作成すると、そのプロジェクトに沢山のコンテンツが格納されます。
    今回は Spacewar のプロジェクトから、3Dモデル p1_wedge.fbx をコピーして使用することにします。
    Spacewar は Spacewar をコンパイルする を参照して下さい。
  2. プロジェクトを立ち上げて下さい。
    ソリューションエクスプローラで Content を右クリックして、[新しいフォルダー]から次のサブフォルダーを作成して下さい。
    フォルダー名 説明
    Models メッシュファイルのフォルダー
    Textures テクスチャのフォルダー
  3. 3Dモデルとテクスチャをプロジェクトに取り込みます。
    ソリューションエクスプローラで Content/Models を右クリックして [追加][既存の項目] をクリックします。
    「Spacewar をコンパイルする」のプロジェクトから p1_wedge.fbx を選択して下さい。
    Content/Textures を右クリックして [追加][既存の項目] をクリックします。
    「Spacewar をコンパイルする」のプロジェクトから wedge_p1_diff_v1.tga を選択して下さい。
    ソリューションエクスプローラに選択したコンテンツが表示されます。
    p1_wedge.fbx を選択してプロパティを表示します。
    Asset Name に表示されている "p1_wedge" が p1_wedge.fbx をロードする時の ID です。
    テクスチャファイル(wedge_p1_diff_v1.tga) は p1_wedge.fbx の中で定義されていて、自動的に読み込まれます。

  4. Game1.cs を編集して3Dモデルを回転しながら描画するプログラムを作成します。
    class Game1 で、次の領域を宣言して下さい。
    myModel は、3Dモデルの領域です。
    aspectRatio はアスペクト比(縦横比)を計算する領域です。
    modelPosition はモデルを配置する座標です。
    modelRotation はモデルの回転係数を設定する領域です。
    cameraPosition はカメラを置く座標です。
    keyState はキーの状態を調べる領域です。
        public class Game1 : Microsoft.Xna.Framework.Game
        {
            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;
    
            Model myModel; 
            float aspectRatio;      // アスペクト比
            Vector3 modelPosition = Vector3.Zero; 
            float modelRotation = 0.0f; 
            Vector3 cameraPosition = new Vector3( 0.0f, 50.0f, 5000f ); 
            KeyboardState   keyState;
        
  5. LoadContent() メソッドに myModel を生成するコードを追加します。
    "Models\\p1_wedge" は "Content" フォルダーからの相対パスで、"p1_wedge" は Asset Name に表示されていた ID です。
    コンテンツのルートディレクトリは、テンプレートで作成された下記のメソッドで設定されています。
            public Game1()
            {
                graphics = new GraphicsDeviceManager(this);
                Content.RootDirectory = "Content";
            }
        
    ウインドウのサイズから縦横比を計算して aspectRatio に設定します。
            protected override void LoadContent()
            {
                // Create a new SpriteBatch, which can be used to draw textures.
                spriteBatch = new SpriteBatch(GraphicsDevice);
    
                // TODO: use this.Content to load your game content here
                myModel = Content.Load("Models\\p1_wedge"); 
                aspectRatio = graphics.GraphicsDevice.Viewport.Width / graphics.GraphicsDevice.Viewport.Height; 
    
            }
        
  6. 特に必要は無いようですが UnloadContent() メソッドでアンロードしています。
            protected override void UnloadContent()
            {
                // TODO: Unload any non ContentManager content here
                Content.Unload(); 
    
            }
        
  7. Update() メソッドでタイマの値を取得して、自動的に回転します。
    回転速度は MathHelper.ToRadians(0.1f) で調整して下さい。
            protected override void Update(GameTime gameTime)
            {
                // Allows the game to exit
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
                    Keyboard.GetState().IsKeyDown(Keys.Escape)) this.Exit();
    
                // TODO: Add your update logic here
                modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds * MathHelper.ToRadians( 0.1f ); 
    
                base.Update(gameTime);
            }
        
  8. Draw() メソッドに3Dモデルを描画するコードを追加します。
            protected override void Draw(GameTime gameTime)
            {
                graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
    
                // TODO: Add your drawing code here
                Matrix[] transforms = new Matrix[myModel.Bones.Count]; 
                myModel.CopyAbsoluteBoneTransformsTo( transforms ); 
    
                // モデルを描画します。モデルは複数のメッシュを持つことができるので、ループします。  
                foreach (ModelMesh mesh in myModel.Meshes) 
                { 
                    // メッシュの向きが設定される場所です。カメラおよび射影の向きも設定されます。  
                    foreach (BasicEffect effect in mesh.Effects) 
                    { 
                        effect.EnableDefaultLighting(); 
                        effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateRotationY( modelRotation ) 
                                            * Matrix.CreateTranslation( modelPosition ); 
                        effect.View = Matrix.CreateLookAt( cameraPosition, Vector3.Zero, Vector3.Up ); 
                        effect.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians( 45.0f ), 
                                            aspectRatio, 1.0f, 1000.0f ); 
                    } 
                    // 上記で設定されたエフェクトを使用してメッシュを描画します。 
                    mesh.Draw(); 
                }
    
                base.Draw(gameTime);
        
  9. メニューの [デバッグ] から [デバッグ開始] または [デバッグなしで開始] を選択します。
    コンパイルされ、エラーが無ければコーンのモデルが回転しながら描画されます。

前田稔(Maeda Minoru)の超初心者のプログラム入門

超初心者のプログラム入門(XNA(C#) game program)