若文章讀完微服,請(qǐng)多練習(xí)文章里函數(shù)的寫法鄙才。
1.創(chuàng)建你的項(xiàng)目并新建MyGLView
2.修改你創(chuàng)建的MyGLView添加如下變量(變量后面會(huì)有介紹)
@interface MyGLView ()
{
CAEAGLLayer *_eaglLayer; //OpenGL內(nèi)容只會(huì)在此類layer上描繪
EAGLContext *_context; //OpenGL渲染上下文
GLuint _renderBuffer; //
GLuint _frameBuffer; //
}
3.在 MyGLView.m 中添加如下函數(shù):
+(Class)layerClass{
//OpenGL內(nèi)容只會(huì)在此類layer上描繪
return [CAEAGLLayer class];
}
因?yàn)镺penGLES的描繪必須在CAEAGLLayer上才能顯示出來,所以我們需要重寫這個(gè)函數(shù)择诈,修改view默認(rèn)的layer返回類型
4.設(shè)置_eaglLayer的屬性出皇,添加如下函數(shù):
- (void)setupLayer
{
_eaglLayer = (CAEAGLLayer*) self.layer;
// CALayer 默認(rèn)是透明的,透明對(duì)性能影響大荷科,設(shè)置為不透明對(duì)性能最好
_eaglLayer.opaque = YES;
// 設(shè)置描繪屬性纱注,在這里設(shè)置不維持渲染內(nèi)容以及顏色格式為 RGBA8
_eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
}
5.設(shè)置渲染上下文 _context 屬性狞贱,添加如下函數(shù):
- (void)setupContext {
// 指定 OpenGLES 渲染API的版本瞎嬉,在這里我們使用OpenGLES 3.0氧枣,由于3.0兼容2.0并且功能更強(qiáng)扎谎,為何不用更好的呢
//注:在iOS上,可以支持opengles3.0的最低環(huán)境是iphone5s ios7.0.
EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES3;
_context = [[EAGLContext alloc] initWithAPI:api];
if (!_context) {
NSLog(@"Failed to initialize OpenGLES 3.0 context");
}
// 設(shè)置為當(dāng)前上下文
[EAGLContext setCurrentContext:_context];
}
6.設(shè)置 _renderBuffer烧董,添加如下函數(shù):
-(void)setupRenderBuffer{
glGenRenderbuffers(1, &_renderBuffer); //
glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffer);
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];
}
7.設(shè)置 _frameBuffer,添加如下函數(shù):
-(void)setupFrameBuffer{
glGenFramebuffers(1, &_frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _renderBuffer);
}
8.buffer介紹
1). buffer分為frame buffer和render buffer兩大類,其中frame buffer相當(dāng)于render buffer的管理者,frame buffer object即稱為FBO,常用于做離屏渲染緩沖等廷粒。render buffer則又可分為三類坝茎,color buffer / depth buffer / stencil buffer思喊。
2). 生成frame buffer object的API函數(shù):
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
生成render buffer的API函數(shù)岳服,render buffer的生成函數(shù)是一樣的,buffer句柄類型只有在進(jìn)行分配buffer空間的時(shí)候才會(huì)確定:
glGenRenderbuffers(1, &renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
3). frame buffer僅僅是管理者纲辽,不需要分配空間腺劣;render buffer的存儲(chǔ)空間的分配,對(duì)于不同的render buffer芋酌,使用不同的API進(jìn)行分配,而只有分配空間的時(shí)候脐帝,render buffer句柄才確定其類型
(1). 最基本的是color buffer同云,調(diào)用EGALContext的OC方法為其分配空間
/* Attaches an EAGLDrawable as storage for the OpenGL ES renderbuffer object bound to <target> */
- (BOOL)renderbufferStorage:(NSUInteger)target fromDrawable:(id<EAGLDrawable>)drawable;
(2). 而depth buffer則可以直接調(diào)用openGL本身的API進(jìn)行分配
glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT16, width, height);
4). 上面(1)(2)函數(shù)是用于生成render buffer的存儲(chǔ)空間,生成空間之后堵腹,則需要將renderbuffer跟framebuffer進(jìn)行綁定炸站,調(diào)用glFramebufferRenderbuffer函數(shù)進(jìn)行綁定,后面的繪制才能起作用
5). 接下來可以調(diào)用OpenGL的函數(shù)進(jìn)行繪制處理疚顷,最后則需要調(diào)用EGALContext的OC方法進(jìn)行最終的渲染繪制旱易,這里渲染的是color buffer禁偎,這個(gè)方法會(huì)講buffer渲染到CALayer上面
- (BOOL)presentRenderbuffer:(NSUInteger)target;
6). 還有一個(gè)需要注意的地方是在退出的時(shí)候,需要調(diào)用glDelegateFramebuffers或者glDeleteRenderbuffers函數(shù)刪除frame
buffer或者render buffer
9.開始渲染阀坏,添加如下函數(shù):
-(void)render
{
//設(shè)置清屏顏色,默認(rèn)是黑色如暖,如果你的運(yùn)行結(jié)果是黑色,問題就可能在這兒
glClearColor(0.3, 0.5, 0.8, 1.0);
/*
glClear指定清除的buffer
共可設(shè)置三個(gè)選項(xiàng)GL_COLOR_BUFFER_BIT全释,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT
也可組合如:glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
這里我們只用了color buffer装处,所以只需清除GL_COLOR_BUFFER_BIT
*/
glClear(GL_COLOR_BUFFER_BIT);
[_context presentRenderbuffer:_renderBuffer];
}
10.重寫 initWithFrame 方法,并調(diào)用上述函數(shù):
-(instancetype)initWithFrame:(CGRect)frame{
if (self==[super initWithFrame:frame]) {
[self setupLayer];
[self setupContext];
[self setupRenderBuffer];
[self setupFrameBuffer];
[self render];
}
return self;
}
11.使用與運(yùn)行結(jié)果:
在你的ViewController中導(dǎo)入MyGLView頭文件并在viewDidLoad方法中添加如下代碼:
MyGLView *openGLView = [[MyGLView alloc]initWithFrame:self.view.bounds];
self.view = openGLView;
// [self.view addSubview:openGLView];
運(yùn)行結(jié)果如下:
接下來的文章會(huì)使用到OpenGLES的坐標(biāo)點(diǎn)浸船,這里先介紹下在OpenGL里,它的坐標(biāo)表現(xiàn):
它的x寝蹈、y李命、z的范圍都在-1到1之間,坐標(biāo)原點(diǎn)在圖中正方體的中心箫老。如圖畫的一個(gè)白色三角形封字,它的三個(gè)坐標(biāo)分別是:(-0.5,0.5,0.0)、(-0.5,-0.5,0.0)和(0.5,-0.5,0.0)耍鬓,請(qǐng)對(duì)著圖好好理解理解.
所有教程代碼在此 : https://github.com/qingmomo/iOS-OpenGLES-