netlib.narod.ru< Назад | Оглавление | Далее >

Управление конвейером содержимого

Как вы узнали в главе 1, конвейер содержимого используется для импорта игровых ресурсов, таких как текстуры, шейдеры и звуковые файлы. Вместо простого добавления их в ваш проект, подобно другим неподдерживаемым файлам в Visual Studio (или XNA Studio), файлы содержимого обрабатываются и затем компилируются в двоичные файлы содержимого, которые могут быть загружены из вашей игры (рис. 3.1).


Рис. 3.1

Рис. 3.1


Раньше программисты игр писали собственные процедуры импорта данных для игрового содержимого или использовали один из доступных форматов, таких, как формат файлов .x для файлов моделей в DirectX. Часто доступные форматы файлов оказывались неподходящими, слишком медленными или недостаточно гибкими для добавления в игру новых возможностей. Это одна из причин по которой почти каждая коммерческая игра имеет собственный формат файлов и лежащую в его основе уникальную запрограммированную логику. Преимущество здесь в том, что только разработчики игры знают внутреннюю структуру формата и могут расширять или менять его так часто, как пожелают. Однако, добавление трехмерного содержимого в вашу игру таким способом требует большого объема работы. Загрузка текстур обычно не слишком сложна, поскольку существует множество библиотек и даже при создании собственного формата файлов, он фактически будет только содержать пикселы, хранящиеся как 24 или 32-разрядные цветовые значения. Все может стать несколько труднее, если вы попытаетесь использовать сжатие или захотите применять аппаратно сжатые текстуры, такие как формат DXT, но DirectX имеет много полезных методов, которые помогут вам в этом.

С другой стороны, загрузка данных трехмерных моделей более сложна, особенно в XNA, где у вас есть не только данные о геометрии, но и шейдеры для визуализации трехмерных объектов, а также, конечно, данные материалов, сообщающие шейдерам какие цвета, текстуры и параметры использовать. В DirectX большинство уроков и примеров используют формат файлов .x, но для многих проектов формат .x может оказаться неподходящим. Например, если вы используете наложение нормалей и необходимо, чтобы данные геометрии содержали касательные, формат файлов .x будет не слишком полезен. Вам надо будет генерировать касательные в вашем приложении и решать возникающие из-за этого проблемы. Например, в одной из моих старых игр, Rocket Commander, была точно такая же проблема, потребовавшая сложного процесса загрузки модели и восстановления касательных.

Работа с другими игровыми данными, такая как загрузка звуковых файлов (.wav), шейдеров (.fx) или каких-либо еще данных (например, .xml) могут быть более прямолинейными из-за того, что ваша игра или используемый каркас предоставляют достаточное количество полезных классов для быстрой загрузки всего необходимого, но тогда вы можете столкнуться с проблемами при запуске игры с тем же самым содержимым на другой платформе. Например, вы можете на платформе Windows использовать звуковые файлы ACPCM, применять скомпилированные файлы пиксельных шейдеров модели 1.1 или просто загружать несколько файлов .jpg в качестве текстур. Но на Xbox 360 нет поддержки ACPCM, звуки должны быть либо в формате PCM, либо в собственном формате Xbox, XMA, код шейдеров должен быть в формате, который принимает Xbox, и загрузка текстур тоже работает по-другому. Эта проблема становится еще сложнее, если в будущем планируется поддерживать большее количество платформ.

Для упрощения загрузки игрового содержимого XNA позволяет вам просто перетащить необработанные файлы содержимого в ваш проект XNA Studio и они будут обработаны и скомпилированы в правильный выходной формат для выбранной платформы. Например, ваши звуковые файлы могут быть обработаны на основе параметров вашего проекта XACT — у вас будут различные выходные форматы и сжатие, но все исходные звуковые файлы для волновых банков будут одними и теми же и обновлять их надо будет в одном месте. Идея великолепна, но она требует поддержки любого формата необработанных файлов содержимого, что непрактично, поскольку существует множество форматов файлов и вы не знаете, какой из них будет использоваться. Например, один из ваших художников может использовать Photoshop и сохранять файлы .psd, в то время как другие будут работать с Gimp или PaintShop или даже с программой Paint из Windows. Существуют еще тысячи различных графических утилит и программ. Кроме того, вы не знаете, какие данные извлекать; многие форматы могут содержать несколько слоев и, возможно, художник хотел, чтобы был доступ к каждому из них, либо наоборот, обеспечить доступ только к результату их объединения.

Поддерживаемые форматы файлов

Вместо того, чтобы отбрасывать что-нибудь, используйте один из доступных обработчиков и поддерживаемые форматы или попробуйте сами написать собственный обработчик содержимого (см. главу 7), если думаете, что в этом есть необходимость.

