Опубликован: 14.08.2012 | Уровень: специалист | Доступ: платный
Самостоятельная работа 16:

Основы трехмерной графики в XNA

< Лекция 6 || Самостоятельная работа 16: 123 || Самостоятельная работа 17 >

23.2. Вывод трехмерных моделей

Выводя графические примитивы, рассмотренные в предыдущем примере, довольно сложно и трудоемко создавать игровые сцены. Гораздо большими возможностями обладает подход к работе с трехмерной графикой, использующий вывод заранее подготовленных трехмерных моделей. Само по себе создание трехмерных моделей требует немало времени и искусства, для этого применяются специальные программы. В деле создания игр выделяется отдельная группа сотрудников – 3D-моделеров, которые занимаются исключительно созданием трехмерных моделей.

Мы использовали готовую бесплатную трехмерную модель Free Lowpoly Round Shield с сайта http://www.turbosquid.com.

Для вывода модели на экран необходимо добавить в проект соответствующие ей ресурсы, в нашем случае – модель в формате .FBX и текстуру в формате .JPG. Далее следует загрузить модель в игру, настроить её свойства и вывести на экран.

В трехмерной графике существует такое понятие, как Mesh (Сеть, иногда пользуются русской калькой с этого слова – мэш). Трехмерные модели состоят из сетей – линий, соединяющих вершины. Модель может состоять из нескольких взаимодействующих сетей, каждую из которых нужно обработать при выводе модели.

Создадим новый проект – P16_2 для демонстрации техники вывода трехмерной модели. На рис. 23.2 вы можете видеть окно Обозреватель решений этого проекта и окно Свойства для текстуры, предназначенной для наложения на модель. Трехмерные модели, которые предусматривают использование текстур, содержат в своих файлах указание на то, каким образом накладывать текстуру на объект, а так же – на файл текстуры. В нашем случае адрес файла текстуры задан в относительном выражении – то есть система будет искать этот файл в той же папке, в которой расположен файл трехмерной модели. Текстура подвергается преобразованиям в соответствии с командами, записанными в файле трехмерной модели, поэтому мы отключили параметр Действия при построении в свойствах текстуры.

Настройка свойств текстуры

Рис. 23.2. Настройка свойств текстуры

пример 23.2 содержит код класса Game1, реализующего вывод модели на экран.

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

namespace P16_2
{
    /// <summary>
    /// Это главный тип игры
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        // Модель для вывода
        Model myModel;
        //Мировая матрица
        Matrix WorldMatrix;
        //Соотношение сторон окна вывода
        float aspectRatio;
        //Угол поворота для вращения модели
        float angle;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.IsFullScreen = true;
            // Частота кадра на Windows Phone по умолчанию — 30 кадров в секунду.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            // Дополнительный заряд аккумулятора заблокирован.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
        }

        /// <summary>
        /// Позволяет игре выполнить инициализацию, необходимую перед запуском.
        /// Здесь можно запросить нужные службы и загрузить неграфический
        /// контент.  Вызов base.Initialize приведет к перебору всех компонентов и
        /// их инициализации.
        /// </summary>
        protected override void Initialize()
        {
            // ЗАДАЧА: добавьте здесь логику инициализации

            base.Initialize();
        }

        /// <summary>
        /// LoadContent будет вызываться в игре один раз; здесь загружается
        /// весь контент.
        /// </summary>
        protected override void LoadContent()
        {
            //загрузка модели
            myModel = Content.Load<Model>("RoundShield");
            //Установка соотношения сторон окна вывода
            aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width /
            (float)graphics.GraphicsDevice.Viewport.Height;

            // ЗАДАЧА: используйте здесь this.Content для загрузки контента игры
        }

        /// <summary>
        /// UnloadContent будет вызываться в игре один раз; здесь выгружается
        /// весь контент.
        /// </summary>
        protected override void UnloadContent()
        {
            // ЗАДАЧА: выгрузите здесь весь контент, не относящийся к ContentManager
        }

        /// <summary>
        /// Позволяет игре запускать логику обновления мира,
        /// проверки столкновений, получения ввода и воспроизведения звуков.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Update(GameTime gameTime)
        {
            // Позволяет выйти из игры
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            //увеличим угол поворота на 1
            angle++;
            //установим новую мировую матрицу
            //поворот по оси Y равен углу angle, поворот по X - 
            //angle, деленному на 5
            WorldMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(angle)) *
                Matrix.CreateRotationX(MathHelper.ToRadians(angle / 5.0f));
            //Для каждой сети в модели
            foreach (ModelMesh mesh in myModel.Meshes)
            {
                //Для каждого эффекта в сети
                foreach (BasicEffect effect in mesh.Effects)
                {
                    //Установить освещение
                    effect.AmbientLightColor = new Vector3(1.0f, 1.0f, 1.0f);
                    effect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
                    effect.LightingEnabled = true;

                    //установить матрицы
                    effect.World = WorldMatrix;
                    effect.View = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 120.0f), Vector3.Zero, Vector3.Up);
                    effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
                         aspectRatio, 1.0f, 1000.0f);
                }
            }


            base.Update(gameTime);
        }

        /// <summary>
        /// Вызывается, когда игра отрисовывается.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            // Вывод модели
            foreach (ModelMesh mesh in myModel.Meshes)
            {
                mesh.Draw();
            }
            base.Draw(gameTime);

        }
    }
}
Листинг 23.2. Код класса Game1

На рис. 23.3 вы можете видеть окно проекта.

Окно проекта P16_2

Рис. 23.3. Окно проекта P16_2

23.3. Выводы

В этой лабораторной работе мы ознакомились с формированием трехмерных объектов средствами XNA и с выводом заранее созданных трехмерных объектов. Второй способ гораздо перспективнее первого, так как позволяет конструировать модели в специальных визуальных редакторах, а в XNA лишь выводить модели и управлять ими. Первый способ предусматривает полное описание модели средствами XNA.

23.4. Задание

Создайте или найдите в Интернете трехмерную модель, выведите её на экран, используя BasicEffect, освойте управление игровой сценой с помощью рассмотренных в лабораторной работе методов.

< Лекция 6 || Самостоятельная работа 16: 123 || Самостоятельная работа 17 >
Гулич Анна
Гулич Анна
Невозможно пройти тесты, в окне с вопросами пусто
Сашечка Огнев
Сашечка Огнев
Россия, Красноярский край
Андрей Корягин
Андрей Корягин
Россия, Пенза, Вазерская средняя школа, 2001