前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS开发-OpenGL ES入门教程1

iOS开发-OpenGL ES入门教程1

作者头像
落影
发布2018-04-27 14:50:53
1.3K0
发布2018-04-27 14:50:53
举报
文章被收录于专栏:落影的专栏落影的专栏

前言

这里是一篇新手教程,环境是Xcode7+OpenGL ES 2.0,目标写一个OpenGL ES的hello world。 OpenGL ES系列教程在这里。 OpenGL ES系列教程的代码地址

你的star和fork是我的源动力,你的意见能让我走得更远

核心思路

通过GLKit,尽量简单地实现把一张图片绘制到屏幕。

效果展示

具体细节

1、新建OpenGL ES上下文
代码语言:javascript
复制
- (void)setupConfig {
    //新建OpenGLES 上下文
    self.mContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; //2.0,还有1.0和3.0
    GLKView* view = (GLKView *)self.view; //storyboard记得添加
    view.context = self.mContext;
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;  //颜色缓冲区格式
    [EAGLContext setCurrentContext:self.mContext];
}

GLKView* view = (GLKView *)self.view;这里需要在storyboard里面把view的类设置成GLKView,其他代码是OpenGL ES上下文的创建。

2、顶点数组和索引数组
代码语言:javascript
复制
//顶点数据,前三个是顶点坐标,后面两个是纹理坐标
    GLfloat squareVertexData[] =
    {
        0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
        0.5, 0.5, -0.0f,    1.0f, 1.0f, //右上
        -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
        
        0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
        -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
        -0.5, -0.5, 0.0f,   0.0f, 0.0f, //左下
    };

顶点数组里包括顶点坐标,OpenGLES的世界坐标系是[-1, 1],故而点(0, 0)是在屏幕的正中间。 纹理坐标系的取值范围是[0, 1],原点是在左下角。故而点(0, 0)在左下角,点(1, 1)在右上角。 索引数组是顶点数组的索引,把squareVertexData数组看成4个顶点,每个顶点会有5个GLfloat数据,索引从0开始。

3、顶点数据缓存
代码语言:javascript
复制
    //顶点数据缓存
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(GLKVertexAttribPosition); //顶点数据缓存
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0); //纹理
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);

这是本章节的核心内容

  • glGenBuffers申请一个标识符
  • glBindBuffer把标识符绑定到GL_ARRAY_BUFFER
  • glBufferData把顶点数据从cpu内存复制到gpu内存
  • glEnableVertexAttribArray 是开启对应的顶点属性
  • glVertexAttribPointer设置合适的格式从buffer里面读取数据
4、纹理贴图
代码语言:javascript
复制
- (void)uploadTexture {
    //纹理贴图
    NSString* filePath = [[NSBundle mainBundle] pathForResource:@"for_test" ofType:@"jpg"];
    NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft, nil];//GLKTextureLoaderOriginBottomLeft 纹理坐标系是相反的
    GLKTextureInfo* textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
    //着色器
    self.mEffect = [[GLKBaseEffect alloc] init];
    self.mEffect.texture2d0.enabled = GL_TRUE;
    self.mEffect.texture2d0.name = textureInfo.name;
}
  • GLKTextureLoader读取图片,创建纹理GLKTextureInfo
  • 创建着色器GLKBaseEffect,把纹理赋值给着色器

基础

代码带了很多注释,百度下相应的概念,会有更多解释。 如果对OpengGL ES感兴趣,但是却毫无图形学基础的,可以看看LearnOpenGL教程

思考题

  • 1、代码中有6个顶点坐标,能否使用更少的顶点显示一个图像?
  • 2、顶点缓存数组可以不用glBufferData,要如何实现?
  • 3、如果把这个图变成左右两只对称的熊猫,该如何改?

这里可以下载demo代码。

思考题答案

思考题1: 可以使用四个顶点,绘制2个三角形 的6个顶点中有2个是重复的,使用索引可以减少重复。

思考题2: 顶点缓存数组可以不用glBufferData,要如何实现?顶点数组可以通过glBufferData放入缓存,也可以直接通过glVertexAttribPointer最后一个参数,直接把顶点数组从CPU传送到GPU。区别:glBufferData里面的顶点缓存可以复用,glVertexAttribPointer是每次都会把顶点数组从CPU发送到GPU,影响性能。

思考题3: 如果把这个图变成左右两只对称的熊猫,该如何改?把屏幕切分成4个三角形,左边两个三角形同上,右边两个三角形的纹理坐标的x值调整即可。

一个热血青年想在业余时间做更多的尝试,做一些能帮助别人也能受惠自己的事情。 思来想去,决定延续现在写文章的思路——用自己的经历和知识给职场填坑,让人少走弯路。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.03.25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 核心思路
  • 效果展示
  • 具体细节
    • 1、新建OpenGL ES上下文
      • 2、顶点数组和索引数组
        • 3、顶点数据缓存
          • 4、纹理贴图
          • 基础
          • 思考题
          • 思考题答案
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档