Я видел много примеров того, как визуализировать спрайты из таблицы спрайтов, но я не понял, почему это самый распространенный способ работы со спрайтами в 2d играх.
Я начал с 2d рендеринга спрайтов в нескольких демонстрационных приложениях, которые я сделал, имея дело с каждым кадром анимации для каждого данного типа спрайта в качестве своей собственной текстуры - и эта коллекция текстур хранится в словаре. Кажется, это работает для меня и вполне подходит для моего рабочего процесса, так как я обычно делаю свои анимации в виде файлов gif / mng, а затем извлекаю кадры в отдельные png-файлы.
Есть ли заметное преимущество в производительности при рендеринге с одного листа, а не с отдельных текстур? С современным оборудованием, способным выводить миллионы полигонов на экран сто раз в секунду, имеет ли это значение для моих двухмерных игр, которые имеют дело с несколькими десятками прямоугольников размером 50x100 пикселей?
Детали реализации загрузки текстуры в графическую память и ее отображения в XNA кажутся довольно абстрактными. Все, что я знаю, это то, что текстуры привязываются к графическому устройству, когда они загружаются, а затем во время игрового цикла текстуры визуализируются партиями. Так что мне не ясно, влияет ли мой выбор на производительность.
Я подозреваю, что есть некоторые очень веские причины, по которым большинство разработчиков 2D-игр, похоже, используют их, я просто не понимаю, почему.
источник
Ответы:
Сильный аргумент в пользу использования спрайт-листов заключается в том, что количество доступных текстур на графической карте может быть ограничено. Поэтому вашей графической библиотеке постоянно приходится удалять текстуры и перераспределять текстуры на графическом процессоре. Гораздо эффективнее просто выделить большую текстуру один раз.
Также учтите, что размеры текстур обычно имеют степень 2. Поэтому, если у вас Sprite размером 50x100 пикселей, вы будете размещать текстуры размером 64x128 пикселей или в худшем случае 128x128 пикселей. Это просто трата графической памяти. Лучше упакуйте все спрайты в текстуру 1024x1024px, что позволит использовать спрайты 20x10, и вы потеряете только 24 пикселя по горизонтали и вертикали. Иногда даже спрайты разных размеров объединяются в один огромный спрайт-лист, чтобы использовать текстуру максимально эффективно.
Приложение. Очень важной причиной для использования спрайт-листов является уменьшение количества обращений к графическому процессору, что может оказать существенное влияние на производительность. Об этом говорилось в других ответах, и я добавляю это для полноты картины, чтобы это стало более наглядным.
источник
Я бы сказал, что аргументом для использования будет возможность визуализировать несколько вещей за один вызов отрисовки. Возьмем, к примеру, рендеринг шрифта, без таблицы спрайтов вам нужно будет рендерить каждый символ с отдельной заменой текстуры, а затем вызовом отрисовки. Бросьте их в таблицу спрайтов, и вы сможете рендерить целые предложения одним вызовом отрисовки (разностные символы в шрифте выбираются просто указанием различных UV для углов). Это гораздо более эффективный способ рендеринга, когда очень много затрат на рендеринг на многих платформах связано с слишком большим количеством вызовов API.
Это также может помочь сэкономить место, но в первую очередь это зависит от того, что вы упаковываете в таблицу спрайтов.
источник
Каждый колл-вызов имеет определенное количество накладных расходов. Используя спрайт-листы, вы можете пакетно рисовать вещи, которые не используют один и тот же кадр анимации (или, в более общем смысле, все, что на одном материале), значительно повышая производительность. Это может не иметь большого значения для современных ПК в зависимости от вашей игры, но это определенно имеет значение, скажем, для iPhone.
источник
В дополнение к соображениям производительности, спрайт листы могут быть полезны при создании искусства; каждый персонаж может быть на своем листе, и вы можете увидеть все кадры, просто прокручивая их. Это помогает мне последовательно смотреть на все кадры.
Кроме того, я кодирую в AS3, и для каждого файла изображения требуется отдельная инструкция по встраиванию. Я предпочел бы иметь одно встраивание всей таблицы спрайтов, а не 24 встраивания для всех фреймов, даже если я использую отдельный класс ресурсов.
источник
Другая причина использования спрайт-листов с XNA заключается в том, что при разработке Xbox360 существует известная проблема, связанная с медленным временем развертывания / загрузки по сравнению с количеством файлов в вашем проекте. Таким образом, объединение множества небольших файлов изображений в один файл изображения поможет решить эту проблему.
источник
Я не буду здесь упоминать память / графический процессор, поскольку таких ответов достаточно.
Вместо этого он может прояснить ваше искусство, когда вы работаете над ним - и после. Вместо того, чтобы пролистывать 10 изображений, чтобы увидеть цикл ходьбы, вы можете увидеть все кадры за один раз. Если вы хотите распространить это, у вас есть только 1 файл вместо 10.
Кроме того, более чистым (с организационной точки зрения) было бы использовать файл character.png и врага.png от персонажа от 01 до до персонажа 10, затем от персонажа от 01 до персонажа 05 и так далее.
источник
Графическая память не имеет раздутого управления памятью, как файловые системы на дисках; обратный случай - он прост и быстр .
Одним из таких простых и быстрых способов управления памятью может быть то же самое, что иметь только один гигантский спрайт 4096x4096, который разрезается на несколько меньших спрайтов путем уменьшения его ширины и / или высоты вдвое. (Существует похожая одномерная техника управления памятью, но я забыл название.) В конце концов, должна быть выполнена дефрагментация.
Чтобы пропустить такое управление памятью во время выполнения , разработчики автоматически заполняют отдельные большие спрайты несколькими меньшими спрайтами во время компиляции или даже в процессе разработки графики.
источник
Также не забывайте, что операции ввода / вывода могут спасти вас во время инициализации. Если вы загружаете с CD-привода, каждый файл является дополнительным вызовом ввода / вывода, и может потребоваться некоторое время для поиска (современные жесткие диски занимают около 15 мс на файл, CD, может быть, 50-100 мс?). Это может сэкономить вам много времени инициализации, так как нужно выбрать только один файл. Это также позволяет вашей ОС кэшировать эти операции ввода-вывода, если ваше приложение выполняет что-то еще (например, ожидание графического процессора).
источник
Кроме того, что я более эффективен, я нахожу это проще. Требуется немного поработать, чтобы убедиться, что ваши изображения всегда находятся в пределах их границ при создании рисунка, но гораздо легче видеть все изображения, с которыми вы имеете дело в данный момент.
На мой взгляд, проще в написании кода. У меня просто есть массив объектов, таких как:
Затем для каждого элемента я даю ему два значения, лист и прямоугольник. Лист будет индексом в массиве объектов, а прямоугольник будет индексом в массиве rects этого листа.
источник