GLEssentials/Source/Classes/iOS/EAGLView.m
/* |
Copyright (C) 2015 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
The EAGLView class is a UIView subclass that renders OpenGL scene. |
*/ |
#import "EAGLView.h" |
#import "ES2Renderer.h" |
@interface EAGLView () |
{ |
ES2Renderer* _renderer; |
EAGLContext* _context; |
NSInteger _animationFrameInterval; |
CADisplayLink* _displayLink; |
} |
@end |
@implementation EAGLView |
// Must return the CAEAGLLayer class so that CA allocates an EAGLLayer backing for this view |
+ (Class) layerClass |
{ |
return [CAEAGLLayer class]; |
} |
// The GL view is stored in the storyboard file. When it's unarchived it's sent -initWithCoder: |
- (instancetype) initWithCoder:(NSCoder*)coder |
{ |
if ((self = [super initWithCoder:coder])) |
{ |
// Get the layer |
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; |
eaglLayer.opaque = TRUE; |
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: |
[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; |
_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; |
if (!_context || ![EAGLContext setCurrentContext:_context]) |
{ |
return nil; |
} |
_renderer = [[ES2Renderer alloc] initWithContext:_context AndDrawable:(id<EAGLDrawable>)self.layer]; |
if (!_renderer) |
{ |
return nil; |
} |
_animating = FALSE; |
_animationFrameInterval = 1; |
_displayLink = nil; |
} |
return self; |
} |
- (void) drawView:(id)sender |
{ |
[EAGLContext setCurrentContext:_context]; |
[_renderer render]; |
} |
- (void) layoutSubviews |
{ |
[_renderer resizeFromLayer:(CAEAGLLayer*)self.layer]; |
[self drawView:nil]; |
} |
- (NSInteger) animationFrameInterval |
{ |
return _animationFrameInterval; |
} |
- (void) setAnimationFrameInterval:(NSInteger)frameInterval |
{ |
// Frame interval defines how many display frames must pass between each time the |
// display link fires. The display link will only fire 30 times a second when the |
// frame internal is two on a display that refreshes 60 times a second. The default |
// frame interval setting of one will fire 60 times a second when the display refreshes |
// at 60 times a second. A frame interval setting of less than one results in undefined |
// behavior. |
if (frameInterval >= 1) |
{ |
_animationFrameInterval = frameInterval; |
if (_animating) |
{ |
[self stopAnimation]; |
[self startAnimation]; |
} |
} |
} |
- (void) startAnimation |
{ |
if (!_animating) |
{ |
// Create the display link and set the callback to our drawView method |
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView:)]; |
// Set it to our _animationFrameInterval |
[_displayLink setFrameInterval:_animationFrameInterval]; |
// Have the display link run on the default runn loop (and the main thread) |
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; |
_animating = TRUE; |
} |
} |
- (void)stopAnimation |
{ |
if (_animating) |
{ |
[_displayLink invalidate]; |
_displayLink = nil; |
_animating = FALSE; |
} |
} |
- (void) dealloc |
{ |
// tear down context |
if ([EAGLContext currentContext] == _context) |
[EAGLContext setCurrentContext:nil]; |
} |
@end |
Copyright © 2015 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2015-08-07