Знакомство с XNA Game Studio 4.0

Знакомство с XNA Game Studio 4.0

Вот и вышла финальная версия XNA Game Studio 4.0, которая принесла с собой множество изменений. Некоторые из их мы попробуем рассмотреть с рамках данной серии статей.

Начнем с наиболее значимых нововведений (точнее, с наиболее значимого нововведения). В новой версии XNA Game Studio появилась поддержка Windows Phone 7, что не может не радовать. Такое изменение должно дать новый стимул для изучения XNA Framework, по крайней мере это верно для России, так как теперь и жители России смогут разрабатывать и продавать приложения для Windows Phone 7 и Xbox 360, используя специальный сервис от Microsoft (аналог App Store,если хотите), но об этом позже.

В первых бета-версиях XNA Game Studio 4.0 требовала для своей работы DirectX 10.1, что «оставляло за бортом» всех пользователей Windows XP, на котором данная версия не поддерживается.

К счастью, с выходом финальной версии, это ограничение было устранено и пользователи Windows XP снова смогут использовать последнюю версию XNA Framework, правда разрабатывать для Windows Phone 7 все равно не получится, только Windows и Xbox 360. Хотя это не должно быть такой уж проблемой: можно разрабатывать игру для Windows, а потом портировать ее под Windows Phone 7, благо делается это легко и приятно (разумеется, нужно с самого начала разработки проекта учитывать ограничения Windows Phone 7 вроде отсутствия поддержки собственных шейдеров или отсутсвия мыши и клавиатуры).

Итак, для пользователей Windows XP доступна отдельная версия XNA Game Studio 4.0 (предварительно нужно еще установить Visual Studio 2010!), которая может быть бесплатно скачана по ссылке:

http://create.msdn.com/en-us/resources/downloads

или более точно:

http://go.microsoft.com/fwlink/?LinkId=197288

Заодно стоит отметить, что и сайт Creators Club обновился и теперь имеет новый адрес: create.msdn.com. Большинство примеров на сайте уже переведено на новую версию XNA Framework, что не может не радовать.

Начнем работу с XNA Game Studio 4.0.

Сперва создадим новый проект и посмотрим, какие файлы входят в него через Solution Explorer:

Первое, что мы увидим — это новая структура решения (в смысле Solution). Ранее, как вы помните, создавался только один проект. Теперь же мы видим сразу два проекта, зато теперь у нас пропала папка Content, в которую мы раньше складывали все игровое создержимое.

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

Кстати, слово Content в скобках около названия проекта появилось не просто так. Если открыть свойства проекта, то мы увидим свойство Content Root Directory со значением Content. Эта название папки, в которую будут помещаться скомпилированные файлы с ресурсами. Можно выбрать любое другое подходящее название. Если вы поменяете название папки, то также нужно не забыть изменить свойство RootDirectory объекта ContentManager в основной программе.

У такого решения есть очевидные положительные стороны. Я приведу, пожалуй, не столь очевидное преимущество такого разделения. Получается, что теперь существует специальный тип проекта: Empty Content Project 4.0. Его очень сильно не хватало с предыдущих версиях в тех случаях, когда нужно интегрировать XNA Framework в Windows Forms приложение. Если вы не сталкивались с этим, то считайте, что вам повезло.

<Лирическое отступление>

В свое время я готовил доклад для techdays.ru по этой теме (так я его и не подготовил). Мне нужно было за 10-15 интегрировать XNA контрол в Windows Forms и сделать с ним что-нибудь интересное (например, плеер или редактор фотографий). Одной из проблем как раз была загрузка контента в приложение. Для этого требовалось создать проект Content Project. Но как это сделать без написания руками.proj файла было не понятно. Даже один из разработчиков из команды XNA, в ответ на мое письмо, сказал, что это в принципе сложновато… Думаю, что когда один из ведущих разработчиков технологии говорит, что что-то с этой технологией сделать трудно, то это действительон трудно J

</Лирическое отступление>

Вернемся к структуре проекта и посмотрим содержимое файла Program.cs.

