
示例最終效果
這篇筆記的關(guān)鍵在于對OpenGL ES繪圖7個步驟中的函數(shù)各個參數(shù)的的解讀,筆者之前看別人的文章被這些函數(shù)的參數(shù)弄的暈頭轉(zhuǎn)向,看了這本書之后終于理解透徹。
準(zhǔn)備
- 首先復(fù)習(xí)一下為緩存提供數(shù)據(jù)的7個步驟,可以在第一篇筆記中查看,這里不再贅述。
- iOS中使用OpenGL ES的框架為GLKit,Demo中會使用UIViewController的子類
GLKViewController作為主控制器,將控制器的view轉(zhuǎn)換為GLKView,這樣可以省去設(shè)置GLKView代理等操作。
需要注意本例中直接使用默認(rèn)新建的項目,需要在storyboard中修改ViewController中View的類型為GLKView,需要在ViewController.h中把父類改為GLKViewController。
- 示例概要:
- 準(zhǔn)備三角形頂點數(shù)據(jù)數(shù)組
- 設(shè)置GLKView的上下文為當(dāng)前的上下文
- 設(shè)置著色器屬性
- 申請、綁定、緩存頂點數(shù)據(jù)
- 在代理方法中,準(zhǔn)備繪圖
- 著色器準(zhǔn)備
- 清理
- 啟用緩存頂點數(shù)據(jù)、設(shè)置指針、繪圖
- dealloc方法中刪除緩存數(shù)據(jù)
示例解說
一、準(zhǔn)備頂點數(shù)據(jù)數(shù)組
- 聲明一個結(jié)構(gòu)體保存一個頂點的數(shù)據(jù)
- 創(chuàng)建一個C數(shù)組保存三角形的3個頂點
/** 保存每個頂點的數(shù)據(jù) */
typedef struct vector {
GLKVector3 positionCoords;
}SceneVertex;
/** 保存三角形3個頂點的數(shù)據(jù) */
static const SceneVertex vertices[] = {
{{-0.5, -0.5, 0}},
{{ 0.5, -0.5, 0}},
{{-0.5, 0.5, 0}}
};
二、設(shè)置當(dāng)前的上下文為view的上下文
/** 強轉(zhuǎn)view為GLKView,需要在storyboard中也要修改 */
GLKView *view = (GLKView *)self.view;
/** 斷言,判斷view的類型 */
NSAssert([view isMemberOfClass:[GLKView class]], @"View controller's view is not a GLKView");
/** 創(chuàng)建一個OpenGL ES 2.0的上下文給view */
view.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
/** 將view的上下文設(shè)置為當(dāng)前的上下文 */
[EAGLContext setCurrentContext:view.context];
三、設(shè)置著色器,三角顏色及背景色
/** 為OpenGL ES 2.0創(chuàng)建一個默認(rèn)的基本效果并提供給片元著色器程序,用于之后的繪圖渲染 */
_baseEffect = [[GLKBaseEffect alloc] init];
_baseEffect.useConstantColor = GL_TRUE;
_baseEffect.constantColor = GLKVector4Make(200.0, /** 紅 */
0.0, /** 綠 */
0.0, /** 藍 */
1.f); /** alpha */
/** 設(shè)置背景色,存儲到當(dāng)前的上下文中 */
glClearColor(1.0, 1.0, 1.0, 1.0);
四、申請、綁定、緩存
函數(shù)的參數(shù)說明已經(jīng)在注釋中寫的非常詳細了!
/** 申請、綁定并初始化一塊緩存,將繪圖信息保存到GPU的當(dāng)中 */
/** ①申請 */
glGenBuffers(1, /** 指定要生成的緩存標(biāo)識符的數(shù)量 */
&vertexBufferID); /** 指針:緩存標(biāo)識符的地址 */
/** ②綁定 */
glBindBuffer(GL_ARRAY_BUFFER, /** 綁定什么類型的緩存:頂點屬性數(shù)組 */
vertexBufferID); /** 需要綁定的緩存的標(biāo)識符(標(biāo)識符為0表示沒有緩存,就不會綁定數(shù)據(jù)) */
/** ③緩存數(shù)據(jù) */
glBufferData(GL_ARRAY_BUFFER, /** 初始化緩存信息 */
sizeof(vertices), /** 緩存需要拷貝的大小 */
vertices, /** 需要拷貝的數(shù)據(jù):拷貝數(shù)據(jù)的地址 */
GL_STATIC_DRAW); /** 提示:告訴上下文緩存適合放到GPU內(nèi)存中,因為數(shù)據(jù)很少被更改,可以幫助OpenGL ES優(yōu)化內(nèi)存 */
五、開始繪圖
當(dāng)GLKView需要重新繪制時就會調(diào)用代理方法
glkView:drawInRect:-
在代理方法內(nèi),開始準(zhǔn)備繪圖工作
/** 準(zhǔn)備繪制 */ [_baseEffect prepareToDraw]; /** 清理之前的繪圖 */ glClear(GL_COLOR_BUFFER_BIT); -
啟用頂點數(shù)據(jù)、設(shè)置指針、開始繪圖
/** ④啟用頂點數(shù)據(jù) */ glEnableVertexAttribArray(GLKVertexAttribPosition); /** ⑥設(shè)置指針:目的在于告訴OpenGL ES頂點數(shù)據(jù)在哪里以及解釋每個頂點保存的數(shù)據(jù) */ glVertexAttribPointer(GLKVertexAttribPosition, /** 頂點數(shù)據(jù) */ 3, /** 每個頂點包含3個數(shù)據(jù) */ GL_FLOAT, /** 頂點數(shù)據(jù)類型 */ GL_FALSE, /** 固定點數(shù)據(jù)是否歸一化或直接轉(zhuǎn)固定值:不轉(zhuǎn)換,直接使用float類型數(shù)據(jù),可以幫助OpenGL ES優(yōu)化內(nèi)存 */ sizeof(SceneVertex), /** 步幅:從一個頂點到另一個需要跨過多少字節(jié),取單個頂點大小 */ NULL); /** 告訴OpenGL ES可以從當(dāng)前綁定的頂點緩存的開始位置訪問頂點數(shù)據(jù) */ glDrawArrays(GL_TRIANGLES, /** 告訴GPU怎樣渲染緩存內(nèi)的頂點數(shù)據(jù):渲染三角形 */ 0, /** 第一個需要渲染的頂點位置 */ 3); /** 渲染的頂點數(shù)量 */
六、最后的清理工作
在dealloc方法中清理緩存
/** 如果有緩存的情況下 */
if (vertexBufferID != 0) {
/** ⑦刪除緩沖區(qū)數(shù)據(jù) */
glDeleteBuffers(1, &vertexBufferID);
/** 將標(biāo)識符設(shè)置為0 */
vertexBufferID = 0;
}
/** 將當(dāng)前上下文設(shè)置nil */
[EAGLContext setCurrentContext:nil];
小結(jié)
- 示例算是OpenGL ES中最簡單的,只是為了熟悉7個步驟而生,旨在熟悉基本的流程、函數(shù)及函數(shù)的各個參數(shù)。
- 代碼會在后續(xù)統(tǒng)一上傳到github,其實基本上都貼出來了,當(dāng)然有需要的可以自行下載。