准备
首先复习一下为缓存提供数据的7个步骤,可以在第一篇笔记中查看,这里不再赘述。
iOS中使用OpenGL ES的框架为GLKit,Demo中会使用UIViewController的子类GLKViewController作为主控制器,将控制器的view转换为GLKView,这样可以省去设置GLKView代理等操作。
需要注意本例中直接使用默认新建的项目,需要在storyboard中修改ViewController中View的类型为GLKView,需要在ViewController.h中把父类改为GLKViewController。
示例概要:
准备三角形顶点数据数组
设置GLKView的上下文为当前的上下文
设置着色器属性
申请、绑定、缓存顶点数据
在代理方法中,准备绘图
着色器准备
清理
启用缓存顶点数据、设置指针、绘图
dealloc方法中删除缓存数据
示例解说
一、准备顶点数据数组
声明一个结构体保存一个顶点的数据
创建一个C数组保存三角形的3个顶点
/** 保存每个顶点的数据 */typedefstructvector{ GLKVector3 positionCoords;}SceneVertex;/** 保存三角形3个顶点的数据 */staticconstSceneVertex vertices[] = { {{-0.5, -0.5,0}}, {{0.5, -0.5,0}}, {{-0.5,0.5,0}}};
二、设置当前的上下文为view的上下文
/** 强转view为GLKView,需要在storyboard中也要修改 */GLKView *view = (GLKView *)self.view;/** 断言,判断view的类型 */NSAssert([view isMemberOfClass:[GLKView class]],@"View controller's view is not a GLKView");/** 创建一个OpenGL ES 2.0的上下文给view */view.context= [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];/** 将view的上下文设置为当前的上下文 */[EAGLContext setCurrentContext:view.context];
三、设置着色器,三角颜色及背景色
/** 为OpenGL ES 2.0创建一个默认的基本效果并提供给片元着色器程序,用于之后的绘图渲染 */_baseEffect = [[GLKBaseEffect alloc] init];_baseEffect.useConstantColor = GL_TRUE;_baseEffect.constantColor = GLKVector4Make(200.0,/** 红 */0.0,/** 绿 */0.0,/** 蓝 */1.f);/** alpha *//** 设置背景色,存储到当前的上下文中 */glClearColor(1.0,1.0,1.0,1.0);
四、申请、绑定、缓存
函数的参数说明已经在注释中写的非常详细了!
/** 申请、绑定并初始化一块缓存,将绘图信息保存到GPU的当中 *//** ①申请 */glGenBuffers(1,/** 指定要生成的缓存标识符的数量 */&vertexBufferID);/** 指针:缓存标识符的地址 *//** ②绑定 */glBindBuffer(GL_ARRAY_BUFFER,/** 绑定什么类型的缓存:顶点属性数组 */vertexBufferID);/** 需要绑定的缓存的标识符(标识符为0表示没有缓存,就不会绑定数据) *//** ③缓存数据 */glBufferData(GL_ARRAY_BUFFER,/** 初始化缓存信息 */sizeof(vertices),/** 缓存需要拷贝的大小 */vertices,/** 需要拷贝的数据:拷贝数据的地址 */GL_STATIC_DRAW);/** 提示:告诉上下文缓存适合放到GPU内存中,因为数据很少被更改,可以帮助OpenGL ES优化内存 */
五、开始绘图
当GLKView需要重新绘制时就会调用代理方法glkView:drawInRect:
在代理方法内,开始准备绘图工作
/** 准备绘制 */[_baseEffect prepareToDraw];/** 清理之前的绘图 */glClear(GL_COLOR_BUFFER_BIT);
启用顶点数据、设置指针、开始绘图
/** ④启用顶点数据 */glEnableVertexAttribArray(GLKVertexAttribPosition);/** ⑥设置指针:目的在于告诉OpenGL ES顶点数据在哪里以及解释每个顶点保存的数据 */glVertexAttribPointer(GLKVertexAttribPosition,/** 顶点数据 */3,/** 每个顶点包含3个数据 */GL_FLOAT,/** 顶点数据类型 */GL_FALSE,/** 固定点数据是否归一化或直接转固定值:不转换,直接使用float类型数据,可以帮助OpenGL ES优化内存 */sizeof(SceneVertex),/** 步幅:从一个顶点到另一个需要跨过多少字节,取单个顶点大小 */NULL);/** 告诉OpenGL ES可以从当前绑定的顶点缓存的开始位置访问顶点数据 */glDrawArrays(GL_TRIANGLES,/** 告诉GPU怎样渲染缓存内的顶点数据:渲染三角形 */0,/** 第一个需要渲染的顶点位置 */3);/** 渲染的顶点数量 */
六、最后的清理工作
在dealloc方法中清理缓存
/** 如果有缓存的情况下 */if(vertexBufferID !=0) {/** ⑦删除缓冲区数据 */glDeleteBuffers(1, &vertexBufferID);/** 将标识符设置为0 */vertexBufferID =0;}/** 将当前上下文设置nil */[EAGLContext setCurrentContext:nil];