OpenGLES渲染

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

先用OpenGLES显示一张图片:

  1. //
  2. // ShowViewController.m
  3. // OpenGLES
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "ShowViewController.h"
  9. #import <GLKit/GLKit.h>
  10. #import <CoreImage/CoreImage.h>
  11.  
  12. @interface ShowViewController ()
  13. @property (nonatomic, strong) GLKView *viewBuffer;
  14. @end
  15.  
  16. @implementation ShowViewController
  17.  
  18. - (void)viewDidLoad
  19. {
  20. [super viewDidLoad];
  21.  
  22. // 获取OpenGLES渲染环境
  23. EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
  24.  
  25. // 根据图片获取尺寸
  26. UIImage *image = [UIImage imageNamed:@"demo.png"];
  27. CIImage *ciimage = [[CIImage alloc] initWithImage:image];
  28. CGRect rect = CGRectMake(, , image.size.width, image.size.height);
  29.  
  30. // 初始化GLKView并指定OpenGLES渲染环境
  31. _viewBuffer = [[GLKView alloc] initWithFrame:rect context:eaglContext];
  32. [self.view addSubview:_viewBuffer];
  33.  
  34. // 与OpenGLES绑定
  35. [_viewBuffer bindDrawable];
  36.  
  37. // 定义绘制区域(像素描述)
  38. CGRect rectInPixels = \
  39. CGRectMake(0.0, 0.0, _viewBuffer.drawableWidth, _viewBuffer.drawableHeight);
  40.  
  41. // 初始化CIImage的环境,指定在OpenGLES2上操作(此处只在GPU上操作)
  42. CIContext *context = \
  43. [CIContext contextWithEAGLContext:eaglContext
  44. options:@{kCIContextWorkingColorSpace:[NSNull null]}];
  45.  
  46. // 开始绘制
  47. [context drawImage:ciimage
  48. inRect:rectInPixels
  49. fromRect:[ciimage extent]];
  50.  
  51. // 显示
  52. [_viewBuffer display];
  53. }
  54.  
  55. @end

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

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

  1. //
  2. // RootViewController.m
  3. // OpenGLES
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "RootViewController.h"
  9. #import <GLKit/GLKit.h>
  10. #import <CoreImage/CoreImage.h>
  11. #import <QuartzCore/QuartzCore.h>
  12.  
  13. @interface RootViewController ()
  14.  
  15. @property (nonatomic, strong) GLKView *viewBuffer;
  16.  
  17. @property (nonatomic, strong) CIContext *ciContext;
  18. @property (nonatomic, strong) CIImage *ciImage;
  19. @property (nonatomic, strong) CIFilter *ciFilter;
  20.  
  21. @end
  22.  
  23. @implementation RootViewController
  24.  
  25. - (void)viewDidLoad
  26. {
  27. [super viewDidLoad];
  28.  
  29. // 获取OpenGLES2渲染环境
  30. EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
  31.  
  32. // 初始化一个viewBuffer,并指定在OpenGLES2环境渲染
  33. CGRect rect = CGRectMake(, ,
  34. [UIImage imageNamed:@"demo"].size.width,
  35. [UIImage imageNamed:@"demo"].size.height);
  36. _viewBuffer = [[GLKView alloc] initWithFrame:rect
  37. context:eaglContext];
  38.  
  39. // 绑定将这个view与OpenGLES2绑定
  40. [_viewBuffer bindDrawable];
  41. [self.view addSubview:_viewBuffer];
  42.  
  43. // 初始化CIImage的环境,指定在OpenGLES2上操作(此处只在GPU上操作)
  44. _ciContext = [CIContext contextWithEAGLContext:eaglContext
  45. options:@{kCIContextWorkingColorSpace:[NSNull null]}];
  46.  
  47. // 获取CIImage
  48. _ciImage = [[CIImage alloc] initWithImage:[UIImage imageNamed:@"demo"]];
  49.  
  50. // 初始化一个CIFilter
  51. _ciFilter = [CIFilter filterWithName:@"CISepiaTone"];
  52. [_ciFilter setValue:_ciImage forKey:kCIInputImageKey];
  53. [_ciFilter setValue:@ forKey:kCIInputIntensityKey];
  54.  
  55. // 定义绘制区域(像素描述)
  56. CGRect rectInPixels = \
  57. CGRectMake(0.0, 0.0, _viewBuffer.drawableWidth, _viewBuffer.drawableHeight);
  58.  
  59. // 开始绘制
  60. [_ciContext drawImage:_ciImage
  61. inRect:rectInPixels
  62. fromRect:[_ciImage extent]];
  63. [_viewBuffer display];
  64.  
  65. UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
  66. [self.view addSubview:slider];
  67. [slider addTarget:self
  68. action:@selector(event:)
  69. forControlEvents:UIControlEventValueChanged];
  70. slider.minimumValue = ;
  71. slider.maximumValue = ;
  72. }
  73.  
  74. - (void)event:(UISlider *)slider
  75. {
  76. [_ciFilter setValue:[NSNumber numberWithFloat:slider.value]
  77. forKey:kCIInputIntensityKey];
  78.  
  79. // 定义绘制区域(像素描述)
  80. CGRect rectInPixels = \
  81. CGRectMake(0.0, 0.0, _viewBuffer.drawableWidth, _viewBuffer.drawableHeight);
  82.  
  83. [_ciContext drawImage:[_ciFilter outputImage]
  84. inRect:rectInPixels
  85. fromRect:[_ciImage extent]];
  86. [_viewBuffer display];
  87. }
  88.  
  89. @end