Он немного изменился и теперь выглядит следующим образом:

using System;

namespace XNA4Test
{
#if WINDOWS || XBOX
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
#endif
}

Итак, можно заметить, что наше приложение скомпилируется только если мы попытаемся скомпилировать его под Windows или Xbox. (Если быть более точными, то приложение скомпилируется и выполнится только если в свойствах проекта на вкладке Build определена константа WINDOWS или XBOX (Conditional Compilation Symbols). Это за вас делает Visual Studio при создании проекта под определенную платформу).

Раз уж мы залезли в настройки проекта, то посмотрим на основное нововведение в этой части (кстати, также очень важное нововведение). Посмотрим на вкладку XNA Game Studio в настройках проекта.

Тут мы видим свойство Game Profile, которое отвечает за настройки графики (если можно так выразиться) и может быть установлено в режим Reach или HiDef.

Режим HiDef соответствует более хорошему качеству, с другой стороны он не поддерживается на Windows Phone 7.

Рассмотрим различия между двумя этими профилями:

Reach HiDef
Поддерживаемые платформы Windows Phone 7 Series, Xbox 360, Windows PC с DirectX 9 совместимым GPU, который поддерживает как минимум шейдерную модель 2.0 Xbox 360, and any Windows PC with a DirectX 10 (тут есть определенная хитрость, об этом читайте по ссылке ниже) GPU
Шейдерная модель 2.0  (Windows Phone не поддерживает шейдеры кроме встроенных) 3.0+  (Xbox 360 поддерживает расширения шейдеров, такие как vfetch, которые не поддерживаются на Windows)
Максимальный размер текстуры 2048 4096
Максимальный размер кубической карты (cubemap) 512 4096
Максимальный размер объемных текстур Объемные текстуры не поддерживаются 256
Поддержка текстур с разрешением не равным степеням двойки Условно: нельзя использовать режим адресации wrap, пирамидальную фильтрацию (mipmaps), или DXT сжатие Есть
Поддержка кубических карт с разрешением не равным степеням двойки Нет Есть
Поддержка объемных текстур с разрешением не равным степеням двойки Объемные текстуры не поддерживаются Есть
Максимальное количество примитивом в одном цикле рисования (на самом деле не совсем так, но я не смог лучше перевести. Оригинал выглядит так: Max primitives per draw call) 65535 1048575
Формат индексных буферов 16 bit 16 и 32 bit
Формат вершин Color, Byte4, Single, Vector2, Vector3, Vector4, Short2, Short4, NormalizedShort2, NormalizedShort4 Все форматы из профиля Reach, а также HalfVector2, HalfVector4
Форматы текстур Color, Bgr565, Bgra5551, Bgra4444, NormalizedByte2, NormalizedByte4, Dxt1, Dxt3, Dxt5 Все форматы из профиля Reach, плюс Alpha8, Rg32, Rgba64, Rgba1010102, Single, Vector2, Vector4, HalfSingle, HalfVector2, HalfVector4. Текстуры с форматом, использующим вещественные числа не поддерживают фильтрацию.
Форматы вершинных текстур Вершинные текстуры не поддерживаются Single, Vector2, Vector4, HalfSingle, HalfVector2, HalfVector4
Форматы поверхностей рисования (render targets) Различные Различные
Поддержка множетсвенных поверхностей рисования (MRT) Нет
До 4. Все поверхности должны иметь одинаковую битовую глубину. Поддерживается альфа блендинг и отдельные маски на каждую поверхность.
Поддержка Occlusion queries Нет Есть
Раздельный альфа блендинг Нет Есть
Blend.SourceAlphaSaturation Только для SourceBlend, нельзя для DestinationBlend Есть
Максимум потоков вершин 16 16
Максимальный шаг в потоке (Max stream stride) 255 255

 

Более подробно о профилях обязательно почитайте тут:

http://blogs.msdn.com/b/shawnhar/archive/2010/03/12/reach-vs-hidef.aspx

