iOS开发-OpenGL ES入门教程1

http://www.jianshu.com/p/750fde1d8b6a

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

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

核心思路

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

效果展示

具体细节

1、新建OpenGL ES上下文

- (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、顶点数组和索引数组

//顶点数据,前三个是顶点坐标,后面两个是纹理坐标
    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、顶点数据缓存

    //顶点数据缓存
    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、纹理贴图

- (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值调整即可。


作者:落影loyinglin链接:http://www.jianshu.com/p/750fde1d8b6a來源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
时间: 2024-10-02 01:56:38

iOS开发-OpenGL ES入门教程1的相关文章

iOS开发- OpenGL ES屏幕截图

之前写过一个常规的屏幕截图:http://blog.csdn.net/hitwhylz/article/details/17189351 可是发现这个办法对于OpenGL 无用.  获取到的数据为空. 所以这里介绍下OpenGL ES屏幕截图. 1.初始化. CAEAGLLayer *eaglLayer = (CAEAGLLayer *) self.layer; eaglLayer.drawableProperties = @{ kEAGLDrawablePropertyRetainedBack

iOS 平台开发OpenGL ES程序注意事项

本人最近从Android平台的OpenGL ES开发转到iOS平台的OpenGL ES开发,由于平台不同,所以开发中会有一些区别,再次列出需要注意的几点. 1.首先需要了解iOS主要开发框架,再次仅介绍开发OpenGL ES应用常用的几个: CoreGraphics.framework  ——包含Quartz 2D接口(Core Graphics框架参考) Foundation.framework ——包含Cocoa Foundation层的类和方法(Foundation框架参考) OpenGL

iOS开发60分钟入门

iOS开发60分钟入门 原文:https://github.com/qinjx/30min_guides/blob/master/ios.md 本文面向已有其它语言(如Java,C,PHP,Javascript)编程经验的iOS开发初学者,初衷在于了解如何开始开发iOS App,学习目标包括: 能使用Xcode IDE.模拟器 能修改.调试已有iOS App 能在已有应用内创建新模块 能创建新应用 能发布应用到App Store 本文不包含任何高级的iOS开发知识,已学会iOS开发的同学不要看,

iOS开发-UI 从入门到精通(二)

iOS开发-UI 从入门到精通(二)是对 iOS开发-UI 从入门到精通(一)知识点的巩固,主要以习题练习为主,增强实战经验,为以后做开发打下坚实的基础! ※开发环境和注意事项: 1.前期iOS-UI开发我们需要手动管理内存,所以我们要把ARC关掉(Xcode关掉ARC的步骤): (1)打开Xcode选中当前工程: (2)选中Build Settings: (3)在输入框内输入count: (4)选择Objective-C Automatic Reference Counting  将其设置为 

IOS开发语言Swift入门连载---可选链

IOS开发语言Swift入门连载-可选链 可选链(Optional Chaining) 是一种可以请求和调用属性.方法及下标脚本的过程,它的可选性体现于请求或调用的目标当前可能为空(nil ).如果可选的目标有值,那么调用就会成功:相反,如果选择的目标为空(nil ),则这种调用将返回空(nil ).多次请求或调用可以被链接在一起形成一个链,如果任何一个节点为空(nil )将导致整个链失效. 注意: 的可选链和 Objective-C 中的消息为空有些相像,但是 Swift 可以使用在任意类型中

IOS开发语言Swift入门连载---类型转换

IOS开发语言Swift入门连载-类型转换 类型转换可以判断实例的类型,也可以将实例看做是其父类或者子类的实例. 类型转换在 Swift 中使用is 和 as 操作符实现.这两个操作符提供了一种简单达意的方式去检查值的类型或者转换它的类型. 你也可以用来检查一个类是否实现了某个协议,就像在 Checking for Protocol Conformance部分讲述的一样. 定义一个类层次作为例子 你可以将它用在类和子类的层次结构上,检查特定类实例的类型并且转换这个类实例的类型成为这个层次结构中的

IOS开发语言Swift入门连载---类和结构体

IOS开发语言Swift入门连载-类和结构体 类和结构体是人们构建代码所用的一种通用且灵活的构造体.为了在类和结构体中实现各种功能,我们必须要严格按照常量.变量以及函数所规定的语法规则来定义属性和添加方法. 与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件.你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口. 注意: 通常一个类 的实例被称为对象 .然而在Swift 中,类和结构体的关系要比在其他语言中更加的密切,本

IOS开发语言Swift入门连载---属性

IOS开发语言Swift入门连载-属性 属性将值跟特定的类.结构或枚举关联.存储属性存储常量或变量作为实例的一部分,计算属性计算(而不是存储)一个值.计算属性可以用于类.结构体和枚举里,存储属性只能用于类和结构体. 存储属性和计算属性通常用于特定类型的实例,但是,属性也可以直接用于类型本身,这种属性称为类型属性. 另外,还可以定义属性监视器来监控属性值的变化,以此来触发一个自定义的操作.属性监视器可以添加到自己写的存储属性上,也可以添加到从父类继承的属性上. 存储属性 简单来说,一个存储属性就是

IOS开发语言Swift入门连载---闭包

IOS开发语言Swift入门连载-闭包 闭包是自包含的函数代码块,可以在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 lambdas 函数比较相似. 闭包可以捕获和存储其所在上下文中任意常量和变量的引用. 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包.Swift 会为您管理在捕获过程中涉及到的所有内存操作. 注意: 如果您不熟悉捕获(capturing)这个概念也不用担心,您可以在 值捕获 章节对其进行详细了