iOS 动画 第六章 专用图层

    //shapeLayer
[self matchPeople];
    
    //圆角
[self cornerRadiusTest];
    
    //CATextLayer
[self textLayerTest];
    
    //富文本
[self attributedStringTest];
    
    //transformLayer
[self transformLayerTest];
    
    //gradientLayer
[self gradientLayerTest];
[self gradientLayerLocationsTest];
    
    //replicatorLayer
[self replicatorLayerTest];
    //反射
[self reflectionViewTest];
    
    //scrollLayer
[self scrollViewTest];
    
    //tiledLayer
[self tiledLayerTest];
    
    //CAEmitterLayer
[self emitterLayerTest];
    
    //CAEAGLLayer
[self EAGLLayerTest];
    
    //AVPlayerLayer
[self AVPlayerLayerTest];

//CAShapeLayer:是一个通过矢量图形而不是bitmap来绘制的图层子类。CAShapeLayer属性是CGPathRef类型
//创建一个CGPath
//lineWith(线宽,用点表示单位),lineCap(线条结尾的样子),和lineJoin(线条之间的结合点的样子);但是在图层层面你只有一次机会设置这些属性。如果你想用不同颜色或风格来绘制多个形状,就不得不为每个形状准备一个图层了。

- (void)matchPeople {
    containerView = [[UIView alloc] init];
    containerView.frame = CGRectMake(20.f, 20.f, 300.0f, 300.0f);
    [self.view addSubview:containerView];
    
    //create path
    UIBezierPath *path = [[UIBezierPath alloc] init];
    
    [path moveToPoint:CGPointMake(175.0f, 100.0f)];
    [path addArcWithCenter:CGPointMake(150.0f, 100.0f) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
    
    [path moveToPoint:CGPointMake(150, 125)];
    [path addLineToPoint:CGPointMake(150, 175)];
    [path addLineToPoint:CGPointMake(125, 225)];
    
    [path moveToPoint:CGPointMake(150, 175)];
    [path addLineToPoint:CGPointMake(175, 225)];
    
    [path moveToPoint:CGPointMake(100, 150)];
    [path addLineToPoint:CGPointMake(200, 150)];
    
    //create shape layer
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.strokeColor = [UIColor redColor].CGColor;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.lineWidth = 5;
    shapeLayer.lineJoin = kCALineJoinRound;
    shapeLayer.lineCap = kCALineCapRound;
    shapeLayer.path = path.CGPath;
    //add it to our view
    [containerView.layer addSublayer:shapeLayer];
}

圆角

- (void)cornerRadiusTest {
    containerView = [[UIView alloc] init];
    containerView.frame = CGRectMake(20.f, 20.f, 300.0f, 300.0f);
    [self.view addSubview:containerView];
    
    //define path parameters
    CGRect rect = CGRectMake(50, 50, 100, 100);
    CGSize radii = CGSizeMake(20, 20);
    UIRectCorner corners = UIRectCornerTopLeft|UIRectCornerBottomRight|UIRectCornerTopRight|UIRectCornerBottomLeft;
    //create path
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:radii];
    //create shape layer
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.strokeColor = [UIColor redColor].CGColor;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.lineWidth = 5;
    shapeLayer.lineJoin = kCALineJoinRound;
    shapeLayer.lineCap = kCALineCapRound;
    shapeLayer.path = path.CGPath;
    //add it to our view
    [containerView.layer addSublayer:shapeLayer];
}

CATextLayer

//Core Animation提供了一个CALayer的子类CATextLayer,它以图层的形式包含了UILabel几乎所有的绘制特性,并且额外提供了一些新的特性。

