OpenGL

在开始我们的学习之旅之前首先定义下什么是OpenGL。OpenGL主要被认为是一个API(anApplication Programming Interface:应用程序编程接口),它为我们提供了大量的功能,我们可以使用它来处理图形和图像。然而,OpenGL本身并不是一个API,只是一个规范,由Khronos组织开发和维护。
GLKViewController:UIViewController的子类,接收当视图需要重绘时的消息
GLKView:UIView的子类,简化了通过用Core Animation层来自动创建并管理帧缓存和渲染缓存共享内存所需要做的工作。
创建OpenGL ES上下文
创建一个GLKViewController,在ViewdidLoad生命周期中:

GLKView *view= (GLKView *)self.view; //创建OpenGL ES2.0上下文 view.context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2]; //设置当前上下文 [EAGLContext setCurrentContext:view.context];

声明一个GLKBaseEffect属性
@property (nonatomic,strong)GLKBaseEffect *baseEffect;

并且在ViewDidLoad实例化
self.baseEffect = [[GLKBaseEffect alloc]init]; //使用静态颜色绘制 self.baseEffect.useConstantColor = GL_TRUE; //设置默认绘制颜色,参数分别是 RGBA self.baseEffect.constantColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f); //设置背景色为黑色 glClearColor(0.0f,0.0f,0.0f,1.0f);

我们需要绘制一个三角形自然需要三个顶点,OpenGL ES采用的笛卡尔坐标系
//顶点结构体 typedef struct{ GLKVector3 positionCoords; }sceneVertex; //三角形的三个顶点 static const sceneVertex vertices[] = { {{-0.5f,-0.5f,0.0}}, {{0.5f,-0.5f,0.0}}, {{-0.5f,0.5f,0.0}}, };

  1. 生成缓存并且为缓存提供数据,这是最重要的一步
//声明缓存ID属性 @property (nonatomic,assign)GLuint *vertextBufferID;

//viewdidload中生成并绑定缓存数据 glGenBuffers(1, &vertextBufferID); glBindBuffer(GL_ARRAY_BUFFER, vertextBufferID); //绑定指定标识符的缓存为当前缓存 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  • glGenBuffers申请一个标识符
  • glBindBuffer 将标识符绑定到GL_ARRAY_BUFFER
  • glBufferData复制顶点数据从CPU到GPU
接下来在GLKViewController的
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
代理方法中
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{ [self.baseEffect prepareToDraw]; //Clear Frame Buffer glClear(GL_COLOR_BUFFER_BIT); //开启缓存 glEnableVertexAttribArray(GLKVertexAttribPosition); //设置缓存数据指针 glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, //小数点固定数据是否被改变 sizeof(sceneVertex), NULL); //从开始位置 //绘图 glDrawArrays(GL_TRIANGLES, 0, 3); }

  • glEnableVertexAttribArray 开启对应的顶点缓存属性
  • glVertexAttribPointer 设置指针从顶点数组中读取数据
  • glDrawArrays 绘制图形
  1. 释放缓存数据
    在dealloc方法中释放掉缓存数据
- (void)dealloc{ GLKView *view = (GLKView *)self.view; [EAGLContext setCurrentContext:view.context]; if ( 0 != vertextBufferID) { glDeleteBuffers(1, &vertextBufferID); vertextBufferID = 0; } }

【OpenGL】最后的运行结果图如下
[图片上传失败...(image-9af797-1523929667421)]
拓展小问题:1. 如何将背景色改成红色 2. 如何将三角形颜色改成黑色,而不是现在的白色
  • (void)glkView:(GLKView *)view drawInRect:(CGRect)rect是GLKViewController系统给我们回调的绘制消息,该方法会一直被调用,和display方法一致
EAGLContext上下文本质上是个状态机,只有在当前上下文下,Opengl ES API调用才会生效
链接:https://www.jianshu.com/p/9c002f2583f6

    推荐阅读