使用 XNA 建立簡單 3D 遊戲/新增天空球體
為了渲染天空球體,我們將建立一個新的渲染類,類似於用於渲染魚類的類,但經過修改以允許模型在沒有骨骼結構的情況下渲染。首先,透過右鍵單擊專案,選擇“新增”/“新建項”並選擇“類”來建立一個新的類檔案。將類和檔名更改為“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;
根據你的喜好進行調整,你應該會看到一個類似於我在這裡的螢幕。
