Эффективный способ рисования в OpenGL ES - PullRequest
11 голосов
/ 02 октября 2010

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

Метод 1, который я сейчас использую: так как все кубы имеют одинаковые размеры, я вычисляю буфер вершин, индексный буфер, нормальный буфер и буфер цвета только один раз. Во время обновления сцены я перебираю все кубы, выполняю bufferData () для того же набора буферов, а затем рисую треугольную сетку куба с помощью вызова drawElements (). Так как каждый куб находится в разной позиции, я перевожу mvMatrix перед рисованием. bufferData () и drawElements () выполняются для каждого куба. В этом методе я, вероятно, экономлю много памяти, не вычисляя буферы каждый раз. Но я делаю много вызовов drawElements ().

Метод 2: обрабатывать все кубы как набор многоугольников, разбросанных по всей сцене. Вычислить вершины, индекс, цвет, нормальные буферы для каждого многоугольника (фактически, треугольники внутри многоугольников) и поместить их в память видеокарты за один вызов метода bufferData (). Затем нарисуйте их одним вызовом drawElements (). Преимущество этого подхода заключается в том, что я делаю только один вызов bindBuffer и drawElements. Недостатком является то, что я использую много памяти для создания буферов.

Мой опыт работы с OpenGL достаточно ограничен, чтобы не знать, какой из вышеперечисленных методов лучше с точки зрения производительности.

Я использую это в приложении WebGL, но это общий вопрос OpenGL ES.

Ответы [ 3 ]

14 голосов
/ 13 октября 2010

Я реализовал метод 2, и он победил оползнем. Предполагаемая обратная сторона большого объема памяти, казалось, была только моим воображением. Фактически сборщик мусора вызывался в методе 2 только один раз, тогда как в методе 1 он вызывался 4-5 раз.

Ваш сценарий OpenGL может отличаться от моего, но если вы пришли сюда в поисках советов по повышению производительности, урок из этого вопроса: определить части вашей сцены, которые не меняются часто. Независимо от того, насколько они велики, поместите их в один набор буферов (VBO) и загрузите в графическую память минимальное количество раз. Вот как VBO предназначены для использования. Пропускная способность памяти между клиентом (т. Е. Вашим приложением) и видеокартой очень важна, и вы не хотите использовать ее часто без причины.

Прочтите раздел «Объекты буфера вершин» в гл. 6 «Руководства по программированию OpenGL ES 2.0», чтобы понять, как они должны использоваться. http://opengles -book.com /

5 голосов
/ 05 октября 2011

Я знаю, что на этот вопрос уже дан ответ, но я думаю, что стоит указать презентацию Google IO об оптимизации WebGL:

http://www.youtube.com/watch?v=rfQ8rKGTVlg

Они охватывают, по сути, ту же самую проблему (множество одинаковых форм с разными цветами / позициями) и говорят о некоторых замечательных способах оптимизации такой сцены (и у них тоже динамично!)

0 голосов
/ 13 октября 2010

Я предлагаю следующий подход:

При загрузке:

  1. Создать буфер координат (для одного куба) и загрузить его в VBO (gl.glGenBuffers, gl.glBindBuffer)

На ничьей:

  1. Буфер привязки (gl.glBindBuffer)

  2. Нарисуйте каждую ячейку (цикл)

    2,1.Переместить текущую позицию в центр текущего куба (gl.glTranslatef(position.x, position.y, position.z)

    2.2.Нарисуйте текущий куб (gl.glDrawArrays)

    2.3.Вернуть позицию назад (gl.glTranslatef(-position.x, -position.y, -position.z))

...