update: 2012/06/13
reference:
1. OpenGL ES 2.0 for iPhone Tutorial | Ray Wenderlich
2. I touchs: OpenGL ES 2.0 Tutorial Part 1 - 1
3. I touchs: OpenGL ES 2.0 Tutorial Part 1 - 2
4. I touchs: OpenGL ES 2.0 Tutorial Part 1 - 3
5. I touchs: OpenGL ES 2.0 Tutorial Part 1 - 4
6. I touchs: OpenGL ES 2.0 Tutorial Part 1 - 5
位移
A. 說明:
1. 矩陣轉換, 可以讓我們在空間中輕易地移動頂點, 以取代之前用手工的方式
在頂點陣列裡逐一修改頂點資料.
2. 到目前為止, 我們的 vertex shader 利用投影矩陣來更改每個頂點的位置, 我們
也可以使用一個稱為 "model-view" 的轉換, 來對物體作: 位移, 縮放與旋轉矩陣
的應用.
----------------------------------------------------------------------------------
B. 開啟 SimpleVertex.glsl 檔案, 修改如下:
attribute vec4 Position; attribute vec4 SourceColor;
varying vec4 DestinationColor;
uniform mat4 Projection;
//@add
uniform mat4 Modelview;
void main(void) {
DestinationColor = SourceColor;
//gl_Position = Projection * Position;
//@update: add applying the modelview matrix to the position.
gl_Position = Projection * Modelview * Position;
}
----------------------------------------------------------------------------------
C. 開啟 OpenGLView.h 檔案, 修改如下:
....@interface OpenGLView : UIView
{
//@add
CAEAGLLayer *_eaglLayer;
EAGLContext *_context;
GLuint _colorRenderBuffer;
//@add
GLuint _positionSlot;
GLuint _colorSlot;
//@add for uniform
GLuint _projectionUniform;
GLuint _modelViewUniform;
}
....
----------------------------------------------------------------------------------
D. 開啟 OpenGLView.m 檔案, 修改如下:
//step01....
- (void)compileShaders
{
....
//@add for projection (at bottom of compileShaders)
//
// get the handle we need to set the Projection input variable in the vertex shader.
_projectionUniform = glGetUniformLocation(programHandle, "Projection");
//@add for get the reference to the model view uniform input variable
_modelViewUniform = glGetUniformLocation(programHandle, "Modelview");
}
//step02
....
- (void)render
{
....
//@add for projection (before the call to glViewport)
//
// create a projection matrix
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
// pass data to the vertex shader
//
// glMatrix: converts them matrix into the array format OpenGL uses.
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
//@add for modelView transform (before the call to glViewport)
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
//
// CC3VectorMake: Returns a CC3Vector structure constructed
// from the vector components
//
// CC3Vector CC3VectorMake(GLfloat x, GLfloat y, GLfloat z);
//
// 說明:
// 1. 沿著 Z 軸的位移, 固定為 -7
// 2. 無沿著 Y 軸的位移
// 3. 沿著 X 軸的位移: (sin 的值介於 -1 ~ 1; 週期為 2π)
// 以每 3.14x2 秒為週期, 值介於 -1 ~ 1 之間.
[modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
//@add: draw our new vertex data to the screen
//
// 1. 設定要繪製在 UIView 上的範圍, 此處為畫到整個視窗上
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
....
}
//step03
....
// 所有個別頂點的資訊:
// {位置1, 顏色1}, {位置2, 顏色2}, {位置3, 顏色3}, {位置4, 顏色4}
//@update: Revert vertices back to z-value 0
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}}
};
/*
//@update for projection
//
// to fit within the near/far planes.
// This just sets the z-coordinate for each vertex to -7.
const Vertex Vertices[] = {
{{1, -1, -7}, {1, 0, 0, 1}},
{{1, 1, -7}, {0, 1, 0, 1}},
{{-1, 1, -7}, {0, 0, 1, 1}},
{{-1, -1, -7}, {0, 0, 0, 1}}
};
*/
編譯並執行:
說明: 由於只呼叫一次 render 方法, 因此物體不會移動.
----------------------------------------------------------------------------------
E. 同步 "繪製" 與 "顯示更新頻率"
1. 說明:
觀念上, 我們希望使用 OpenGL 來繪製的時間點與螢幕更新的頻率能夠
同步進行. 幸運地, Apple 提供了一個簡單的類別來處理: CADisplayLink .
參考: CADisplayLink Class Reference .
2. 開啟 OpenGLView.h 檔案, 修改如下:
....觀念上, 我們希望使用 OpenGL 來繪製的時間點與螢幕更新的頻率能夠
同步進行. 幸運地, Apple 提供了一個簡單的類別來處理: CADisplayLink .
參考: CADisplayLink Class Reference .
2. 開啟 OpenGLView.h 檔案, 修改如下:
//@add
- (void)setupLayer; // Set layer to opaque(不透明)
- (void)setupContext; // Create OpenGL context
- (void)setupRenderBuffer; // Create a render buffer
- (void)setupFrameBuffer; // Create a frame buffer
//- (void)render; // render something
//@update: Modify render method to take a parameter
- (void)render:(CADisplayLink *)displayLink;
//@add
- (GLuint)compileShader:(NSString *)shaderName withType:(GLenum)shaderType;
- (void)compileShaders;
- (void)setupVBOs; // Creating Vertex Buffer Objects
- (void)setupDisplayLink;
@end
3. 開啟 OpenGLView.m 檔案, 修改如下:
// step01
//@add: render something
//- (void)render
- (void)render:(CADisplayLink *)displayLink
{
....
}
....
// step02
//@add
- (void)setupDisplayLink
{
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
....
// step03
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
//@add
[self setupLayer]; // Set layer to opaque(不透明)
[self setupContext]; // Create OpenGL context
[self setupRenderBuffer]; // Create a render buffer
[self setupFrameBuffer]; // Create a frame buffer
//@add
[self compileShaders];
[self setupVBOs]; // Creating Vertex Buffer Objects
//[self render]; // render something
//@update
[self setupDisplayLink];
}
return self;
}
....
4. 編譯並執行:
說明: 使用 CADisplayLink, 每個影格都會呼叫 render: 方法, 因而更新了基於
目前時間點 sin() 函式的轉換, 所以物體會沿著 X 軸以 2π(2 x 3.14)秒
為週期, 在 -1 ~ 1 之間作位移.
目前時間點 sin() 函式的轉換, 所以物體會沿著 X 軸以 2π(2 x 3.14)秒
為週期, 在 -1 ~ 1 之間作位移.
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。