将这个View封装一下吧.

GPUView.h + GPUView.m

  1. //
  2. // GPUView.h
  3. // OpenGLES
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import <UIKit/UIKit.h>
  9. #import <GLKit/GLKit.h>
  10. #import <CoreImage/CoreImage.h>
  11.  
  12. @interface GPUView : UIView
  13.  
  14. - (void)drawCIImage:(CIImage *)ciImage;
  15.  
  16. @end
  1. //
  2. // GPUView.m
  3. // OpenGLES
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "GPUView.h"
  9.  
  10. @interface GPUView ()
  11.  
  12. @property (nonatomic, assign) CGRect rectInPixels;
  13. @property (nonatomic, strong) CIContext *context;
  14. @property (nonatomic, strong) GLKView *showView;
  15.  
  16. @end
  17.  
  18. @implementation GPUView
  19.  
  20. - (id)initWithFrame:(CGRect)frame
  21. {
  22. self = [super initWithFrame:frame];
  23. if (self)
  24. {
  25. // 获取OpenGLES渲染环境
  26. EAGLContext *eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
  27.  
  28. // 初始化GLKView并指定OpenGLES渲染环境 + 绑定
  29. _showView = [[GLKView alloc] initWithFrame:frame context:eaglContext];
  30. [_showView bindDrawable];
  31.  
  32. // 添加进图层
  33. [self addSubview:_showView];
  34.  
  35. // 创建CIContext环境
  36. _context = \
  37. [CIContext contextWithEAGLContext:eaglContext
  38. options:@{kCIContextWorkingColorSpace:[NSNull null]}];
  39.  
  40. // 定义绘制区域(像素描述)
  41. _rectInPixels = \
  42. CGRectMake(0.0, 0.0, _showView.drawableWidth, _showView.drawableHeight);
  43. }
  44. return self;
  45. }
  46.  
  47. - (void)drawCIImage:(CIImage *)ciImage
  48. {
  49. // 开始绘制
  50. [_context drawImage:ciImage
  51. inRect:_rectInPixels
  52. fromRect:[ciImage extent]];
  53.  
  54. // 显示
  55. [_showView display];
  56. }
  57.  
  58. @end

