Подтвердить что ты не робот

Оптимизация загрузки OpenGL ES на iPhone

У меня есть игра Open GL ES на iPhone. Моя частота кадров довольно сочная, ~ 20 кадров в секунду. Используя инструмент производительности Xcode OpenGL ES на iPhone 3G, он показывает:

Использование рендерера: от 95% до 99%

Использование Tiler: ~ 27%

Я рисую много довольно больших изображений с большим количеством смешивания. Если я уменьшу количество обращенных изображений, кадры начнутся от ~ 20 до ~ 40, хотя результаты инструмента производительности останутся примерно такими же (рендеринг все еще максимизирован). Я думаю, что меня ограничивает скорость заполнения iPhone 3G, но я не уверен.

Мои вопросы: как я могу определить с большей детализацией, где узкое место? Это моя самая большая проблема, я просто не знаю, что происходит все время. Если это fillrate, есть ли что-нибудь, что я делаю, чтобы улучшить его, а не рисовать меньше?

Я использую текстурные атласы. Я попытался свести к минимуму привязки к изображениям, хотя это не всегда возможно (порядок рисования, не все подходит для одной текстуры 1024x1024 и т.д.). Каждый кадр меняет 10 изображений. Это кажется довольно разумным, но я могу ошибаться.

Я использую вершинные массивы и glDrawArrays. У меня нет большой геометрии. Я могу попытаться быть более точным, если это необходимо. Каждое изображение состоит из двух треугольников, и я стараюсь, чтобы все было возможно, хотя часто (возможно, в половине случаев) изображения рисуются с помощью отдельных вызовов glDrawArrays. Помимо изображений, у меня есть ~ 60 треугольников, которые геометрия отображается в ~ 6 вызовах glDrawArrays. Я часто glTranslate перед вызовом glDrawArrays.

Будет ли улучшена частота кадров для переключения на VBOs? Я не думаю, что это огромное количество геометрии, но, возможно, это быстрее по другим причинам?

Есть ли определенные вещи, чтобы следить за тем, что может снизить производительность? Например, следует ли избегать glTranslate, glColor4g и т.д.

Я использую glScissor в 3-х местах за фрейм. Каждое использование состоит из 2 вызовов glScissor, один для его настройки и один для reset для того, что было. Я не знаю, есть ли здесь влияние на производительность.

Если бы я использовал PVRTC, он мог бы работать быстрее? В настоящее время все мои изображения GL_RGBA. У меня нет проблем с памятью.

Одна из моих полноэкранных текстур - 256х256. Было бы лучше использовать 480x320, чтобы телефон не делал никакого масштабирования? Есть ли другой общий совет по производительности для размеров текстур?

Вот приблизительное представление о том, что я рисую в следующем порядке:

1) Переключиться на перспективную матрицу. 2) Нарисуйте полноэкранное фоновое изображение 3) Нарисуйте полноэкранное изображение с прозрачностью (у этого есть прокручиваемая текстура). 4) Нарисуйте несколько спрайтов. 5) Переключитесь на орто-матрицу. 6) Нарисуйте несколько спрайтов. 7) Переключиться на перспективную матрицу. 8) Нарисуйте спрайты и другую текстурированную геометрию. 9) Переключитесь на орто-матрицу. 10) Нарисуйте несколько спрайтов (например, игровой HUD).

Шаги 1-6 нарисуют кучу фонового материала. 8 рисует большую часть игрового контента. 10 рисует HUD.

Как вы можете видеть, существует много слоев, некоторые из них полноэкранные, а некоторые спрайты довольно большие (1/4 экрана). Слои используют прозрачность, поэтому я должен нарисовать их в обратном порядке. Это дополнительно осложняется необходимостью рисовать различные слои в орто и других в перспективе.

Я с радостью предоставит дополнительную информацию, если она будет восстановлена. Заранее благодарю за любые рекомендации по производительности или общие советы по моей проблеме!

Edit:

Я добавил несколько журналов, чтобы узнать, сколько вызовов glDrawArrays я делаю, и сколько данных. Я делаю около 20 вызовов glDrawArray для каждого кадра. Обычно от 1 до 6 из них имеют около 40 вершин каждый. Остальные вызовы обычно всего 2 вершины (одно изображение). Я просто использую glVertexPointer и glTexCoordPointer.

4b9b3361

Ответ 1

Учитывая, что использование Renderer в основном составляет 100%, это указывает на то, что узким местом является заполнение, текстурирование и смешивание пикселей. Методы, предназначенные для оптимизации обработки вершин (VBOs и вершинных форматов) или использования ЦП (дозаряд вызова вызова), скорее всего, не помогут, поскольку они не ускорят обработку пикселей.

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

Ответ 2

