OpenGL ES:新手村中的 HelloWorld

421 查看

111396375-e7bca2b8c027029b

前言


对于OpenGL ES,本人现在还是一个小白,所以我将用小白视角对OpenGL ES进行小白式的讲解.希望能通过如此帮助更多的人.同时我要感谢一个人,那就是落影loyinglin,落影大神关于OpenGL ES方面的知识写的非常的详细,大家可以去参考.好了,开始战斗吧.

 

OpenGL ES简介


OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。该API由Khronos集团定义推广,Khronos是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准。

OpenGL ES 是从 OpenGL 裁剪的定制而来的,去除了glBegin/glEnd,四边形(GL_QUADS)、多边形(GL_POLYGONS)等复杂图元等许多非绝对必要的特性。经过多年发展,现在主要有两个版本,OpenGL ES 1.x 针对固定管线硬件的,OpenGL ES 2.x 针对可编程管线硬件。OpenGL ES 1.0 是以 OpenGL 1.3 规范为基础的,OpenGL ES 1.1 是以 OpenGL 1.5 规范为基础的,它们分别又支持 common 和 common lite两种profile。lite profile只支持定点实数,而common profile既支持定点数又支持浮点数。 OpenGL ES 2.0 则是参照 OpenGL 2.0 规范定义的,common profile发布于2005-8,引入了对可编程管线的支持。

那么上面说了这么一些到底是什么意思呢.其实就是说OpenGL ES是移动端处理图像的一个C语言库.

 

OpenGL ES的显示图像


在iOS中,我们平常要加载一张图片会怎么做呢?一个是使用UIKit框架的UIImage,一个是使用Core Graphics框架直接绘制.那么OpenGL ES是如何展现图像的呢?今天我们就先用OpenGL ES中的GLKBaseEffect来展现图像.实现效果如下所示.

121396375-ce71b00b8544aef8

HelloWorld的实现过程


一、 准备工作

为了简便省时,我决定直接在ViewController中修改代码,首先我们先导入GLKit.h头文件,紧接着那个将ViewController的类型修改为GLKViewController.

131396375-5822c2ab2700f209

然后在Main.storyboard修改ViewController中view的类型为GLKView.如图所示.

141396375-b78b0256fadeaa93

上面的准备工作已经是做完了,那么接下来,就是正题部分了,我们现在ViewController.m中声明两个属性.一个是OpenGL ES 上下文属性的EAGLContext对象,一个是矩阵相关的GLKBaseEffect对象.

通过官方的API文档,我们知道,EAGLContext对象管理一个OpenGL ES渲染环境状态信息,命令,以及使用OpenGL ES的所需要资源。OpenGL ES执行任何命令之前,都需要通过EAGLContext对象来实现。同时官方文档也提到,绘制一个上下文之前,你必须完成framebuffer对象绑定到上下文。

GLKBaseEffect这个类实现了OpenGL ES 1.0公共(common)的shading行为,简化(从1.0)到OpenGL ES 2.0的转化。它们也提供了让光和纹理(lighting and texturing)工作的简单方法。GLKBaseEffect对象提供了着色器这一功能.其实着色器应该算的上是OpenGL ES的一大特色,但是GLKBaseEffect已经包含了这一功能,相当于封装了着色器.现在只是知道有着色器就行.
接下来,我们了解两个方法,他们的刷新频率和屏幕的刷新频率是一致的.我们需要在- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect这个方法中进行渲染操作.

 

二、ViewDidLoad的配置工作

我们接下来在ViewDidLoad中需要做以下几个工作.

1、配置OpenGL ES 上下文信息

代码讲解:第一行代码是对控制器自身的EAGLContext对象使用- (instancetype) initWithAPI:(EAGLRenderingAPI) api;进行初始化.EAGLRenderingAPI是一个枚举类型.包含了三个值,分别代表着1.0、2.0和3.0的OpenGL ES,我们现在使用的OpenGL ES2.0,所以选择的是kEAGLRenderingAPIOpenGLES2;

第二行和第三行代码则是把当前控制器的View的context设置为self.mContext.

第四行代码则是设置页面的颜色缓冲区格式,默认的也是GLKViewDrawableColorFormatRGBA8888,所以不做设置也可以.

第五行代码则是将此“EAGLContext”实例设置为OpenGL的“当前激活”的“Context”。这样,以后所有“GL”的指令均作用在这个“Context”上。

2、配置绘制矩阵数组信息

OpenGL ES的坐标系是和iOS常用的Quartz 2D坐标系是不一样的.OpenGL ES是左手坐标系,Quartz 2D坐标系则是右手坐标系.OpenGL ES的坐标系是以中心为原点,原点到屏幕的边缘为单位1(不管屏幕尺寸如何变化,都是单位1).OpenGL ES的坐标系如下所示.

151396375-253dbd1ad707c153

OpenGL ES的坐标系

接下来,我们创建顶点数组,数组中的元素类型为GLfloat类型.数组中包含了两个坐标一个是顶点坐标(x,y,z轴信息),一个是纹理坐标(x,y信息),注意,顶点要与纹理的点一一对应.关于纹理相关只是可以参考我在SpriteKit的文集中的SpriteKit框架之SKTextureAtlas第一部分内容.代码如下所示.

(PS:问什么要这么创建数组呢?难道是系统规定的?回答:并不是,数组的形式规则定好之后,我们可以按照一定的规律取出对应的数据元素.然后进行操作.)

上面的顶点坐标组成看似是一个正方形,但是实际上真的如此吗?NONONO,事实上,由于屏幕的宽高不相同的原因.所选择区域会是下面的这个样子的.

161396375-eaefa9be0eec6ad0
对于初学者还有个容易忽视的技术点,那就是 在OpenGL ES只能绘制三角形,不能绘制多边形,但是在OpenGL中确实可以直接绘制多边形.
那么我们改如何绘制一个矩形呢?我们可以认为一个矩形是两个三角形拼接而成的.这时候,我们就需要整出另外一个东西:那就是顶点索引数组.有了它就可以规定绘制的顺序.如下所示.