Use UIMotionEffect with OpenGL ES

喜欢而已 提交于 2019-12-11 12:06:14

问题


I'm using OpenGL ES (2.0) exclusively for my app. I'm trying to get UIMotionEffect to work with one of my OpenGL objects - where all I need are the "tilt" values.

UIInterpolatingMotionEffect can only be applied to a UIView, and a hack would be to apply UIInterpolatingMotionEffect to a UIView and grab the values from there per frame, while not rendering the supposed UIView. But it seems far too hack-ish to be the only solution.

I tried to subclass UIMotionEffect, but couldn't figure out how - (NSDictionary *)keyPathsAndRelativeValuesForViewerOffset:(UIOffset)viewerOffset worked (ie. what calls it and how to retrieve the values I need).

Any ideas on how could I use UIMotionEffect with OpenGL?


回答1:


I finally tested the method suggested by @rickster: connect UIInterpolatingMotionEffect to my GLKView/GL View pass keys that are custom made and just retrieve them. Unfortunately, that idea royally fails.

First, the keys that are passed to UIInterpolatingMotionEffect must be UIView animatable properties, and can't be custom variables/properties. Considering most people wouldn't want their entire context to parallax in one way direction/intensity, this method will fail.

Second, you can't just retrieve the values. If you pass center.x as a key, UIInterpolatingMotionEffect won't update center.x since the changes are considered "animations". As such, you have you retrieve the animated center.x, for example [[view.layer presentationLayer] center];

Final Notes: Just create a separate UIView on the main thread, add it to your UIViewController and systematically retrieve values from it (also on the main thread). I found that to be the simplest solution by far.

Also, since I needed to retrieve the values on a separate thread, I'm generally 1 value behind, as I dispatch to the main thread to retrieve the current value, while at the same time retrieving the last value set (make sure the variable is thread-safe/atomic).

EDIT

Since its best to access the presentationLayer on the main thread, but my method is called for a thread that isn't main, I dispatch the main thread to retrieve the value and place it in an atomic property. I would then return the atomic property outside the thread. This makes sure my secondary thread doesn't get blocked by the main thread, and I can retrieve the values I need.

Here's the code I used to retrieve values from a thread that isn't the main thread:

@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;
}



回答2:


UIInterpolatingMotionEffect works by using key-value coding to set a value for any numeric property on a UIView. This can be any property you define, not just those built into the UIView class.

You need some kind of UIView to get your content on screen. If you're using OpenGL ES on iOS, you're (preferably) using GLKView, which is a UIView subclass that manages its own GL framebuffers and gives you a place to write GL drawing code to render into those framebuffers. (If you're not using GLKView, you're probably using some kind of custom UIView subclass that uses a CAEAGLLayer to render its contents.)

Either way, if you've got GL-rendered content on the screen already, you already have a UIView. If that view isn't your own custom subclass (whether a direct UIView subclass or GLKView subclass), you can make it one, and define your own custom properties on it. Then set up your UIInterpolatingMotionEffect to use those properties. In your view subclass, or whatever object is responsible for your GL rendering, read the values of those properties and use them to set up your scene. (For example, you could use them to set up a ModelView matrix, and pass that to a shader uniform.)



来源:https://stackoverflow.com/questions/21740713/use-uimotioneffect-with-opengl-es

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!