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

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

· Всего пользователей: 7,142
· Новый пользователь: Sarahseato
Последние фото
Thurs Puzzle
Thurs Puzzle
Альбом: XNA Games

Thurs Puzzle
Thurs Puzzle
Альбом: XNA Games

Thurs Puzzle
Thurs Puzzle
Альбом: XNA Games

Блоги
general
» Unity3D – Chunky ...
general
» Unity3D: Simple p...
dampirik
» Записки программи...
dampirik
» Локализация прило...
dampirik
» Эффективность рас...
general
» HLSL: Шейдер воды
general
» Unity 3D: Управле...
general
» Unity 3D: FPS scr...
yavshoke
» XboxOne - интерес...
dampirik
» Push уведомления ...
Поддержка
microsoft.com
1gb.ru - Дом для вашего сайта
Производительность при использовании класса SpriteBatch

Задача

При неправильном использовании класса SpriteBatch, ваше приложение будет выполняться ужасно медленно, если вы захотите отрисовывать большое количество изображений.

Решение

Как уже было упомянуто в разделе 3-1, создание нового класс SpriteBatch каждый фрейм или отдельный рендеринг каждого изображения (между вызовами методов Begin и End класса SpriteBatch) уничтожит вашу производительность. Но есть и более тонкие аспекты, о которых Вы должны знать.

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

Оптимизация производительности: режимы cортировки спрайтов

Метод Begin класса SpriteBatch позволяет вам устанавливать SpriteSortMode. Но прежде, чем я подробно их опишу, вы должны знать, как вашей видеокарте нравится работать и конечно что она не любит.

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

Учитывая это, вы можете перейти к возможным режимам сортировки спрайтов, которые определяются как параметр в методе SpriteBatch.Begin:


Deferred: Это режим SpriteSortMode по умолчанию. Вы вряд ли захочется его использовать, поскольку в этом режиме фактически никакая сортировка не используется. Всякий раз, когда вы добавляете спрайт к пакету, вызывая метод SpriteBatch.Draw, спрайт просто размещается в вершине стека. Когда вы вызываете метод SpriteBatch.End, все спрайты в стеке рисуются в том порядке, в каком спрайты были помещены в стек.
Texture: Обычно, для оптимальной производительности и простоты, вы будете использовать этот режим. Когда вы вызываете метод SpriteBatch. End, все изображения, которые выпомещали в стек, сортируются по текстурам, прежде, чем XNA фактически попросит, чтобы ваша видеокарта их нарисовала. Таким образом, ваша видеокарта может рисовать все треугольники, использующие одинаковую текстуру в одном прогоне, и вы уменьшите число раз, когда вы должны прервать работу видеокарты, чтобы изменить текстуру. Однако, в случаях, когда вы используете альфа-прозрачность, это может вызвать проблемы, и вы можете захотеть использовать один из следующих режимов.


BackToFront: При использовании альфа-смешивания вы захотите объекты, которые являются ­самыми дальними рисоваться вначале. Чтобы понять почему, прочитайте предыдущий раздел. Для этого случая, метод SpriteBatch.Draw, который добавляет изображение к классу SpriteBatch, имеет перегрузку, которая принимает layerDepth. Используя это значение с плавающей точкой, вы можете определить, глубину сортировки спрайтов, где 1.0f указывает уровень, который является самым дальним (который будет, например, содержать вашу траву), и 0.0f указывает уровень, который является самым близким (в котором например находятся камни). Вы можете определить любое число промежуточных значений. При использовании режима BackToFront, всякий раз, когда вы вызываете метод SpriteBatch.End, изображения в SpriteBatch будут отсортированы так, что самый дальний уровень будет рисоваться сначала.


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


Immediate: В противоположность всем другим режимам, в этом режиме XNA не будет ожидать вызова метода SpriteBatch.End, чтобы отрисовать все изображения в классе SpriteBatch. Пока вы добавляете изображения, которые используют одну текстуру в SpriteBatch, вызывая SpriteBatch.Draw, SpriteBatch поместит их в стек. Однако, если вы попробуете отрисовать спрайт, который использует другую текстуру, спрайты в текущем стеке будут немедленно отрисованы.

При использовании первых четырех режимов, только при вызове SpriteBatch.End, спрайты будут отсортированы, состояния рендеринга установлены, а треугольники и текстуры отправятся видеокарте. Это позволяет вам использовать несколько объектов класса SpriteBatch и добавлять новые спрайты к ним в случайном порядке, или даже рисовать трехмерные объекты, используя их собственные состояния рендеринга.

Однако используя режим Immediate, состояния рендеринга будут установлены когда вы вызываете метод SpriteBatch.Begin, f спрайты будут предоставлены после вызова SpriteBatch. Draw. Это означает, что у вас есть возможность изменять состояния рендеринга! Таким образом, вы можете обратиться к большему количеству режимов альфа-смешивания или даже рисовать спрайты, используя пользовательский пиксельный шейдер! Однако, рисуя изображения с использованием режима Immediate, вы не должны использовать ничего больше, например, трехмерные объекты, потому что вы вероятно измените состояния рендеринга, делая так. Когда вы захотите продолжать рисовать спрайты с вашим SpriteBatch, состояния рендеринга не будут восстановлены, таким образом вы будете выводить спрайты, используя состояния рендеринга и пиксельный шейдер трехмерного объекта.

Оптимизация производительности: сохранение нескольких изображений в одном графическом файле

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