- (void)textLayerTest {
    UIView *lableView = [[UIView alloc] init];
    lableView.frame = CGRectMake(20.0, 20.0, 300, 300);
    [self.view addSubview:lableView];
    
    //create a text layer
    CATextLayer *textLayer = [CATextLayer layer];
    textLayer.frame = lableView.bounds;
    [lableView.layer addSublayer:textLayer];
    
    //set text attributes
    textLayer.foregroundColor = [UIColor blackColor].CGColor;
    textLayer.alignmentMode = kCAAlignmentJustified;
    textLayer.wrapped = YES;
    
    //choose a font
    UIFont *font = [UIFont systemFontOfSize:15];
    
    //set layer font
    CFStringRef fontName = (__bridge CFStringRef)font.fontName;
    CGFontRef fontRef = CGFontCreateWithFontName(fontName);//CGFontRef类型还是CTFontRef类型(Core Text字体)
    textLayer.font = fontRef;//CFTypeRef
    textLayer.fontSize = font.pointSize;
    CGFontRelease(fontRef);
    
    //choose some text
    NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing \ elit. Quisque massa arcu, eleifend vel varius in, facilisis pulvinar \ leo. Nunc quis nunc at mauris pharetra condimentum ut ac neque. Nunc elementum, libero ut porttitor dictum, diam odio congue lacus, vel \ fringilla sapien diam at purus. Etiam suscipit pretium nunc sit amet \ lobortis";
    
    //set layer text
    textLayer.string = text;//id类型  可以用NSString也可以用NSAttributedString来指定文本了
    //contentsScale并不关心屏幕的拉伸因素而总是默认为1.0。
    textLayer.contentsScale = [UIScreen mainScreen].scale;
}

富文本

//NSAttributedString.iOS 6及以上可以用新的NSTextAttributeName实例来设置我们的字符串属性,在iOS 5及以下,用Core Text,也就是需要把Core Text framework添加到项目中。

- (void)attributedStringTest {
    UIView *lableView = [[UIView alloc] init];
    lableView.frame = CGRectMake(20.0, 20.0, 300, 300);
    [self.view addSubview:lableView];

    //create a text layer
    CATextLayer *textLayer = [CATextLayer layer];
    textLayer.frame = lableView.bounds;
    textLayer.contentsScale = [UIScreen mainScreen].scale;
    [lableView.layer addSublayer:textLayer];
    
    //set text attributes
    textLayer.alignmentMode = kCAAlignmentJustified;
    textLayer.wrapped = YES;
    
    //choose a font
    UIFont *font = [UIFont systemFontOfSize:15];
    
    //choose some text
    NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing \ elit. Quisque massa arcu, eleifend vel varius in, facilisis pulvinar \ leo. Nunc quis nunc at mauris pharetra condimentum ut ac neque. Nunc elementum, libero ut porttitor dictum, diam odio congue lacus, vel \ fringilla sapien diam at purus. Etiam suscipit pretium nunc sit amet \ lobortis";
    
    //create attributed string
    NSMutableAttributedString *string = nil;
    string = [[NSMutableAttributedString alloc] initWithString:text];
    
    //convert UIFont to a CTFont
    CFStringRef fontName = (__bridge CFStringRef)font.fontName;
    CGFloat fontSize = font.pointSize;
    CTFontRef fontRef = CTFontCreateWithName(fontName, fontSize, NULL);
    
    //set text attributes
    NSDictionary *attributes = @{(__bridge id)kCTForegroundColorAttributeName:(__bridge id)[UIColor blackColor].CGColor, (__bridge id)kCTFontAttributeName:(__bridge id)fontRef};
    [string setAttributes:attributes range:NSMakeRange(0, [text length])];
    
    attributes = @{
                   (__bridge id)kCTForegroundColorAttributeName:(__bridge id)[UIColor redColor].CGColor,
                   (__bridge id)kCTUnderlineStyleAttributeName:@(kCTUnderlineStyleSingle),
                   (__bridge id)kCTFontAttributeName:(__bridge id)fontRef
                   };
    [string setAttributes:attributes range:NSMakeRange(6, 5)];
    
    //release the CTFont we created earlier
    CFRelease(fontRef);
    
    //set layer text
    textLayer.string = string;
}

行距和字距

//由于绘制的实现机制不同(Core Text和WebKit),用CATextLayer渲染和用UILabel渲染出的文本行距和字距也不是不尽相同的。

UILabel的替代品

//继承UILabel,然后添加一个子图层CATextLayer并重写显示文本的方法。
//我们继承了UIView,那我们就可以重写+layerClass方法使得在创建的时候能返回一个不同的图层子类。UIView会在初始化的时候调用+layerClass方法,然后用它的返回类型来创建宿主图层。
//例子:LayerLabel.h

CATransformLayer

