iOS上绘制图形的方式很多,UIKit
,CoreGraphics
,SpriteKit
,OpenGL ES
,Metal
等可以绘制图形。这里是OpenGL ES
的零基础入门学习。
OpenGL ES
是一套非常底层但使用非常广泛的C语言
API,专为移动设备定制,可在不同的手机系统或浏览器上使用,渲染效果非常好非常流畅。
开始创建窗口的学习,本章的学习目标是用OpenGL ES 渲染一个窗口。
- 1.创建一个完整的openGL ES代码过程
- 2.渲染一个窗口
第一步,创建一个Single View Application工程
第二步,创建UIView的子类MyOpenGLView。
第三步,先导入OpenGLES.framework
和GLKit.framework
两个库,并在MyOpenGLView引入OpenGL ES头文件GLKit。
第四步,配置OpenGL ES渲染的上下文EAGLContext
EAGLContext
An EAGLContext object manages an OpenGL ES rendering context—the state information, commands, and resources needed to draw using OpenGL ES. To execute OpenGL ES commands, you need a current rendering context.
Drawing resources, such as textures and renderbuffers, are managed for the EAGLContext object by an EAGLSharegroup object associated with the context. When you initialize a new EAGLContext object, you can choose to have it create a new sharegroup, or you can use one obtained from a previously created context.
Before drawing to a context, you must bind a complete framebuffer object to the context. For more information on configuring rendering contexts.
EAGLContext对象管理着OpenGLES的渲染context,即所有绘制的状态,命令及资源信息,并控制GPU去执行渲染运算。
绘制如textures及renderbuffers的过程,是由一个与context绑定的EAGLSharegroup对象来管理的。当初始化一个EAGLContext对象的时候,可选择新建一个sharegroup,或者使用已有的,这一点我们往往采用系统默认即可。在绘制到context之前,我们要先绑定一个完整的framebuffer对象到context中。
1.设置上下文 (set up context)
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
if (!context)
{
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
}
if (![EAGLContext setCurrentContext:context])
{
NSLog(@"setting currentContext faile");
return;
}
必须在CAEAGLLayer上才能绘制OpenGLES内容。
2.渲染的图层layer(rendering layer)
CAEAGLLayer *layer = (CAEAGLLayer *)self.layer;
layer.opaque = YES;// CALayer 默认是透明的,必须将它设为不透明才能让其可见
layer.contentsScale = [UIScreen mainScreen].scale;// 设备的分辨率
如果在viewController
中,使用[self.view.layer addSublayer:layer];
添加在当前view的图层中即可。
不过我们现在创建的是了UIView的子类MyOpenGLView,所以直接重写UIView
的+layerClass
类方法即可
+ (Class)layerClass
{
return [CAEAGLLayer class];
}
第五步,配置渲染缓冲区(Render Buffer)
渲染缓冲区类似一个平面,用于保存绘制内容,并使用某种数据类型加以填充,比如颜色值。我们在此创建的是颜色缓冲区,用以保存所绘制的颜色信息,缓冲区大小由CAEAGLLayer
的bounds中size指定,这在处理屏幕旋转时是个非常重要的条件。通常,屏幕发生旋转时,屏幕的宽高值互换,故需要重新创建帧缓冲区等内容,后续文档将详细讨论此问题。OpenGL ES
有Frame buffer
、Render buffer
、Data buffer
等类型的缓冲区,它们的作用各不相同。
3.配置渲染缓冲区 (Configurate render buffer)
GLuint renderBuffer;
//创建一个渲染缓冲区对象
glGenRenderbuffers(1, &renderBuffer);
//将该渲染缓冲区对象绑定到管线上
glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
//在绑定好渲染缓冲区后,通知EAGLContext让CAEAGLLayer实例中分配存储空间,用以保存后续绘制的内容
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];
renderBuffer
对象本身不能直接使用,不能挂载到GPU上而直接输出内容的,要使用frameBuffer
。
第六步,配置帧缓冲区(Frame Buffer)
4.配置帧缓冲区 (configurate frame buffer)
GLuint frameBuffer;
//创建一个帧染缓冲区对象
glGenFramebuffers(1, &frameBuffer);
//将该帧染缓冲区对象绑定到管线上
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
//将创建的渲染缓冲区绑定到帧缓冲区上,并使用颜色填充
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, frameBuffer);
先设置renderbuffer,然后设置framebuffer,顺序不能互换。
第七步,配置清屏颜色(glClearColor)
5.配置清空屏幕所用的颜色 (configurate clear buffer color)
glClearColor(1.0, 0.0, 0.0, 1.0);
// 用来指定要用清屏颜色来清除由mask指定的buffer,此处是color buffer
glClear(GL_COLOR_BUFFER_BIT);
// 将指定renderBuffer渲染在屏幕上
[context presentRenderbuffer:GL_RENDERBUFFER];
完成上面七个步骤后,我们就可以渲染出一个红色的屏幕,如下图所示
重要代码如下:
本文源码可以在这里获得:https://github.com/476455183/OpenGLES