Правильным подходом может быть размещение изображений, которые несколько соотносятся друг с другом в одно большое изображение, как как показано слева на рисунке 3-4. Таким образом, вы должны использовать параметр sourceRectangle метода SpriteBatch.Draw, чтобы определить, какая часть большого изображения содержит изображение, которое вы фактически хотите нарисовать, как показано во фрагменте кода раздела 3-3.

В изображении, показанном на рисунке 3-4, каждое подизображение содержит 40х40 пикселов. Код примера 3-3 определяет несколько прямоугольников, которые указывают, где подизображения позиционированы в одном большом графическом файле. Определение одного из этих прямоугольников в третьем параметре в методе SpriteBatch.Draw заставит это подизображение отрисоваться на экране.

Использование нескольких SpriteBatches

Как вы видели до сих пор, SpriteBatch — очень сильный объект. Вы могли группировать изображения всей игры в отдельный SpriteBatch, сортировать их и легко отрисовывать на экране. Однако, есть случаи, когда вы возможно захотите использовать несколько классов SpriteBatch.

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

Вы хотите немного дыма позади механизмов плоскостей, медленно исчезновения, и конечно большого количества дыма в следе после ракет. Если вы представляете все эти изображения, используя отдельный SpriteBatch, у вас есть проблема: вы хотите, чтобы все изображения были отсортированы по текстурам, чтобы добиться оптимальной производительности. Однако, вы нуждаетесь в плоскостях и ракетах, которые будут рисовать сначала, таким образом после этого вы можете смешивать их со своими спрайтам дыма. Это потребовало бы, чтобы ваши спрайты были сортированы по их layerDepth!

Решение находится при использовании двух объектов класса SpriteBatch: planeBatch и smokeBatch. В начале вашего метода Draw вы вызываете метод Begin обоих классов SpriteBatch. Затем, для каждой плоскости или ракеты, вы добавляете изображение плоскости или ракеты к planeBatch и дым позади плоскости или ракеты к smokeBatch. PlaneBatch может быть сортирован по текстуре, и smokeBatch может быть сортирован с использованием метода BackToFront. После того, как все изображения будут добавлены к пакетам, вы сначала вызываете метод End planeBatch, который заставит все изображения плоскостей и ракет отсортироваться по текстурам, и они будут рисоваться на экран с хорошей производительностью. Затем, вы вызываете smokeBatch.End, который заставит спрайты дыма смешаться с изображением. Так, у вас есть оптимальная производительность для того, чтобы рисовать ваши плоскости, и в то же время происходит корректное смешивание!

Перевод раздела 3-4 из книги XNA 3.0 Game Programming Recipes: A Problem-Solution Approach.  Остальные переводы смотрите на сайте www.x-graph.ru

Комментарии
#1 | IIporpammep 31.10.2012 14:47:57
"Как уже было упомянуто в разделе 3-1" это перевод какой-то книги? если да, неплохо бы указать её название.
#2 | aklemen 31.10.2012 18:21:32
Указал название книги в конце статьи.
#3 | IGreench 01.11.2012 10:32:10
Полезная статья! Спасибо =)
Добавить комментарий
Пожалуйста, залогиньтесь для добавления комментария.
Рейтинги
Рейтинг доступен только для пользователей.

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

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

Пароль



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

11.12.2023

11.12.2023
[img]https://x.pin
-up-world.com/imag
es/img4.jpg[/img]
[url=https://ofoi.
cenditt.loan/new-k
atiana-kay-fucking
-with-lucky-fan-p1
-porn-scenes/]133K
67% New Katiana

11.12.2023
[img]https://wwt.s
sgameadmin2.com/im
ages/img4.jpg[/img
]
[url=https://k.smi
letaxservice.com/r
edirect/SFpEdDR1cG
V4czNKMmxlQi9tVytI
d3dxWW9GWTd5Zk52TD
VVMG1mc3YvUmlDMWUw

11.12.2023

11.12.2023

10.12.2023
[img]https://ey.os
prey-holidays.uk/i
mages/img10.jpg[/i
mg]
[url=https://nby.h
ighlyresponsible.c
om/696488/sexyfeet
girl2020-gotta-kee
p-them-soft-lookin
g-

30.11.2023
[img]https://nuggi
e.army/images/img1
5.jpg[/img]
German Porno kostenlos - Deutsche Pornos & Pornofilme. [url=ht

30.11.2023

30.11.2023
[img]https://where
ijoin.com/images/i
mg8.jpg[/img]
Voir Films VF VOSTFR - . [url=http://mvig.j
ulieemontelaro.com
/]omegleX

30.11.2023
[img]https://steam
unlocked.tangobliv
ion.com/images/img
14.jpg[/img]
Top - Rated Live Sex Cam Videos to Watch Online. [

29.11.2023

29.11.2023
[img]https://chaii
t.com/images/img8.
jpg[/img]
Ottmaza.live - Ottmaza.Com Official Website | Ottmaza | Ottmaza.Net | Ottmaz

29.11.2023
[img]https://ezyja
mb.co.uk/images/im
g10.jpg[/img]
Free Porn - Sex, Tube Videos, XXX Pics, Pussy in Porno

29.11.2023
[img]https://launc
hbusinessloans.org
/images/img15.jpg[
/img]
Asyalı - Koreli Japon Seks Filmleri Türkçe A

29.11.2023
[img]https://panen
poker.org/images/i
mg8.jpg[/img]
[url=http://watchm
ovies.seoullittlem
all.com/]Junkie Musik Lossless &#ff7dee MГєsica ElectrГіnica p

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