实现同样的效果:

  1. //
  2. // ShowViewController.m
  3. // OpenGLES
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "ShowViewController.h"
  9. #import <CoreImage/CoreImage.h>
  10. #import "GPUView.h"
  11.  
  12. @interface ShowViewController ()
  13. @property (nonatomic, strong) CIFilter *ciFilter;
  14. @property (nonatomic, strong) GPUView *gpuView;
  15. @end
  16.  
  17. @implementation ShowViewController
  18.  
  19. - (void)viewDidLoad
  20. {
  21. [super viewDidLoad];
  22.  
  23. // 根据图片获取尺寸
  24. UIImage *image = [UIImage imageNamed:@"demo.png"];
  25. CIImage *ciimage = [[CIImage alloc] initWithImage:image];
  26. CGRect rect = CGRectMake(, , image.size.width, image.size.height);
  27.  
  28. // 初始化GPUView
  29. _gpuView = [[GPUView alloc] initWithFrame:rect];
  30. [self.view addSubview:_gpuView];
  31. [_gpuView drawCIImage:ciimage];
  32.  
  33. // 初始化一个CIFilter
  34. _ciFilter = [CIFilter filterWithName:@"CISepiaTone"];
  35. [_ciFilter setValue:ciimage forKey:kCIInputImageKey];
  36. [_ciFilter setValue:@ forKey:kCIInputIntensityKey];
  37.  
  38. // 初始化一个UISlider
  39. UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
  40. [self.view addSubview:slider];
  41. [slider addTarget:self
  42. action:@selector(event:)
  43. forControlEvents:UIControlEventValueChanged];
  44. slider.minimumValue = ;
  45. slider.maximumValue = ;
  46. }
  47.  
  48. - (void)event:(UISlider *)slider
  49. {
  50. [_ciFilter setValue:[NSNumber numberWithFloat:slider.value]
  51. forKey:kCIInputIntensityKey];
  52. [_gpuView drawCIImage:[_ciFilter outputImage]];
  53. }
  54.  
  55. @end

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

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

  1. //
  2. // ShowViewController.m
  3. // OpenGLES
  4. //
  5. // Copyright (c) 2014年 Y.X. All rights reserved.
  6. //
  7.  
  8. #import "ShowViewController.h"
  9. #import <CoreImage/CoreImage.h>
  10. #import "GPUView.h"
  11.  
  12. @interface ShowViewController ()
  13. @property (nonatomic, strong) CIFilter *ciFilter1;
  14. @property (nonatomic, strong) CIFilter *ciFilter2;
  15. @property (nonatomic, strong) GPUView *gpuView;
  16.  
  17. @property (nonatomic, strong) UISlider *slider1;
  18. @property (nonatomic, strong) UISlider *slider2;
  19. @end
  20.  
  21. @implementation ShowViewController
  22.  
  23. - (void)viewDidLoad
  24. {
  25. [super viewDidLoad];
  26.  
  27. // 根据图片获取尺寸
  28. UIImage *image = [UIImage imageNamed:@"demo.png"];
  29. CIImage *ciimage = [[CIImage alloc] initWithImage:image];
  30. CGRect rect = CGRectMake(, , image.size.width, image.size.height);
  31.  
  32. // 初始化GPUView
  33. _gpuView = [[GPUView alloc] initWithFrame:rect];
  34. [self.view addSubview:_gpuView];
  35. [_gpuView drawCIImage:ciimage];
  36.  
  37. // 初始化一个CIFilter
  38. _ciFilter1 = [CIFilter filterWithName:@"CISepiaTone"];
  39. [_ciFilter1 setValue:ciimage forKey:kCIInputImageKey];
  40. [_ciFilter1 setValue:@.f forKey:kCIInputIntensityKey];
  41.  
  42. _ciFilter2 = [CIFilter filterWithName:@"CIHueAdjust"];
  43. [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey];
  44. [_ciFilter2 setValue:@.f forKeyPath:kCIInputAngleKey];
  45.  
  46. // 初始化UISlider
  47. _slider1 = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
  48. [self.view addSubview:_slider1];
  49. [_slider1 addTarget:self
  50. action:@selector(event1:)
  51. forControlEvents:UIControlEventValueChanged];
  52. _slider1.minimumValue = ;
  53. _slider1.maximumValue = ;
  54. _slider1.value = 0.5f;
  55.  
  56. _slider2 = [[UISlider alloc] initWithFrame:CGRectMake(, , , )];
  57. [self.view addSubview:_slider2];
  58. [_slider2 addTarget:self
  59. action:@selector(event2:)
  60. forControlEvents:UIControlEventValueChanged];
  61. _slider2.minimumValue = -3.14f;
  62. _slider2.maximumValue = +3.14f;
  63. _slider2.value = .f;
  64. }
  65.  
  66. - (void)event1:(UISlider *)slider
  67. {
  68. [_ciFilter1 setValue:[NSNumber numberWithFloat:_slider1.value]
  69. forKey:kCIInputIntensityKey];
  70. [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey];
  71. [_ciFilter2 setValue:[NSNumber numberWithFloat:_slider2.value] forKeyPath:kCIInputAngleKey];
  72. [_gpuView drawCIImage:[_ciFilter2 outputImage]];
  73. }
  74.  
  75. - (void)event2:(UISlider *)slider
  76. {
  77. [_ciFilter1 setValue:[NSNumber numberWithFloat:_slider1.value]
  78. forKey:kCIInputIntensityKey];
  79. [_ciFilter2 setValue:[_ciFilter1 outputImage] forKeyPath:kCIInputImageKey];
  80. [_ciFilter2 setValue:[NSNumber numberWithFloat:_slider2.value] forKeyPath:kCIInputAngleKey];
  81. [_gpuView drawCIImage:[_ciFilter2 outputImage]];
  82. }
  83.  
  84. @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. LDAP落地实战(一):OpenLDAP部署及管理维护

    公司内部会有许多第三方系统或服务,例如Svn,Git,VPN,Jira,Jenkins等等,每个系统都需要维护一份账号密码以支持用户认证,当然公司也会有许多的主机或服务器,需要开放登录权限给用户登录使 ...

  2. facebook 摘要生成阅读笔记(二) Abstractive Sentence Summarization with Attentive Recurrent Neural Networks

    整体流程与第一篇差不多,只是在encoder和decoder加入了RNN Encoder: 1. ai=xi+li ai=词向量+词在序列中的位置信息(相当于一个权重,[M, 1]) 流程: 先是CN ...

  3. Python远程连接主机之paramiko模块

    Python的paramiko模块能够连接远程主机,并在该主机上执行命令,和该主机之间进行文件传输.paramiko支持用明文密码登录远程主机和秘钥登录.使用之前要安装一下这个模块哈,pip inst ...

  4. PTA (Advanced Level) 1021 Deepest Root

    Deepest Root A graph which is connected and acyclic can be considered a tree. The hight of the tree ...

  5. 【BI】资料收集

    从无到有--什么是BI 什么是BI(Business Intelligence) - @我爱菊花 - 博客园 http://www.cnblogs.com/jiesin/archive/2008/06 ...

  6. Python---战机小游戏,学习pygame

    import pygame # 导入游戏包 pygame.init() # 导入并初始化所有pygame模块,使用其他模块之前必须先调用init()方法 print('下面是游戏代码:') # 绘制矩 ...

  7. *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<WKWebViewConfiguration 0x1701bcd20> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the k

    问题描述: ionic项目,windows下正常,打包android可正常运行: 因为需要打包到iPhone (ios 11.0.1)上测试,将代码拿到Mac OS环境下(重新npm install. ...

  8. .net core 2.2 部署CentOS7(5)部署.net core mvc

    目录: .net core 2.2 部署CentOS7(1)安装虚拟机 .net core 2.2 部署CentOS7(2)给虚拟机安装CentOS7 .net core 2.2 部署CentOS7( ...

  9. spring jpa和mybatis整合

    spring jpa和mybatis整合 前一阵子接手了一个使用SpringBoot 和spring-data-jpa开发的项目 后期新加入一个小伙伴,表示jpa相比mybatis太难用,多表联合的查 ...

  10. Java生成xlsx格式的excel文件

    xlsx格式的写入的数据量据说有百万级,结合实际需要该格式. public static void main(String[] args) throws Exception { OutputStrea ...