一、GLKit框架概述
GLKit 框架的设计目标是为了简化并加快基于OpenGL / OpenGL ES 的应⽤开发。 此框架封装了数学库、背景纹理加载、预先创建的着⾊器效果,以及标准视图和视图控制器,来帮助开发者实现渲染循环。
GLKit框架提供了功能和类,可以减少创建新的基于着⾊器的应⽤程序所需的工作量,或者支持依赖早期版本的OpenGL ES或OpenGL提供的固定函数顶点或片段处理的现有应用程序。
GLKView 提供绘制场所(View),继承于UIView
GLKViewController(扩展于标准的UIKit 设计模式. ⽤于绘制视图内容的管理与呈现.)
苹果弃用OpenGL ES ,但iOS开发者可以继续使⽤.
二、GLKit 苹果文档介绍
The GLKView class provides an OpenGL ES–based equivalent of the standard UIView drawing cycle.
A UIView instance automatically configures its graphics context so that your drawRect: implementation need only perform Quartz 2D drawing commands, and a GLKView instance automatically configures itself so that your drawing method need only perform OpenGL ES drawing commands. The GLKView class provides this functionality by maintaining a framebuffer object that holds the results of your OpenGL ES drawing commands, and then automatically presents them to Core Animation once your drawing method returns.
Like a standard UIKit view, a GLKit view renders its content on demand. When your view is first displayed, it calls your drawing method—Core Animation caches the rendered output and displays it whenever your view is shown. When you want to change the contents of your view, call its setNeedsDisplaymethod and the view again calls your drawing method, caches the resulting image, and presents it on screen. This approach is useful when the data used to render an image changes infrequently or only in response to user action. By rendering new view contents only when you need to, you conserve battery power on the device and leave more time for the device to perform other actions.
三、使⽤GLKit视图呈现OpenGL ES内容
- FrameBuffer帧缓冲区,存储了深度缓冲区和颜色缓冲区,GLKit已经实现了创建帧缓冲区,不需要开发者创建
- 将开发者写的代码如glClear清除背景颜色、设置uniform、绑定纹理、绘制图形等写入到帧缓冲区
- GLKit从帧缓冲区中取出结果显示到屏幕上
四、配置GLKit视图
- (void)viewDidLoad{
[super viewDidLoad];
//创建OpenGL ES上下文并将其分配给从故事板加载的视图
GLKView * view =(GLKView *)self.view;
//context中存储OpenGL ES的相关状态,初始化时指定API,2.0与3.0没有太大的区别
view.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
//配置视图创建的渲染缓冲区
view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; //指定颜色缓冲区的格式,RGBA各占8位
view.drawableDepthFormat = GLKViewDrawableDepthFormat24; //指定深度缓冲区,一般使用Format24
view.drawableStencilFormat = GLKViewDrawableStencilFormat8;
//启⽤多重采样
view.drawableMultisample = GLKViewDrawableMultisample4X;
}
-(void)drawRect:(CGRect)rect
{
//清除帧缓冲区
glClearColor(0.0f,0.0f,0.1f,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//使⽤先前配置的纹理,着⾊器和顶点数组绘制
glBindTexture(GL_TEXTURE_2D, _planetTexture);
glUseProgram(_diffuseShading);
glUniformMatrix4fv(_uniformModelViewProjectionMatrix, 1, 0,
_modelViewProjectionMatrix.m);
glBindVertexArrayOES(_planetMesh);
glDrawElements(GL_TRIANGLE_STRIP, 256, GL_UNSIGNED_SHORT);
}
五、GLKit功能
加载纹理;
提供高性能的数学运算,比如3D数学的计算;
提供常见的着色器;
提供视图以及视图控制器。
六、GLKit 常用API
- GLKit纹理加载
- GLKTextureInfo 创建OpenGL 纹理信息
/*
name:OpenGL 上下文中纹理名称
target:纹理绑定的目标
height:加载的纹理高度
width:加载的纹理宽度
textureOrigin:加载纹理中的原点位置
alphaState:加载纹理中alpha分量状态
containsMipmaps:布尔值,加载的纹理是否包含mip贴图
*/
- GLTextureLoader 简化从各种资源文件中加载纹理
/*
初始化
- initWithShareGroup: 初始化一个新的纹理加载到对象中
- initWithShareContext: 初始化一个新的纹理加载对象
从文件中加载纹理(加载纹理中实际已经执行了解压缩,Core Graphic将JPEG、png图片解压成了位图)
+ textureWithContentsOfFile:options:error: 从文件加载2D纹理图像并从数据中创建新的纹理
- textureWithContentsOfFile:options:queue:completionHandler: 从文件中异步加载2D纹理图像,并根据数据创建新纹理
从URL加载纹理
- textureWithContentsOfURL:options:error: 从URL加载2D纹理图像并从数据创建新纹理
- textureWithContentsOfURL:options:queue:completionHandler: 从URL异步加载2D纹理图像,并根据数据创建新纹理
从内存中加载纹理
- textureWithContentsOfData:options:error: 从内存空间加载2D纹理图像并根据数据创建新纹理
- textureWithContentsOfData:options:queue:completionHandler: 从内存空间异步加载2D纹理图像,并根据数据创建新纹理
从CGImage创建纹理
- textureWithCGImage:options:error: 从Quartz图像加载2D纹理图像并从数据创建新纹理
- textureWithCGImage:options:queue:completionHandler: 从Quartz图像异步加载2D纹理图像,并根据数据创建新纹理
从URL创建多维纹理
+ cubeMapWithContentsOfURL:options:error: 从单个URL加载立方体贴图纹理图像,并从数据创建新纹理
- cubeMapWithContentsOfURL:options:queue:completionHandler: 从单个URL异步加载立方体贴图纹理图像,并根据数据创建新纹理
从文件加载多维纹理创建纹理
+ cubeMapWithContentsOfFile:options:error: 从单个文件加载立方体贴图纹理图像,并从数据中创建新纹理
- cubeMapWithContentsOfFile:options:queue:completionHandler: 从单个文件异步加载立方体贴图纹理图像,并从数据中创建新纹理
+ cubeMapWithContentsOfFiles:options:error: 从一系列文件中加载立方体贴图纹理图像,并从数据中创建新纹理
- cubeMapWithContentsOfFiles:options:queue:completionHandler: 从一系列文件异步加载立方体贴图纹理图像,并从数据中创建新纹理
*/
- GLKit OpenGL ES视图渲染
- GLKView 使用OpenGL ES绘制内容的视图默认实现
/*
初始化视图
- initWithFrame:context: 初始化新视图
*/
- (instancetype)initWithFrame:(CGRect)frame context:(EAGLContext *)context;
/*
代理
delegate 视图的代理
*/
@property (nullable, nonatomic, assign) IBOutlet id delegate;
/*
配置帧缓冲区对象
drawableColorFormat 颜色渲染缓存区格式
drawableDepthFormat 深度渲染缓存区格式
drawableStencilFormat 模板渲染缓存区格式
drawableMultisample 多重采样缓存区的格式
*/
@property (nonatomic) GLKViewDrawableColorFormat drawableColorFormat; // 颜色缓冲区格式
@property (nonatomic) GLKViewDrawableDepthFormat drawableDepthFormat; // 深度缓冲区格式
@property (nonatomic) GLKViewDrawableStencilFormat drawableStencilFormat; // 模板缓冲区格式
@property (nonatomic) GLKViewDrawableMultisample drawableMultisample; // 多重采样
/*
帧缓存区属性,只读状态
drawableHeight 底层缓存区对象的高度,以像素为单位
drawableWidth 底层缓存区对象的宽度,以像素为单位
*/
@property (nonatomic, readonly) NSInteger drawableWidth;
@property (nonatomic, readonly) NSInteger drawableHeight;
/*
绘制视图的内容
context 绘制视图内容时使用的OpenGL ES 上下文
bindDrawable 将底层FrameBuffer对象绑定到OpenGL ES
enableSetNeedsDisplay 布尔值,指定视图是否响应使得视图内容无效的消息,设置是否显示
display 立即重绘视图内容
snapshot 绘制视图内容并将其作为新图像对象返回
*/
@property (nonatomic, retain) EAGLContext *context;
- (void)bindDrawable;
@property (nonatomic) BOOL enableSetNeedsDisplay;
- (void)display;
@property (readonly, strong) UIImage *snapshot;
/*
删除视图FrameBuffer对象
deleteDrawable 删除与视图关联的可绘制对象
*/
- (void)deleteDrawable;
- GLKViewDelegate 用于GLKView对象回调方法
/*
绘制视图的内容
- glkView:drawInRect: 绘制视图内容,关于绘图的实现都在这里操作(必须实现此代理)
*/
@protocol GLKViewDelegate
@required
/*
Required method for implementing GLKViewDelegate. This draw method variant should be used when not subclassing GLKView.
This method will not be called if the GLKView object has been subclassed and implements -(void)drawRect:(CGRect)rect.
*/
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect;
@end
- GLKViewController 管理OpenGL ES 渲染循环的视图控制器
/*
更新
- (void)update 更新视图内容
- (void)glkViewControllerUpdate:
*/
/*
Required method for implementing GLKViewControllerDelegate. This update method variant should be used
when not subclassing GLKViewController. This method will not be called if the GLKViewController object
has been subclassed and implements -(void)update.
*/
- (void)glkViewControllerUpdate:(GLKViewController *)controller;
/*
配置帧速率
preferredFramesPerSecond 视图控制器调用视图以及更新视图内容的速率,也就是帧之间切换的速率,默认30fps
framesPerSecond 视图控制器调用视图以及更新其内容的实际速率
*/
@property (nonatomic) NSInteger preferredFramesPerSecond;
@property (nonatomic, readonly) NSInteger framesPerSecond;
/*
配置GLKViewController 代理
delegate 视图控制器的代理
*/
@property (nullable, nonatomic, assign) IBOutlet id delegate;
/*
获取有关View更新信息
frameDisplayed 视图控制器自创建以来发送的帧更新数
timeSinceFirstResume 自视图控制器第一次恢复发送更新事件以来经过的时间量
timeSinceLastResume 自上次视图控制器恢复发送更新事件以来更新的时间量
timeSinceLaseUpdate 自上次视图控制器调用委托方法以及经过的时间量
timeSinceLastDraw 自上次视图控制器调用视图display方法以来经过的时间量
*/
@property (nonatomic, readonly) NSInteger framesDisplayed;
@property (nonatomic, readonly) NSTimeInterval timeSinceFirstResume;
@property (nonatomic, readonly) NSTimeInterval timeSinceLastResume;
@property (nonatomic, readonly) NSTimeInterval timeSinceLastUpdate;
@property (nonatomic, readonly) NSTimeInterval timeSinceLastDraw;
- GLKViewControllerDelegate 渲染循环回调方法
/*
处理更新事件
- glkViewControllerUpdate: 在显示每个帧之前调用
暂停/回复通知
- glkViewController: willPause: 在渲染循环暂停或恢复之前调用
*/
@protocol GLKViewControllerDelegate
@required
/*
Required method for implementing GLKViewControllerDelegate. This update method variant should be used
when not subclassing GLKViewController. This method will not be called if the GLKViewController object
has been subclassed and implements -(void)update.
*/
- (void)glkViewControllerUpdate:(GLKViewController *)controller;
@optional
/*
Delegate method that gets called when the pause state changes.
*/
- (void)glkViewController:(GLKViewController *)controller willPause:(BOOL)pause;
@end
- GLKBaseEffect 一种简单的光照/着色系统,用于基于着色器OpenGL渲染
/*
命名Effect
label 给Effect(效果)命名
配置模型视图转换,缩放旋转等
transform 绑定效果时应用于顶点数据的模型视图,投影和纹理变换
配置光照效果
lightingType 用于计算每个片段的光照策略,GLKLightingType
GLKLightingType
GLKLightingTypePerVertex 表示在三角形中每个顶点执行光照计算,然后在三角形进行插值
GLKLightingTypePerPixel 表示光照计算的输入在三角形内插入,并且在每个片段执行光照计算
配置光照
lightModelTwoSided 布尔值,表示为基元的两侧计算光照
material 计算渲染图元光照使用的材质属性
lightModelAmbientColor 环境颜色,应用效果渲染的所有图元
light0 场景中第一个光照属性
light1 场景中第二个光照属性
light2 场景中第三个光照属性
GLKBaseEffect 提供了三个光照两个纹理可供使用,当场景中超过这个数量时需要自定义着色器
配置纹理
texture2d0 第一个纹理属性
texture2d1 第二个纹理属性
textureOrder 纹理应用于渲染图元的顺序
配置雾化
fog 应用于场景的雾属性
配置颜色信息
colorMaterialEnable 布尔值,表示计算光照与材质交互时是否使用颜色顶点属性
useConstantColor 布尔值,表示是否使用常量颜色,常量颜色默认黑色
constantColor 不提供每个顶点颜色数据时使用常量颜色
准备绘制效果
- prepareToDraw 准备渲染
*/