教程
OpenGLES入門教程1-Tutorial01-GLKit
OpenGLES入門教程2-Tutorial02-shader入門
OpenGLES入門教程3-Tutorial03-三維變換
OpenGLES入門教程4-Tutorial04-GLKit進階
這一次是進階教程示姿。
代碼參考自這本書
OpenGL ES應用開發(fā)實踐指南 iOS卷
效果展示
核心思路
通過AGLKVertexAttribArrayBuffer類管理頂點數(shù)組威蕉,sphere.h獲取地球和月亮的頂點允坚、法線、紋理坐標,用矩陣棧操作矩陣,通過正視投影變換和透視投影變換進行投影淮阐。
具體細節(jié)
1蔓腐、AGLKElementIndexArrayBuffer類
AGLKElementIndexArrayBuffer是頂點緩存管理類
GLsizeiptr 類型就是long
GLsizei 類型是int32_t
核心函數(shù)
- 創(chuàng)建頂點緩存數(shù)組
- (id)initWithAttribStride:(GLsizeiptr)aStride
numberOfVertices:(GLsizei)count
bytes:(const GLvoid *)dataPtr
usage:(GLenum)usage;
- 重新緩存頂點數(shù)組
- (void)reinitWithAttribStride:(GLsizeiptr)aStride
numberOfVertices:(GLsizei)count
bytes:(const GLvoid *)dataPtr;
- 分配頂點數(shù)據(jù)
通過glVertexAttribPointer
設置頂點數(shù)據(jù)
- (void)prepareToDrawWithAttrib:(GLuint)index
numberOfCoordinates:(GLint)count
attribOffset:(GLsizeiptr)offset
shouldEnable:(BOOL)shouldEnable
- 繪制
+ (void)drawPreparedArraysWithMode:(GLenum)mode
startVertexIndex:(GLint)first
numberOfVertices:(GLsizei)count;
2矩乐、sphere.h球體
球體的頂點坐標數(shù)組、法線數(shù)組回论、紋理坐標數(shù)組散罕,直接使用即可。
3傀蓉、矩陣棧
把矩陣MatrixA放入棧中緩存欧漱,然后對矩陣進行操作,得到新的矩陣MatrixB葬燎;
最后把矩陣出棧误甚,可以得到原始矩陣MatrixA。
是對矩陣的緩存作用谱净,在有矩陣有多個狀態(tài)時很方便窑邦。
具體看下面矩陣數(shù)值的變化:
//地球
- (void)drawEarth
{
self.baseEffect.texture2d0.name = self.earthTextureInfo.name;
self.baseEffect.texture2d0.target = self.earthTextureInfo.target;
/*
current matrix:
1.000000 0.000000 0.000000 0.000000
0.000000 1.000000 0.000000 0.000000
0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 -5.000000 1.000000
*/
GLKMatrixStackPush(self.modelviewMatrixStack);
GLKMatrixStackRotate(
self.modelviewMatrixStack,
GLKMathDegreesToRadians(SceneEarthAxialTiltDeg),
1.0, 0.0, 0.0);
/*
current matrix:
1.000000 0.000000 0.000000 0.000000
0.000000 0.917060 0.398749 0.000000
0.000000 -0.398749 0.917060 0.000000
0.000000 0.000000 -5.000000 1.000000
*/
GLKMatrixStackRotate(
self.modelviewMatrixStack,
GLKMathDegreesToRadians(self.earthRotationAngleDegrees),
0.0, 1.0, 0.0);
/*
current matrix:
0.994522 0.041681 -0.095859 0.000000
0.000000 0.917060 0.398749 0.000000
0.104528 -0.396565 0.912036 0.000000
0.000000 0.000000 -5.000000 1.000000
*/
self.baseEffect.transform.modelviewMatrix =
GLKMatrixStackGetMatrix4(self.modelviewMatrixStack);
[self.baseEffect prepareToDraw];
[AGLKVertexAttribArrayBuffer
drawPreparedArraysWithMode:GL_TRIANGLES
startVertexIndex:0
numberOfVertices:sphereNumVerts];
/*
current matrix:
0.994522 0.041681 -0.095859 0.000000
0.000000 0.917060 0.398749 0.000000
0.104528 -0.396565 0.912036 0.000000
0.000000 0.000000 -5.000000 1.000000
*/
GLKMatrixStackPop(self.modelviewMatrixStack);
/*
current matrix:
1.000000 0.000000 0.000000 0.000000
0.000000 1.000000 0.000000 0.000000
0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 -5.000000 1.000000
*/
self.baseEffect.transform.modelviewMatrix =
GLKMatrixStackGetMatrix4(self.modelviewMatrixStack);
}
4、變換
GLKMatrix4MakeFrustum
是透視投影變換
GLKMatrix4MakeOrtho
是正視投影變換
if([aControl isOn])
{
self.baseEffect.transform.projectionMatrix =
GLKMatrix4MakeFrustum(
-1.0 * aspectRatio,
1.0 * aspectRatio,
-1.0,
1.0,
2.0,
120.0);
// self.baseEffect.transform.projectionMatrix =
// GLKMatrix4MakePerspective(1.0, aspectRatio, 1.0, 50.0);
}
else
{
self.baseEffect.transform.projectionMatrix =
GLKMatrix4MakeOrtho(
-1.0 * aspectRatio,
1.0 * aspectRatio,
-1.0,
1.0,
1.0,
120.0);
}
透視投影的六個參數(shù)如下圖
投影是在近平面壕探。(和視線焦點距離為near的是近平面奕翔,far的是遠平面)
總結
這次的代碼改自第五章第六個樣例,可以學習作者的代碼風格浩蓉,功能分工派继。
附上源碼