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
7. I touchs: OpenGL ES 2.0 Tutorial Part 1 - 6
旋轉
A. 開啟 OpenGLView.h 檔案, 修改如下:
....
@interface OpenGLView : UIView
{
//@add
CAEAGLLayer *_eaglLayer;
EAGLContext *_context;
GLuint _colorRenderBuffer;
//@add
GLuint _positionSlot;
GLuint _colorSlot;
//@add for uniform
GLuint _projectionUniform;
GLuint _modelViewUniform;
//@add
float _currentRotation;
}
....
----------------------------------------------------------------------------------
B. 開啟 OpenGLView.m 檔案, 修改如下:
....
- (void)render:(CADisplayLink *)displayLink
{
....
//@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)];
//@add for rotation
//
// increment by 90 degrees every second
_currentRotation += displayLink.duration * 90;
//
// add a rotation to the model view matrix:
// The rotation is along both the x and y axis, and 0 along the z axis.
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, 0)];
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);
....
}
....
編譯並執行:
可以看到正方形(平面)以 3D 的方式翻轉.
----------------------------------------------------------------------------------
C. 3D 立方體
1. 開啟 OpenGLView.m 檔案, 修改如下:
// step01
....
// 所有個別頂點的資訊:
// {位置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 3D Cube
// 8 個頂點
const Vertex Vertices[] = {
{{1, -1, 0}, {1, 0, 0, 1}},
{{1, 1, 0}, {1, 0, 0, 1}},
{{-1, 1, 0}, {0, 1, 0, 1}},
{{-1, -1, 0}, {0, 1, 0, 1}},
{{1, -1, -1}, {1, 0, 0, 1}},
{{1, 1, -1}, {1, 0, 0, 1}},
{{-1, 1, -1}, {0, 1, 0, 1}},
{{-1, -1, -1}, {0, 1, 0, 1}}
};
....
// step02
// 產生三角形的頂點索引:
//
// 每三個頂點組成一個三角形:
// 第一個三角形: 由頂點索引為 0, 1 與 2 所組成
// 第二個三角形: 由頂點索引為 2, 3 與 0 所組成
/*
const GLubyte Indices[] = {
0, 1, 2,
2, 3, 0
};
*/
//@update for 3D Cube
// 6 個面
const GLubyte Indices[] = {
// Front
0, 1, 2,
2, 3, 0,
// Back
4, 6, 5,
4, 7, 6,
// Left
2, 7, 3,
7, 6, 2,
// Right
0, 4, 1,
4, 1, 5,
// Top
6, 2, 1,
1, 6, 5,
// Bottom
0, 3, 7,
0, 7, 4
};
....
2. 編譯並執行:
你可以看到立方體的內部, 這樣看起來不是很正確.
D. 啟動深度測試(depth testing)
1. 說明:
當啟動 depth testing, OpenGL 就可以對每個要繪製的 pixel 之 Z 軸
保持追蹤; 只有當該 pixel 前方沒有東西時, 才會繪製出這個 pixel.
2. 開啟 OpenGLView.h 檔案, 修改如下:
....
@interface OpenGLView : UIView
{
//@add
CAEAGLLayer *_eaglLayer;
EAGLContext *_context;
GLuint _colorRenderBuffer;
//@add
GLuint _positionSlot;
GLuint _colorSlot;
//@add for uniform
GLuint _projectionUniform;
GLuint _modelViewUniform;
//@add
float _currentRotation;
GLuint _depthRenderBuffer;
}
....
//@add
- (GLuint)compileShader:(NSString *)shaderName withType:(GLenum)shaderType;
- (void)compileShaders;
- (void)setupVBOs; // Creating Vertex Buffer Objects
- (void)setupDisplayLink;
- (void)setupDepthBuffer;
@end
3. 開啟 OpenGLView.m 檔案, 修改如下:
// step01
....
//@add
- (void)setupDepthBuffer
{
// creates a depth buffer
glGenRenderbuffers(1, &_depthRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
// alloacates the storage
//
// use glRenderbufferStorage not
// renderBufferStorage(special case for the color render buffer)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, self.frame.size.width, self.frame.size.height);
}
....
// step02
....
- (void)setupFrameBuffer
{
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// Attach the render buffer you created earlier to the frame buffer's GL_COLOR_ATTACHMENT0 slot.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, _colorRenderBuffer);
//@add: associate the new depth buffer with the render buffer.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
}
....
// step03
....
- (void)render:(CADisplayLink *)displayLink{
// Specify the RGB and alpha (transparency) values to use when clearing the screen.
//
//glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0); // 除法會降低效能
glClearColor(0.0, 0.4078, 0.2157, 1.0);
// Actually perform the clearing
//glClear(GL_COLOR_BUFFER_BIT);
//@update: clear the depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST); // enable depth testing
....
}
....}
// step04
....
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
//@add
[self setupLayer]; // Set layer to opaque(不透明)
[self setupContext]; // Create OpenGL context
//@add
[self setupDepthBuffer];
[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. 編譯並執行:
正常的旋轉立方體
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。