OpenGLES渲染

OpenGLES渲染

OpenGLES渲染

OpenGLES使用GPU渲染图片,不占用CPU,但其使用还是挺复杂的.

先用OpenGLES显示一张图片:

//

//  ShowViewController.m

//  OpenGLES

//

//  Copyright (c) 2014年 Y.X. All rights reserved.

//



#import "ShowViewController.h"

#import <GLKit/GLKit.h>

#import <CoreImage/CoreImage.h>



@interface ShowViewController ()

@property (nonatomic, strong) GLKView   *viewBuffer;

@end



@implementation ShowViewController



- (void)viewDidLoad

{

    [super viewDidLoad];



    // 获取OpenGLES渲染环境

    EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    

    // 根据图片获取尺寸

    UIImage *image = [UIImage imageNamed:@"demo.png"];

    CIImage *ciimage = [[CIImage alloc] initWithImage:image];

    CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);

    

    // 初始化GLKView并指定OpenGLES渲染环境

    _viewBuffer = [[GLKView alloc] initWithFrame:rect context:eaglContext];

    [self.view addSubview:_viewBuffer];

    

    // 与OpenGLES绑定

    [_viewBuffer bindDrawable];

    

    // 定义绘制区域(像素描述)

    CGRect rectInPixels = \

        CGRectMake(0.0, 0.0, _viewBuffer.drawableWidth, _viewBuffer.drawableHeight);

    

    // 初始化CIImage的环境,指定在OpenGLES2上操作(此处只在GPU上操作)

    CIContext *context = \

        [CIContext contextWithEAGLContext:eaglContext

                                  options:@{kCIContextWorkingColorSpace:[NSNull null]}];

    

    // 开始绘制

    [context drawImage:ciimage

                inRect:rectInPixels

              fromRect:[ciimage extent]];

    

    // 显示

    [_viewBuffer display];

}



@end

OpenGLES渲染

只是显示一张图片而已,就需要写这么多的代码-_-!!!!

他有什么优势呢?其实,它的优势是实时渲染图片,不卡的.

//

//  RootViewController.m

//  OpenGLES

//

//  Copyright (c) 2014年 Y.X. All rights reserved.

//



#import "RootViewController.h"

#import <GLKit/GLKit.h>

#import <CoreImage/CoreImage.h>

#import <QuartzCore/QuartzCore.h>



@interface RootViewController ()



@property (nonatomic, strong) GLKView   *viewBuffer;



@property (nonatomic, strong) CIContext *ciContext;

@property (nonatomic, strong) CIImage   *ciImage;

@property (nonatomic, strong) CIFilter  *ciFilter;



@end



@implementation RootViewController



- (void)viewDidLoad

{

    [super viewDidLoad];



    // 获取OpenGLES2渲染环境

    EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    

    // 初始化一个viewBuffer,并指定在OpenGLES2环境渲染

    CGRect rect = CGRectMake(0, 0,

                             [UIImage imageNamed:@"demo"].size.width,

                             [UIImage imageNamed:@"demo"].size.height);

    _viewBuffer = [[GLKView alloc] initWithFrame:rect

                                         context:eaglContext];

    

    // 绑定将这个view与OpenGLES2绑定

    [_viewBuffer bindDrawable];

    [self.view addSubview:_viewBuffer];

    

    // 初始化CIImage的环境,指定在OpenGLES2上操作(此处只在GPU上操作)

    _ciContext = [CIContext contextWithEAGLContext:eaglContext

                                           options:@{kCIContextWorkingColorSpace:[NSNull null]}];

    

    // 获取CIImage

    _ciImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"demo"]];

    

    // 初始化一个CIFilter

    _ciFilter = [CIFilter filterWithName:@"CISepiaTone"];

    [_ciFilter setValue:_ciImage forKey:kCIInputImageKey];

    [_ciFilter setValue:@0 forKey:kCIInputIntensityKey];

    

    // 定义绘制区域(像素描述)

    CGRect rectInPixels = \

        CGRectMake(0.0, 0.0, _viewBuffer.drawableWidth, _viewBuffer.drawableHeight);

    

    // 开始绘制

    [_ciContext drawImage:_ciImage

                   inRect:rectInPixels

                 fromRect:[_ciImage extent]];

    [_viewBuffer display];

    

    UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 400, 320, 20)];

    [self.view addSubview:slider];

    [slider addTarget:self

               action:@selector(event:)

     forControlEvents:UIControlEventValueChanged];

    slider.minimumValue = 0;

    slider.maximumValue = 1;

}



