zoukankan      html  css  js  c++  java
  • 梦想成真 XNA (9) 3D 模型

    [索引页]
    [源码下载] 


    梦想成真 XNA (9) - 3D 模型



    作者:webabcd


    介绍
    XNA: 3D 模型。通过键盘的“上下左右”键旋转 3D 模型


    示例
    绘制一个 3D 模型,并通过“上下左右”键控制它的旋转(按键盘 R 键加载此 Demo)
    3D/3DModel/RotationDirection.cs

    namespace XNA.Component._3D._3DModel
    {
        /// <summary>
        /// 旋转方向
        /// </summary>
        public enum RotationDirection
        {
            Up,
            Down,
            Left,
            Right
        }
    }
    


    3D/3DModel/MyCamera.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    
    namespace XNA.Component._3D._3DModel
    {
        /// <summary>
        /// 自定义摄像机类
        /// </summary>
        public class MyCamera : Microsoft.Xna.Framework.GameComponent
        {
            // View 矩阵,用于设置摄像机的位置和方向
            public Matrix View { get; protected set; }
            // Projection 矩阵,用于将 3D 物体投影到 2D 屏幕上
            public Matrix Projection { get; protected set; }
    
            public MyCamera(Game game, Vector3 pos, Vector3 target, Vector3 up)
                : base(game)
            {
                /*
                 * Matrix CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) - 实例化视图矩阵
                 *     Vector3 cameraPosition - 摄像机的位置坐标
                 *     Vector3 cameraTarget - 摄像机镜头的朝向向量
                 *     Vector3 cameraUpVector - 摄像机机身的顶部的上方的向量
                 */
                View = Matrix.CreateLookAt(pos, target, up);
    
                /*
                 * CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance) - 实例化投影矩阵
                 *     float fieldOfView - Y 轴方向上的视角弧度,一般是四分之一个 PI
                 *     float aspectRatio - 可视区的长宽比,一般就是游戏窗口的宽除以游戏窗口的高
                 *     float nearPlaneDistance - 当物体离摄像机多近时无法看清
                 *     float farPlaneDistance - 当物体离摄像机多远时无法看清
                 */
                Projection = Matrix.CreatePerspectiveFieldOfView(
                    MathHelper.PiOver4, // 四分之一个 PI(MathHelper 里有很多实用的功能)
                    (float)Game.Window.ClientBounds.Width /
                    (float)Game.Window.ClientBounds.Height,
                    1, 
                    3000
                );
            }
    
            public override void Initialize()
            {
                base.Initialize();
            }
    
            public override void Update(GameTime gameTime)
            {
                base.Update(gameTime);
            }
        }
    }
    


    3D/3DModel/MyModel.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    
    namespace XNA.Component._3D._3DModel
    {
        /// <summary>
        /// 自定义 3D 模型类
        /// </summary>
        public class MyModel
        {
            // Model - 代表 3D 模型。代表 2D 对象的是 Texture2D
            private Model _model;
    
            // 旋转矩阵
            private Matrix _rotation = Matrix.Identity;
    
            // 初始矩阵
            private Matrix _world = Matrix.Identity;
    
            public MyModel(Model model, Matrix world)
            {
                _model = model;
                _world = world;
            }
    
            /// <summary>
            /// 绘制 3D 模型
            /// </summary>
            public void Draw(MyCamera camera)
            {
                /*
                 * 一个 Model 对象里有多个 ModelMesh 对象,每个 ModelMesh 对象包含了此网格的纹理、颜色等信息
                 */
                foreach (ModelMesh mesh in _model.Meshes)
                {
                    /*
                     * 一个 ModelMesh 对象里有多个用于绘制 ModelMesh 的 Effect
                     */
                    foreach (BasicEffect effect in mesh.Effects)
                    {
                        //  使用默认光源效果
                        effect.EnableDefaultLighting();
    
                        effect.Projection = camera.Projection;
                        effect.View = camera.View;
                        effect.World = GetWorld();
                    }
    
                    // 绘制 ModelMesh
                    mesh.Draw();
                }
            }
    
            /// <summary>
            /// 根据方向(上下左右)计算旋转矩阵
            /// </summary>
            public void Rotate(RotationDirection direction)
            {
                switch (direction)
                {
                    case RotationDirection.Up:
                        _rotation *= Matrix.CreateRotationX(-MathHelper.Pi / 180); // 绕 X 轴旋转的弧度
                        break;
                    case RotationDirection.Down:
                        _rotation *= Matrix.CreateRotationX(MathHelper.Pi / 180);
                        break;
                    case RotationDirection.Left:
                        _rotation *= Matrix.CreateRotationY(-MathHelper.Pi / 180); // 绕 Y 轴旋转的弧度
                        break;
                    case RotationDirection.Right:
                        _rotation *= Matrix.CreateRotationY(MathHelper.Pi / 180);
                        break;
                }
            }
    
            /// <summary>
            /// 获取世界矩阵,即初始矩阵乘以旋转矩阵
            /// </summary>
            public Matrix GetWorld()
            {
                return _world * _rotation;
            }
        }
    }
    


    3D/3DModel/Demo.cs

    /*
     * XNA 只支持 .x 和 .fbx 格式的 3D 模型文件 
     * 本例所用 3D 模型的位置在:XNAContent/3DModel/Spaceship.x
     * 
     * 本例演示:通过键盘的“上下左右”键旋转 3D 模型
     */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    
    namespace XNA.Component._3D._3DModel
    {
        public class Demo : Microsoft.Xna.Framework.DrawableGameComponent
        {
            private MyCamera _camera;
            private List<MyModel> _models = new List<MyModel>();
    
            public Demo(Game game)
                : base(game)
            {
    
            }
    
            public override void Initialize()
            {
                // 添加摄像机组件
                _camera = new MyCamera(Game, new Vector3(0, 0, 50), Vector3.Zero, Vector3.Up);
                Game.Components.Add(_camera);
    
                base.Initialize();
            }
    
            protected override void LoadContent()
            {
                // 添加两个不同位置的 3D 模型
                _models.Add(new MyModel(Game.Content.Load<Model>(@"3DModel\Spaceship"), Matrix.Identity * Matrix.CreateTranslation(-10, -5, -20)));
                _models.Add(new MyModel(Game.Content.Load<Model>(@"3DModel\Spaceship"), Matrix.Identity * Matrix.CreateTranslation(10, 5, 0)));
    
                base.LoadContent();
            }
    
            public override void Update(GameTime gameTime)
            {
                // 根据用户的按键(上下左右),旋转 3D 模型
                KeyboardState keyboardState = Keyboard.GetState();
    
                foreach (MyModel model in _models)
                {
                    if (keyboardState.IsKeyDown(Keys.Up))
                        model.Rotate(RotationDirection.Up);
                    else if (keyboardState.IsKeyDown(Keys.Down))
                        model.Rotate(RotationDirection.Down);
                    else if (keyboardState.IsKeyDown(Keys.Left))
                        model.Rotate(RotationDirection.Left);
                    else if (keyboardState.IsKeyDown(Keys.Right))
                        model.Rotate(RotationDirection.Right);
                }
    
                base.Update(gameTime);
            }
    
            public override void Draw(GameTime gameTime)
            {
                GraphicsDevice.Clear(Color.CornflowerBlue);
    
                // 绘制 3D 模型
                foreach (MyModel model in _models)
                {
                    model.Draw(_camera);
                }
    
                base.Update(gameTime);
            }
        }
    }
    



    OK 
    [源码下载]

  • 相关阅读:
    常用数据结构之哈希表
    常用数据结构之队列
    常用的数据结构之栈
    常用的数据结构之链表
    Zabbix3.4监控Windows机器CPU使用率
    在Pycharm中导入第三方模块库(诸如:matplotlib、numpy等)
    WARNING: You are using pip version 20.2.4; however, version 20.3.1 is available.
    npm无法安装node-sass的解决方法
    常见的树形结构封装
    Mac安装MySql
  • 原文地址:https://www.cnblogs.com/webabcd/p/2150127.html
Copyright © 2011-2022 走看看