//CATransformLayer不同于普通的CALayer,因为它不能显示它自己的内容。只有当存在了一个能作用域子图层的变换它才真正存在。CATransformLayer并不平面化它的子图层,所以它能够用于构造一个层级的3D结构,比如我的手臂示例。

- (CALayer *)faceWithTransform:(CATransform3D)transform {
    //create cube face layer
    CALayer *face = [CALayer layer];
    face.frame = CGRectMake(-50, -50, 100, 100);
    
    //apply a random color
    CGFloat red = (rand() / (double)INT_MAX);
    CGFloat green = (rand() / (double)INT_MAX);
    CGFloat blue = (rand() / (double)INT_MAX);
    face.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0f].CGColor;
    
    //apply the transform and return
    face.transform = transform;
    return  face;
}

- (CALayer *)cubeWithTransform:(CATransform3D)transform {
    //create cube layer
    CATransformLayer *cube = [CATransformLayer layer];
    
    //add cube face 1
    CATransform3D ct = CATransform3DMakeTranslation(0, 0, 50);
    [cube addSublayer:[self faceWithTransform:ct]];
    
    //add cube face 2
    ct = CATransform3DMakeTranslation(50, 0, 0);
    ct = CATransform3DRotate(ct, M_PI_2, 0, 1, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    
    //add cube face 3
    ct = CATransform3DMakeTranslation(0, -50, 0);
    ct = CATransform3DRotate(ct, M_PI_2, 1, 0, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    
    //add cube face 4
    ct = CATransform3DMakeTranslation(0, 50, 0);
    ct = CATransform3DRotate(ct, -M_PI_2, 1, 0, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    
    //add cube face 5
    ct = CATransform3DMakeTranslation(-50, 0, 0);
    ct = CATransform3DRotate(ct, -M_PI_2, 0, 1, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    
    //add cube face 6
    ct = CATransform3DMakeTranslation(0, 0, -50);
    ct = CATransform3DRotate(ct, M_PI, 0, 1, 0);
    [cube addSublayer:[self faceWithTransform:ct]];
    
    //center the cube layer within the container
    CGSize containerSize = containerView.bounds.size;
    cube.position = CGPointMake(containerSize.width/2.0, containerSize.height/2.0   );
    
    //apply the transform and return
    cube.transform = transform;
    return cube;
}

- (void)transformLayerTest {
    containerView = [[UIView alloc] init];
    containerView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    [self.view addSubview:containerView];
    
    //set up the perspective transform
    CATransform3D pt = CATransform3DIdentity;
    pt.m34 = -1.0/500.0f;
    containerView.layer.sublayerTransform = pt;
    
    //set up the transform for cube 1 and add it
    CATransform3D c1t = CATransform3DIdentity;
    c1t = CATransform3DTranslate(c1t, -100, 0, 0);
    CALayer *cube1 = [self cubeWithTransform:c1t];
    [containerView.layer addSublayer:cube1];
    
    //set up the transform for cube 2 and add it
    CATransform3D c2t = CATransform3DIdentity;
    c2t = CATransform3DTranslate(c2t, 100, 0, 0);
    c2t = CATransform3DRotate(c2t, -M_PI_4, 1, 0, 0);
    c2t = CATransform3DRotate(c2t, -M_PI_4, 0, 1, 0);
    CALayer *cube2 = [self cubeWithTransform:c2t];
    [containerView.layer addSublayer:cube2];
}

//CAGradientLayer:是用来生成两种或更多颜色平滑渐变的。

基础渐变

//colors属性:数组成员接受CGColorRef类型的值
//startPoint和endPoint属性,他们决定了渐变的方向。这两个参数是以单位坐标系进行的定义,所以左上角坐标是{0, 0},右下角坐标是{1, 1}

- (void)gradientLayerTest {
    containerView = [[UIView alloc] init];
    containerView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    [self.view addSubview:containerView];
    
    //create gradient layer and add it to our container view
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = containerView.bounds;
    [containerView.layer addSublayer:gradientLayer];
    
    //set gradient colors
    gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor blueColor].CGColor];
    
    //set gradient start and end points
    gradientLayer.startPoint = CGPointMake(0, 0);
    gradientLayer.endPoint = CGPointMake(1, 1);
}

多重渐变

//locations属性是一个浮点数值的数组(以NSNumber包装)。这些浮点数定义了colors属性中每个不同颜色的位置,同样的,也是以单位坐标系进行标定。0.0代表着渐变的开始,1.0代表着结束。

- (void)gradientLayerLocationsTest {
    containerView = [[UIView alloc] init];
    containerView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    [self.view addSubview:containerView];

    //create gradient layer and add it to our container view
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = containerView.bounds;
    [containerView.layer addSublayer:gradientLayer];
    
    //set gradient colors
    gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor blueColor].CGColor, (__bridge id)[UIColor greenColor].CGColor   ];
    //set locations
    gradientLayer.locations = @[@0.0, @0.25, @0.5];
    
    //set gradient start and end points
    gradientLayer.startPoint = CGPointMake(0, 1);
    gradientLayer.endPoint = CGPointMake(1, 1);
}

