跳轉到內容

使用 XNA 建立簡單 3D 遊戲 / 渲染模型

來自華夏公益教科書,開放世界開放書籍

首先,開啟 Visual c#,選擇“檔案”/“新建專案”。在那裡選擇建立一個新的 C# 專案。

您應該會看到標準的 XNA 啟動程式碼。從之前下載的蒙皮模型示例中新增專案“SkinnedModelPipeline”和“SkinnedModelWindows”,並透過輸入using SkinnedModel;以及其他 using 語句,並在右鍵單擊您的專案並選擇“新增引用”下的它們來新增對它們的引用。

此外,請確保該類透過更改類的第一行來引用“Game”類,如下所示。

public class ModelRenderer : Microsoft.Xna.Framework.Game

並將“SkinnedModelWindows”專案中的“SkinnedModel.fx”檔案放入專案的 content 資料夾中,因為您的模型將使用它進行渲染。

魚渲染器

[編輯 | 編輯原始碼]

接下來,建立一個名為“ModelRenderer”的新遊戲元件檔案。從這裡,新增以下類變數。

public AnimationPlayer animationPlayer; //Controls the animation, references a method in the pre-loaded project
public AnimationClip clip; //Contains the animation clip currently playing
public Model currentModel; //Model reference
public SkinningData skinningData; //Used by the AnimationPlayer method
public Vector3 Translation = new Vector3(0, 0, 0); //Fishes current position on the screen
public Vector3 Rotation = new Vector3(0, 0, 0); //Current rotation
public float Scale = 1.0f; //Current scale

將建構函式更改如下。

public ModelRenderer(Model currentModelInput)
{
    currentModel = currentModelInput;
    // Look up our custom skinning information.
    skinningData = currentModel.Tag as SkinningData;
    if (skinningData == null)
        throw new InvalidOperationException
            ("This model does not contain a SkinningData tag.");
    // Create an animation player, and start decoding an animation clip.
    animationPlayer = new AnimationPlayer(skinningData);
}

這段程式碼(或多或少取自原始示例)初始化了最終將用於動畫過程的方法。

接下來,刪除預製更新方法中的程式碼,並用以下程式碼替換它。

if ((clip != null))
    animationPlayer.Update(gameTime.ElapsedGameTime, true, Matrix.Identity);

此處的 .Update 方法將確保由該方法當前播放的動畫將按順序播放,並與使用傳遞的“gameTime”的所有其他內容同步。

該類的主要成分是下面的 Draw 方法

public void ModelDraw(GraphicsDevice device, Vector3 cameraPosition, Vector3 cameraTarget, float farPlaneDistance)
{
    Matrix[] bones = animationPlayer.GetSkinTransforms();
    for (int i = 0; i < bones.Length; i++)
    {
        bones[i] *= 
              Matrix.CreateRotationX(Rotation.X) //Computes the rotation
            * Matrix.CreateRotationY(Rotation.Y)
            * Matrix.CreateRotationZ(Rotation.Z)
            * Matrix.CreateScale(Scale) //Applys the scale
            * Matrix.CreateWorld(Translation, Vector3.Forward, Vector3.Up); //Move the models position
    }

    float aspectRatio = (float)device.Viewport.Width /
                        (float)device.Viewport.Height;

    // Compute camera matrices.
    Matrix view = Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Right);

    //Create the 3D projection for this model
    Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio,
        1.0f, farPlaneDistance);

    // Render the skinned mesh.
    foreach (ModelMesh mesh in currentModel.Meshes)
    {
        foreach (Effect effect in mesh.Effects)
        {
            effect.Parameters["Bones"].SetValue(bones);
            effect.Parameters["View"].SetValue(view);
            effect.Parameters["Projection"].SetValue(projection);
        }
        mesh.Draw();
    }
}

為了本教程的需要,我們不必太擔心這一點。

新增一個新方法,該方法將從父檔案呼叫,該方法將呼叫預載入的“SkinnedModel”的元素,並播放動畫。

public void PlayAnimation(String Animation)
{
    clip = skinningData.AnimationClips[Animation];
    if (clip != animationPlayer.CurrentClip)
    animationPlayer.StartClip(clip);
}

當我們擴充套件實際遊戲玩法的邏輯時,我們將向這段程式碼新增內容(因為它是一個非常方便的地方來儲存我們將使用的魚的例項變數),但目前,這足以涵蓋系統所需的基​​礎知識,接下來我們可以關注使用它來渲染模型。

使用你的渲染器

[編輯 | 編輯原始碼]

在專案中的“Content”下建立一個名為“Models”的新資料夾,並將您的魚模型和所有 .tga 紋理檔案新增到其中。現在右鍵單擊“引用”資料夾,並新增“SkinnedModelPipeline”。這將允許您透過進入模型的屬性並將渲染器更改為新的“SkinnedModelProcessor”來選擇正確的渲染器。如果無法選擇它,請確保透過右鍵單擊它們並選擇“生成”來生成兩個“SkinnedModel”專案。

現在回到您的父檔案。新增一些新的類變數;

ModelRenderer FishMen; //Your new Fish model
Vector3 cameraPosition; //Defines the position of the camera in the 3D space
Vector3 cameraTarget; //Defines your camera target
float farPlaneDistance = 400f; //Defines your plane distance, the higher, the less 3D 'fog' and the more is displayed

並透過進入更新方法並新增以下行來使用它

FishMen.Update(gameTime);
cameraPosition = cameraTarget = FishMen.Translation;
cameraPosition.Z += 20.0f;

在方法的開頭,並在繪製方法中新增

FishMen.ModelDraw(device, cameraPosition, cameraTarget, farPlaneDistance);

在您的

GraphicsDevice.Clear(Color.CornflowerBlue);

行之後。

最後,在“LoadContent”方法的開頭新增以下內容。

Model currentModel; //Temporary storage for your new model

Content.RootDirectory = "Content";
currentModel = Content.Load<Model>("Models\\FishModel"); //Loads your new model, point it towards your model
FishMen = new ModelRenderer(currentModel);
FishMen.Translation = new Vector3(0f);//Move it to the centre
FishMen.PlayAnimation("Swim");//Play the default swimming animation

現在,執行您的應用程式,一切應該正常工作。

華夏公益教科書