我专门为我的应用程序使用OpenGL ES(2.0)。我试图让UIMotionEffect
使用我的一个OpenGL对象 - 我需要的只是“倾斜”值。
UIInterpolatingMotionEffect
只能应用于UIView
,黑客就是将UIInterpolatingMotionEffect
应用于UIView
并从每帧抓取值,而不是渲染假定的UIView
。但它似乎是唯一的解决方案。
我尝试将UIMotionEffect
子类化,但无法弄清楚- (NSDictionary *)keyPathsAndRelativeValuesForViewerOffset:(UIOffset)viewerOffset
是如何工作的(即调用它以及如何检索我需要的值)。
关于如何在OpenGL中使用UIMotionEffect
的任何想法?
答案 0 :(得分:5)
我最后测试了@rickster建议的方法:将UIInterpolatingMotionEffect
连接到我自己定制的GLKView / GL View传递键并检索它们。不幸的是,这个想法在皇室成功了。
首先,传递给UIInterpolatingMotionEffect
的密钥必须是UIView
可动画的属性,并且不能是自定义变量/属性。考虑到大多数人不希望他们的整个背景在单向/强度上出现视差,这种方法会失败。
其次,您不能只检索值。如果您将center.x
作为密钥传递,UIInterpolatingMotionEffect
将不会更新center.x
,因为这些更改被视为“动画”。因此,您可以检索动画center.x
,例如[[view.layer presentationLayer] center];
最终注释:只需在主线程上创建一个单独的UIView
,将其添加到UIViewController
并系统地从中检索值(也在主线程上)。到目前为止,我发现这是最简单的解决方案。
此外,由于我需要在单独的线程上检索值,因此我通常会抛出一个值,因为我调度到主线程以检索当前值,同时检索最后一个值集(make确定变量是线程安全的/原子的。)
修改强>
由于它最好在主线程上访问presentationLayer,但是我的方法被调用一个不是main的线程,我调度主线程来检索值并将它放在一个原子属性中。然后我会在线程外返回原子属性。这确保我的辅助线程不会被主线程阻塞,我可以检索我需要的值。
这是我用来从不是主线程的线程中检索值的代码:
@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;
}
答案 1 :(得分:1)
UIInterpolatingMotionEffect
通过使用键值编码为UIView
上的任何数字属性设置值。这可以是您定义的任何属性,而不仅仅是UIView
类中内置的属性。
您需要某种UIView
才能在屏幕上显示您的内容。如果您在iOS上使用OpenGL ES,那么(最好)使用GLKView
,这是一个UIView
子类,用于管理自己的GL帧缓冲区,并为您提供编写GL绘图代码以进行渲染的位置进入那些帧缓冲区。 (如果您没有使用GLKView
,那么您可能正在使用某种使用UIView
呈现其内容的自定义CAEAGLLayer
子类。)
无论哪种方式,如果您已经在屏幕上显示了GL渲染内容,您已经拥有UIView
。如果该视图不是您自己的自定义子类(无论是直接UIView
子类还是GLKView
子类),您可以将其设置为一个,并在其上定义自己的自定义属性。然后设置UIInterpolatingMotionEffect
以使用这些属性。在视图子类或任何负责GL渲染的对象中,读取这些属性的值并使用它们来设置场景。 (例如,您可以使用它们来设置ModelView矩阵,并将其传递给着色器制服。)