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類型
//創(chuàng)建一個CGPath
//lineWith(線寬,用點表示單位),lineCap(線條結(jié)尾的樣子),和lineJoin(線條之間的結(jié)合點的樣子);但是在圖層層面你只有一次機(jī)會設(shè)置這些屬性。如果你想用不同顏色或風(fēng)格來繪制多個形狀,就不得不為每個形狀準(zhǔn)備一個圖層了。

- (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并不關(guān)心屏幕的拉伸因素而總是默認(rèn)為1.0。
    textLayer.contentsScale = [UIScreen mainScreen].scale;
}

富文本

//NSAttributedString.iOS 6及以上可以用新的NSTextAttributeName實例來設(shè)置我們的字符串屬性,在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;
}

行距和字距

//由于繪制的實現(xiàn)機(jī)制不同(Core Text和WebKit),用CATextLayer渲染和用UILabel渲染出的文本行距和字距也不是不盡相同的。

UILabel的替代品

//繼承UILabel,然后添加一個子圖層CATextLayer并重寫顯示文本的方法。
//我們繼承了UIView,那我們就可以重寫+layerClass方法使得在創(chuàng)建的時候能返回一個不同的圖層子類。UIView會在初始化的時候調(diào)用+layerClass方法,然后用它的返回類型來創(chuàng)建宿主圖層。
//例子:LayerLabel.h

CATransformLayer

//CATransformLayer不同于普通的CALayer,因為它不能顯示它自己的內(nèi)容。只有當(dāng)存在了一個能作用域子圖層的變換它才真正存在。CATransformLayer并不平面化它的子圖層,所以它能夠用于構(gòu)造一個層級的3D結(jié)構(gòu),比如我的手臂示例。

- (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:是用來生成兩種或更多顏色平滑漸變的。

基礎(chǔ)漸變

//colors屬性:數(shù)組成員接受CGColorRef類型的值
//startPoint和endPoint屬性,他們決定了漸變的方向。這兩個參數(shù)是以單位坐標(biāo)系進(jìn)行的定義,所以左上角坐標(biāo)是{0, 0},右下角坐標(biāo)是{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屬性是一個浮點數(shù)值的數(shù)組(以NSNumber包裝)。這些浮點數(shù)定義了colors屬性中每個不同顏色的位置,同樣的,也是以單位坐標(biāo)系進(jìn)行標(biāo)定。0.0代表著漸變的開始,1.0代表著結(jié)束。

- (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:的目的是為了高效生成許多相似的圖層。它會繪制一個或多個圖層的子圖層,并在每個復(fù)制體上應(yīng)用不同的變換。

重復(fù)圖層(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:它自動適應(yīng)bounds的原點以便圖層內(nèi)容出現(xiàn)在滑動的地方
//- (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  適應(yīng)小圖渲染代碼以對應(yīng)安排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:是一個高性能的粒子引擎,被用來創(chuàng)建實時例子動畫如:煙霧,火,雨等等這些效果
//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屬性指定了一個可以混合圖片內(nèi)容顏色的混合色。在示例中,我們將它設(shè)置為桔色。
//例子某一屬性的變化范圍。比如emissionRange屬性的值是2π,這意味著例子可以從360度任意位置反射出來。如果指定一個小一些的值,就可以創(chuàng)造出一個圓錐形
//指定值在時間線上的變化。比如,在示例中,我們將alphaSpeed設(shè)置為-0.4,就是說例子的透明度每過一秒就是減少0.4,這樣就有發(fā)射出去之后逐漸小時的效果。

CAEAGLLayer

//當(dāng)iOS要處理高性能圖形繪制,必要時就是OpenGL。
//OpenGL提供了Core Animation的基礎(chǔ),它是底層的C接口,直接和iPhone,iPad的硬件通信,極少地抽象出來的方法。OpenGL沒有對象或是圖層的繼承概念。它只是簡單地處理三角形。OpenGL中所有東西都是3D空間中有顏色和紋理的三角形。用起來非常復(fù)雜和強(qiáng)大,但是用OpenGL繪制iOS用戶界面就需要很多很多的工作了
//在iOS 5中,蘋果引入了一個新的框架叫做GLKit,它去掉了一些設(shè)置OpenGL的復(fù)雜性,提供了一個叫做CLKView的UIView的子類,幫你處理大部分的設(shè)置和繪制工作。前提是各種各樣的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緊密地結(jié)合在一起,提供了一個CALayer子類來顯示自定義的內(nèi)容類型。

- (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這些類可以單獨寫一章的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容