001-OpenGL ES之绘制三角形

这里是OpenGL ES第一次上手, 文章的目的是实现绘制一个三角形

GLKView是一个使用OpenGL ES进行绘图的默认实现, GLKView简化了绘图的配置

实现一个绘图需要7个步骤
  1. 为缓存生成一个独
  2. 为接下来的运算绑
  3. 复制数组到缓存
  4. 启动
  5. 设置指针
  6. 绘图
    7)释放资源
//本例中使用的事从storyboard中加载, 所以需要把Main.storyboard的类关联到GLKViewController
@interface ViewController : GLKViewController
{
   GLuint vertexBufferID; //顶点数据缓存的标识符
}

//GLKBaseEffect是GLKit提供的一个内建类, GLKBaseEffect的存在是为了简化很多OpenGL ES 的常用操作, GLKBaseEffect隐藏了多个iOS版本对OpenGL ES支持的差异,  
@property (strong, nonatomic) GLKBaseEffect *baseEffect;

@end
//定义一个C语言的结构体SceneVertex, 用于保存GLKVector3数据, 顶点的坐标可以用一个起始于远点的矢量来表示
typedef struct {
   GLKVector3  positionCoords;
}SceneVertex;

//vertices变量是一个用顶点数据初始化的C语言的数组, 这个变量用于定义一个三角形
static const SceneVertex vertices[] =
{
   {{-0.5f, -0.5f, 0.0}}, 
   {{ 0.5f, -0.5f, 0.0}}, 
   {{-0.5f,  0.5f, 0.0}}  
};

OpenGL ES的坐标和UIView的坐标是不一样的, 下图展示的及时上面定义的三角形的坐标

屏幕快照 2017-07-03 下午1.59.36.png

设置OpenGL ES上线下文

- (void)setEGALContext {
   //创建一个GLKView
   GLKView *view = (GLKView *)self.view;
   NSAssert([view isKindOfClass:[GLKView class]],
            @"View controller's view is not a GLKView");
   
   //初始化EAGLContext上线文, 给GLKView绑定EAGL
   /**
    * kEAGLRenderingAPIOpenGLES2代表的事OpenGL ES 2.0
    */
   view.context = [[EAGLContext alloc]
                   initWithAPI:kEAGLRenderingAPIOpenGLES2];
   
   //给当前的OpenGL ES设置将会用到的上下文
   [EAGLContext setCurrentContext:view.context];

}

GLKBaseEffect提供了不依赖于所使用的OpenGL ES版本的控制OpenGL ES 渲染的方法
如果没有GLKBaseEffect和GLKit类, 完成这个简单的例子需要在OpenGL ES 2.0 的Shading Language编写一个小的GPU程序, GLKBaseEffect会在需要的时候自动创建GPU程序

- (void)setBaseEffect {
    self.baseEffect = [[GLKBaseEffect alloc] init];
    self.baseEffect.useConstantColor = GL_TRUE;
    //控制渲染颜色的方式有很多种, 下面是一个恒定的白色三角形, 使用一个保存颜色四个元素的结构体来设置恒定的颜色
    //颜色格式为RGBA
    GLKVector4 vector4 = GLKVector4Make(
                                        1.0f,
                                        1.0f,
                                        1.0f,
                                        1.0f);
    
    self.baseEffect.constantColor = vector4;

}

创建并使用一个用于保存顶点数据的顶点属性数组缓存, 主要用于CPU控制的内存与GPU控制的内存之间的数据交换的唯一标识符

   1) 为缓存生成一个独一无二的标识符
   2) 为接下来的运算绑定缓存
   3) 复制数组到缓存
