跳转到内容

使用 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;

根据你的喜好进行调整,你应该会看到一个类似于我在这里的屏幕。

华夏公益教科书