跳轉到內容

使用 XNA 建立簡單 3D 遊戲/新增天空球體

來自 Wikibooks,開放世界開放書籍

建立你的天空球體渲染器

[編輯 | 編輯原始碼]

為了渲染天空球體,我們將建立一個新的渲染類,類似於用於渲染魚類的類,但經過修改以允許模型在沒有骨骼結構的情況下渲染。首先,透過右鍵單擊專案,選擇“新增”/“新建項”並選擇“類”來建立一個新的類檔案。將類和檔名更改為“GenericModelRenderer”。

將預設的 using 語句更改為以下內容。

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SkinnedModel;

並確保該類使用 XNA 名稱空間,方法是在類名後加上

: Microsoft.Xna.Framework.Game

.

新增以下類變數和建構函式。public Model currentModel; public Vector3 Translation = new Vector3(0, 0, 0); public Vector3 Rotation = new Vector3(0, 0, 0); public float Scale = 1.0f;

public GenericModelRenderer(Model currentModelInput)
{
    currentModel = currentModelInput;
}

與之前的程式碼不同,我們不需要初始化動畫播放器,因此需要更少的初始化。你會看到這個類與“ModelDraw”方法等效的部分也具有類似的趨勢。

public void ModelDraw(GraphicsDevice device, Vector3 cameraPosition, Vector3 cameraTarget, float farPlaneDistance)
{
    Matrix[] transforms = new Matrix[currentModel.Bones.Count];
    currentModel.CopyAbsoluteBoneTransformsTo(transforms);

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

    //Calculate the aspect ratio, set the aspect axis and screen zoom.
    int aspectConstraint = 1;  /* 0 = Maintain Vertical FOV, 1 = Conditional Aspect Ratio, 2 = Maintain Horizontal FOV */
    float aspectRatio = (float)device.Viewport.Width / (float)device.Viewport.Height;
    float aspectOrigin = 16.0f / 9.0f; /* Aspect ratio condition in which changes axis direction if the current display is below this. Default is 1. */
    float zoomFactor = 1.0f;
    
    switch (aspectConstraint)
    {
       case 1:
         if (aspectRatio < aspectOrigin)
           {
              zoomFactor = zoomFactor * (aspectRatio / aspectOrigin);
           }
         break;
    
       case 2:
         zoomFactor = zoomFactor * (aspectRatio / aspectOrigin);
         break;
    }

    Matrix projection = Matrix.CreatePerspectiveFieldOfView(2.0f * Math.Atan(Math.Tan(MathHelper.ToRadians(45.0f / 2.0f) / zoomFactor), aspectRatio, 1.0f, farPlaneDistance);

    // Draw the model. A model can have multiple meshes, so loop.
    foreach (ModelMesh mesh in currentModel.Meshes)
    {
        // This is where the mesh orientation is set, as well as our camera and projection.
        foreach (BasicEffect effect in mesh.Effects)
        {
            effect.World = transforms[mesh.ParentBone.Index] *
                Matrix.CreateRotationX(Rotation.X) *
                Matrix.CreateRotationY(Rotation.Y) *
                Matrix.CreateRotationZ(Rotation.Z) *
                Matrix.CreateScale(Scale) *
                Matrix.CreateWorld(Translation, Vector3.Forward, Vector3.Up);

            effect.View = view;
            effect.Projection = projection;
        }
        mesh.Draw();
    }
}

請注意,繪製方法使用與其他魚類程式碼相同的引數,可以在或多或少相同的方式使用。

使用你的渲染器

[編輯 | 編輯原始碼]

在你的模型資料夾中建立一個名為“SkySphere”的新資料夾,並將你的模型和紋理新增到其中。返回到你的主“Game1”檔案,並新增新的類變數

GenericModelRenderer SkySphere; //Your SkySphere model

.

進入你的 LoadContent 檔案,並新增以下幾行來初始化該類並設定模型以進行渲染。

currentModel = Content.Load<Model>("Models\\SkySphere\\SkyModel");
SkySphere = new GenericModelRenderer(currentModel);//Add the skysphere

在繪製方法中,在魚類模型繪製方法的相同位置新增以下一行。

SkySphere.ModelDraw(GraphicsDevice, cameraPosition, cameraTarget, farPlaneDistance);

渲染程式碼,如果你與我的設定相同,你應該會看到一個這樣的螢幕。

你可能會注意到這不是我們需要的。我們可以透過調整 SkySphere 類中的公共變數來調整位置和比例。在我的例子中,我在 LoadContent() 方法中的類初始化之後添加了以下更改。

SkySphere.Translation.X = 120.0f;
SkySphere.Translation.Z = 15.0f;
SkySphere.Scale = 30.0f;

根據你的喜好進行調整,你應該會看到一個類似於我在這裡的螢幕。

華夏公益教科書