2010-11-02 3 views
1

У меня есть приложение для iPad с пользовательским интерфейсом, написанным в OpenGL ES 2.0, некоторые элементы интерфейса скрыты по умолчанию, и когда мне нужно показать их, есть довольно большая задержка, прежде чем они на самом деле показывают (о 300-500 мс на элементе управления, который содержит около 20 других элементов управления внутри), используя Instru.app, я определил, что при рендеринге каждого уникального объекта требуется много времени, чтобы сделать его первым, а затем после того, как он был визуализирован как минимум один раз, а разница время рендеринга огромно. Вот код, у меня есть для рендеринга и этот код показан Instruments принимая все эту задержку:первый вызов glDrawArrays очень медленный на iPad

- (void)render:(id <ESRenderer>)renderer 
{ 
    [shader useShader]; 
    glEnableVertexAttribArray(ATTRIB_VERTEX); 
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, _squareVertices); 
    glEnableVertexAttribArray(ATTRIB_TEXTCOORD); 
    glVertexAttribPointer(ATTRIB_TEXTCOORD, 2, GL_SHORT, 0, 0, coords); 
    float x1 = self.position.x; 
    float y1 = self.position.y; 
    glUniform1f(shader.ext_uniforms[UNIFORM_TRANSLATE_X], -x1+_squareVertices[0]); 
    glUniform1f(shader.ext_uniforms[UNIFORM_TRANSLATE_Y], -y1+_squareVertices[1]); 
    glUniform1f(shader.ext_uniforms[UNIFORM_ROTATE], self.rotation); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
    glDisableVertexAttribArray(ATTRIB_VERTEX); 
    glDisableVertexAttribArray(ATTRIB_TEXTCOORD); 
} 

Когда он вызывается по крайней мере, один раз он отлично работает быстро. Мой затенения очень просто тоже:

vec4 col = texture2D(texture, coordVarying); 
gl_FragColor = col; 

Спасибо!

ответ

1

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

EDIT: как указано в другом ответе, есть также данные текстуры, которые могут быть переданы.

+0

Объем данных всего 8 поплавков плюс короткие шорты в виде texcoords, также шейдер довольно мал, и я загружаю, привязываю переменные и связываю его со временем загрузки приложения. Поэтому в моем вызове [shader useShader] следуют: - (void) useShader { \t glUseProgram (_program); \t glBindTexture (GL_TEXTURE_2D, _texture); \t glUniform1i (униформа [UNIFORM_TEXTURE], 0); } –

+0

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

0

Реализации OpenGL обычно загружают текстуры «лениво», т. Е. Текстура фактически инициализируется при первом использовании (в значительной степени то, что сказал jv42, но не данные геометрии). Возможно, это то, что происходит здесь. Если вы не меняете свои текстуры между объектами, вы получаете одинаковые замедления?

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

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

+0

У меня есть менеджер текстур, поэтому было легко попробовать, я указал использовать только 1 текстуру во всем приложении, но ничего не изменилось, поэтому это не текстуры :( –

+0

Вы совершенно правы, я не упоминал текстуры , исправлено в моем посте. – jv42

0

У меня тоже есть. Для меня это была проблема с текстурой. На NVIDA все быстро развивалось. Но моя оптическая оптимизация привела к тому, что карта ATI ушла в отставку.

Работаю с текстурой размером 4720 x 5600 (около), и современные карты хорошо работают с ней.

Я попытался оптимизировать границы, используя Wrapmode = GL_CLAMP_TO_BORDER_ARB. Поэтому мне нужно предоставить аргумент границы glTeximage2D как минимум == 1. Поскольку сомнительная карта не поддерживала границу в HW, оказалось, что для одного кадра требуется 20 секунд. Возвращаясь к GL_CLAMP_TO_BORDER + border param == 0, он снова ускоряется.