Навигация
· XNA FAQ
· С чего начать
· Конкурсы
· Обратная связь
· XNA Блоги
Сейчас на сайте
· Гостей: 1

· Пользователей: 0

· Всего пользователей: 3,684
· Новый пользователь: headron
Последние фото
Эх, чуть не проспал закрытие.
Эх, чуть не проспал ...
Альбом: XNA Engine

GB
GB
Альбом: XNA Engine

South Park Coon & Friends
South Park Coon & Fr...
Альбом: XNA Games

Блоги
yavshoke
» XboxOne - интерес...
dampirik
» Push уведомления ...
dampirik
» Реклама,статистик...
Chort
» XNA и StartCoroutine
Chort
» Curve Class
dampirik
» Реклама, статисти...
dampirik
» Увеличение скорос...
dampirik
» Реклама, статисти...
general
» Распаковка DxtCom...
general
» Как работать с XN...
Поддержка
microsoft.com
1gb.ru - Дом для вашего сайта
Статистика посещений:

Вывод сцены в текстуру

Задача

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

Решение

Самое простое решение использует метод device.ResolveBackBuffer, который сохраняет текущее содержание заднего буфера в текстуру.

Однако, если вы хотите, чтобы сцена была выведена только  в текстуру, или в текстуру определенного размера, сначала вы должны изменить цель рендеринга от экрана до заданной в памяти, используя метод device.SetRenderTarget. Как только сцена будет ­полностью сохранена в этой цели, вы можете сохранить ее содержимое в текстуру.

Как это сделать

Самый простой подход вывести сцену на экран и скопировать содержимое заднего буфера в ResolveTexture2D. Поэтому,  сначала вы должны создать объект ResolveTexture2D, способный сохранить содержимое заднего буфера. Это означает, что его размер и формат должны быть теми же самыми, как размером и формат заднего буфера.  Добавьте этот код к своему методу LoadContent, чтобы создать объект ResolveTexture2D:

PresentationParameters pp = device.PresentationParameters;
resolveTexture = new ResolveTexture2D(device, pp.BackBufferWidth, pp.BackBufferHeight, 1, device.DisplayMode.Format);

Первая строка получает текущие PresentationParameters, содержащие все подробности о текущей конфигурации графического устройства. Они включают текущую ширину, высоту, и формат данных текущего заднего буфера. Вторая строка создает объект ResolveTexture2D на основании этих параметров настройки.

Создав объект ResolveTexture2D, вы можете использовать его, чтобы получить текущее содержимое заднего буфера. В вашем методе Draw, в точке, где вы хотите фиксировать содержимое заднего буфера, добавте эти строки:

device.ResolveBackBuffer(resolveTexture); resolveTexture.SaveCoutput.bmp", ImageFileFormat.Bmp);

Это разместит текущее содержимое заднего буфера в вашей переменной resolveTexture. Поскольку ResolveTexture2D наследуется от класса Texture2D, Вы можете использовать ее в любом случае, где вы использовали бы нормальный Texture2D. В этом примере текстура сохраняется в файл.

■Предупреждение. Из-за аппаратных особенностей, после вызова метода device. ResolveBackBuffer, содержимое заднего буфера сбрасывается!

Использование пользователькой цели рендеринга с размером, равным экрану

Вместо того, чтобы рендерить в задний буфер, вы можете определить пользовательский RenderTarget2D и активизировать его перед визуализацией. Таким образом, ничто не будет рисоваться на экране, в то время как активной является пользовательская цель рендеринга. Цель рендеринга  (RenderTarget) это часть памяти на видеокарте, которая может использоваться для вывода в нее изображения. После того, как все визуализировано, вы можете копировать содержимое RenderTarget в текстуру.

Добавьте переменную, которая будет хранить RenderTarget:

RenderTarget2D renderTarget;

и создайте ее экземпляр в методе LoadContent:

PresentationParameters pp = device.PresentationParameters;
renderTarget = new RenderTarget2D(device, pp.BackBufferWidth, pp.BackBufferHeight, 1, device.DisplayMode.Format);

Вы определяете ширину и высоту вашего RenderTarget, указываете, сколько уровней mipmap он должен иметь (см. примечание относительно mipmaps в разделе 3-6), и установите формат данных. В этом примере вы используете одинаковые значения с текущим задним буфером.

■ Примечание: Как всегда, mipmapping (см. примечание в предыдущем рецепте) может быть применен, только если ширина/высота вашей текстуры кратна степени 2. Так, если вы получаете ошибку, когда определяете любое другое число mip-уровней более 1, это может быть причиной.

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

device.SetRenderTarget(0, renderTarget);

См. раздел 6-10 для объяснения первого параметра этого метода. Вы должны поместить эту строку перед выполнением очистки в вашем методе Draw, потому что содержимое вашего RenderTarget должно быть очищено прежде, чем вы выведите что-нибудь на него. Затем, вы рендерите целую сцену, и после того, как рендеринг закончен, вы хотите скопировать содержимое RenderTarget  ­в текстуру. Прежде, чем вы сможете сделать это, вы должны активировать другую цель рендеринга. В этом коде вы устанавливаете значение по умолчанию, представляя задний буфер (содержимое которого будет выводиться на экран) как активную цель рендеринга, определяя второй параметр как null:

device.SetRenderTarget(o, null);
Texture2D resolvedTexture = renderTarget.GetTexture();

