512x512 Текстура, вызывающая огромное напряжение графического процессора на iPhone, несмотря на мозаику - PullRequest
2 голосов
/ 16 мая 2009

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

  • Я отображаю только одну предварительно загруженную большую текстуру ( 512x512 пикселей ) со скоростью 60 кадров в секунду, и использование рендеринга составляет около 40%.
  • Моя текстура смешивается с использованием GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, единственной функции GL, которую я использую .
  • Я пытался сделать текстуру меньше, а мозаику it, которая не имела значения .
  • Я использую текстурный 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);

drawView:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 1536); //(16*16 parts * 6 vertices)  

Ответы [ 5 ]

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

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

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

1 голос
/ 29 июня 2009

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

0 голосов
/ 29 июня 2009

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

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

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

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

0 голосов
/ 29 июня 2009

В чем именно заключается проблема?
Вы получаете 60 кадров в секунду, что является гладким и шелковистым.

Кому интересно, если использование рендера составляет 40%?

0 голосов
/ 16 мая 2009

Читать этот пост.

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

EDIT:

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

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