Текстура 512x512 вызывает огромную нагрузку на графический процессор iPhone, несмотря на тайлинг

StackOverflow https://stackoverflow.com/questions/872560

Вопрос

Я тестирую свою простую реализацию OpenGL ES (2D-игру) на iPhone и Я замечаю высокую загрузку рендеринга при использовании профилировщика.Вот факты:

  • я показываю только одна предустановленная большая текстура (512x512 пикселей) при 60 кадрах в секунду, а загрузка рендеринга составляет около 40%.
  • Моя текстура смешана с использованием GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, единственная функция GL, которую я использую.
  • Я попробовал сделать текстуру меньше и плитка это, которое не имело никакого значения.
  • Я использую атлас текстур PNG размером 1024x1024 пикселей.

Мне очень странно, что это одна текстура вызывает такое интенсивное использование графического процессора.

Стоит ли этого ожидать? Что я делаю не так?

РЕДАКТИРОВАТЬ: Мой код:

// OpenGL setup is identical to OpenGL ES template
// initState is called to setup
// timer is initialized, drawView is called by the timer

- (void) initState
{
    //usual init declarations have been omitted here        
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);     
    glEnableClientState (GL_VERTEX_ARRAY);
    glVertexPointer     (2,GL_FLOAT,sizeof(Vertex),&allVertices[0].x);          
    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer   (2,GL_FLOAT,sizeof(Vertex),&allVertices[0].tx);     
    glEnableClientState (GL_COLOR_ARRAY);
    glColorPointer      (4,GL_UNSIGNED_BYTE,sizeof(Vertex),&allVertices[0].r);    
}    
- (void) drawView
{       
    [EAGLContext setCurrentContext:context];
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity();

    GLfloat width  = backingWidth /2.f; 
    GLfloat height = backingHeight/2.f; 

    glOrthof(-width, width, -height, height, -1.f, 1.f);
    glMatrixMode(GL_MODELVIEW);
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);       
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);       
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];      
    [self checkGLError];        
}

РЕДАКТИРОВАТЬ: Я сделал несколько улучшений, но ни одно из них не смогло снизить использование рендеринга.Я разделил текстуру на части 32x32, изменил тип координат и координат текстуры с GLfloat на GLshort и добавил дополнительные вершины для дегенеративных треугольников.

Обновления:

initState:(указатель вершины и текстуры теперь GL_SHORT)

glMatrixMode(GL_TEXTURE);
glScalef(1.f / 1024.f, 1.f / 1024.f, 1.f / 1024.f);
glMatrixMode(GL_MODELVIEW);
glScalef(1.f / 16.f, 1.f/ 16.f, 1.f/ 16.f);

рисоватьView:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 1536); //(16*16 parts * 6 vertices)  
Это было полезно?

Решение

Прочтите этот пост.

Разрешение 512x512, вероятно, слишком оптимистично для iPhone.

РЕДАКТИРОВАТЬ:

Я предполагаю, что вы это уже прочитали, но если нет ознакомьтесь с руководством Apple по оптимальной производительности OpenGl ES на iPhone.

Другие советы

Я пишу приложение, которое отображает пять текстур размером 512x512 друг на друге в 2D-среде с использованием GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, и я могу получить около 14 кадров в секунду.Вам действительно нужно 60 кадров в секунду?Для игры, я думаю, 24-30 будет вполне достаточно.Кроме того, по возможности используйте сжатие текстур PVR.Есть пример, который включен в SDK.

  1. Надеюсь, ты не забыл отключить GL_BLEND когда оно тебе уже не нужно.
  2. Вы можете попытаться оптимизировать пропускную способность памяти — использовать форматы 16 бит на пиксель или PVRTC.ИМХО, с твоим кэшем текстур размера текстуры вообще не помогает.
  3. Не забывайте, что ваш фреймбуфер используется в качестве текстуры пользовательским интерфейсом iPhone.Если он создан как 32-битный RGBA, он будет подвергнут альфа-смешиванию еще раз.Для оптимальной производительности лучше всего подходят 16-битные 565-битные буферы кадров (но при этом страдает качество графики).

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

И наконец.Это всего лишь мобильный маломощный графический процессор, не предназначенный для огромных экранов и высокой скорости заполнения.Альфа-смешение обходится дорого, разница на чипах PowerVR может составлять 3-4 раза.

В чем именно проблема?
Вы получаете 60 кадров в секунду, и это очень плавно.

Кого волнует, если загрузка рендеринга составляет 40%?

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

Попробуй это:разделите свой квадроцикл и повторите тесты.Итак, если у вас 1 четверной, сделайте его 4.Потом 16.и так далее, и посмотрите, поможет ли это.Ключевым моментом является уменьшение фактического количества пикселей, на которые ссылается каждый примитив.

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

ИЛИ - Я совершенно не прав, потому что я действительно не знаю аппаратного обеспечения iPhone, а также знаю, что чип PVR - странный зверь по сравнению с тем, к чему я привык (PS2, PSP).Тем не менее, это простой тест, и мне интересно, поможет ли он.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top