Эффективное рисование примитивов в openGL ES 2.0 - PullRequest
3 голосов
/ 22 марта 2012

Я пишу игру на Android, и она продвигается достаточно хорошо.Я стараюсь сделать все как можно более эффективным, поэтому я храню как можно больше в объектах буфера вершин, чтобы избежать ненужной загрузки ЦП.Однако простой процесс эффективного рисования множества несвязанных примитивов или даже цепочек спрайтов различной длины (например, рисование текста на экране) ускользает от меня.

Цель этих примитивов - меню и кнопки, так какну как текст.

Для рисования меню я мог бы просто создать массив вершин для каждого элемента (фон меню, кнопки и т. Д.), Но, поскольку все они - просто четырехугольники, это кажется очень неэффективным.Я также мог бы создать своего рода функцию drawQuad (), которая позволит мне просто прозрачно загрузить единственный сохраненный массив вершин с данными для xy / height & width / color / texture / what.Тем не менее, каждый раз перезагружая каждый элемент массива новыми координатами и другими данными, чтобы скопировать его в буфер с плавающей запятой (для ребят из C ++ это особый шаг, который вы должны сделать в Java для передачи данных в GL), поэтомуможет переслать его в графический процессор также чувствует себя неэффективным, хотя я не знаю, как еще я мог бы это сделать.(Одно повышение эффективности, которое я мог видеть, это установка четырехугольных координат в единичный квадрат, а затем использование Uniforms для его масштабирования, но это кажется не масштабируемым).

Для текста это еще хуже, так как я не знаюкак долго будет длиться текст, и не нужно создавать большие буферы для текста большего размера (что приводит к случайному срабатыванию GC позже).Альтернативой является рисование каждой буквы независимой командой рисования, но это также кажется очень неэффективным даже для сотен букв на экране (поскольку я прочитал, что вы должны попытаться использовать как можно меньше команд рисования).

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

1 Ответ

2 голосов
/ 27 марта 2012

Вам следует попробовать разобраться в идее чередования данных для ваших вызовов glDrawArrays. Конечно, эта ссылка предназначена для iphone, но внизу страницы есть хорошая графика, которая подробно описывает эту концепцию. http://iphonedevelopment.blogspot.com/2009/06/opengl-es-from-ground-up-part-8.html

Я собираюсь предположить, что для рисования ваших символов вы указываете некоторые координаты вершин и некоторые текстуры в некоторый вид растрового изображения шрифта, чтобы выбрать правильный символ. Таким образом, вы можете представить, что ваш FloatBuffer выглядит как

[vertex 1] [texcoord 1] [vertex 2] [texcoord 2] [vertex 3] [texcoord 3]

[vertex 2] [texcoord 2] [vertex 3] [texcoord 3] [vertex 4] [texcoord 4]

Вышеприведенное будет представлять один символ в вашем предложении, если вы используете GL_TRIANGLES, и вы могли бы расширить эту идею, чтобы иметь вершины 5–8 для представления второго символа и т. Д. И т. Д. Теперь вы можете нарисовать весь ваш текст на экране одним вызовом glDrawArrays. Теперь вас может беспокоить наличие избыточных данных в вашем FloatBuffer, но экономия будет огромной. Например, при рендеринге чайника с 1200 вершинами и наличии этих избыточных данных в моем буфере я смог получить очень заметное увеличение скорости по сравнению с вызовом glDrawArrays для каждого отдельного треугольника, может быть, примерно в 10 раз лучше.

У меня есть небольшая демонстрация sourceforge, где я использую чередование данных для рендеринга чайника, о котором я упоминал ранее. Это ShaderProgramTutorial.rar. https://sourceforge.net/projects/androidopengles/files/ShaderProgram/ Посмотрите в teapot.java в функции onDrawFrame, чтобы увидеть его.

Кроме того, на этой странице sourceforge можно найти и другие полезные материалы для вашего будущего Android OpenGL ES 2.0, забавного!

...