glBindTexture () + glBegin (foo) медленно? - PullRequest
4 голосов
/ 26 января 2011

Я создаю небольшую игру для MacOS, используя Cocoa + OpenGL для создания GUI.Игра представляет собой BoulderDash-Clone, так что в основном это 2D-массив объектов, а не ЭТО много (уровень подобен 40 объектам в ширину и 25 объектам в высоту).Многие объекты анимированы, поэтому я должен динамически извлекать текстуры при их рисовании (я использую NSTimer, чтобы постоянно перерисовывать сцену для анимации).Похоже, это вызывает серьезные проблемы с производительностью.

Сначала я сделал

for(y1, ..., yn) for(x1, ..., xn)
{
  glBindTexture(foo);
  glBegin(GL_QUAD);
    [drawing the quad with texture]
  glEnd();
}

, который работал, но был очень медленным (Activity Monitor показывал 20% загрузки ЦП).Поскольку я еще не создавал никаких текстур, я использую заполнитель, который позволил мне протестировать

glBindTexture(foo);
for(y1, ..., yn) for(x1, ..., xn)
{
   glBegin(GL_QUAD);
     [drawing of quad with texture]
   glEnd();
}

, что было намного быстрее (загрузка процессора 2%).Поэтому я подумал, что это glBindTexture (), что вызвало значительное замедление.Затем я попытался выяснить, насколько медленным является glBindTexture (), и сделал

for(y1, ..., yn) for(x1, ..., xn)
{
  glBindTexture(foo);
  // no drawing this time
}

, что также было очень быстро (загрузка ЦП 2%).Почему это так?

В конечном итоге мне придется поместить glBindTexture () и рисунок в один и тот же цикл, так как я должен связать текстуру в соответствии с объектом и его анимацией.Поэтому мне нужно выяснить, что вызывает проблемы с производительностью в первом примере кода и как я могу ускорить процесс.Я всегда думал, что несколько сотен объектов с разными текстурами не будут такими медленными с OpenGL.О, и я уже однажды строил эту игру с Java + JOGL, и если я правильно помню, я делал то же самое, и это было намного быстрее.Разве Objective-C / C ++ не должен разрушать производительность Java?

1 Ответ

4 голосов
/ 26 января 2011

Спецификация OpenGL дает реализациям немного свободы, когда дело доходит до обработки команд. Ваш glBindTexture() вызов может просто установить int в очереди команд, который фактически не обрабатывается, пока вы не поменяете местами буферы или не вызовете glFinish() / glFlush(). Он может даже (в основном) игнорироваться, если вы вызываете его, а затем не предоставляете OpenGL какую-либо геометрию для использования с ним.

Используйте текстурные атласы для сокращения glBindTexture() вызовов.

glBegin() и друзья - самый медленный способ отправки геометрии в OpenGL. Постарайтесь максимально упорядочить свою геометрию и использовать массивы вершин / VBOs , чтобы сократить накладные расходы при вызове функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...