2014-02-12 4 views
1

Я использую OpenGL ES (2.0) исключительно для своего приложения. Я пытаюсь получить UIMotionEffect для работы с одним из моих объектов OpenGL - где все, что мне нужно, это значения «наклона».Использование UIMotionEffect с OpenGL ES

UIInterpolatingMotionEffect может быть применен только к UIView и хак будет применять UIInterpolatingMotionEffect к UIView и захватить ценности оттуда за кадр, а не делает предполагаемую UIView. Но, похоже, слишком хак-иш является единственным решением.

Я попытался подкласса UIMotionEffect, но не смог понять, как работает - (NSDictionary *)keyPathsAndRelativeValuesForViewerOffset:(UIOffset)viewerOffset (то есть, что его вызывает и как получить нужные значения).

Любые идеи о том, как я могу использовать UIMotionEffect с OpenGL?

ответ

5

Наконец-то я проверил метод, предложенный @rickster: подключите UIInterpolatingMotionEffect к моим ключам доступа GLKView/GL, которые изготовленные на заказ и просто извлекающие их. К сожалению, эта идея рояльно терпит неудачу.

Прежде всего, ключи, которые передаются в UIInterpolatingMotionEffect, должны быть UIView анимированными свойствами и не могут быть настраиваемыми переменными/свойствами. Учитывая, что большинство людей не хотят, чтобы весь их контекст был параллаксом в одном направлении/интенсивности, этот метод потерпит неудачу.

Во-вторых, вы не можете просто получить значения. Если вы передадите center.x в качестве ключа, UIInterpolatingMotionEffect не будет обновлять center.x, так как изменения считаются «анимациями». Таким образом, у вас есть вы извлекаете мультипликационного center.x, например [[view.layer presentationLayer] center];

Конечные ноты: Просто создать отдельный UIView в главном потоке, добавьте его в UIViewController и систематически извлекать значения из него (также в основном потоке). Я обнаружил, что это самое простое решение.

Кроме того, поскольку мне нужно было получить значения в отдельном потоке, я, как правило, 1 значение позади, так как я отправляю в основной поток для получения текущего значения и в то же время извлекаю последний набор значений (убедитесь, что переменная является потокобезопасной/атомной).

EDIT

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

Вот код, который я использовал для извлечения значений из потока, который не является основной поток:

@property (atomic) GLKVector2 currentOffset; 
@property (atomic, readonly) GLKVector2 offset; 

- (GLKVector2)offset 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     CGRect frame = [[self.view.layer presentationLayer] frame]; 
     self.currentOffset = (GLKVector2){-frame.origin.x, -frame.origin.y}; 
    }); 

    return self.currentOffset; 
} 
+0

Можете ли вы предоставить более подробно в пункте 4, где вы ответить на ваш вопрос? –

+0

@JohnStephen done :) –

+0

Спасибо, это было очень полезно! –

1

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

Для получения вашего содержимого на экране вам понадобится UIView. Если вы используете OpenGL ES на iOS, вы (предпочтительно) используете GLKView, который является подклассом UIView, который управляет своими собственными фреймбуферами GL и дает вам место для записи кода рисования GL для рендеринга в эти фреймбуферы. (Если вы не используете GLKView, вы, вероятно, использовать какой-то пользовательский UIView подкласс, который использует CAEAGLLayer для отображения его содержимого.)

В любом случае, если у вас есть GL-отображаемое содержимое на экране уже , у вас уже есть UIView. Если это представление не является вашим собственным подклассом (будь то прямой подкласс UIView или GLKView), вы можете сделать его одним и определить свои собственные пользовательские свойства на нем. Затем настройте свой UIInterpolatingMotionEffect, чтобы использовать эти свойства. В вашем представлении подкласс или какой-либо объект отвечает за ваш рендеринг GL, прочитайте значения этих свойств и используйте их для настройки вашей сцены. (Например, вы могли бы использовать их для создания матрицы ModelView и передать это в форму шейдера.)

Смежные вопросы