Большой прокручивающийся фон в OpenGL ES
-
03-07-2019 - |
Вопрос
Я работаю над 2D-игрой с прокруткой для iPhone.У меня есть большой фон изображения, скажем, 480 × 6000 пикселей, из которых видна только часть (ровно один экран, 480 × 320 пикселей).Каков наилучший способ получить такой фон на экране?
В настоящее время я разделил фон на несколько текстур (чтобы обойти ограничение на максимальный размер текстуры) и нарисовал весь фон в каждом кадре в виде текстурированной треугольной полосы.Прокрутка осуществляется путем преобразования матрицы modelview.Для рамки с ножницами установлен размер окна 480 × 320 пикселей.Это не должно быть быстрым, я просто хотел получить работающий код, прежде чем приступать к оптимизации.
Я подумал, что, возможно, реализация OpenGL была бы достаточно умной, чтобы отбросить невидимую часть фона, но согласно некоторому измерительному коду, который я написал, похоже, что фоновое отображение занимает в среднем 7 мс, а максимальное - 84 мс.(Это измеряется в симуляторе.) Это примерно половина всего цикла рендеринга, т.е.довольно медленно для меня.
Нарисовать фон должно быть так же просто, как скопировать примерно 480 × 320 пикселей из одной части видеопамяти в другую, или, другими словами, очень быстро.Каков наилучший способ приблизиться к такой производительности?
Решение
Это самый быстрый способ сделать это.Что вы можете сделать для повышения производительности:
- Попробуйте разные форматы текстур.Предположительно, в документах SDK есть подробная информация о предпочтительном формате, и, по-видимому, чем меньше, тем лучше.
- Отбирайте полностью закадровые плитки самостоятельно
- Разделите изображение на более мелкие текстуры
Я предполагаю, что вы рисуете с масштабированием 1:1;так ли это на самом деле?
Редактировать: Упс.Более внимательно прочитав ваш вопрос, я должен дать еще один совет: Тайминги, сделанные на симуляторе, ничего не стоят.
Другие советы
Быстрое решение:
Создайте геометрическую матрицу плиток (предпочтительно квадратиков) так, чтобы со всех сторон видимой области была хотя бы одна строка / столбец внеэкранных плиток.
Нанесите текстуры на все эти плитки.
Как только одна плитка окажется за пределами видимой области, вы можете освободить эту текстуру и привязать новую.
Переместите плитки, используя в качестве позиции значение, равное модулю ширины плитки и высоты плитки (чтобы плитка переместилась в исходное положение, когда она переместится ровно на одну плитку в длину).Также не забудьте переназначить текстуры во время этой операции.Это позволяет вам загружать очень маленькую сетку / очень мало текстурной памяти в любой момент времени.Что, я думаю, особенно важно в GL ES.
Если у вас есть свободная память и вы все еще страдаете от низкой скорости загрузки (хотя этого не следует делать при таком количестве текстур).Вы могли бы создать механизм потоковой передачи текстур, который предварительно загружает текстуры в более быструю память (независимо от того, что может быть на вашем целевом устройстве), когда вы достигаете новой области.Отображение в виде текстур в этом случае будет осуществляться из этой более быстрой памяти, когда это необходимо.Просто убедитесь, что вы можете предварительно загрузить его, не используя всю память, и не забудьте освободить его динамически, когда в этом нет необходимости.
Вот ссылка на движок плиток GL (не ES).Я сам им не пользовался, поэтому не могу поручиться за его функциональность, но, возможно, он сможет вам помочь: http://www.mesa3d.org/brianp/TR.html