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