//CAReplicatorLayer:的目的是为了高效生成许多相似的图层。它会绘制一个或多个图层的子图层,并在每个复制体上应用不同的变换。

重复图层(Repeating Layers)

- (void)replicatorLayerTest {
    containerView = [[UIView alloc] init];
    containerView.frame = CGRectMake(20, 20, 300, 300);
    containerView.backgroundColor = [UIColor blackColor];
    [self.view addSubview:containerView];
    
    //create a replicator layer and add it to our view
    CAReplicatorLayer *replicator = [CAReplicatorLayer layer];
    replicator.frame = containerView.bounds;
    [containerView.layer addSublayer:replicator];
    
    //configure the replicator
    replicator.instanceCount = 10;
    
    //apply a transform for each instance
    CATransform3D transform = CATransform3DIdentity;
    transform = CATransform3DTranslate(transform, 0, 25, 0);
    transform = CATransform3DRotate(transform, M_PI/5.0f, 0, 0, 1);
    transform = CATransform3DTranslate(transform, 0, -25, 0);
    replicator.instanceTransform = transform;
    
    // apply a color shift for each instance
    replicator.instanceBlueOffset = -0.1;
    replicator.instanceGreenOffset = -0.1;
    
    //create a sublayer and place it inside the replicator
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(50, 50, 50.0f, 50.0f);
    layer.backgroundColor = [UIColor whiteColor].CGColor;
    [replicator addSublayer:layer];
}

反射

