发布时间:2025-12-09 11:56:57 浏览次数:2
OpenGLES入门教程1-Tutorial01-GLKit OpenGLES入门教程2-Tutorial02-shader入门 OpenGLES入门教程3-Tutorial03-三维变换 OpenGLES入门教程4-Tutorial04-GLKit进阶 这一次是进阶教程。
代码参考自这本书
OpenGL ES应用开发实践指南 iOS卷
地球和月亮
通过AGLKVertexAttribArrayBuffer类管理顶点数组,*** sphere.h获取地球和月亮的顶点、法线、纹理坐标,用矩阵栈操作矩阵,通过正视投影变换和透视投影变换***进行投影。
AGLKElementIndexArrayBuffer是顶点缓存管理类 GLsizeiptr 类型就是long GLsizei 类型是int32_t
- (id)initWithAttribStride:(GLsizeiptr)aStride numberOfVertices:(GLsizei)count bytes:(const GLvoid *)dataPtr usage:(GLenum)usage; - (void)reinitWithAttribStride:(GLsizeiptr)aStride numberOfVertices:(GLsizei)count bytes:(const GLvoid *)dataPtr;glVertexAttribPointer 设置顶点数据- (void)prepareToDrawWithAttrib:(GLuint)index numberOfCoordinates:(GLint)count attribOffset:(GLsizeiptr)offset shouldEnable:(BOOL)shouldEnable+ (void)drawPreparedArraysWithMode:(GLenum)mode startVertexIndex:(GLint)first numberOfVertices:(GLsizei)count;球体的顶点坐标数组、法线数组、纹理坐标数组,直接使用即可。
把矩阵MatrixA放入栈中缓存,然后对矩阵进行操作,得到新的矩阵MatrixB; 最后把矩阵出栈,可以得到原始矩阵MatrixA。 是对矩阵的缓存作用,在有矩阵有多个状态时很方便。 具体看下面矩阵数值的变化:
//地球- (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);}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); }透视投影的六个参数如下图
透视投影
投影是在近平面。(和视线焦点距离为near的是近平面,far的是远平面)
珍藏图-参悟投影变换的核心
这次的代码改自第五章第六个样例,可以学习作者的代码风格,功能分工。 附上源码