前言
本文是關(guān)于OpenGL ES的系統(tǒng)性學習過程,記錄了自己在學習OpenGL ES時的收獲。
這篇文章的目標是搭建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一般它被認為是一個API(Application Programming Interface, 應(yīng)用程序編程接口),包含了一系列可以操作圖形、圖像的函數(shù)。然而,OpenGL本身并不是一個API,它僅僅是一個由Khronos組織制定并維護的規(guī)范(Specification)。OpenGL ES 是專門為手持設(shè)備制定的 3D 規(guī)范,它是 OpenGL 的簡化版。目前較新的 iOS 支持OpenGL ES 3.0。
效果概述
實現(xiàn)思路
1、建立項目,創(chuàng)建OpenGLESView;
2、初始化OpenGLES上下文;
3、創(chuàng)建幀緩存和渲染緩存,并進行綁定;
4、清屏并進行相關(guān)繪制;
5、清理緩存;
實現(xiàn)過程
1、建立項目,創(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 當然還可以選擇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);
}
// 將當前上下文設(shè)置為我們創(chuàng)建的上下文
if (![EAGLContext setCurrentContext:_context]) {
NSLog(@"Failed to set current OpenGL context");
exit(1);
}
}```
3、創(chuàng)建幀緩存和渲染緩存,并進行綁定
```OC
- (void)setupFrameAndRenderBuffer
{
glGenRenderbuffers(1, &_colorRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
// 為 color renderbuffer 分配存儲空間
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];
glGenFramebuffers(1, &_frameBuffer);
// 設(shè)置為當前 framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
// 將 _colorRenderBuffer 裝配到 GL_COLOR_ATTACHMENT0 這個裝配點上
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, _colorRenderBuffer);
}
幀緩存:它是屏幕所顯示畫面的一個直接映象,又稱為位映射圖(Bit Map)或光柵。幀緩存的每一存儲單元對應(yīng)屏幕上的一個像素,整個幀緩存對應(yīng)一幀圖像。
渲染緩存:是OpenGLES管理的一處高效內(nèi)存區(qū)域,它可以儲存格式化的圖像數(shù)據(jù)。渲染緩存中的數(shù)據(jù)只有關(guān)聯(lián)到一個幀緩存對象才有意義,并且需要保正圖像緩存格式必須與OpenGLES要求的渲染格式相符(比如:不能將顏色值渲染到深度緩存中)。
幀緩存附件:
附件名稱 | 描述 |
---|---|
GL_COLOR_ATTACHMENT(0-i) | 第i個顏色緩存(0-GL_MAX_COLOR_ATTACHMENTS-1)0為默認的顏色緩存 |
GL_DEPTH_ATTACHMENT | 深度緩存 |
GL_STENCIL_ATTACHMENT | 模板緩存 |
函數(shù):
- 分配n個未使用的幀緩存對象,并將它存儲到framebuffers中。
glGenFramebuffers (GLsizei n, GLuint* framebuffers)
- 設(shè)置一個可讀可寫的幀緩存。當?shù)谝淮蝸斫壎硞€幀緩存的時候,它會分配這個對象的存儲空間并初始化,此后再調(diào)用這個函數(shù)的時候會將指定的幀緩存對象綁定為當前的激活狀態(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 被裝配到那個裝配點上,其值是GL_COLOR_ATTACHMENTi, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT中的一個,分別對應(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個未使用的渲染緩存對象,并將它存儲到renderbuffers中。注意:返回的 id不會為0,0是OpenGL ES 保留的,我們也不能使用 id 為0的 renderbuffer。
glGenRenderbuffers (GLsizei n, GLuint* renderbuffers)
- 創(chuàng)建并綁定渲染緩存。當?shù)谝淮蝸斫壎硞€渲染緩存的時候,它會分配這個對象的存儲空間并初始化,此后再調(diào)用這個函數(shù)的時候會將指定的渲染緩存對象綁定為當前的激活狀態(tài)。
glBindRenderbuffer (GLenum target, GLuint renderbuffer)
- 為當前綁定的渲染緩存對象分配圖像數(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、清屏并進行相關(guān)繪制
- (void)render
{
glClearColor(1.0, 1.0, 0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
//將指定 renderbuffer 呈現(xiàn)在屏幕上,在這里我們指定的是前面已經(jīng)綁定為當前 renderbuffer 的那個,在renderbuffer可以被呈現(xiàn)之前,必須調(diào)用renderbufferStorage:fromDrawable: 為之分配存儲空間。
[_context presentRenderbuffer:GL_RENDERBUFFER];
}
- 用來設(shè)置清屏顏色,默認為黑色;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 |