- (void)event:(UISlider *)slider

{

    [_ciFilter setValue:[NSNumber numberWithFloat:slider.value]

                 forKey:kCIInputIntensityKey];

    

    // 定义绘制区域(像素描述)

    CGRect rectInPixels = \

    CGRectMake(0.0, 0.0, _viewBuffer.drawableWidth, _viewBuffer.drawableHeight);

    

    [_ciContext drawImage:[_ciFilter outputImage]

                 inRect:rectInPixels

               fromRect:[_ciImage extent]];

    [_viewBuffer display];

}



@end

将这个View封装一下吧.

GPUView.h + GPUView.m

//

//  GPUView.h

//  OpenGLES

//

//  Copyright (c) 2014年 Y.X. All rights reserved.

//



#import <UIKit/UIKit.h>

#import <GLKit/GLKit.h>

#import <CoreImage/CoreImage.h>



@interface GPUView : UIView



- (void)drawCIImage:(CIImage *)ciImage;



@end
//

//  GPUView.m

//  OpenGLES

//

//  Copyright (c) 2014年 Y.X. All rights reserved.

//



#import "GPUView.h"



@interface GPUView ()



@property (nonatomic, assign)  CGRect     rectInPixels;

@property (nonatomic, strong)  CIContext *context;

@property (nonatomic, strong)  GLKView   *showView;



@end



@implementation GPUView



- (id)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self)

    {

        // 获取OpenGLES渲染环境

        EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

        

        // 初始化GLKView并指定OpenGLES渲染环境 + 绑定

        _showView = [[GLKView alloc] initWithFrame:frame context:eaglContext];

        [_showView bindDrawable];

        

        // 添加进图层

        [self addSubview:_showView];

        

        // 创建CIContext环境

        _context = \

            [CIContext contextWithEAGLContext:eaglContext

                                      options:@{kCIContextWorkingColorSpace:[NSNull null]}];

        

        // 定义绘制区域(像素描述)

        _rectInPixels = \

            CGRectMake(0.0, 0.0, _showView.drawableWidth, _showView.drawableHeight);

    }

    return self;

}



- (void)drawCIImage:(CIImage *)ciImage

{

    // 开始绘制

    [_context drawImage:ciImage

                 inRect:_rectInPixels

              fromRect:[ciImage extent]];

    

    // 显示

    [_showView display];

}



@end

实现同样的效果:

//

//  ShowViewController.m

//  OpenGLES

//

//  Copyright (c) 2014年 Y.X. All rights reserved.

//



#import "ShowViewController.h"

#import <CoreImage/CoreImage.h>

#import "GPUView.h"



@interface ShowViewController ()

@property (nonatomic, strong) CIFilter  *ciFilter;

@property (nonatomic, strong) GPUView   *gpuView;

@end



@implementation ShowViewController



- (void)viewDidLoad

{

    [super viewDidLoad];



    // 根据图片获取尺寸

    UIImage *image   = [UIImage imageNamed:@"demo.png"];

    CIImage *ciimage = [[CIImage alloc] initWithImage:image];

    CGRect rect      = CGRectMake(0, 0, image.size.width, image.size.height);

    

    // 初始化GPUView

    _gpuView = [[GPUView alloc] initWithFrame:rect];

    [self.view addSubview:_gpuView];

    [_gpuView drawCIImage:ciimage];

    

    // 初始化一个CIFilter

    _ciFilter = [CIFilter filterWithName:@"CISepiaTone"];

    [_ciFilter setValue:ciimage forKey:kCIInputImageKey];

    [_ciFilter setValue:@0 forKey:kCIInputIntensityKey];

    

    // 初始化一个UISlider

    UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 400, 320, 20)];

    [self.view addSubview:slider];

    [slider addTarget:self

               action:@selector(event:)

     forControlEvents:UIControlEventValueChanged];

    slider.minimumValue = 0;

    slider.maximumValue = 1;

}