- (void)reflectionViewTest {
    containerView = [[UIView alloc] init];
    containerView.frame = CGRectMake(20, 20, 300, 300);
    [self.view addSubview:containerView];
    
    ReflectionView *reflectionView = [[ReflectionView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    
    UIImage *image = [UIImage imageNamed:@"Meal"];
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(0, 0, 100, 100);
    layer.contents =  (__bridge id)image.CGImage;
    [reflectionView.layer addSublayer:layer];
    
    [containerView addSubview:reflectionView];
}

CAScrollLayer

//frame属性是由bounds属性自动计算而出的,所以更改任意一个值都会更新其他值。
//-scrollToPoint:它自动适应bounds的原点以便图层内容出现在滑动的地方
//- (void)scrollPoint:(CGPoint)p;
//- (void)scrollRectToVisible:(CGRect)r;
//@property(readonly) CGRect visibleRect;

- (void)scrollViewTest {
    ScrollView *scrollView = [[ScrollView alloc] initWithFrame:CGRectMake(20.0, 20.0f, 300, 300)];
    UIImage *image = [UIImage imageNamed:@"Meal"];
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(0, 0, 100, 100);
    layer.contents =  (__bridge id)image.CGImage;
    [scrollView.layer addSublayer:layer];
    [self.view addSubview:scrollView];
    
}

CATiledLayer

//CATiledLayer为载入大图造成的性能问题提供了一个解决方案:将大图分解成小片然后将他们单独按需载入
//小片裁剪

- (void)tiledLayerTest {
    
    scrollView = [[UIScrollView alloc] init];
    scrollView.frame = CGRectMake(0, 0, 300, 300);
    
    [self.view addSubview:scrollView];
    
    //add the tiled layer
    CATiledLayer *tileLayer = [CATiledLayer layer];
    tileLayer.frame = CGRectMake(0, 0, 2048, 2048);
    tileLayer.delegate = self;
    //Retina小图
    tileLayer.contentsScale = [UIScreen mainScreen].scale;
    [scrollView.layer addSublayer:tileLayer];
    
    
    //configure the scroll view
    scrollView.contentSize = tileLayer.frame.size;

    //draw layer
    [tileLayer setNeedsDisplay];
}

#pragma mark CALayerDelegate
- (void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)ctx {
    //determine title coordinate
    CGRect bounds = CGContextGetClipBoundingBox(ctx);
    NSInteger x = floor(bounds.origin.x / layer.tileSize.width);
    NSInteger y = floor(bounds.origin.y / layer.tileSize.height);
    
    //Retina小图
    //tileSize是以像素为单位
    //determine tile coordinate  适应小图渲染代码以对应安排scale的变化
//    CGRect bounds = CGContextGetClipBoundingBox(ctx);
//    CGFloat scale = [UIScreen mainScreen].scale;
//    NSInteger x = floor(bounds.origin.x / layer.tileSize.width * scale);
//    NSInteger y = floor(bounds.origin.y / layer.tileSize.height * scale);
    
    //load tile image
//    NSString *imageName = [NSString stringWithFormat: @"Meal_%02i_%02i", x, y];
//    NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageName ofType:@"jpg"];
//    UIImage *tileImage = [UIImage imageWithContentsOfFile:imagePath];
    UIImage *tileImage = [UIImage imageNamed:@"Meal"];
    
    //draw tile
    UIGraphicsPushContext(ctx);
    [tileImage drawInRect:bounds];
    UIGraphicsPopContext();
}

烟雾,火,雨等等这些效果

//CAEmitterLayer:是一个高性能的粒子引擎,被用来创建实时例子动画如:烟雾,火,雨等等这些效果
//CAEmitterCell:一个CAEmitterCell类似于一个CALayer:它有一个contents属性可以定义为一个CGImage

- (void)emitterLayerTest {
    containerView = [[UIView alloc] init];
    containerView.frame = CGRectMake(20, 20, 300, 300);
    containerView.backgroundColor = [UIColor blackColor];
    [self.view addSubview:containerView];
    
    //create particle emitter layer
    CAEmitterLayer *emitter = [CAEmitterLayer layer];
    emitter.frame = containerView.bounds;
    [containerView.layer addSublayer:emitter];
    
    //configure emitter
    emitter.renderMode = kCAEmitterLayerAdditive;
    emitter.emitterPosition = CGPointMake(emitter.frame.size.width / 2.0, emitter.frame.size.height / 2.0);
    
    //create a particle template
    CAEmitterCell *cell = [[CAEmitterCell alloc] init];
    cell.contents = (__bridge id)[UIImage imageNamed:@"Star"].CGImage;
    cell.birthRate = 150;
    cell.lifetime = 5.0;
    cell.color = [UIColor colorWithRed:1 green:0.5 blue:0.1 alpha:1.0].CGColor;
    cell.alphaSpeed = -0.4;
    cell.velocity = 50;
    cell.velocityRange = 50;
    cell.emissionRange = M_PI * 2.0;
    
    //add particle template to emitter
    emitter.emitterCells = @[cell];
}

CAEMitterCell

//这种粒子的某一属性的初始值。比如,color属性指定了一个可以混合图片内容颜色的混合色。在示例中,我们将它设置为桔色。
//例子某一属性的变化范围。比如emissionRange属性的值是2π,这意味着例子可以从360度任意位置反射出来。如果指定一个小一些的值,就可以创造出一个圆锥形
//指定值在时间线上的变化。比如,在示例中,我们将alphaSpeed设置为-0.4,就是说例子的透明度每过一秒就是减少0.4,这样就有发射出去之后逐渐小时的效果。

CAEAGLLayer

//当iOS要处理高性能图形绘制,必要时就是OpenGL。
//OpenGL提供了Core Animation的基础,它是底层的C接口,直接和iPhone,iPad的硬件通信,极少地抽象出来的方法。OpenGL没有对象或是图层的继承概念。它只是简单地处理三角形。OpenGL中所有东西都是3D空间中有颜色和纹理的三角形。用起来非常复杂和强大,但是用OpenGL绘制iOS用户界面就需要很多很多的工作了
//在iOS 5中,苹果引入了一个新的框架叫做GLKit,它去掉了一些设置OpenGL的复杂性,提供了一个叫做CLKView的UIView的子类,帮你处理大部分的设置和绘制工作。前提是各种各样的OpenGL绘图缓冲的底层可配置项仍然需要你用CAEAGLLayer完成,它是CALayer的一个子类,用来显示任意的OpenGL图形。

- (void)EAGLLayerTest {
    glView = [[UIView alloc] init];
    glView.frame = CGRectMake(0, 0, 300, 300);
    glView.backgroundColor = [UIColor blackColor];
    [self.view addSubview:glView];
    
    //set up context
    glContext = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
    [EAGLContext setCurrentContext:glContext];
    
    //set up layer
    glLayer = [CAEAGLLayer layer];
    glLayer.frame = glView.bounds;
    [glView.layer addSublayer:glLayer];
    glLayer.drawableProperties = @{kEAGLDrawablePropertyRetainedBacking:@NO, kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8};
    
    //set up base effect
    effect = [[GLKBaseEffect alloc] init];
    
    //set up buffers
    [self setUpBuffers];
    
    //draw frame
    [self drawFrame];
}

- (void)setUpBuffers {
    //set up frame buffer
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    
    //set up color render buffer
    glGenRenderbuffers(1, &colorRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
    [glContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:glLayer];
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
    
    //check success
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        NSLog(@"Failed to make complete framebuffer object:%i", glCheckFramebufferStatus(GL_FRAMEBUFFER));
    }
}

- (void)drawFrame {
    //bind framebuffer & set viewport
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glViewport(0, 0, framebufferWidth, framebufferHeight);
    
    //bind shader program
    [effect prepareToDraw];
    
    //clear the screen
    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.0, 0.0, 0.0, 1.0f);
    
    //set up vertices
    GLfloat vertices[] = {
        -0.5f, -0.5f, -1.0f, 0.0f, 0.5f, -1.0f, 0.5f, -0.5f, -1.0f,
    };
    
    //set up colors
    GLfloat colors[] = {
        0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
    };
    
    //draw triangle
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribColor);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    glVertexAttribPointer(GLKVertexAttribColor,4, GL_FLOAT, GL_FALSE, 0, colors);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    
    //present render buffer
    glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
    [glContext presentRenderbuffer:GL_RENDERBUFFER];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:YES];
    [self tearDownBuffers];
}