Профиль влияет на настройки Content Pipeline, причем HiDef является расширением Reach. Таким образом, получается, что контент, скомпилированный с настройками Reach может использоваться и в профиле HiDef без перекомпиляции, а вот обратное утверждение неверно.

Что еще нужно знать об этом параметре: в некоторых случаях (если у вас старая видеокарта) вы не сможете использовать HiDef режим даже для Windows приложений. Тогда нужно переставить профиль на Reach.

Класс Game1 у нас не изменился по сравнению с XNA Framework 3.1, что хорошо.

Давайте напишем какое-нибудь простейшее приложение. Для этого добавим в проект XNA4TestContent картинку (в моем случае это «Blue Hills.jpg»).

Загрузим картинку в LoanContent

 

        Texture2D tex;

 

 

        protected override void LoadContent()        {            // Create a new SpriteBatch, which can be used to draw textures.            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here            tex = Content.Load<Texture2D>("blue hills");        }

 

 

А в Draw нарисуем ее при помощи spriteBatch.Draw()

 

        protected override void Draw(GameTime gameTime)        {            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here            spriteBatch.Begin();

            spriteBatch.Draw(tex,                 new Rectangle(0,0,GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height),                 Color.White);

            spriteBatch.End();

            base.Draw(gameTime);        }

 

То есть все как раньше (а вот в 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 XNA4Test{    /// <summary>    /// This is the main type for your game    /// </summary>    public class Game1 : Microsoft.Xna.Framework.Game    {        GraphicsDeviceManager graphics;        SpriteBatch spriteBatch;        Texture2D tex;

        public Game1()        {            graphics = new GraphicsDeviceManager(this);            Content.RootDirectory = "Content";        }

        /// <summary>        /// Allows the game to perform any initialization it needs to before starting to run.        /// This is where it can query for any required services and load any non-graphic        /// related content.  Calling base.Initialize will enumerate through any components        /// and initialize them as well.        /// </summary>        protected override void Initialize()        {            // TODO: Add your initialization logic here

            base.Initialize();        }

        /// <summary>        /// LoadContent will be called once per game and is the place to load        /// all of your content.        /// </summary>        protected override void LoadContent()        {            // Create a new SpriteBatch, which can be used to draw textures.            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here            tex = Content.Load<Texture2D>("blue hills");        }

        /// <summary>        /// UnloadContent will be called once per game and is the place to unload        /// all content.        /// </summary>        protected override void UnloadContent()        {            // TODO: Unload any non ContentManager content here        }

        /// <summary>        /// Allows the game to run logic such as updating the world,        /// checking for collisions, gathering input, and playing audio.        /// </summary>        /// <param name="gameTime">Provides a snapshot of timing values.</param>        protected override void Update(GameTime gameTime)        {            // Allows the game to exit            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)                this.Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);        }

        /// <summary>        /// This is called when the game should draw itself.        /// </summary>        /// <param name="gameTime">Provides a snapshot of timing values.</param>        protected override void Draw(GameTime gameTime)        {            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here            spriteBatch.Begin();

            spriteBatch.Draw(tex,                 new Rectangle(0,0,GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height),                 Color.White);

            spriteBatch.End();

            base.Draw(gameTime);        }    }}

 

 

 

Запись опубликована в рубрике Uncategorized. Добавьте в закладки постоянную ссылку.

7 отзывов на “Знакомство с XNA Game Studio 4.0

  1. IGreench:

    большоooooе спасибо =)

  2. Уведомление: Некоторые интересные ссылки (Март) | Александр Богатырев: сфера

  3. Уведомление: ??????????? ????????? ?? ????????? ? ???????? Microsoft ?? ??????? ????? – ?????? 2011 - MSDN Blogs

  4. Уведомление: Технические материалы по продуктам и решениям Microsoft на русском языке – апрель 2011 | Alexander Knyazev: блог

  5. Guest:

    Спасибо за очень полезную статью))
    Но почему-то представленный на странице код очень некрасиво вылез за рамки….

  6. Kilo:

    Да код вылез за рамки, исправьте пожайлуста

Ответить на Guest Отменить ответ