Так как вы активизировали задний буфер, все, что вы рендерите, с этого времени будет выводиться на экран, как обычно. Кроме того, последняя строка загружает содержимое, которое вы визуализировали в пользовательский RenderTarget в переменную resolvedTexture. Удостоверьтесь, что вы делаете все в этом порядке:

  1. Во-первых, активизируете свой пользовательский RenderTarget.
  2. Очищаете пользовательскую цель рендеринга (если нужно).
  3. Визуализируете все, что вам нужно.
  4. Дезактивируйте пользовательскую цель рендеринга, активизируя другую цель рендеринга.
  5. Размещаете содержимое вашего RenderTarget  в текстуру.

Установка пользовательской цели рендеринга, не равной экрану

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

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

Если вы будете хотеть поставить цель рендеринга с другим отношением ширины/высоты, чем ваше окно, то ваша матрица проекции для окна не будет больше допустима для вашего RenderTarget, потому что он был создан с использованием отношения ширины/высоты вашего экрана (см. раздел 2-1). Это означает, что вы должны будете определить новую матрицу проекции, которая соответствует вашей пользовательской цели рендеринга:

PresentationParameters pp = device.PresentationParameters;
int width = pp.BackBufferWidth / 2;
int height = pp.BackBufferHeight / 4;
renderTarget = new RenderTarget2D(device, width, height, 1, device.DisplayMode.Format);
rendertargetProjectionMatrix = Matrix.CreatePerspectiveField0fview(MathHelper.Pi0ver4, (float)width / (float)height, 0.5f, l00.0f);

Сначала вы определяете разрешение, которое должна иметь цель рендеринга и создаете соответствующую цели рендеринга матрицу проекции. Ширина вашей новой цели рендеринга будет половиной ширины вашего окна, в то время как ее высота будет четвертью высоты окна. Теперь всякий раз, когда вы передаете сцену в новый RenderTarget, вы должны указывать, что хотите использовать матрицу проекции вашего RenderTarget вместо матрицы проекции, соответствующей окну.

Код

Инициализируйте объект RenderTarget2D, и установите его разрешение, которое вам необходимо. Обратите внимание, что если вы сохраняете ее содержимое в текстуру, размер текстуры будет тем же самым что и у RenderTarget.

protected override void LoadContent()
{
    device = graphics.GraphicsDevice;
    basicEffect = new BasicEffect(device, null);
    cCross = new CoordCross(device);
    SpriteBatch = new SpriteBatch(device);

    presentationParameters pp = device.PresentationParameters;
    int width = pp.BackBufferWidth / 2;
    int height = pp.BackBufferHeight / 4;
    renderTarget = new RenderTarget2D(device, width, height, 1, device.DisplayMode.Format);
    rendertargetProjectionMatrix = Matrix.CreatePerspectiveField0fview(MathHelper.Pi0ver4, (float)width / (float)height, 0.5f, l00.0f);
}

В методе Draw вы активизируете свою пользовательскую цель рендеринга, очищаете ее, рендерите в нее, дезактивируете, и сохраняете содержимое в текстуру. Важно отметить то, что вы используете свой rendertargetProjectionMatrix, чтобы рисовать трехмерные объекты в вашу пользовательскую цель рендеринга (показано в следующем коде). Опционально, эта текстура отображается на экран, с использованием SpriteBatch:

protected override void Draw(GameTime gameTime)
{
    device.SetRenderTarget(0, renderTarget);
    device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1,0);
    cCross.Draw(fpsCam.ViewMatrix, rendertargetProjectionMatrix); device.SetRenderTarget(0, null);
    Texture2D resolvedTexture = renderTarget.GetTexture();

    graphics.GraphicsDevice.Clear(Color.Tomato); spriteBatch.Begin();
    spriteBatch.Draw(resolvedTexture, new Vector2(100, 100), Color.White);
    spriteBatch.End();

    base.Draw(gameTime);
}

Перевод раздела 3-8 из книги "XNA 3.0 Game Programming Recipes: A Problem-Solution Approach".  Остальные переводы смотрите на сайте www.x-graph.ru
Комментарии
Нет комментариев.
Добавить комментарий
Пожалуйста, залогиньтесь для добавления комментария.
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Авторизация
Логин

Пароль



Вы не зарегистрированы?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Мини-чат
Вы должны авторизироваться, чтобы добавить сообщение.

27.08.2014
Я умею немного на asp.net + html и css

22.08.2014
на ASP mvc 3 есть пару проектов. Могу помочь, если нужно. Обидно, если закроется Frown

21.08.2014
я тоже ноль

21.08.2014
Я в вебе только с php занимался да и то на уровне чтоб работало.

21.08.2014
Я в вебе полный ноль…

21.08.2014
Переводить его надо, хоть на ту же азуру. И двиг менять на что-то современное. Если есть веб-разрабы - можем скооперироваться. Один делать не буду.

21.08.2014
не знаю всех нюансов по оплате и все хорошее когда нибудь заканчивается

21.08.2014
А что случилось?

21.08.2014
похоже сайт будет работать до 28го числа

09.08.2014
Апи пока не видел. Но есть приложение в магазине Live Lock Screen BETA, так что думаю скоро будет

08.08.2014
Я про API для Update1. На нем работает это

08.08.2014
А что именно нужно? Чтото и сейчас открыто http://msdn.micro.
...105).aspx

06.08.2014
Кто-нибудь слышал об открытии доступа к Lock Screen Api?

31.07.2014
VPDExpress на базе MVS 2012, ни в какую не ловит исключения. Даже если их сам создаешь. И всех так?

25.07.2014
С днем системного администратора причастных к этой профессии! По случаю - тортик от жены

RSS каналы сайта
XNA - Новости
XNA - Статьи
XNA - Форум
XNA - Галерея
XNA - Файлы
Время загрузки: 0,03 секунд 8,709,461 уникальных посетителей