Я разрабатываю 2D sidescrolling игру, и я должен оптимизировать свой код мозаичного размещения для получения лучшей частоты кадров. С прямо сейчас я использую атлас структуры и 16x16 мозаики для 480x320 разрешение экрана. Уровень прокручивает в обоих направлениях и значительно больше, чем 1 экран (тысячи пикселей). Я использую glTranslate для фактической прокрутки.
До сих пор я попробовал:
Таща всю карту как Дисплейный список (большой на небольшом уровне, способ замедлиться на большом)
Разделение карты в Дисплейные списки, половина размера экрана, затем отборе дисплейных списков (все еще замедляется для 2-направленной прокрутки, превышает ограничения, не эффективно),
Любой совет ценится, но в особенности я задаюсь вопросом:
Спасибо :)
Вот как я бы сделал для кодирования быстрого движка 2D-плитки:
Сначала я бы четко разделил динамические плитки (персонажи, предметы ...) и статические (уровень).
Для рисования статических плиток (плитки, которые составляют весь уровень) я бы использовал статический буфер (хранящийся в объекте буфера), который содержит каждую позицию плитки (x, y, слой) и индекс к данным текстуры атласа (i). Поскольку ваш атлас текстуры содержит плитки фиксированного размера 16x16 пикселей, вы можете легко вычислить координаты текстуры вершинного шейдера для каждой вершины.
Для рисования уровня я бы использовал один вызов отрисовки (с использованием экземпляра) полосы треугольников, образующих четырехугольник, данные вершин хранятся в статическом VBO (состоящем из 4 вершин), а данные индекса - в статическом IBO (состоящем из 4 индекса), используя значения для каждого экземпляра для вычисления атрибута вершин в вершинном шейдере.
Это даст вам почти "бесплатную" отсечку тайлов на GPU, поскольку оборудование для обрезки работает очень быстро.
Даже если у вас большое количество тайлов на вашем уровне, скажем, 30 * 20 (тайлов / на экране) и около ~ 50 экранов / уровень, это будет 30 000 тайлов. Я думаю, что это все еще приемлемо (даже на графических процессорах низкого уровня. Кстати, вы нацеливаетесь на iPhone / Android? Если да, создание экземпляров / шейдеры недоступны в OpenGL ES 1.0, а OpenGL ES 2.0 не поддерживает создание экземпляров, но может выполнять шейдеры, так что вы будете необходимо расчленить данные экземпляра тайлов в VBO / IBO и использовать GL_TRIANGLES
. Вы можете расчленить меньше данных и сэкономить память графического процессора, вычисляя атрибуты вершин в шейдере).
В любом случае лучше не дублировать данные тайлов текстуры и сохранить атлас текстуры, а также VBO и IBO.
Я бы использовал динамический VBO (и статический IBO, представляющий GL_TRIANGLES
, поэтому 0,1,2, 2,1,3, 0 + 4,1 + 4,2 +4 ..,), представляющий позиции тайлов, координаты текстур, слои, и обновляет их с помощью видимых динамических тайлов на экране через glBufferSubData
и рисует эти тайлы через glDrawElements
.
Конечно, это означает, что у вас есть максимальное количество динамических плиток, которые вы можете нарисовать на glDrawElements
, поэтому, если вы столкнетесь с этим пределом, вам придется выполнить второе обновление / отрисовку VBO. .
Если ваша реализация OpenGL не поддерживает VBO / IBO (как в OpenGL ES 1.0), используйте вместо этого VA. Я не рекомендую использовать DL или немедленный режим (его нет в OpenGL ES).
Наконец, используйте glOrtho
для перемещения камеры по уровню, увеличения / уменьшения и т. Д. Удачи!