Советы по ускорению OpenGL ES 1.1 на iPhone

Я работаю над приложением для iPhone, которое сильно зависит от OpenGL. Прямо сейчас он работает немного медленно на iPhone 3G, но выглядит быстро на новом 32G iPod Touch. Я предполагаю, что это связано с аппаратным обеспечением. В любом случае, я хочу, чтобы производительность iPhone напоминала производительность iPod Touch. Я полагаю, что я делаю много вещей неоптимально в OpenGL, и я хотел бы получить совет о том, какие улучшения принесут мне наибольшую отдачу.

Мой рендеринг сцены выглядит примерно так:

  • Повторите 35 раз
    • glPushMatrix
    • glLoadIdentity
    • glTranslate
    • Повторить 7 раз
      • glBindTexture
      • glVertexPointer
      • glNormalPointer
      • glTexCoordPointer
      • glDrawArrays (GL_TRIANGLES,...)
    • glPopMatrix

Мои координаты вершин, нормалей и текстур уже чередуются.

Итак, какие шаги я должен предпринять, чтобы ускорить это? Какой шаг вы бы попробовали в первую очередь?

Моя первая мысль - устранить все эти вызовы glBindTexture() с помощью Атласа текстур.

Как насчет более эффективных матричных операций? Я понимаю, что версии gl*() не слишком эффективны.

Как насчет VBO?

Обновить

Всего 8260 треугольников. Размеры текстур - 64x64 png. Есть 58 различных текстур.

Я не управлял инструментами.

Обновление 2

После запуска инструмента OpenGL ES на iPhone 3G я обнаружил, что моя утилита Tiler находится в диапазоне 90-100%, а моя утилита рендеринга находится в диапазоне 30%.

Обновление 3

Texture Atlasing не оказала заметного влияния на проблему. Диапазоны использования остаются такими же, как указано выше.

Обновление 4

Преобразование моих указателей вершин и нормалей в GL_SHORT, казалось, улучшило FPS, но использование Tiler все еще находится в диапазоне 90% большую часть времени. Я все еще использую GL_FLOAT для моих текстурных координат. Я полагаю, что смогу свалить их в GL_SHORT и сохранить еще четыре байта на вершину.

Обновление 5

Преобразование моих координат текстуры в GL_SHORT привело к еще одному увеличению производительности. Теперь я постоянно получаю>30 FPS. Коэффициент использования плит по-прежнему составляет около 90%, но часто падает в диапазоне 70-80%. Использование рендерера колеблется около 50%. Я полагаю, это может быть связано с масштабированием координат текстуры из матричного режима GL_TEXTURE.

Я все еще ищу дополнительные улучшения. Я хотел бы приблизиться к 40 кадрам в секунду, поскольку это то, что получает мой iPod Touch, и там он шелковисто гладкий. Если кто-то все еще обращает на себя внимание, то какие другие висящие фрукты я могу выбрать?

6 ответов

Решение

С использованием тайлера все еще выше 90%, вы, вероятно, все еще ограничены пропускной способностью вершин. Ваше использование рендерера выше, потому что графический процессор рендерит больше кадров. Если ваш основной упор делается на повышение производительности на старых устройствах, то ключ все еще заключается в сокращении количества данных вершин, необходимых для каждого треугольника. У этого есть две стороны:

Сокращение объема данных на вершину: теперь, когда все ваши атрибуты вершины уже GL_SHORTСледующее, что нужно сделать, это найти способ сделать то, что вы хотите, используя меньше атрибутов или компонентов. Например, если вы можете жить без зеркального освещения, использование освещения DOT3 вместо освещения с фиксированной функцией OpenGL ES заменит ваши 3 шорта (+ 1 меньше отступа) для нормалей на 2 шорта для дополнительной координаты текстуры. В качестве дополнительного бонуса вы сможете освещать свои модели на пиксель.

Сокращение количества вершин, необходимых для каждого треугольника: при рисовании с индексированными треугольниками вы должны убедиться, что ваши индексы отсортированы для максимального повторного использования. Проведение вашей геометрии с помощью инструмента PVRTTriStrip от Imagination Technologies, вероятно, будет лучшим выбором.

Если у вас есть только 58 различных текстур 64x64, то текстурный атлас кажется хорошей идеей, поскольку все они поместились бы в одну текстуру 512x512... если вы не полагаетесь на режимы обтекания текстур, я бы, по крайней мере, попробовал этот.

В каком формате ваши текстуры? Вы можете попробовать использовать сжатую текстуру PVRTC; Я думаю, что это меньше загружает Tiler, и я был приятно удивлен качеством изображения даже для текстур с 2 битами на пиксель. (Хорошо для естественных изображений, не хорошо, если вы делаете что-то похожее на 8-битную видеоигру)

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

Обновление после результатов инструментов:

Этот вопрос имеет аналогичный результат в инструментах для вас, возможно, этот совет также применим в вашем случае (в основном сокращение числа вершин чисел)

Самая большая победа в графическом программировании сводится к следующему:

Пакетный, Пакетный, Пакетный

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

Объедините все эти текстуры в атлас и значительно сократите количество вызовов.

Этот веб-инструмент может быть полезен: http://zwoptex.zwopple.com/

Вы просматривали "Руководство по программированию OpenGL ES для iPhone OS" в центре разработчиков? В разделе "Лучшие практики для данных вершин и текстур" есть разделы.

Ваши данные отформатированы, чтобы можно было использовать треугольные полосы?

С точки зрения минимальных усилий, последовательность изменений для вас, вероятно, будет:

  • Уменьшение размера атрибута вершины
  • ОБВ

Обратите внимание, что когда вы делаете это, вы должны убедиться, что компоненты выровнены по их собственному выравниванию, то есть, плавающие или полные целые находятся на 4-байтовых границах, шорты на 2-байтовых границах. Если вы этого не сделаете, это подорвет вашу производительность. Может быть полезно мысленно отобразить его, указав порядок атрибутов в качестве определения структуры, чтобы вы могли проверить правильность расположения и выравнивания.

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

Чтобы попытаться преобразовать ваши текстуры в 16-битный формат RGB565, посмотрите этот код в почтенном Apple Texture2D.m, найдите kTexture2DPixelFormat_RGB565

http://code.google.com/p/cocos2d-iphone/source/browse/branches/branch-0.1/OpenGLSupport/Texture2D.m

(этот код загружает PNG и конвертирует их в RGB565 во время создания текстуры; я не знаю, существует ли формат файла RGB565 как таковой)

Для получения дополнительной информации о сжатых текстурах PVRTC (которые выглядели намного лучше, чем я ожидал, когда я их использовал, даже при 2 битах на пиксель), см. Пример Apple PVRTextureLoader:

http://developer.apple.com/iPhone/library/samplecode/PVRTextureLoader/index.html

в нем есть как код для загрузки текстур PVRTC в ваше приложение, так и инструкции по использованию texturetool для преобразования ваших файлов.png в файлы.pvr.

Другие вопросы по тегам