Изменения при работе с RenderTargets в XNA 2.0/3.0
Перевод записи блога Shawn Hargreaves - одного из разработчиков XNA framework.
Плохие новости:
Если у вас есть программа использующая рендертаргеты (rendertargets) и она прекрасно работает на XNA Framework 1.0, еще не факт что она будет работать на XNA 2.0.
Хорошие новости:
Работа сабжа стала более логичной.
Сейчас все объясню…
Как работают рендертаргеты в версии 1.0
В Windows:
1. Каждый рендертаргет размещается в отдельной части видеопамяти
2. После выбора рендертаргета вы можете отрисовывать в эту видеопамять
3. После завершения отрисовки, вы вызываете метод GetTexture и можете использовать эту часть видеопамяти как текстуру
4. Мы можете производить запись в различные рендертаргеты бесчисленное количество раз и состояние контента всегда будет валидным
На XBOX 360:
1. Все рендертаргеты делят специально выделенной области EDRAM памяти
2. Это означает, что в один промежуток времени только один рендертаргет может существовать физически
3. Когда вы закончили отрисовку в рендертаргет, метод GraphicsDevice.ResolveRenderTarget копирует данные из EDRAM в отдельную область текстурной памяти
4. Затем вы можете использовать эту текстуру для своих нужд
5. Но EDRAM в данный момент может быть занята другим рендертаргетом!
6. Работа производится не совсем так, как вы этого можете ожидать:
7. Отрисовка в задний буфер (EDRAM содержит только что отрисованные данные)
8. Переключаемся на рендертаргет
9. Отрисовка в рендертаргет (EDRAM содержит только что отрисованные данные)
10. Вызываем Resolve рендертаргета (RenderTarget.GetTexture() содержит копию данных, которые мы только что отрисовали)
11. Переключаемся на задний буфер (И вот тут нас ждет засада! В процессе переключения, предыдущий рендертаргет перезаписал данные которые были созданы в процессе записи в задний буфер, таким образом, в EDRAM больше нет изображения заднего буфера)
В итоге:
* Каждый раз при переключении рендертаргета, содержимое EDRAM перезаписывается, так что данные предыдущего рендертаргета (включая задний буфер) уничтожаются
* Но, если данные рендертаргета связать с текстурой, данные не перезатераются
Все будет нормально, в случае:
1. Отрисовка в рендертаргет A
2. Отрисовка в рендертаргет B
3. Отрисовка текстур из рендертаргетов A и B в рендертаргет C
Но, не будет нормально, при:
1. Отрисовка в рендертаргет A
2. Отрисовка в рендертаргет B
3. Переключение обратно на рендертаргет A и продолжить запись поверх него
Довольно легко можно написать приложение, которое будет замечательно работать на одной платформе, но так же легко оно будет не работать при запуске на другой платформе.
Как работают рендертаргеты в версии 2.0
По умолчанию:
1. Вы получаете поведение XBOX
2. На XBOX ничего не изменилось
3. В Windows мы автоматически очищаем ваши рендертаргеты, эмулируя поведение XBOX
4. Это довольно быстро на обеих платформах (очистка дешевая операци)
Если вам не нравится поведение по умолчанию:
1. Вы можете указать другой RenderTargetUsage
2. В параметре конструктора RenderTarget2D
3. Для изменения поведения для заднего буфера используйте событие GraphicsDeviceManager.PreparingDeviceSettings для изменения GraphicsDeviceInformation.PresentationParameters.RenderTargetUsage
4. Указать RenderTargetUsage.PreserveContents
5. На Windows работает так же, как и прежде
6. На XBOX мы автоматически копируем данные из текстуры в EDRAM, для восстановления содержимого рендертаргета, на который вы переключаетесь
7. Это очень дорого! Используйте данный функционально только если у вас есть запас по производительности
8. Указать RenderTargetUsage.PlatformContents чтобы вернуться к поведению версии 1.0, которые различны у Windows и XBOX
Рекомендации:
По возможности используйте режим по умолчанию RenderTargetUsage.DiscardContents. Он показывает хорошую производительность и пригоден для применения на обеих платформах.
Прочие хорошести:
В версии 2.0 больше нет необходимости вызывать метод GraphicsDevice.ResolveRenderTarget, а фактически вы даже не сможете его вызвать, так как мы его убрали. Мы делаем это автоматически когда вы переключаетесь между рендертаргетами.
В 2.0 на XBOX мы теперь поддерживаем множественные рендертаргеты - multiple simultaneous rendertargets (MRT)
949 Прочтений • [Изменения при работе с RenderTargets в XNA 2.0/3.0] [08.08.2012] [Комментариев: 0]