Learn OpenGL ES with iOS
OpenGL ES是专为嵌入式设备设计的一个3D图形API,是OpenGL的子集。iOS系统自带了OpenGL ES框架。包含 OpenGL ES 1.1、 OpenGL ES 2.0 和 OpenGL ES 3.0。
需要注意的是OpenGL ES 3.0需要iOS7及以上的系统。
学习OpenGL ES推荐LearnOpenGL系列教程。如作者所言,它确实做到了提供一个既易懂又完整的教程。你可以完全遵循教程进行学习,毕竟OpenGL ES 是OpenGL的一个子集,大部分情况下是通用的。你也可以跟着教程使用iOS来实现一遍。基于上述教程在iOS上学习的实践,本人封装了一个简单的工程learnopengl-ios,包含几个示例,方便大家学习。
本文主要谈谈iOS如何使用OpenGL ES,以及对照教程学习可能遇到的问题。
iOS如何使用OpenGL ES
iOS可以通过3种方式使用OpenGL ES。
- 使用
GLKit
框架, 它提供了对OpenGL ES的封装,无需自己实现渲染循环,方便你专注于实现。我们一般使用这种方式就可以了。 - 使用
CAEAGLLayer
类,较麻烦,需要自己创建framebuffer
,配置渲染循环等。但是考虑到跨平台等特性的话,使用此种方式较好,游戏引擎cocos2d-x
就是使用该方式与iOS平台进行集成。 - 另外我们可以使用
OpenGL ES
来进行离屏渲染。获取渲染后的结果在其它地方进行使用。
常见问题
使用OpenGL ES,一般学习都是看的 OpenGL
的相关资料、书籍。OpenGL ES 作为Open GL的子集必定有些出入。 而iOS平台上又有自己的调用方式,所以又有一些平台方面上的出入,下面是我记录的一些问题。
一、精度问题。
片段着色器float类型必须指定其精度类型。
因为在OpenGL ES标准中,着色器各种类型变量都有默认的精度的类型,片段着色器中float类型除外。
对于精度类型的指定,有两种方式,其一是通过全局的方式进行指定, 如:
//全局指定
precision lowp float;
也可以逐项进行指定,如:
lowp float color;
varying mediump vec2 Coord;
lowp ivec2 foo(lowp mat3);
highp mat4 m;
另外在OpenGL ES 中,浮点型常量的书写,如下所示的方式会编译出错,
FragColor = vec4(1);
需要写成:
FragColor = vec4(1.0);
二、开启缓冲。
使用GLKView开启缓冲的话需要进行配置GLKView的属性:
- 开启深度缓冲需要设置
drawableDepthFormat
属性 - 开启模板缓冲需要设置
drawableStencilFormat
属性
三、MultiSample。
iOS平台通过APPLE_framebuffer_multisample
扩展来提供MultiSample
。
四、默认FrameBuffer一定是0么?
使用GLKit时,默认的framebuffer并不一定是0,那么我们切换回默认的framebuffer调用下列方法可能就并不适用。
glBindFramebuffer(GL_FRAMEBUFFER, 0);
使用GLKit切换回默认framebuffer的方法如下:
[(GLKView *)self.view bindDrawable];
五、几何着色器。
OpenGL ES标准并没有几何着色器。
六、 GPUImage无法使用bool类型。
GPUImage的使用SHADER_STRING
方式定义shader,当shader中使用了bool类型,会出现如下编译错误:
ERROR: 0:1: '_Bool' : syntax error syntax error
原因是GPUImageView 使用 SHADER_STRING()来解析着色器。
而在Objective-C中bool定义为_Bool,LLVM在编译过程中发现了bool并将其替换为_Bool,导致着色器编译出错。