一·什么是OpenGL ES?
先说一下OpenGL,它被定义为是一个跨平台和跨编程语言的图形程序接口API。当你要处理高性能图形绘制的时候,它是最后的杀手锏。当然,因为是最底层的东西。所以使用起来也非常的复杂。
OpenGL ES 是OpenGL 的一个子集。是现代移动设备绘图功能的基础。OpenGL ES定义了嵌入式3D绘图的标准。在iOS5中苹果引入了一个GLKit框架,这个框架简化了很多常用的编程如任务,隐藏了OpenGL ES版本间的差异,使用这个框架可以用提高软件开发的生产效率。下面我们会通过一个例子来展示GLKit的神奇之处。
二·帧缓存和像素颜色缓存
帧缓存:GPU要知道应该在内存中的哪个位置存储已经渲染出来的图像像素数据。接受渲染结果的缓存区叫做帧缓存。(frame buffer object)
像素颜色缓存:帧缓存会保存OpenGL ES的渲染结果,因此为了渲染到一个CoreAnimation层上,程序需要一个连接到某个层的帧缓存。简言之,每个程序用足够的内存配置一个层来保存像素颜色数据。帧缓存可以配置多个叫做渲染缓存的缓存来接受多种类型的输出。与层分享数据的帧缓存必须要有一个像素颜色渲染缓存。其他缓存是可选的。
这里的概念可能有点模糊。没关系。接下来看。相信你会懂得。
三·Rendering to a Core Animation Layer(渲染到CoreAnimation层)
Core Animation是iOS上图形渲染和动画的中央基础架构。 您可以使用承载使用不同iOS子系统呈现的内容的图层(例如UIKit,Quartz 2D和OpenGL ES)来构建应用程序的用户界面或其他可视化显示。 OpenGL ES通过CAEAGLLayer类连接到Core Animation,这是一种特殊类型的Core Animation层,其内容来自OpenGL ES渲染缓冲区。Core Animation将renderbuffer(渲染缓存)的内容与其他图层合成,并在屏幕上显示生成的图像。
CAEAGLLayer通过提供两个关键的功能为OpenGL ES提供这种支持:
1.为renderbuffer分配共享存储。
2.它将渲染缓冲区呈现给Core Animation,用渲染缓冲区的数据替换图层的先前内容。
这个模型的优点是核心动画层的内容不需要在每个帧中绘制,只有当渲染的图像改变时。
四·代码解释
0.创建一个OpenGLESView,继承UIView,通过重写OpenGLESView的 + (Class)layerClass 方法来返回一个CAEAGLLayer实例
+ (Class)layerClass {
return [CAEAGLLayer class];
}
1.创建上下文,并设置当前上下文为我们创建的上下文
//创建上下文
EAGLContext *context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
// 设置当前上下文为我们创建的上下文
[EAGLContext setCurrentContext:_context];
2.创建CAEAGLLayer对象并配置其属性。
为了获得最佳性能,请将图层的opaque属性的值设置为YES。
CAEAGLLayer *_eagllayer;
_eagllayer = (CAEAGLLayer *)self.layer;
_eagllayer.opaque = YES;
//设置描述属性
//kEAGLDrawablePropertyRetainedBacking保留背景,NO表示在屏幕上显示绘制整个内容
//kEAGLColorFormatRGBA8告诉coreAnimation用8位来保存层内的每个像素的每个颜色元素的值
_eagllayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO],kEAGLDrawablePropertyRetainedBacking,
kEAGLColorFormatRGBA8,
kEAGLDrawablePropertyColorFormat, nil];
3.创建并绑定一个 帧缓存(frame buffer object)
GLuint _framebuffer; //缓存标识符
glGenFramebuffers(1,&_framebuffer); //第一个参数:指定要生成的缓存标识符的数量,第二个参数:是一个指针,指向生成的标识符的内存保存位置
glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); //把新创建的帧缓冲(_framebuffer)绑定到GL_FRAMEBUFFER目标上
4.创建并绑定一个 像素颜色渲染缓存,跟创建帧缓存差不多
GLuint _colorRenderbuffer;
glGenRenderbuffers(1,&_colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER,_colorRenderbuffer); //将_colorRenderbuffer绑定到GL_RENDERBUFFER目标上
5.上面我们已经创建了一个像素颜色渲染缓存(_colorRenderbuffer),通过调用是上下文的renderbufferStorage:fromDrawable:方法并传递图层对象作为参数来分配它的存储。 宽度,高度和像素格式取自图层,用于为_colorRenderbuffer分配存储空间
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eagllayer];
5.将像素颜色渲染缓存附加到帧缓冲的颜色附件点上
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer);
6.清屏操作
glClearColor(0.0f,0.0f,0.0f,1.0f) //指定清屏的颜色,你可以认为是设置背景颜色
//用指定的清屏颜色来清除由mask指定的buffer
//mask 可以是 GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT的自由组合。
glClear(mask);
7.将结果呈现给CoreAnimation
将_colorRenderbuffer绑定到上下文并呈现它。 这使得完成的帧被交给核心动画。
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];
8.清理缓存
glDeleteFramebuffers(1, &_frameBuffer);
_frameBuffer =0;
glDeleteRenderbuffers(1, &_colorRenderbuffer);
_colorRenderbuffer =0;
到这里,我们通过自定义图层CAEAGLLayer来实现了渲染。我们看下效果图。
GLKit框架是为了简化iOS上OpenGL ES的开发,同样的实现上面相同的效果,GLKit只需要寥寥几句就可以完成。。
1.导入GLKit框架,创建一个GLKitController继承 GLKViewController,
2.设置GLKView的上下文,GLKView是Cocoa Touch UIView类的内建子类。GLKView简化了通过用CoreAnimation层来自动创建并管理帧缓存和渲染缓存共享内存所需要做的工作
GLKView *view = (GLKView *)self.view;
view.context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:view.context];
3.指定清屏颜色
glClearColor(0.5f, 0.5f, 1.0f, 1.0f);
4.实现- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect代理,实现渲染。
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
glClear(GL_COLOR_BUFFER_BIT);
}
到此。结束。运行。一样的效果。
参考文献
《苹果开发文档》
《OpenGL ES应用开发实践指南》
http://blog.csdn.net/icetime17/article/details/50429658
http://www.jianshu.com/p/750fde1d8b6a
网友评论