netlib.narod.ru | < Назад | Оглавление | Далее > |
Эксперименты с вершинами и рисованием примитивов, конечно, замечательны, но если вы хотите создать игру со сложными трехмерными объектами, это едва ли будет лучшим выбором.
В главе 1 вы видели, что конвейер содержимого XNA поддерживает много форматов файлов, включая файлы определения трехмерных объектов X и FBX. Эти файлы хранят описания трехмерных объектов, известные как 3D-модели (3D-model) или просто модели (model).
В качестве простого определения можно сказать, что модель — это иерархия сеток, которые могут визуализироваться независимо, а сетка (mesh) — это набор взаимосвязанных вершин вместе с некоторой информацией о визуализации. XNA предоставляет специальные классы для манипуляций с моделями и сетками: Model и ModelMesh.
Чтобы создать программу, которая работает с моделями, вы сперва должны загрузить модель в вашу программу как новое содержимое.
Для этого щелкните правой кнопкой мыши по проекту в Solution Explorer и выберите в появившемся меню Add | Existing Content, измените тип файла на Content Pipeline Files, и укажите файл X или FBX. В этом разделе вы используете файл Cube.X, простой файл с описанием куба, поставляемый с DirectX Software Development Kit (SDK), который можно скачать с сайта Microsoft (http://www.microsoft.com/directx).
После того, как содержимое добавлено в ваш проект, вы должны объявить переменную модели для хранения ссылки на это содержимое, на уровне класса Game1:
Model myModel;
В методе LoadContent вы должны добавить единственную строку кода для загрузки модели:
myModel = Content.Load<Model>("Cube");
И, наконец, вы должны включить в метод Draw цикл, который проходит по всем сеткам в модели и рисует каждую из них. Хотя в нашей простой модели всего одна сетка, использование описанного подхода позволяет получить код, готовый к рисованию сложных моделей:
// Перебираем каждую сетку модели foreach (ModelMesh mesh in myModel.Meshes) { // Рисуем текущую сетку mesh.Draw(); }
Если вы сейчас запустите программу, то увидите уже загруженную сетку с вращающимися осями трехмерной системы координат, созданными в предыдущем разделе, как показано на рис. 7.17.
Рис. 7.17. Первый вид трехмерной модели (куба)
Изображение на рис. 7.17 не слишком захватывающее, поскольку две детали не позволяют выглядеть ему как куб: во-первых, камера направлена прямо на одну из граней куба, поэтому вы видите его как квадрат. Помимо этого, отключено освещение, поэтому каждая грань освещена абсолютно одинаково. Здесь нет теней, помогающих вам отличить одну грань от другой.
Для решения этих проблем вам надо повернуть модель, чтобы она была лучше расположена (и, возможно, немного масштабировать, чтобы она не закрывала оси) и применить освещение при визуализации модели.
Вы правы, если вспоминаете класс BasicEffect, который использовали в предыдущем разделе: с BasicEffect вы можете применить преобразования к объекту (через свойство World), установить матрицы Projection и View (которые должны быть у каждого эффекта), и ценой небольших усилий включить источник света по умолчанию, как вы видели, когда мы говорили об эффектах ранее в этой главе. Вы можете использовать те же самые матрицы проекции и вида, что применяются для cls3DAxis; поворот на 45 градусов по осям X и Y развернет куб таким образом, что вы сможете видеть три из его граней.
Используя эффект для визуализации трехмерных объектов, вы должны помнить, что модель состоит из нескольких сеток, поэтому вам необходим цикл, перебирающий все сетки и применяющий ко всем ним эффект. Помимо этого у сетки может быть набор эффектов, позволяющий визуализировать различные части сетки с различными эффектами — полезная вещь для сложных сеток. Поскольку у вас может быть несколько эффектов для одной сетки, вам потребуется второй цикл, перебирающий все эффекты каждой сетки, чтобы обеспечить применение того же эффекта ко всем частям сетки.
В простых моделях, таких как ваш куб, у вас только одна сетка и только один эффект для этой сетки. Однако, создание обобщенного кода позволит вам использовать ту же самую программу для более сложных моделей.
Ниже приведен итоговый код создания и использования эффекта. Вы должны поместить его в метод LoadContent:
// Вычисляем форматное соотношение для модели float aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width / graphics.GraphicsDevice.Viewport.Height; // Конфигурируем базовое освещение и выполняем простой поворот модели // (чтобы оно было заметно на экране) foreach (ModelMesh mesh in myModel.Meshes) foreach (BasicEffect effect in mesh.Effects) { // Вращаем модель и делаем ее немного меньше (50%) effect.World = Matrix.CreateScale(0.5f) * Matrix.CreateRotationX(MathHelper.ToRadians(45.0f)) * Matrix.CreateRotationY(MathHelper.ToRadians(45.0f)); // Устанавливаем матрицу проекции для модели effect.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10.0f); effect.View = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 3.0f), Vector3.Zero, Vector3.Up); effect.EnableDefaultLighting(); }
На рис. 7.18 показан результат выполнения программы с только что созданным эффектом.
Рис. 7.18. Повернутый, масштабированный и освещенный куб
netlib.narod.ru | < Назад | Оглавление | Далее > |