Если у вас много файлов содержимого или есть какие-либо данные для игры в собственном формате, вы можете решить либо написать собственный обработчик, а потом использовать в проекте скомпилированные и импортированные данные, либо использовать старый способ с самостоятельной загрузкой файлов содержимого. Например, гоночная игра, которую вы напишете в последней части этой книги, использует ландшафты со значениями высот, импортируемыми из растрового файла. Вполне возможна обработка растрового файла и вывод данных высот ландшафта для игры, но это требует значительной работы — простая загрузка данных высот гораздо проще и требуется только один раз.

Преимущества и недостатки

Одним из недостатков конвейера содержимого является то, что скомпилированное содержимое никак нельзя изменить. После того, как вы запустите вашу игру или развернете игру на компьютере клиента либо на Xbox 360, все файлы содержимого будут хранить только ранее скомпилированные данные. Предположим, вы написали редактор частиц с поддержкой шейдеров для всех частиц. Если вы хотите динамически изменить шейдеры, текстуры или другие параметры частиц во время работы редактора, вам потребуется перезагрузка текстур, шейдеров и т.д. Но поскольку вам нужно сперва скомпилировать содержимое в XNA Studio, необходимо остановить приложение, добавить файлы в проект XNA Studio, повторить компиляцию и подождать, пока заново будет собрано все содержимое, и затем запустить программу снова. В случае если вы только тестируете и настраиваете эффекты частиц, это может очень раздражать и значительно замедлять процесс разработки. Возможно, для таких программ лучше динамически загружать текстуры, шейдеры и параметры частиц, и вообще не использовать конвейер содержимого.

Вот трюк, который я использую в большинстве проектов с большим количеством файлов содержимого: скомпилируйте их все и сделайте так, чтобы они не изменялись слишком часто (только раз в пару дней). После этого вы можете использовать проект-заглушку для компилирования всего игрового содержимого и просто копировать скомпилированный файл содержимого в ваш настоящий проект. Когда вы используете тестирование модулей и гибкие методологии, о которых говорилось в прошлой главе, вам придется запускать приложение несколько сотен раз в день и каждый запуск должен выполняться как можно быстрее.

Преимущества конвейера содержимого в том, что скомпилированные данные (файлы .xnb) не могут быть прочитаны другими программами, за исключением движка XNA, и процесс загрузки обычно выполняется быстрее, поскольку данные уже представлены именно в том формате, который требуется игре. Например, текстуры всегда хранятся как файлы DXT и используют уровни детализации, если вы указали это в свойствах содержимого. При этом игре надо только загрузить данные текстуры в одном быстром вызове и затем передать их видеокарте для визуализации, что тоже является очень быстрым процессом. Это еще важнее для данных трехмерных моделей. Если вы взглянете на игру Rocket Commander и выполните ее профилировку, то увидите, что загрузка трехмерных моделей и генерация всех дополнительных данных и касательных в основном выполняется при инициализации (более 90%), и игры XNA в которых в 10 раз больше моделей загружаются еще быстрее. Загружать все данные так быстро, как только возможно, очень важно и для Xbox 360, поскольку игры для консолей обычно характеризуются малым временем загрузки.

Управление каталогами содержимого

Ну что же, вы немного узнали о преимуществах и недостатках использования конвейера содержимого; теперь мы чуть больше сосредоточимся на программировании игр и каждодневных проблемах. Если вы взглянете на каталоги содержимого для игры Rocket Commander и XNA Racer (рис. 3.2), то увидите, что в Rocket Commander используется много различных каталогов, а в XNA Racer всего два простых каталога.


Рис. 3.2

Рис. 3.2


Взглянув на рисунок можно ожидать, что в Rocket Commander больше содержимого, но на самом деле XNA Racer использует в 10 раз больше трехмерных моделей, а также гораздо больше текстур, музыки и звуковых файлов.

Вы можете спросить, почему Rocket Commander использует так много каталогов. В этой игре нет конвейера содержимого, и все необходимое для каждой части игры надо хранить в организованной и простой для поиска структуре каталогов. Например, папка Textures хранит все необходимые текстуры для меню и игрового интерфейса, подкаталог Models хранит текстуры для трехмерных моделей, подкаталог Effects хранит текстуры для эффектов и т.д.

В XNA вы не можете использовать структуры каталогов такого вида, поскольку большинство файлов содержимого, особенно трехмерные модели, могут требовать рекурсивной загрузки набора других файлов содержимого (см. рис. 3.3).


Рис. 3.3

Рис. 3.3


Как видите, модель Apple загружается из файла Apple.x, который рекурсивно загружает Apple.dds, AppleNormal.dds и NormalMapping.fx. Обработчик содержимого ожидает, что все эти файлы находятся в одном и том же каталоге, что заставляет вас использовать один каталог для всех трехмерных моделей и используемых ими текстур и шейдеров. Кроме того, большинство шейдеров используются и для других трехмерных данных, и вы можете запутаться из-за дублирования шейдеров и наличия их в нескольких каталогах. Вы также иногда можете загружать текстуры для нестандартных трехмерных данных (например, в XNA Racer модель держателя дорожного ограждения использует ту же текстуру, что и генерируемый объект дорожного ограждения).