- (void)dealloc {
    [self tearDownBuffers];
    [EAGLContext setCurrentContext:nil];
}

- (void)tearDownBuffers {
    if (framebuffer) {
        //delete framebuffer
        glDeleteFramebuffers(1, &framebuffer);
        framebuffer = 0;
    }
    if (colorRenderbuffer) {
        //delete color render buffer
        glDeleteRenderbuffers(1, &colorRenderbuffer);
        colorRenderbuffer = 0;
    }
}

AVPlayerLayer

框架(AVFoundation)提供的 它和Core Animation紧密地结合在一起,提供了一个CALayer子类来显示自定义的内容类型。

- (void)AVPlayerLayerTest {
    containerView = [[UIView alloc] init];
    containerView.frame = CGRectMake(20.0, 20.0, 300, 300);
    [self.view addSubview:containerView];
    
    //get video URl
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"Vedio" withExtension:@"mp4"];
    
    //create player and layer layer
    AVPlayer *player = [AVPlayer playerWithURL:url];
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
    
    //set player layer frame and attach it to our view
    playerLayer.frame = containerView.bounds;
    [containerView.layer addSublayer:playerLayer];
    
    //因为AVPlayerLayer是CALayer的子类,它继承了父类的所有特性。
    //transform layer
    CATransform3D transform = CATransform3DIdentity;
    transform.m34 = -1.0 / 500.0;
    transform = CATransform3DRotate(transform, M_PI_4, 1, 1, 0);
    playerLayer.transform = transform;
    
    //add rounded corners and border
    playerLayer.masksToBounds = YES;
    playerLayer.cornerRadius = 20.0f;
    playerLayer.borderColor = [UIColor redColor].CGColor;
    playerLayer.borderWidth = 5.0f;
    
    //play the video
    [player play];
}

//我们只是了解到这些图层的皮毛,像CATiledLayer和CAEMitterLayer这些类可以单独写一章的。

你可能感兴趣的:(iOS 动画 第六章 专用图层)