前言
对于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来展现图像.实现效果如下所示.
HelloWorld的实现过程
一、 准备工作
为了简便省时,我决定直接在ViewController中修改代码,首先我们先导入GLKit.h头文件,紧接着那个将ViewController的类型修改为GLKViewController.
然后在Main.storyboard修改ViewController中view的类型为GLKView.如图所示.
上面的准备工作已经是做完了,那么接下来,就是正题部分了,我们现在ViewController.m中声明两个属性.一个是OpenGL ES 上下文属性的EAGLContext对象,一个是矩阵相关的GLKBaseEffect对象.
1 2 3 4 5 6 7 |
@interface ViewController () @property(nonatomic,strong)EAGLContext *mContext; @property(nonatomic,strong)GLKBaseEffect *mEffect; @end |
通过官方的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
这个方法中进行渲染操作.
1 2 3 |
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect; -(void)update; |
二、ViewDidLoad的配置工作
我们接下来在ViewDidLoad中需要做以下几个工作.
1、配置OpenGL ES 上下文信息
1 2 3 4 5 6 7 8 9 10 |
self.mContext = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2]; GLKView *view = (GLKView *)self.view; view.context = self.mContext; //颜色缓冲区格式 view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; [EAGLContext setCurrentContext:self.mContext]; |
代码讲解:第一行代码是对控制器自身的EAGLContext对象使用- (instancetype) initWithAPI:(EAGLRenderingAPI) api;
进行初始化.EAGLRenderingAPI是一个枚举类型.包含了三个值,分别代表着1.0、2.0和3.0的OpenGL ES,我们现在使用的OpenGL ES2.0,所以选择的是kEAGLRenderingAPIOpenGLES2
;
1 2 3 4 5 6 |
typedef NS_ENUM(NSUInteger, EAGLRenderingAPI) { kEAGLRenderingAPIOpenGLES1 = 1, kEAGLRenderingAPIOpenGLES2 = 2, kEAGLRenderingAPIOpenGLES3 = 3, }; |
第二行和第三行代码则是把当前控制器的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的坐标系如下所示.
接下来,我们创建顶点数组,数组中的元素类型为GLfloat类型.数组中包含了两个坐标一个是顶点坐标(x,y,z轴信息),一个是纹理坐标(x,y信息),注意,顶点要与纹理的点一一对应.关于纹理相关只是可以参考我在SpriteKit的文集中的SpriteKit框架之SKTextureAtlas第一部分内容.代码如下所示.
(PS:问什么要这么创建数组呢?难道是系统规定的?回答:并不是,数组的形式规则定好之后,我们可以按照一定的规律取出对应的数据元素.然后进行操作.)
1 2 3 4 5 6 7 8 |
//顶点数据,前三个是顶点坐标,后面两个是纹理坐标 GLfloat squareVertexData[] = { 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, //左下 0.5, 0.5, -0.0f, 1.0f, 1.0f, //右上 }; |
上面的顶点坐标组成看似是一个正方形,但是实际上真的如此吗?NONONO,事实上,由于屏幕的宽高不相同的原因.所选择区域会是下面的这个样子的.
那么我们改如何绘制一个矩形呢?我们可以认为一个矩形是两个三角形拼接而成的.这时候,我们就需要整出另外一个东西:那就是顶点索引数组.有了它就可以规定绘制的顺序.如下所示.
/h4>
对于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来展现图像.实现效果如下所示. HelloWorld的实现过程一、 准备工作为了简便省时,我决定直接在ViewController中修改代码,首先我们先导入GLKit.h头文件,紧接着那个将ViewController的类型修改为GLKViewController. 然后在Main.storyboard修改ViewController中view的类型为GLKView.如图所示. 上面的准备工作已经是做完了,那么接下来,就是正题部分了,我们现在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已经包含了这一功能,相当于封装了着色器.现在只是知道有着色器就行.
二、ViewDidLoad的配置工作我们接下来在ViewDidLoad中需要做以下几个工作. 1、配置OpenGL ES 上下文信息
代码讲解:第一行代码是对控制器自身的EAGLContext对象使用
第二行和第三行代码则是把当前控制器的View的context设置为self.mContext. 第四行代码则是设置页面的颜色缓冲区格式,默认的也是 第五行代码则是将此“EAGLContext”实例设置为OpenGL的“当前激活”的“Context”。这样,以后所有“GL”的指令均作用在这个“Context”上。 2、配置绘制矩阵数组信息OpenGL ES的坐标系是和iOS常用的Quartz 2D坐标系是不一样的.OpenGL ES是左手坐标系,Quartz 2D坐标系则是右手坐标系.OpenGL ES的坐标系是以中心为原点,原点到屏幕的边缘为单位1(不管屏幕尺寸如何变化,都是单位1).OpenGL ES的坐标系如下所示. 接下来,我们创建顶点数组,数组中的元素类型为GLfloat类型.数组中包含了两个坐标一个是顶点坐标(x,y,z轴信息),一个是纹理坐标(x,y信息),注意,顶点要与纹理的点一一对应.关于纹理相关只是可以参考我在SpriteKit的文集中的SpriteKit框架之SKTextureAtlas第一部分内容.代码如下所示. (PS:问什么要这么创建数组呢?难道是系统规定的?回答:并不是,数组的形式规则定好之后,我们可以按照一定的规律取出对应的数据元素.然后进行操作.)
上面的顶点坐标组成看似是一个正方形,但是实际上真的如此吗?NONONO,事实上,由于屏幕的宽高不相同的原因.所选择区域会是下面的这个样子的. 对于初学者还有个容易忽视的技术点,那就是 在OpenGL ES只能绘制三角形,不能绘制多边形,但是在OpenGL中确实可以直接绘制多边形.
那么我们改如何绘制一个矩形呢?我们可以认为一个矩形是两个三角形拼接而成的.这时候,我们就需要整出另外一个东西:那就是顶点索引数组.有了它就可以规定绘制的顺序.如下所示. |