update: 2012/06/25
reference:
1. Beginning OpenGL ES 2.0 with GLKit Part 2 | Ray Wenderlich
2. I touchs: OpenGL ES 2.0 with GLKit Part 1 - 2
GLKBaseEffect 介紹
A. 建立簡單的正方形頂點資料
1. 說明:
a. 正方形的頂點將被設置如下:
V0: 座標(1, -1), 顏色: 紅
V1: 座標(1, 1), 顏色: 綠
V2: 座標(-1, 1), 顏色: 藍
V3: 座標(-1, -1), 顏色: 黑
b. 在 OpenGL ES 中, 只能使用三角形來繪製幾何圖形, 所以我們可以利用
二個三角形來產生正方形, 如上圖所示: 一個三角形使用頂點 V0, V1, V2;
另一個三角形使用頂點 V2, V3, V0.
(說明: 你可以將頂點資料組成任何產生三角形的方式)
2. 開啟 HelloGLKitViewController.m 檔案, 修改如下:
#import "HelloGLKitViewController.h"
///////////////////////////////////////////////////////
//@start: add for vertex data */
// 用來儲存每個頂點的資訊: 位置(x,y,z), 顏色(r,g,b,a)
typedef struct {
float Position[3];
float Color[4];
} Vertex;
// 所有個別頂點的資訊:
// {位置1, 顏色1}, {位置2, 顏色2}, {位置3, 顏色3}, {位置4, 顏色4}
const Vertex Vertices[] = {
{{1, -1, 0}, {1, 0, 0, 1}},
{{1, 1, 0}, {0, 1, 0, 1}},
{{-1, 1, 0}, {0, 0, 1, 1}},
{{-1, -1, 0}, {0, 0, 0, 1}}
};
// 產生三角形的頂點索引:
//
// 每三個頂點組成一個三角形:
// 第一個三角形: 由頂點索引為 0, 1 與 2 所組成
// 第二個三角形: 由頂點索引為 2, 3 與 0 所組成
const GLubyte Indices[] = {
0, 1, 2,
2, 3, 0
};
//@ end: add for vertex data
///////////////////////////////////////////////////////
....
----------------------------------------------------------------------------------
B. 建立 Vertex Buffer Objects
1. 說明:
a. 要將頂點資料送至 OpenGL, 最佳方式是經由頂點緩衝區物件
(Vertex Buffer Objects).
b. 根本上來說, Vertex Buffer Objects 是一種 OpenGL 物件, 用來將頂點資料
儲存到緩衝區裡.
c. 有二種類型的 vertex buffer objects, 一種用來保存(追蹤)每個頂點的資料
(像之前的 Vertices 陣列); 另一種用來保存(追蹤)建立三角形的頂點索引
(像之前的 Indices 陣列).
2. 開啟 HelloGLKitViewController.h 檔案, 修改如下:
#import <GLKit/GLKit.h>
@interface HelloGLKitViewController : GLKViewController
{
}
//@add
- (void)setupGL;
- (void)tearDownGL;
@end
3. 開啟 HelloGLKitViewController.m 檔案, 修改如下:
....
// step 1:
@interface HelloGLKitViewController ()
{
//@add
float _curRed;
BOOL _increasing;
GLuint _vertexBuffer;
GLuint _indexBuffer;
}
....
// step 2:
//@add
- (void)setupGL
{
// Set the current OpenGL context to the current context.
[EAGLContext setCurrentContext:self.context];
// Create a new Vertex Buffer object
glGenBuffers(1, &_vertexBuffer);
// Bind vertexBuffer to GL_ARRAY_BUFFER
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
// send the data over to OpenGL-land.
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
}
....
// step 3:
//@add: delete the vertex and index buffers:
- (void)tearDownGL
{
[EAGLContext setCurrentContext:self.context];
glDeleteBuffers(1, &_vertexBuffer);
glDeleteBuffers(1, &_indexBuffer);
}
....
// step 4:
- (void)viewDidLoad
{
....
//@add
[self setupGL];
}
....
// step 5:
- (void)viewDidUnload
{
[super viewDidUnload];
//add
[self tearDownGL];
....
}
....
----------------------------------------------------------------------------------
C. GLKBaseEffect 介紹
1. 說明:
a. 在 OpenGL ES 2.0 中, 要在場景繪製出任何的幾何圖形, 必須要建立二個
稱為 shader 的微小程式.
註: shader 常翻譯為著色器, 對 Fragment(像素/片段) shader 而言還算吻合;
但是對於主要處理頂點位置的 vertex(頂點) shader 就不貼切了.
b. Shaders 以類似 C 語言的語法被寫成, 稱作 GLSL(OpenGL Shading Language),
有二種基本類型的 shaders: Vertex shader 與 Fragment shader.
c. Vertex shader:(頂點著色器)
在場景中的每個頂點都會呼叫一次 vertex shader 這個小程式. Vertex shader
的工作是去執行某些計算, 例如: 光源位置, 幾何轉換(位移, 旋轉, 縮放)等,
最後會算出每個頂點最終的位置, 並且傳遞一些資料給 fragment shader.
d. Fragment shader:(像素著色器)
同樣地, 在場景中的每個像素都會呼叫一次 fragment shader 這個小程式.
Fragment shader 最主要的工作是設定每個像素最終的顏色.
e. GLKBaseEffect 是一個輔助類別, 它為你實作了一些常用的 shaders.
GLKBaseEffect 的目的是: 提供大部份在 OpenGL ES 1.0 中可用的功能,
使 App 較容易從 OpenGL ES 1.0 轉成 OpenGL ES 2.0.
----------------------------------------------------------------------------------
D. GLKBaseEffect 的使用步驟
1. 建立一個 GLKBaseEffect
通常, 當你建立 OpenGL context 時, 就會建立其中一個 GLKBaseEffect. 你能夠
(並且應該) 對不同的幾何圖形再使用相同的 GLKBaseEffect, 並且只需重新設定
屬性. 在場景的背後, GLKBaseEffect 只會散佈對 shaders 有所改變的那些屬性.
2. 設定 GLKBaseEffect 屬性
你可以設定: 光源, 轉換(位移, 旋轉, 縮放), 以及其它 GLKBaseEffect 的 shaders
會用來繪製幾何圖形的屬性.
3. 在 GLKBaseEffect 上呼叫 prepareToDraw
任何時候, 你在 GLKBaseEffect 上更改一個屬性, 你需要先呼叫 prepareToDraw
來讓 shaders 能正確地設定. 這也會賦予 GKBaseEffect 的 shaders 成為目前的
shader program.
4. 啟用 "預先定義好的" 的屬性
通常, 當你建好你自己的 shaders, 它們帶有稱為 attributes 的參數, 並且你可以
在 App 中寫程式碼來取得 attributes 參數的 IDs. 對 GLKBaseEffect 內建的
shaders 而言, 那些 attributes 參數是已經 "預先定義好的" 常數, 如:
GLKVertexAttribPosition 或 GLKVertexAttribColor. 所以你需要啟用任何想要
傳遞到 shaders 裡的參數, 並且將這些參數參照到資料.
5. 繪製你的幾何圖形
一旦你都設定好之後, 就可以使用標準的 OpenGL 繪圖指令, 如: glDrawArrays
或 glDrawElements, 它就會依照你設定的效果來繪製.
----------------------------------------------------------------------------------
E. 備註:
1. GLKBaseEffect 最棒的一件事就是: 如果你使用它們, 你就不需要寫任何的
shaders. 當然, 如果你想要也可以用混搭的方式: 用 GLKBaseEffect 來繪製
某些圖形; 再用你自己寫的 shaders 繪製另外的圖形. 如果你看看 OpenGL
的樣板專案, 就會看到這樣的例子.
2. 在這篇教學文章中, 會將焦點放在只使用 GLKBaseEffect, 因為主要的目的是
讓你能夠儘快的使用新的 GLKit 功能, 它是相當容易的.
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。