Каким образом UIImageView анимируется так плавно? (Или: как заставить OpenGL эффективно анимировать покадровые текстуры)

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

Я попытался выполнить покадровую анимацию вручную в пользовательском OpenGL, где для каждого кадра я привязываю новую текстуру и рисую ее на одном и том же точечном спрайте. Это работает, но очень медленно по сравнению с UIImageView способностью абстрагироваться. Я загружаю все текстуры заранее, но повторная привязка выполняется каждый кадр. Для сравнения, UIImageView принимает отдельные изображения, а не атлас текстуры, поэтому я предполагаю, что он делает то же самое.

Это 76 изображений, загружаемых индивидуально, а не в виде атласа текстур, и каждое имеет квадрат около 200 пикселей. В OpenGL я подозреваю, что узким местом является необходимость повторного связывания текстуры в каждом кадре. Но как UIImageView это делает, если я ожидал такого же узкого места ?? Создает ли UIImageView каким-то образом атлас «за кулисами», чтобы не было необходимости в повторном связывании текстур? Поскольку в конечном итоге под UIKit работает OpenGL, мне любопытно, как это должно работать.

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

Если бы я действительно получал новый кадр для каждого из 60 кадров в секунду, то для анимации моих 76 кадров потребовалось бы около 1,25 секунды. Действительно, я получаю это с UIImageView, но OpenGL занимает около 3-4 секунд.


person johnbakers    schedule 24.04.2013    source источник


Ответы (2)


Я бы сказал, что ваше узкое место где-то еще. OpenGL более чем способен делать анимацию так, как это делаете вы. Поскольку все текстуры загружены, и вы просто привязываете по одной к каждому кадру, нет времени загрузки или чего-то еще. Рассмотрим для сравнения: у меня есть приложение, которое может во время выполнения генерировать или удалять текстуры и может в какой-то момент иметь большое количество текстур, загруженных на графический процессор, мне нужно связывать все эти текстуры каждый кадр (а не 1 каждый кадр), используя все из буфера глубины, трафарета, нескольких FBO, интенсивного пользовательского ввода, около 5 потоков узкого места в 1 для обработки всего кода GL, и у меня вообще нет проблем с FPS.

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

Итак, чтобы ответить на ваш вопрос, это нормально и здорово, что UIImageView так плавно выполняет свою работу и не должно возникнуть проблем с достижением такой же производительности с openGL. ХОТЯ, есть несколько вещей, которые следует рассмотреть на этом этапе. Как вы можете сказать, что представление изображения не пропускает изображения, вы можете установить указатель на другое изображение 60 раз в секунду, но представление изображения может просто запрашивать перерисовку 30 раз в секунду, а когда оно просто использует текущее назначенное изображение к нему. С другой стороны, с помощью кода GL вы заставляете приложение выполнять перерисовку со скоростью 60 кадров в секунду независимо от того, способно ли оно это делать.

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

И еще одна вещь, я видел, что если вы попытаетесь представить буфер рендеринга со скоростью 100 FPS на большинстве устройств iOS (может быть, все), вы получите только 60 FPS, поскольку метод для представления буфера рендеринга приостановит ваш поток, если он был вызван менее чем за 1/60 с. При этом практически невозможно отображать что-либо со скоростью 60 кадров в секунду на устройствах iOS, и все, что работает с частотой 30+ кадров в секунду, считается хорошим.

person Matic Oblak    schedule 24.04.2013
comment
Спасибо, я собираюсь еще немного покопаться, чтобы увидеть, что я обнаружил в профилировании и т. Д. Кстати, 60 кадров в секунду - это совсем не невозможно, я регулярно получаю это в простых 2D-играх. - person johnbakers; 24.04.2013

«не как текстурный атлас» - это предложение, которое для меня является красным флагом.

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

Вам нужно будет опубликовать исходный код, чтобы получить более точный ответ, чем этот.

person Delete    schedule 24.04.2013
comment
Мой вопрос в том, как UIImageView работает так эффективно, когда он не загружен атласом текстуры. - person johnbakers; 24.04.2013