В любом случае важно помнить, что каждый фрагмент содержимого должен иметь уникальное имя. У вас не может быть модель Apple и текстура Apple. Как видно из строки «Входной файл» на рис. 3.3, вы добавляете только файл Apple.x; все другие файлы добавляются автоматически обработчиком модели. Кроме того, XNA достаточно умна, чтобы переименовать все рекурсивные файлы, поскольку они часто используют текстуры с тем же именем, что и у файла модели. Имена рекурсивных файлов будут заканчиваться на ~0. Вы также не можете установить свойства содержимого для этих рекурсивных файлов, поскольку не добавляете их в ваш проект. Поэтому убедитесь, что для входных файлов уже используется правильный формат (DXT1 и DXT5 в предыдущем примере).

Импорт содержимого и доступ к нему

Теперь вы знаете достаточно, чтобы импортировать какое-нибудь содержимое и обратиться к нему в вашей игре. В предыдущих главах вы уже обращались к некоторым файлам содержимого и бросили краткий взгляд на конвейер содержимого. Сейчас мы пристальнее взглянем на происходящий в действительности процесс и то, как используются файлы содержимого. В главе 7 вы узнаете, как написать собственный обработчик содержимого, расширив обработчик файлов X Model File Processor некоторыми полезными для вашего графического движка возможностями.

В главе 1 вы узнали как добавлять текстуры; просто возьмите файл текстуры (.dds, .jpg, .bmp или .png) и поместите его в ваш проект XNA Studio. Теперь вы можете щелкнуть по текстуре и настроить параметры обработчика Texture Content Processor (рис. 3.4).


Рис. 3.4

Рис. 3.4


Для текстур важно установить правильный режим в параметре Content Processor. Для двухмерных данных из вашей игры, таких как спрайты, тексты и графика интерфейса пользователя (UI), обычно лучше всего использовать 32-разрядный формат Sprite (без сжатия, а это значит, что 32-разрядная текстура размером 1024 × 1024 будет занимать 4 Мбайт).

Трехмерные текстуры используются в трехмерных играх гораздо чаще, чем двухмерные текстуры пользовательского интерфейса, к тому же с каждой игрой текстуры и уровни становятся все больше. Поэтому очень важно уменьшать размеры текстур. Вместо того чтобы сокращать разрешение ваших текстур, ухудшая внешний вид игры, используйте аппаратное сжатие текстур. Вы можете выбрать DXT1 для сжатия цветных текстур с коэффициентом 1:6 и DXT5 для сжатия текстур с альфа-информацией (или сжатия карт нормалей) с коэффициентом 1:4. Это означает, что с текстурами DXT1 в вашей игре может быть в шесть раз больше текстур, при том же объеме занимаемой памяти и без заметной потери качества. Другим трюком является комбинирование или даже генерирование текстур в ваших шейдерах; например, текстуры детализации могут улучшать вид ландшафтов почти не расходуя видеопамять.

Для моделей на данный момент вы можете выбрать только X Model Importer или FBX Model Importer (рис. 3.5). Возможно, в будущем появится больше форматов. Если вы написали собственный обработчик моделей, подобно тому, как мы поступим в главе 7, вы можете выбрать его точно так же, как выбирали обработчик текстур. Для наложения карт нормалей вы можете выбрать специализированный обработчик XNARacer Tangent Model Processor из главы 7. В следующих нескольких главах просто оставляйте предлагаемые по умолчанию параметры.


Рис. 3.5

Рис. 3.5


Если вы следовали способу загрузки текстур, показанному в двух предыдущих главах, то уже знаете, как загружать содержимое в XNA. Текстуры загружаются так:

backgroundTexture = content.Load<Texture2D>("CityGroundSmall");

Трехмерные модели загружаются точно так же — просто замените обобщенный тип метода Load:

appleModel = content.Load<Model>("apple");

Отображение модели несколько сложнее; здесь у вас нет простого метода рисования и вам приходится перебирать все сетки модели, обновлять все шейдерные эффекты и затем визуализировать каждую часть. Подробнее этот процесс мы рассмотрим в главах 5 и 6. Далее, в главе 7 этой книги вы увидите новый класс для загрузки и визуализации моделей, который упрощает отображение трехмерных моделей в вашем трехмерном мире до одной строки кода:

appleModel.Render(Vector3.Zero);

Теперь вы знаете все необходимое о конвейере содержимого. Мы узнаем о нем еще больше в последующих главах, когда будем добавлять трехмерные модели с помощью вашего собственного обработчика моделей с касательными из графического движка, и в главе 9, когда ближе познакомимся с XACT.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz