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(, , 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

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

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

//
// 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(, ,
[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:@ 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(, , , )];
[self.view addSubview:slider];
[slider addTarget:self
action:@selector(event:)
forControlEvents:UIControlEventValueChanged];
slider.minimumValue = ;
slider.maximumValue = ;
} - (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(, , 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:@ forKey:kCIInputIntensityKey]; // 初始化一个UISlider
UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
[self.view addSubview:slider];
[slider addTarget:self
action:@selector(event:)
forControlEvents:UIControlEventValueChanged];
slider.minimumValue = ;
slider.maximumValue = ;
} - (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(, , 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:@.f forKey:kCIInputIntensityKey]; _ciFilter2 = [CIFilter filterWithName:@"CIHueAdjust"];
[_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey];
[_ciFilter2 setValue:@.f forKeyPath:kCIInputAngleKey]; // 初始化UISlider
_slider1 = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
[self.view addSubview:_slider1];
[_slider1 addTarget:self
action:@selector(event1:)
forControlEvents:UIControlEventValueChanged];
_slider1.minimumValue = ;
_slider1.maximumValue = ;
_slider1.value = 0.5f; _slider2 = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
[self.view addSubview:_slider2];
[_slider2 addTarget:self
action:@selector(event2:)
forControlEvents:UIControlEventValueChanged];
_slider2.minimumValue = -3.14f;
_slider2.maximumValue = +3.14f;
_slider2.value = .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

OpenGLES渲染的更多相关文章

  1. 实战OpenGLES--iOS平台使用OpenGLES渲染YUV图片

    上一篇文章 实战FFmpeg--iOS平台使用FFmpeg将视频文件转换为YUV文件 演示了如何将视频文件转换为yuv文件保存,现在要做的是如何将yuv文件利用OpenGLES渲染展示出图像画面.要将 ...

  2. iOS给图片添加滤镜&使用openGLES动态渲染图片

    给图片增加滤镜有这两种方式: CoreImage / openGLES 下面先说明如何使用CoreImage给图片添加滤镜, 主要为以下步骤: #1.导入CIImage格式的原始图片 #2.创建CIF ...

  3. 将Cocos2dX渲染到MFC窗口上

    引用:http://www.cnblogs.com/windeer/archive/2012/11/18/2767750.html 引言 现在智能手机已经慢慢进入大众化,移动类应用开始火爆起来,游戏类 ...

  4. iOS CoreImage图片处理动态渲染(滤镜)

    // //  ViewController.m //  CoreImageOfDong // //  Created by Dong on 15/6/30. //  Copyright (c) 201 ...

  5. 实战FFmpeg + OpenGLES--iOS平台上视频解码和播放

    一个星期的努力终于搞定了视频的播放,利用FFmpeg解码视频,将解码的数据通过OpenGLES渲染播放.搞清楚了自己想知道的和完成了自己的学习计划,有点小兴奋.明天就是“五一”,放假三天,更开心啦. ...

  6. CoreImage 处理图片

    1.CoreImage 滤镜的使用(马赛克模糊) CoreImage是苹果公司为了简化图片处理的难度而开发出来的类库. 随着iOS版本号升级以及硬件性能的不断提升,CoreImage将支持越来越多的滤 ...

  7. iOS动画技术笔记

    概述 在IOS开发中,实现动画操作的地方有很多,典型的是在视图控制器的segue操作时.在同一个视图控制器类中,加载切换不同的视图时,也需要动画效果,还有一些视图对象有动画效果会更好. 插一句,在IO ...

  8. Android Camera2 Opengles2.0 实时滤镜(冷暖色/放大镜/模糊/美颜)

    https://blog.csdn.net/keen_zuxwang/article/details/78363464 demo: http://download.csdn.net/download/ ...

  9. OpenGL绘制一个三角形

    应该建立一个vertex shader文件和一个pixel shader文件,分别命名为shader.vsh和shader.fsh. shader.vsh: attribute vec3 positi ...

随机推荐

  1. 8-lvs-负载均衡

    注意: linux集群的时间需要一致 并发量在千万以上, 一般才会使用此种方式, 基于第四层进行ip欺骗, 使得nginx只接受上行流量, 下行流量通过具体执行的服务器直接返回 由章文嵩博士(淘宝) ...

  2. TCP三次握手/四次挥手

    TCP 三次握手 TCP 连接是通过三次握手进行初始化的.三次握手的目的是同步连接双方的序列号和确认号并交换 TCP 窗口大小信息.以下步骤概述了通常情况下客户端计算机联系服务器计算机的过程: 1.  ...

  3. OOAD之单例模式Singleton的6种写法

    1  主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 一 :第一种 饿汉式(预加载) public class Singleton { private Singleton(){ ...

  4. ZOJ 1203 Swordfish(Prim算法求解MST)

    题目: There exists a world within our world A world beneath what we call cyberspace. A world protected ...

  5. 使用 NodeJS+Express+MySQL 实现简单的增删改查

    关于node.js暂时记录如下,以后有时间一定学习 文章来自简书,作者:sprint,2016-07 使用 Node.js + Express+MySQL 实现简单的增删改查 https://www. ...

  6. 922-按奇偶校验排序数组II

    给定一组A 非负整数,A中的一半整数是奇数,而整数的一半是偶数. 对数组进行排序,以便每当A[i]奇数时,i都是奇数; 无论何时A[i]均匀,i均匀. 您可以返回满足此条件的任何答案数组. 例1: 输 ...

  7. MVC 客户端(Memo = "<img src="http://">")中检测到有潜在的危险的 Request.Form 值 的解决方案

    解释定义:ASP.NET为了阻止跨站脚本攻击,会对向服务器端输入的HTML代码进行防御措施,在使用.NET MVC中,可以对validateinput属性设置,但是,有时需要ASP.NET临时关闭这个 ...

  8. Linux学习6-Linux常用命令(2)

    目录处理命令     命令名称:mkdir 命令英文原意:make directories 命令所在路径:/bin/mkdir 执行权限:所有用户 功能描述:创建新目录 语法:mkdir -p[目录名 ...

  9. CSS3选择器:nth-child和:nth-of-type之间的差异——张鑫旭

    一.深呼吸,直接内容 :nth-child和:nth-of-type都是CSS3中的伪类选择器,其作用近似却又不完全一样,对于不熟悉的人对其可能不是很区分,本文就将介绍两者的不同,以便于大家正确灵活使 ...

  10. github for window 中 git shell 设置代理方法和解决ssl证书错误的问题

    体验了一下传说中的 github for windows(操作git有很多的方法,我还没有学会,所以找了个简单的方法),听说用起来还不错,毕竟也开始接触了github.下载地址是 http://win ...