Посмотрите на Apple " Рекомендации по работе с данными текстур" и " Рекомендации по работе с данными Vertex Data " Руководство по программированию OpenGL ES для iPhone OS. Они настоятельно рекомендуют (как и другие) использовать PVRTC для сжатия ваших текстур, потому что они могут предлагать степень сжатия 8: 1 или 16: 1 над стандартными несжатыми текстурами. Помимо mipmapping, вы, похоже, делаете другую рекомендованную оптимизацию использования атласа текстуры.

Похоже, что вы не ограничены геометрией, потому что (как я обнаружил в этом вопросе) статистика использования Tiler, похоже, указывает, какая часть узкого места вызванный геометрическим размером. Тем не менее, iPhone 3G S (и iPod touch третьего поколения и iPad третьего поколения) поддерживает ускоренные VBOs с аппаратным ускорением, поэтому вы можете дать им шанс и посмотреть, как они влияют на производительность. Они могут не иметь такого эффекта, как сжатие текстур, но их не сложно реализовать.

Ответ 3

Большая победа для (в основном для) 3G также будет фильтром текстуры, который вы используете. Убедитесь, что вы используете фильтрацию "TRILINEAR" и измените ее на "BILINEAR".

Убедитесь, что вы настроили такие текстуры следующим образом:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

и не так:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

Гарри

Ответ 4

Мне захотелось услышать дополнительный ответ, изменив поддержку Framebuffer как 16-битный формат, а не 32-битный.

if ((self = [super initWithCoder:coder])) 
    {
    eaglLayer = (CAEAGLLayer *)self.layer;
    eaglLayer.opaque = YES;
    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                            [NSNumber numberWithBool:NO], 
                                            kEAGLDrawablePropertyRetainedBacking, 
                                            kEAGLColorFormatRGB565,  //kEAGLColorFormatRGBA8 = large frame buff 32bit  // kEAGLColorFormatRGB565 = 16bit frame buffer.
                                            kEAGLDrawablePropertyColorFormat, 
                                            nil];        
}

Что меня разбудило, это профайлер XCode. Он продолжал жаловаться на использование большого буфера кадров, в конце концов я нашел его в разделе инициализации. http://developer.apple.com/library/ios/#documentation/iPhone/Reference/EAGLDrawable_Ref/EAGLDrawable/EAGLDrawable.html  ,  Это единственное изменение позволило моим играм на iPad, Retina и iPod перейти на 60 FPS. Мне еще предстоит переиздать их с этим изменением, поскольку я только что нашел его 3 дня назад:), но я не думаю, что планирую выпустить на 60 кадров в секунду, 30 кадров в секунду отлично подходит для казуальных игр, и я обнаружил, что мои звуковые эффекты вырезаны частота кадров снижается, так что либо перетасовывайте, либо воспроизводите sfx в другом потоке, либо другие решения, чтобы поддерживать эту частоту кадров, если я решаю пойти с 60fps.
Не забудьте сбросить буферы, которые не используются для отображения..

if (fiOSver >= 4.0f) {
    const GLenum discards[]  = {GL_DEPTH_ATTACHMENT_OES};
    glDiscardFramebufferEXT(GL_FRAMEBUFFER_OES,1,discards);
}

[m_oglContext presentRenderbuffer:GL_RENDERBUFFER_OES];

Ответ 5

В аналогичной ситуации (перенос 2D-приключенческой игры на iPad). Моя версия 3GS работала более или менее заперта на 60FPS, положила ее на iPad, сбросила ее (и мою челюсть) до 20 кадров в секунду.

Оказывается, один из немногих вовлеченных в процесс, что PVR-карты ненавидят GL_ALPHA_TEST; на ПК, который на самом деле имеет небольшой положительный эффект (особенно на старых чипах Intel), но это смерть при заполнении на iPhone. Изменение этого параметра на

 glDisable(GL_ALPHA_TEST);

дал мне немедленное повышение на 100% в FPS (до 40 FPS). Неплохо для одной строки кода..:)

Аллана

Ответ 6

Самый большой убийца производительности на платформе iPhone - это количество вызовов вызовов и изменений состояния. Если вы делаете более 20 попыток рисования или изменений состояния, вы столкнетесь с стеной производительности.

Актики дозирования и текстуры - ваш друг.

Ответ 7

Благодаря моему прошлому опыту с openGL ES на старых окнах мобильные устройства со скоростью обработки около 600 МГц обычно уменьшая разрешение окна рендеринга, увеличивают скорость рендеринга.

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

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

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

вам может потребоваться управлять разрешением, как описано в этой статье.

http://www.david-amador.com/2010/09/setting-opengl-view-for-iphone-4-retina-hi-resolution/