上一节中简单的介绍了下如何利用CAEAGLLayer和GLKit框架搭建简单的OpenGLES环境。
这一节中我们将利用GLKit框架绘制一个三角形。
流程
1.新建一个项目,在ViewController中导入GLKit框架,ViewController继承自GLKViewController。
2.在Main.Storyboard中将设置View的class为GLKView.
3.创建一个顶点缓存对象标识,绑定并分配内存 Vertex Buffer Object(VBO)
VBO:显卡存储空间里的一块缓存区(Buffer),用于记录顶点的信息,包括法线,问路坐标等,这个Buffer有它的名字(VBO的ID),OpenGL在GPU的某处记录着这个ID和对应的显存地址(或者地址偏移,类似内存)。
GLuint _vertexBufferID;
// 请求OpenGL ES为图形处理器控制的缓存生成一个独一无二的标识
glGenBuffers(1, &_vertexBufferID);
// 告诉OpenGL ES 为接下来的运算使用哪一个缓存。glBindBuffer只支持两种类型的缓存,GL_ARRAY_BUFFER // 和 GL_ELEMENT_ARRAY_BUFFER,
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID);
/**
让OpenGL ES为当前绑定的缓存分配并初始化足够的连续内存通常是从CPU控制的内存复制数据到GPU分配// 的内存)
第一个参数:用于指定要更新当前上下文中所绑定的是哪一个缓存
第二个参数:要复制进这个缓存的字节的数量
第三个参数:复制的字节的地址
第四个参数:提示了 缓存 在 未来的运算中可能将会被怎样使用
GL_STATIC_DRAW告诉上下文缓存中的内容适合复制到GPU控制的内存,因为很少对其进行修改,这个信息可以帮助OpenGL ES 优化内存使用。
GL_DYNAMIC_DRAW作为提示会告诉上下文,表示该缓存区会被周期性更改变,同时提示OpenGL ES 以不同的方式来处理缓存中的存储。
GL_STREAM_DRAW:表示该缓存区会被频繁更改;
*/
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs), vertexs, GL_STATIC_DRAW);
4.声明一个GLKBaseEffect 实例对象,并初始化属性。
GLKBaseEffect类提供了模拟OpenGL ES 1.1照明和阴影模型提供的许多行为的着色器,包括材质,照明和纹理。 基本效果允许最多三个光和两个纹理应用于场景。
GLKBaseEffect会生成直接在GPU上运行的Shading Language 程序。GLKBaseEffect是程序员专注于应用的功能和图形概念,而无需学习Shading Language。
@property (nonatomic, strong) GLKBaseEffect *baseEffect;
//初始化着色器
self.baseEffect = [[GLKBaseEffect alloc]init];
// 一个开关
self.baseEffect.useConstantColor = GL_TRUE;
// 设置三角形颜色
self.baseEffect.constantColor = GLKVector4Make(0.5f, 0.5f, 1.0f, 1.0f);
5.创建设置上下文
GLKView *view = (GLKView *)self.view;
// 设置view的上下文
view.context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
// 设置当前上下文
[EAGLContext setCurrentContext:view.context];
6.开始渲染
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
// 告诉baseEffect 准备好当前OpenGL ES 的上下文,以便为使用baseEffect生成的属性和Shading Language程序的绘图做好准备
[self.baseEffect prepareToDraw];
// 设置清屏颜色黑色,意思就是设置当前上下文的背景颜色
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 启动顶点缓存渲染操作
glEnableVertexAttribArray(GLKVertexAttribPosition);
/*
glVertexAttribPointer()函数告诉OpenGL ES 顶点数据在哪里,以及怎么解释为每个顶点保存的数据
第一个参数:当前绑定的缓存包含每个定点的位置信息
第二个参数:指示每个位置有3个部分
第三个参数:告诉OpenGL ES每个部分都保存为一个浮点类型的值
第四个参数:告诉OpenGL ES小数点固定数据是否可以被改变。
第五个参数:指定每个顶点的保存需要多少个字节
第六个参数:为NULL告诉OpenGL ES可以从当前绑定的顶点缓存的开始位置访问顶点数据
*/
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(TriangleScence), NULL);
/*
通过调用glDrawArrays()来执行绘图
第一个参数:告诉GPU怎么处理绑定的顶点缓存内的顶点数据,GL_TRIANGLES 三角形,
第二个参数:缓存内需要渲染的第一个顶点的位置
第三个参数:需要渲染的顶点的数量
*/
glDrawArrays(GL_TRIANGLES, 0, 3);
}
7.清理内存
- (void)viewDidDisappear:(BOOL)animated {
if (_vertexBufferID != 0) {
glDeleteBuffers(1, &_vertexBufferID);
_vertexBufferID = 0;
}
((GLKView *)self.view).context = nil;
[EAGLContext setCurrentContext:nil];
}
网友评论