前言
本文是關(guān)于OpenGL ES的系統(tǒng)性學(xué)習(xí)過程,記錄了自己在學(xué)習(xí)OpenGL ES時(shí)的收獲。
這篇文章的目標(biāo)是搭建OpenGL ES開發(fā)環(huán)境。
環(huán)境是Xcode8.1+OpenGL ES 2.0
目前代碼已經(jīng)放到github上面,OpenGL ES入門01-OpenGL ES概述
歡迎關(guān)注我的 OpenGL ES入門專題
概述
OpenGL一般它被認(rèn)為是一個(gè)API(Application Programming Interface, 應(yīng)用程序編程接口),包含了一系列可以操作圖形、圖像的函數(shù)。然而,OpenGL本身并不是一個(gè)API,它僅僅是一個(gè)由Khronos組織制定并維護(hù)的規(guī)范(Specification)。OpenGL ES 是專門為手持設(shè)備制定的 3D 規(guī)范,它是 OpenGL 的簡化版。目前較新的 iOS 支持OpenGL ES 3.0。
效果概述

實(shí)現(xiàn)思路
1、建立項(xiàng)目,創(chuàng)建OpenGLESView;
2、初始化OpenGLES上下文;
3、創(chuàng)建幀緩存和渲染緩存,并進(jìn)行綁定;
4、清屏并進(jìn)行相關(guān)繪制;
5、清理緩存;
實(shí)現(xiàn)過程
1、建立項(xiàng)目,創(chuàng)建OpenGLESView
//
// OpenGLESView.m
// OpenGLES01-環(huán)境搭建
//
// Created by qinmin on 2017/2/9.
// Copyright ? 2017年 qinmin. All rights reserved.
//
#import "OpenGLESView.h"
@interface OpenGLESView ()
@end
@implementation OpenGLESView
@end
2、初始化OpenGLES上下文
- (void)setupContext
{
// 設(shè)置OpenGLES的版本為2.0 當(dāng)然還可以選擇1.0和最新的3.0的版本,以后我們會講到2.0與3.0的差異,目前為了兼容性選擇2.0的版本
_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!_context) {
NSLog(@"Failed to initialize OpenGLES 2.0 context");
exit(1);
}
// 將當(dāng)前上下文設(shè)置為我們創(chuàng)建的上下文
if (![EAGLContext setCurrentContext:_context]) {
NSLog(@"Failed to set current OpenGL context");
exit(1);
}
}```
3、創(chuàng)建幀緩存和渲染緩存,并進(jìn)行綁定
```OC
- (void)setupFrameAndRenderBuffer
{
glGenRenderbuffers(1, &_colorRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
// 為 color renderbuffer 分配存儲空間
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];
glGenFramebuffers(1, &_frameBuffer);
// 設(shè)置為當(dāng)前 framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
// 將 _colorRenderBuffer 裝配到 GL_COLOR_ATTACHMENT0 這個(gè)裝配點(diǎn)上
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, _colorRenderBuffer);
}
幀緩存:它是屏幕所顯示畫面的一個(gè)直接映象,又稱為位映射圖(Bit Map)或光柵。幀緩存的每一存儲單元對應(yīng)屏幕上的一個(gè)像素,整個(gè)幀緩存對應(yīng)一幀圖像。
渲染緩存:是OpenGLES管理的一處高效內(nèi)存區(qū)域,它可以儲存格式化的圖像數(shù)據(jù)。渲染緩存中的數(shù)據(jù)只有關(guān)聯(lián)到一個(gè)幀緩存對象才有意義,并且需要保正圖像緩存格式必須與OpenGLES要求的渲染格式相符(比如:不能將顏色值渲染到深度緩存中)。
幀緩存附件:
| 附件名稱 | 描述 |
|---|---|
| GL_COLOR_ATTACHMENT(0-i) | 第i個(gè)顏色緩存(0-GL_MAX_COLOR_ATTACHMENTS-1)0為默認(rèn)的顏色緩存 |
| GL_DEPTH_ATTACHMENT | 深度緩存 |
| GL_STENCIL_ATTACHMENT | 模板緩存 |
函數(shù):
- 分配n個(gè)未使用的幀緩存對象,并將它存儲到framebuffers中。
glGenFramebuffers (GLsizei n, GLuint* framebuffers)
- 設(shè)置一個(gè)可讀可寫的幀緩存。當(dāng)?shù)谝淮蝸斫壎硞€(gè)幀緩存的時(shí)候,它會分配這個(gè)對象的存儲空間并初始化,此后再調(diào)用這個(gè)函數(shù)的時(shí)候會將指定的幀緩存對象綁定為當(dāng)前的激活狀態(tài)。
glBindFramebuffer (GLenum target, GLuint framebuffer)
- 該函數(shù)是將相關(guān)的 buffer(三大buffer之一)attach到framebuffer上(如果 renderbuffer不為 0,知道前面為什么說glGenRenderbuffers 返回的id 不會為 0 吧)或從 framebuffer上detach(如果 renderbuffer為 0)。參數(shù) attachment 是指定 renderbuffer 被裝配到那個(gè)裝配點(diǎn)上,其值是GL_COLOR_ATTACHMENTi, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT中的一個(gè),分別對應(yīng) color,depth和 stencil三大buffer。
glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
- 判斷是否是程序生成的幀緩存對象,如果是返回GL_TRUE。如果為0或者未分配返回GL_FALSE。
glIsFramebuffer (GLuint framebuffer)
- 釋放幀緩存對象
glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers)
<br />
- 分配n個(gè)未使用的渲染緩存對象,并將它存儲到renderbuffers中。注意:返回的 id不會為0,0是OpenGL ES 保留的,我們也不能使用 id 為0的 renderbuffer。
glGenRenderbuffers (GLsizei n, GLuint* renderbuffers)
- 創(chuàng)建并綁定渲染緩存。當(dāng)?shù)谝淮蝸斫壎硞€(gè)渲染緩存的時(shí)候,它會分配這個(gè)對象的存儲空間并初始化,此后再調(diào)用這個(gè)函數(shù)的時(shí)候會將指定的渲染緩存對象綁定為當(dāng)前的激活狀態(tài)。
glBindRenderbuffer (GLenum target, GLuint renderbuffer)
- 為當(dāng)前綁定的渲染緩存對象分配圖像數(shù)據(jù)空間。在iOS中函數(shù)(- (BOOL)renderbufferStorage:(NSUInteger)target fromDrawable:(id<EAGLDrawable>)drawable)內(nèi)部是通過調(diào)用glRenderbufferStorage來分配圖像數(shù)據(jù)空間。
glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
- 判斷是否是程序生成的渲染緩存,如果是返回GL_TRUE。如果為0或者未分配返回GL_FALSE。
glIsRenderbuffer(GLuint renderbuffer)
- 釋放渲染緩存
glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers)
4、清屏并進(jìn)行相關(guān)繪制
- (void)render
{
glClearColor(1.0, 1.0, 0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
//將指定 renderbuffer 呈現(xiàn)在屏幕上,在這里我們指定的是前面已經(jīng)綁定為當(dāng)前 renderbuffer 的那個(gè),在renderbuffer可以被呈現(xiàn)之前,必須調(diào)用renderbufferStorage:fromDrawable: 為之分配存儲空間。
[_context presentRenderbuffer:GL_RENDERBUFFER];
}
- 用來設(shè)置清屏顏色,默認(rèn)為黑色;glClear (GLbitfieldmask)用來指定要用清屏顏色來清除由mask指定的buffer,mask 可以是 GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT的自由組合。
glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
5、清理緩存
- (void)destoryRenderAndFrameBuffer
{
glDeleteFramebuffers(1, &_frameBuffer);
_frameBuffer = 0;
glDeleteRenderbuffers(1, &_colorRenderBuffer);
_colorRenderBuffer = 0;
}
設(shè)備支持
iOS版本支持情況
| iOS版本 | OpenGL ES版本 |
|---|---|
| 2.x | 1.x |
| 3.0~6.x | 1.x 2.x |
| 7.0 | 1.x 2.x 3.x |
設(shè)備支持情況
| Compatibility | iPhone 7 | iPhone 7 Plus | iPhone 6s | iPhone 6s Plus | iPhone SE | iPhone 6 | iPhone 6 Plus | iPhone 5s | iPhone 5 | iPhone 5c | iPhone 4s | iPhone 4 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| opengles-1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| opengles-2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| opengles-3 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |