Синхронизация макета UIView с кадрами OpenGL

Мы разрабатываем игру с 2d элементами, отображаемыми с UIViews над представлением OpenGL ES (в частности, мы используем GLKit GLKView), и у нас возникают проблемы с сохранением позиций в синхронизации.

В родительском представлении layoutSubviews мы проецируем на экран 3D-позиции в мире и используем их как местоположения для нескольких маркеров UIView в игре. Вся игра обновляется только в ответ на пользователя, перемещающего камеру, и камера каждый раз нажимает на просмотр setNeedsLayout.

Evertime работает отлично, за исключением того, что маркеры кажутся примерно одним кадром из-за синхронизации с 3D-рендерингом. Я говорю примерно потому, что (1) это оценка! и (2) Мне интересно, существует ли проблема многопоточности: не синхронизируется ли GLKView с специальным обратным вызовом обновления экрана или что-то в этом роде?

Есть ли способ подключить представление layoutSubviews, чтобы он синхронизировался с обновлением 3D-представления?

Обновить: странно, вызов layoutIfNeeded сразу после setNeedsLayout делает проблему хуже! Возможно 2 или более фреймов. На самом деле не понимаю этого!

Ответ 1

Что вызывает ваш вызов LayoutSubviews?

Все зависит от того, где в RunLoop запускается ваш вызов против того, где запускается ваш запрос на обновление GLK.

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

(если вы используете OpenGL, тогда вся система "макета" вам не очень-то нравится: GLK работает в своем маленьком мире с переменной частотой кадров, и вы хотите сделать эту контрольную точку)

Ответ 2

Это невозможно сделать правильно, не рисуя кадры видео с помощью OpenGL (рисунок в том же контексте, чтобы вы всегда были уверены, что один кадр содержит одно и то же время видео и анимации). Все остальное, что вы делаете, компенсация частоты кадров, предсказание запаздывания, зависит только от случайности и всегда будет немного несинхронизироваться.

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