- (void)setBufferData {    
    //glGenBuffers用于生成一个独一无二的标识符, 第一个参数指定要生成的缓存的数量为1, 第二个参数指向生成标识符的内存地址, 并保存. 当前情况下, 一个标识符被生成并保存在vertexBufferID实例变量中
    glGenBuffers(1,                // STEP 1
                 &vertexBufferID);
    
    //glBindBuffer函数用于绑定指定标识符的缓存到当前的缓存, OpenGL ES 保存不同类型的缓存到当前上下文的不同部位, 但是在同一时刻只能绑定一个缓存
    //第一个参数是一个常亮, 用于指定缓存的类型, GL_ARRAY_BUFFER类型用于指定一个顶点属性数组, 三角形就是属于这种类型, 第二个参数是要绑定的标识符
    glBindBuffer(GL_ARRAY_BUFFER,  // STEP 2
                 vertexBufferID);
    
    //glBufferData函数复制应用的顶点数据到当前上下文绑定顶点的缓存中
    glBufferData(                  // STEP 3
                 GL_ARRAY_BUFFER,  // 指定当前上下文所绑定的是哪一个缓存
                 sizeof(vertices), // 复制到这个缓存的字节数
                 vertices,         // 要复制的字节的地址
                 GL_STATIC_DRAW);  // 提示缓存在未来会被怎样的使用, GL_STATIC_DRAW会提示上下文缓存中的内容适合复制到GPU控制的内存, 对其很少修改, 这个信息会提示OpenGL ES来优化内存使用
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self setEGALContext];
    
    [self setBaseEffect];
    
    //glClearColor函数用于设置当前上下文的清除颜色, 由RGBA组成, 用于在上下文的帧缓存被清除时初始化每个像素的颜色值
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // background color
    
    [self setBufferData];
}

所有的配置结束之后, 下面开始执行绘图
GLKViewControllerDelegate的代理在配置工作完成之后会自动执行绘图

  • (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
//该方法是GLKView的委托方法, 实现该方法就意味着要告诉GLKBaseEffect去准备号OpenGL ES上下文
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
 {
     [self.baseEffect prepareToDraw];
     
     //清除之前设置的值, 使用glClearColor设置的值
     //注意:  该glClear功能提示OpenGL ES可以丢弃任何现有的帧缓冲区内容,避免了将先前内容加载到内存中的昂贵的内存操作。为确保最佳性能,您应该在绘制之前始终调用此函数。
     glClear(GL_COLOR_BUFFER_BIT);
     
     /**
      * 4) 启动
      * 5) 设置指针
      * 6) 绘图
      */
     //该方法用于启动顶点缓存的渲染操作,
     glEnableVertexAttribArray(      // STEP 4
                               GLKVertexAttribPosition);
     
     //该方法会告诉OpenGL ES 顶点数据在哪里. 以及怎么解释顶点数据,
     glVertexAttribPointer(          // STEP 5
                           GLKVertexAttribPosition,  //当前绑定的缓存包含每个顶点的位置信息
                           3,                   // 每个顶点位置有几个部分
                           GL_FLOAT,            // 告诉OpenGL ES 每个顶点位置都为一个浮点类型的值
                           GL_FALSE,            // 告诉OpenGL ES 小数点固定数据是否可以被改变
                           sizeof(SceneVertex), // 每个顶点的保存需要多少个字节
                           NULL);               // NULL 告诉 OpenGL ES 可以从当前绑定的顶点缓存的开始位置访问顶点数据
     
     
     //执行绘图
     // STEP 6
     glDrawArrays(GL_TRIANGLES, //告诉GPU 如何去处理绑定在顶点缓存内的顶点数据, 该参数是渲染一个三角形
                  0,  // 要渲染的第一个顶点的位置
                  3); // 要渲染的顶点的数量
 }

在我们不需要执行程序时, 别忘记释放资源

- (void)dealloc {
    //获取当前的GLKView
    GLKView *view = (GLKView *)self.view;
    [EAGLContext setCurrentContext:view.context];
    
    /**
     * 7)释放资源
     */
    //删除不在需要的顶点缓存和上下文
    if (0 != vertexBufferID)
    {
        glDeleteBuffers (1,          // STEP 7
                         &vertexBufferID);
        vertexBufferID = 0; //设置为0避免在对应的缓存被删除之后存在未被使用的无效标识符
    }
    
    ((GLKView *)self.view).context = nil; //设置视图的上下文属性为nil
    [EAGLContext setCurrentContext:nil]; //设置当前上下文的属性为nil
    
}

运行之后的效果

Simulator Screen Shot 2017年7月3日 下午3.22.52.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容