OpenGL ES 在 iOS 平台上原生开发环境的 Xcode 工程建立
太阳火神的美丽人生 (http://blog.csdn.net/opengl_es)
本文遵循“署名-非商业用途-保持一致”创作公用协议
转载请保留此句:太阳火神的美丽人生 - 本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
以下构建过程基于的软硬件环境:
开 发 机:Mac Book Air 2012 版 8G内存 128G固态硬盘
操作系统:os x 10.9.1
开发工具:Xcode 5
1、在 Xcode 中创建空的 iOS 工程
点下一步,出现如下图工程信息填写窗口,按图上说明进行填写即可
点按下一步,选择工程存储的磁盘位置,下方有个git版本库管理,建议先留空,此版本xcode的版本控制功能稍显繁杂,如果熟悉可以勾选。
点 Create 按钮就会在目标位置创建如下目录结构的工程:
其中 AppDelegate.h 和 AppDelegate.m 是应用代理类,后续要在该类中加载 OpenGL ES 的视图控制器及视图。
至此,一个空的待用工程建立完成。接下来创建与 OpenGL ES 相关的类,注意与上面工程结构中的差异,以便清楚了解 OpenGL ES 所需的文件。
需要对 iOS 白哥白弟们说明一下,.h 是 objective-c 类的头文件,与 c、c++ 用的扩展名是一样的,但声明不同;.m 是 objective-c 的实现文件。
对 c++ 熟悉的 objective-c 白兄白弟,可以参垢一下 《c++大学教程》,其中对很好地基于对象开发时,声明与实现的分离有很好的描述,这不是语言的内容,但是确是良好基于对象编程所必须知道的。而 objective-c 原生就这样做了,正所谓 “约定重于配置” ,好的约定值得去遵守和铭记。
2、建立 OpenGL ES 视图控制器类 GLESViewController 和 OpenGL ES 视图类 GLESView并呈现
在 xcode 工程导航器中找到 demo 分组,在其下建立 GLES 分组,该部分是 EGL 部分,真正 OpenGL ES 部分,再另建分组,以便后续用 C++ 重写。
在 GLES 分组下建立 GLESViewController 控制器类,继承自 UIViewController,另建立 GSESView 视图类。
以上分组和类建立完成后的工程导航器结构如下:
OpenGL ES 的视图控制器和视图均已建立完成,符合了 iOS 开发的习惯,我们先不考虑 OpenGL ES 部分,先把两者组合起来,在上面的空工程中呈现出来。
敏捷开发就这一点好,每做一件事情之后,都亲测一下,尽早地让程序运行起来,以验证所添加功能的可用性,以避勉把问题带到后续步骤中,增加问题排查的困难,这也是持续集成的主要方法,确保问题划分成小块,实现一块,就集成一块,测试一块,确定没有问题了,再继续向下进行。
就象盖房子一样,和混凝土之前,一定要先对水泥、砂子和碎石以及钢筋做充分的检验,合格后,才能向下施工,要不然,真正和出混凝土,浇注出房屋后,如果房屋出现倒塌,那真的就不知道是哪一环节出了问题了,是施工配比问题,还是水泥或碎石指标不够,你能知道吗?反正我是不各道。
我们这里使用 xib 来构建视图,所以要将初始化方法 initWithFrame 换成 initWithCoder ,代码如下所示:
- (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { // 后续要在这里进行相关初始化操作 } return self; }
另需更改 GLESViewController.xib 中 File's Owner 的类型为 GLESViewController 视图控制器类,View 的类型更改为 GLESView 。
GLESViewController 类头文件中增加一属性,用于按 GLESView 类型引用视图控制器的视图,不用在使用时再现转换,而且由控制器控制其生命周期:
// 弱引用 UIViewController 持有的视图 @property (nonatomic, weak) IBOutlet GLESView *glesView;
// 弱引用当前视图类持有的 Layer 对象 @property (nonatomic, weak) CAEAGLLayer *glesLayer;
+ (Class)layerClass { return [CAEAGLLayer class]; }
- (void)layoutSubviews { // 清除背景颜色 glClearColor(0.0f, 1.0f, 0.0f, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 设置视口 glViewport(0, 0, self.frame.size.width, self.frame.size.height); // 准备顶点及纹理缓冲区、灯光及转换矩阵,绘制图形到桢缓冲区 // 显示桢缓冲内容 [_glesContext presentRenderbuffer:GL_RENDERBUFFER]; }
#import "AppDelegate.h" #import "GLESViewController.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 创建 GLESViewController 实例 GLESViewController *controller = [[GLESViewController alloc] initWithNibName:@"GLESViewController" bundle:nil]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // 将上面创建的 GLESViewController 实例设为窗口的根视图控制器用于显示初始内容 self.window.rootViewController = controller; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; } @end
记得加上两个框架:OpenGLES.framework 和 QuartzCore.framework 分别对应 GLES 和 EGL 两部分功能。
这里只是为了疏理重建工作,有个记录,也是为了别把自已弄晕,所以才按步就班地写这么个搭建过程,有空时再按上面来做一遍,看看哪里不妥,再行修正。