Синхронизация презентации EAGLView с изменением размера кадра на iPhone - PullRequest
4 голосов
/ 27 июня 2011

У меня есть EAGLView, который я изменяю в анимации, с анимацией, управляемой NSTimer, которая вызывает функцию рисования.Поскольку я изменяю размер EAGLView, мне нужно настроить проекцию для вида, чтобы сохранить пропорции содержимого.Функция рисования выглядит следующим образом:

gameView.frame = newFrame;
[gameView setFramebuffer];
[self updateProjection];

/* Drawing to the EAGLView, gameView, here, then... */  

[gameView presentFramebuffer];

Выполните так, однако, содержимое EAGLView выглядит как «ступенчатый» вниз по анимации.Когда я записываю его и смотрю на него кадр за кадром, становится ясно, что проекция корректируется, а затем вид очень быстро изменяется (менее одного кадра анимации).

Я подозреваю, что причиначто изменение в кадре gameView откладывается, и тем временем обновленный кадровый буфер пробивается к экрану.Я пытался использовать CATransactions, чтобы обновление кадра вступило в силу немедленно, но, как я и ожидал, для изменения UIView это ничего не дало.Я полагаю, что я мог бы изменить область просмотра и оставить EAGLView полный кадр, но я беспокоюсь, что это может просто оставить меня с проблемами синхронизации в другом месте (скажем, с обновлениями любых наложенных слоев CALayers).

Кажется ли этокак разумная оценка проблемы?Как я могу предотвратить это, то есть, как я могу наилучшим образом убедиться, что представление кадрового буфера совпадает с изменением в реальном кадре EAGLView (и других элементов CA)?

Спасибо!

1 Ответ

1 голос
/ 11 ноября 2012

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

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

Но вы легко можете обойти проблему: откройте файл xib , содержащий представление, переключитесь на инспектор атрибутов справа.Выберите EAGLView (то же самое относится и к GLKView), и в разделе Вид есть атрибут Mode .Если вы создаете представление программным способом, установите свойство contentMode.

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

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

  • К сожалению, режим redraw не обязательно сделает ваше обновление EAGLView:представление на самом деле перерисовывается, но потенциально со старым содержимым цветового буфера.Это проблема с заполнением буфера в нужное время.

  • Вы можете попытаться изменить размер и предварительно отобразить кадр, достаточно большой, чтобы охватить всю анимацию, прежде чем запускать ее;или вы можете попытаться визуализировать кадр в UIImage, заменить представление на лету, анимировать его, поместить EAGLView назад, но это может серьезно повлиять на производительность.

  • Способ, которым я решил свою проблему, заключался в том, чтобы просто сделать EAGLView достаточно большим.

  • Относительно смешивания других CALayer s, насколько я пытался, я не столкнулся с проблемой синхронизации;EAGLView обновляется, когда это возможно, и другие слои тоже.Просто установите правильные свойства на CAEAGLLayer, если вы используете альфа-канал, и помните, что смешивание слоев при каждом обновлении OpenGL вашей сцены может быть дорогим с точки зрения производительности.

...