- (void)event:(UISlider *)slider

{

    [_ciFilter setValue:[NSNumber numberWithFloat:slider.value]

                 forKey:kCIInputIntensityKey];

    [_gpuView drawCIImage:[_ciFilter outputImage]];

}



@end

看起来简洁多了.....

来点复杂点的,同时操作两个滤镜

//

//  ShowViewController.m

//  OpenGLES

//

//  Copyright (c) 2014年 Y.X. All rights reserved.

//



#import "ShowViewController.h"

#import <CoreImage/CoreImage.h>

#import "GPUView.h"



@interface ShowViewController ()

@property (nonatomic, strong) CIFilter  *ciFilter1;

@property (nonatomic, strong) CIFilter  *ciFilter2;

@property (nonatomic, strong) GPUView   *gpuView;



@property (nonatomic, strong) UISlider  *slider1;

@property (nonatomic, strong) UISlider  *slider2;

@end



@implementation ShowViewController



- (void)viewDidLoad

{

    [super viewDidLoad];



    // 根据图片获取尺寸

    UIImage *image   = [UIImage imageNamed:@"demo.png"];

    CIImage *ciimage = [[CIImage alloc] initWithImage:image];

    CGRect rect      = CGRectMake(0, 0, image.size.width, image.size.height);

    

    // 初始化GPUView

    _gpuView = [[GPUView alloc] initWithFrame:rect];

    [self.view addSubview:_gpuView];

    [_gpuView drawCIImage:ciimage];

    

    // 初始化一个CIFilter

    _ciFilter1 = [CIFilter filterWithName:@"CISepiaTone"];

    [_ciFilter1 setValue:ciimage forKey:kCIInputImageKey];

    [_ciFilter1 setValue:@0.f forKey:kCIInputIntensityKey];

    

    _ciFilter2 = [CIFilter filterWithName:@"CIHueAdjust"];

    [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey];

    [_ciFilter2 setValue:@0.f forKeyPath:kCIInputAngleKey];

    

    // 初始化UISlider

    _slider1 = [[UISlider alloc] initWithFrame:CGRectMake(0, 400, 320, 20)];

    [self.view addSubview:_slider1];

    [_slider1 addTarget:self

               action:@selector(event1:)

     forControlEvents:UIControlEventValueChanged];

    _slider1.minimumValue = 0;

    _slider1.maximumValue = 1;

    _slider1.value = 0.5f;

    

    _slider2 = [[UISlider alloc] initWithFrame:CGRectMake(0, 450, 320, 20)];

    [self.view addSubview:_slider2];

    [_slider2 addTarget:self

                action:@selector(event2:)

      forControlEvents:UIControlEventValueChanged];

    _slider2.minimumValue = -3.14f;

    _slider2.maximumValue = +3.14f;

    _slider2.value = 0.f;

}



- (void)event1:(UISlider *)slider

{

    [_ciFilter1 setValue:[NSNumber numberWithFloat:_slider1.value]

                 forKey:kCIInputIntensityKey];

    [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey];

    [_ciFilter2 setValue:[NSNumber numberWithFloat:_slider2.value] forKeyPath:kCIInputAngleKey];

    [_gpuView drawCIImage:[_ciFilter2 outputImage]];

}



- (void)event2:(UISlider *)slider

{

    [_ciFilter1 setValue:[NSNumber numberWithFloat:_slider1.value]

                  forKey:kCIInputIntensityKey];

    [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey];

    [_ciFilter2 setValue:[NSNumber numberWithFloat:_slider2.value] forKeyPath:kCIInputAngleKey];

    [_gpuView drawCIImage:[_ciFilter2 outputImage]];

}



@end

 

 

 

 

 

你可能感兴趣的:(OpenGL)