ES的基础知识备忘录,当CPU的性能因为等待内存读写而处于次优状态时

之前学习过CoreAnimation之后,ES就是查漏补缺吧,GLKBaseEffect会生成直接在GPU上运行的Shading Language,这个Buffer有它的名字(VBO的ID),当CPU的性能因为等待内存读写而处于次优状态时,这种次优状态就叫做数据饥饿,ES的基础知识备忘录,库

图片 24

灯光

GPU首先为每种三角形的每一个定点试行光线总计,然后把总括的结果插补在极端之间来修改每一种渲染的片元的结尾颜色。由此模拟灯的亮光的品质和光滑度要在于组成各种3D物体的终极的多寡。光线的估测计算是以三角形为单位的,光线的向量与三角面包车型客车法向量的夹角决定了采光量的多少。所以在选择灯的亮光的时候须求在固定中传播法向量的值。GLKit命全权大使用灯的亮光的话正是平素在baseEffect对象里面平素选用light0属性进行安装。设置了那一个脾气之后,纵然未有张开,颜色属性也会失效,而是改为电灯的光的水彩属性,所以一旦还要渲染别的有颜色的物体的时候,要求新建baseEffect实例。

将baseEffect当做片段着色器,况且OpenGL ES
Context是二个状态机,所以完全能够将前多少个固定绘制作而成蓝绿,然后退换baseEffect的水彩填充属性为灰湖绿,再调用绘制,就能将剩余的定位绘制作而成威尼斯绿。

上一节中简易的介绍了下何以行使CAEAGLLayer和GLKit框架搭建轻便的OpenGLES景况。

光线

纹理坐标系

纹理坐标系

  • glTexParameteri参数
    GL_TEXTURE_MIN_FILTEENCORE表示相当多纹素对应较少片元
    GL_TEXTURE_MAG_FILFETucson表示比较多片元对应比较少纹素
    GL_LINEATucson 表示线性插值
    GL_NEACRUISERSET 表示就近采纳

  • 当UV坐标当先ST坐标时候
    GL_TEXTURE_WRAP_S表示U坐标超越了S坐标
    GL_TEXTURE_WRAP_T表示V坐标超过了T坐标
    GL_REPEAT 重复纹理以填满UV区域
    GL_CLAMP_TO_EDGE 取样纹理边缘的纹素

<a name=”fenced-code-block”>顶点数组织设立置值</a>
index: 通用顶点属性索引
size: 顶点数组中为顶点属性指定的分量数量,取值范围1~4
type: 数据格式 ,两个函数都包括的有效值是
      GL_BYTE  GL_UNSIGNED_BYTE  GL_SHORT  GL_UNSIGNED_SHORT  GL_INT  GL_UNSIGNED_INT
      glVertexAttribPointer还包括的值为:GL_HALF_FLOAT GL_FLOAT 等
normalized: 仅glVertexAttribPointer使用,表示非浮点数据类型转换成浮点值时是否应该规范化
stride: 每个顶点由size指定的顶点属性分量顺序存储。stride指定顶点索引i和i+1表示的顶点之间的偏移。
    如果为0,表示顺序存储。如果不为0,在取下一个顶点的同类数据时,需要加上偏移。
ptr: 如果使用“顶点缓冲区对象”,表示的是该缓冲区内的偏移量。

void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr);
// 取值为“整数”版本
void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr);

内需小心的是:上边包车型客车多少个API中的index参数,对应着顶点着色器中的响应变量的任务,能够选取着色器语言GLSL的修饰符来表示:
layout(location = 0) in vec4 a_color; layout(location = 1) in vec4 a_position;
安装颜色的属性的时候,能够选取index=0;使用极限坐标的时候能够安装index=1
或者
使用glBindAttribLocation函数来设置,具体的之后再讲。

这里由于大家选拔iOS封装好的GLkit框架,无需大家设置着色器程序,里面有内置的装置好的index地点,正是底下的变量:

typedef NS_ENUM(GLint, GLKVertexAttrib)
{
    GLKVertexAttribPosition,
    GLKVertexAttribNormal,
    GLKVertexAttribColor,
    GLKVertexAttribTexCoord0,
    GLKVertexAttribTexCoord1
} NS_ENUM_AVAILABLE(10_8, 5_0);

在重返大家的主次,大家采纳GLKit里面包车型客车GLKVertexAttribPositionGLKVertexAttribTexCoord0分级代表顶点坐标纹理坐标八个变量的特性索引。(顶点索引不是终极数据,这里大家无需管那个值)

图片 1

启用顶点数组和点名顶点属性

  • 地点的主次最急需留神的是变量的舞狮很主要,作者是因为错把GLfloat写成CGFloat,导致图片怎么都渲染不出来。

GLKit

ios封装了OpenGL ES,大家得以直接使用GLKit来使用OpenGL
ES。分别采取GLKView和GLKViewController就足以一向操作OpenGL ES了。

以下是私有通晓:GLKBaseEffect封装了有的着色器程序,所以一旦向该对象传入纹理也许颜色,就足以一向渲染出来。

OpenGL
ES的利用进程尽管操作Buffer的经过(见buffer一节的从头到尾的经过)。下边具体讲一下各种函数:

  • glGenBuffers(1,&name):那个方法是用来生成缓存,数量是叁个,传入首地址标志。
  • glBindBuffer(GL_ ARRAY_BUFFEMurano, name):
    评释是三个终极数组类型的buffer,使用相应name的缓存来拍卖接下去的运算。
  • glBufferData(GL_ARRAY_BUFFERubicon,size,data,usage):
    第贰个是项目,第二个是急需申请的内部存款和储蓄器大小,第多个是内需拷贝到GPU内部存款和储蓄器的数量,第多少个是读取频率的标志,用于内部存款和储蓄器优化
  • glEnableVertexAttribArray,暗许就不准的,这里要求张开一下。
  • glVertexAttribPointer(index,size,GL_FLOAT,GL_FALSE,stribe,pointer)。该函数告诉OpenGL怎么样管理传入的终端。因为在终点数组中,一般还要保存纹理的UV数据,所以须要内定项目(地方、颜色、纹理之类的)、大小、步幅以及偏移量,那样的话就可以合理运用终端。
  • 上面就是绘制顶点缓存和删除顶点缓存了。

这一节中我们将使用GLKit框架绘制一个三角形。

GL_TEXTURE_MIN_FILTEWrangler表示非常多纹素对应比较少片元

渲染

用3D数据变动三个2D图像的进程。

这一次的任务是把一张图片用OpenGL ES的不二秘技体现到荧屏上,部分机能应用了GLKit库。

OpenGL流程

图片 2流程图

着色器是单身运营在GPU上的顺序。

该流程图突显说了OpenGL运维的进度,在我们定义了定位数据之后,首要推荐是固定着色器管理牢固数据,我们供给报告OpenGL假设管理稳定。图元,是告诉OpenGL渲染如何的多少,这里渲染的是三角形。几何着色器生成帮衬的几何线段。光栅化是将几何样子调换来像素,片段着色器决定最后每一种像素的水彩(片段着色器饱含3D场景的数目,比如光照、阴影、光的颜色等等),混合是勾兑分裂档期的顺序的部分,因为在那几个等第要混合阿尔法值,所以固然片段着色器分明了最终的颜色,可是混合之后也大概两样。

6.发端渲染

– (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {

// 告诉baseEffect 计划好脚下OpenGL ES
的上下文,以便为使用baseEffect生成的习性和Shading
Language程序的绘图做好企图

[self.baseEffect prepareToDraw];

// 设置清屏颜色石黄黄,意思正是安装当前上下文的背景颜色

glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

glClear(GL_COLOR_BUFFER_BIT);

// 运营顶点缓存渲染操作

glEnableVertexAttribArray(GLKVertexAttribPosition);

/*

glVertexAttribPointer()函数告诉OpenGL ES
顶点数据在哪个地方,以及怎么解释为各类终端保存的多少

首先个参数:当前绑定的缓存包蕴各类定点的地方音讯

其次个参数:提示各类地方有3个部分

其三个参数:告诉OpenGL ES每种部分都保存为三个浮点类型的值

第八个参数:告诉OpenGL ES小数点一定数据是不是足以被改变。

第几个参数:钦点每种终端的保留需求几个字节

第八个参数:为NULL告诉OpenGL
ES能够从近日绑定的巅峰缓存的起来地点访问顶点数据

*/

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT,
GL_FALSE, sizeof(TriangleScence), NULL);

/*

经过调用glDrawArrays()来进行绘图

第八个参数:告诉GPU怎么管理绑定的极端缓存内的终极数据,GL_TRIANGLES
三角形,

其次个参数:缓存内须要渲染的第两个终端的职分

其三个参数:须求渲染的顶点的多寡

*/

glDrawArrays(GL_TRIANGLES, 0, 3);

}

VectorA × VectorB 的矢量积 和 B × A 是来势相反的。

多种纹理

多重纹理可防止止多通道渲染导致的内部存款和储蓄器访谈限制品质境况
self.baseEffect.texture2d1.envMode = GLKTextureEnvModeDecal;
能够开启多种纹理

“顶点坐标” 和 “顶点属性”

概念要绘制图片的顶点坐标纹理坐标
OpenGL ES中坐标系是和iOS常用的Quartz 2D坐标系是差异的,Quartz
2D坐标系属于右手坐标系,OpenGL
ES属于右手坐标系。先说一下右侧坐标系和左臂坐标系。
伸出左手,让拇指和人口成“L”形状,拇指向右,食指向上,中指指向起那方,这时就确立了贰个“左手坐标系”,拇指、食指和中指分表代表x、y、z轴的正方向。“右手坐标系”正是用左边,如下图所示:

图片 3

“右手坐标系”和“右臂坐标系”

在iOS开拓中,显示器左上角是坐标原点,往右是x轴正方向,往下是y轴正方向。而在OpenGL
ES中,显示屏的中间是坐标原点,往右是x轴正方向,往下是y轴正方向,当中z轴的正方向是从显示器往外的趋向,如下图所示:

图片 4

OpenGL ES坐标系

依靠OpenGL
ES的坐标系,大家定义一下要绘制的图纸的多少个顶峰,顶点坐标和纹理坐标是投身贰个GLfloat数组中管理的,定义一组顶点数据的跨度为5,其中前四个存款和储蓄顶点坐标,后三个存款和储蓄纹理坐标,下图一共定义了4个极点,就是矩形的两个极端,须求专心的是,就算坐标都是0.5,不过绘制出来的图样实际不是长方形,因为我们用来最终展现的是摩托罗拉显示屏,手提式有线电话机的长和宽并不对等。

图片 5

顶点坐标和纹理坐标

OpenGL
ES不可能绘制多边形,只好绘制线三角形,OpenGL能够绘制多边形,由于我们绘制的图样是二个矩形,又七个三角构成,正是下图中的多少个顶点索引(0,1,3)和(1,2,3)组成的三角拼成三个矩形

图片 6

顶点索引

依靠顶点索引的个数,总计要绘制的极端的个数

图片 7

终点数量

着色器

OpenGL
ES在ios上的选拔进程封装了着色器的运用进程,无需大家团结编写翻译和链接着色器。

2.在Main.Storyboard少校设置View的class为GLKView.

光线总括重视于表面法向量。法向量也是单位向量。

帧缓存

接收渲染结果的缓冲区叫做帧缓存。
有五个特意的帧缓存,前帧缓存和后帧缓存,调整着显示器像素的终极颜色。
OpenGL ES的上下文物保护存了OpenGL
ES的景观新闻,满含用于渲染数据的缓存地址和摄取渲染结果的缓存地址。

<a name=”fenced-code-block”>常量顶点属性设置值</a>
// 加载index指定的通用顶点属性。
// 下面的API中没有的值默认为1.0,比如glVertexAttrib1f/v设置的值为(x, 1.0, 1.0, 1.0)
void glVertexAttrib1f(GLuint index, GLfloat x);
void glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
void glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
void glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void glVertexAttrib1fv(GLuint index, const GLfloat *values);
void glVertexAttrib2fv(GLuint index, const GLfloat *values);
void glVertexAttrib3fv(GLuint index, const GLfloat *values);
void glVertexAttrib4fv(GLuint index, const GLfloat *values);

纹理

2D纹理的坐标是[0,1],将牢固的坐标和纹理的坐标实行点对点的绑定之后,片段着色器会对纹理实行插值

自己的知道,插值正是将纹理和终极组成的几何图形之间举行映射,进而决断各种像素的颜色。

MipMap是用来消除远处同叁个实体的纹理难点,因为一旦是异域的小的同等物体,若是利用大的贴图会有浪费内部存款和储蓄器的标题,所以须求传入小的贴图。MipMap像下边那几个样子(后三个比前贰个小一半,当先一定的阈值就能使用相应的图形):

图片 8MipMap

1.新建叁个档案的次序,在ViewController中导入GLKit框架,ViewController承继自GLKViewController。

第八个 像素颜色数据的指针

那是一篇OpenGL ES的求学笔记,介绍图像绘制里面用到的定义,学习OpenGL
ES的基础知识备忘录。

<a name=”fenced-code-block”>禁止通用顶点属性</a>
 /*
  index:指定通用顶点数据的索引,这个值的范围从0到支持的最大顶点属性数量减1
*/
void glDisableVertexAttribArray(GLuint index);

深度测量试验

纵深测量试验是OpenGL自动达成的,大家只须要报告OpenGL保存测量试验深度的尺寸,一般是16个人和二十二人大小。然后调用深度函数来支配通过的秘技。一般接纳暗中同意的就能够。在iOS里面包车型地铁代码设置如下:

glGenRenderbuffers(1, &depthRenderBuffer); // Step 1 glBindRenderbuffer(GL_RENDERBUFFER, // Step 2 depthRenderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, // Step 3 GL_DEPTH_COMPONENT16, currentDrawableWidth, currentDrawableHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, // Step 4 GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer);

3.创造二个极端缓存对象标志,绑定并分配内部存款和储蓄器 Vertex Buffer Object(VBO)

VBO:显卡存款和储蓄空间里的一块缓存区(Buffer),用于记录顶点的新闻,富含法线,问路坐标等,那些Buffer有它的名字(VBO的ID),OpenGL在GPU的某处记录着这么些ID和对应的显存地址(恐怕地点偏移,类似内部存款和储蓄器)。

GLuint _vertexBufferID;

// 供给OpenGL ES为图形管理器调节的缓存生成一个天下无敌的标记

glGenBuffers(1, &_vertexBufferID);

// 告诉OpenGL ES
为接下去的运算使用哪三个缓存。glBindBuffer只扶助三种等级次序的缓存,GL_ARRAY_BUFFER
// 和 GL_ELEMENT_ARRAY_BUFFER,

glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID);

/**

 让OpenGL
ES为当下绑定的缓存分配并早先化丰盛的连接内部存款和储蓄器通常是从CPU调节的内部存款和储蓄器复制数据到GPU分配//
 的内部存款和储蓄器)

首先个参数:用于内定要更新当前上下文中所绑定的是哪三个缓存

第1个参数:要复制进那些缓存的字节的多少

其四个参数:复制的字节的地方

第三个参数:提醒了 缓存 在 以往的演算中只怕将会被哪些使用

GL_STATIC_DRAW告诉上下文缓存中的内容符合复制到GPU调控的内部存款和储蓄器,因为比比较少对其实行修改,那些音讯方可扶助OpenGL
ES 优化内部存款和储蓄器使用。

GL_DYNAMIC_DRAW用作提示会告诉上下文,表示该缓存区会被周期性更动动,相同的时候提醒OpenGL
ES 以差异的方法来管理缓存中的存款和储蓄。  

GL_STREAM_DRAW:表示该缓存区会被频频员和转业移;

*/

glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs), vertexs,
GL_STATIC_DRAW);

CPU专长运算,读写内部存储器极慢,当CPU的性质因为等待内部存款和储蓄器读写而处在次优状态时,这种次优状态就叫做数据饥饿。

数据类型

OpenGL ES
坐标是以浮点数来囤积,GPU对浮点运算做了非常的优化,纵然选用任何数据类型的极端也会被调换到浮点型。
图形管理器本质上便是大面积并行矢量管理器。

“顶点缓存” 和 “顶点索引缓存”

程序会保留3D场景数据到RAM中,CPU有专门为其分配的RAM,在图形管理的进程中,GPU也会特意为其分配RAM。使用硬件渲染3D图形的进程差不离统统取决于不一致的内部存款和储蓄器区域的拜见的不二秘技。
OpenGL ES部分运转在CPU上,部分运营在GPU上。OpenGL
ES横跨在多个Computer之间,和煦四个内部存款和储蓄器区域里面包车型客车数据调换,下图表示3D渲染相关的组件之间的数据调换,各个箭头都意味着着贰个渲染质量的瓶颈。

图片 9

硬件组件和OpenGL ES之间的关系

OpenGL ES常常会急速地和煦数据沟通,不过程序与OpenGL
ES的交互格局会追加调换的多少和品种,从二个内部存款和储蓄器区域复制数据到内外三个内部存款和储蓄器区域,速度是周旋相当慢的,别的,在发出内存复制的时候,这两块内部存款和储蓄器都无法用作它用,因此内部存款和储蓄器区域里面包车型客车数据交流尽量防止。最新的嵌入式CPU能够很轻巧的到位以亿为单位的运算,不过内部存款和储蓄器读写只可以在百万单位,那表示,除非CPU能够在每一次从内部存款和储蓄器读取一块数据后有效性的周转5个或许更多的运算,不然管理器的属性就处于次优的意况,也叫数据饥饿,这种场面对于GPU来讲更鲜明。
OpenGL
ES为了缓慢解决那么些难题,定义了缓存(buffer),为缓存提供数据须要以下多少个步骤:

  • 生成 (Generate):央浼OpenGL ES为buffer生成三个终南捷径的标志符
  • 绑定 (Bind):告诉OpenGL ES为接下去的演算使用三个buffer
  • 缓存数据 (Buffer Data):为近些日子绑定的buffer分配并开端化丰盛的内部存款和储蓄器,从cpu调整的内存复制数据到buffer
  • 启用 (Enable) 或者禁止 (Disable):告诉OpenGL
    ES在接下去的渲染中是还是不是利用缓存中的数据
  • 设置指针 (Pointer):告诉OpenGL
    ES在buffer中的数据的品类和所急需探访的数量的内部存款和储蓄器偏移值。
  • 绘图 (Draw):告诉OpenGL
    ES使用当前绑定并启用的buffer中的数据,来渲染场景
  • 删除 (Delete):告诉OpenGL ES删除从前生成的buffer并释放相关的buffer

地方的多少个步骤分别对应着下边包车型地铁多少个OpenGL ES的API:

/* n: 要申请的缓冲区对象数量
   buffer: 指向n个缓冲区的数组指针,该数组存放的是缓冲区的名称
   返回的缓冲区对象名称是0以外的无符号整数,0是OpenGL ES的保留值,不表示具体的缓冲区对象,修改或者查询0的缓冲区状态产生错误
*/
void glGenBuffers(GLsizei n, GLuint *buffer);

 target:用于指定当前的缓冲区对象的"类型"
           GL_ARRAY_BUFFER:数组缓冲区
           GL_ELEMENT_ARRAY_BUFFER:元素数组缓冲区
           GL_COPY_READ_BUFFER:复制读缓冲区
           GL_COPY_WRITE_BUFFER:复制写缓冲区
           GL_PIXEL_PACK_BUFFER:像素包装缓冲区
           GL_PIXEL_UNPACK_BUFFER:像素解包缓冲区
           GL_TRANSFORM_FEEDBACK_BUFFER:变换反馈缓冲区
           GL_UNIFORM_BUFFER:统一变量缓冲区
 buffer: 缓冲区的名称

void glBindBuffer(GLenum target, GLuint buffer);

OpenGL
ES使用数组缓冲区元素数组缓冲区二种缓冲区类型分别钦命顶点图元数据GL_ARRAY_BUFFER类型用于创建保存终点数据的缓冲区对象,GL_ELEMENT_ARRAY_BUFFER用来创设保存图元索引的缓冲区对象。
急需小心的是,在用glBindBuffer绑定从前,分配缓冲区并不一定非得用glGenBuffers,能够内定三个未采用的缓冲区对象。不过为了制止不供给的荒唐,仍然提出使用glGenBuffers让系统给我们分配未利用的缓冲区对象的名号

/* target: 用于指定当前的缓冲区对象的"类型"
   size: 缓冲区数据存储大小,以字节表示
   data: 缓冲区数据的指针
   usage: 应用程序将如何使用缓冲区对象中存储的数据的提示,也就是缓冲区的使用方法,初始值为 GL_STATIC_DRAW
*/

void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage);

缓冲区的应用格局取值有成百上千种,这里大家使用GL_STATIC_DRAW,那一个值的意味是缓冲区目标将被涂改三遍,使用频仍,以绘制图元或钦点的图像。因为我们以往的操作不对其进展改造,只是初步化的时候赋值二遍。这么些取值能够协理OpenGL
ES优化内部存款和储蓄器的选用
倘使选择GL_DYNAMIC_DRAW,意义是缓冲区指标将被另行修改,使用频繁。那会提示上下文,缓存内的数据会频仍转移,OpenGL
ES就能够以分化的法子来拍卖缓存的蕴藏。

回到当前的事例中,具体代码如下:

图片 10

终端数据和终极索引的缓存

帧缓存(frame buffer)

就疑似GPU提供数据的缓存同样,接收渲染结果的缓冲区叫做帧缓存。能够同期设有多数的帧缓存,並且能够透过OpenGL
ES让GPU把渲染结果存款和储蓄到自由的帧缓存中。有front frame buffer和back frame
buffer的概念,front frame
buffer调控显示屏上展现的像素颜色和布局,所以一般不会向来渲染到front frame
buffer中,那样的话就能够让顾客观望未有渲染达成的图像。相反程序会把渲染结果保存到含有back
frame buffer的别的frame buffer中,当back frame
buffer渲染成功将来就能够登时与front frame buffer进行置换。

7.清理内部存款和储蓄器

– (void)viewDidDisappear:(BOOL)animated {

if (_vertexBufferID != 0) {

glDeleteBuffers(1, &_vertexBufferID);

_vertexBufferID = 0;

}

((GLKView *)self.view).context = nil;

[EAGLContext setCurrentContext:nil];

}

八个基本转移

软件架构

每三个iOS原生控件都有三个心心相印的CoreAnimation层。
CoreAnimation合成器使用OpenGL
ES来狠命火速地调整GPU、混合层和切换帧缓存。
OpenGL
ES会有三番两次到层,与层分享数据的帧缓存,至少包蕴二个像素颜色渲染缓存。

渲染

GLKit提供了GLKViewDelegateGLKView个中有个delegate属性,大家要求贯彻这些合同。那一个协议的办法的基础代谢频率和显示屏的刷新频率是一模二样的,在-
(void)glkView:(GLKView *)view
drawInRect:(CGRect)rect这几个措施中开展渲染操作.

图片 11

GLKViewDelegate

在渲染操作中,大家来看多少个API:
OpenGL
ES是二个交互式的渲染系统,在每一帧的早先,将缓冲区的有着剧情早先化为暗许镇。假使想把值一最初集结安装为八个值,缓冲区能够由此glClear函数清除,用三个掩码位来表示应当破除为其钦点值的相继缓冲区

// mask: 指定要清除的缓冲区,由下面几个表示各种OpenGL ES缓冲区的位掩码联合组成:
    GL_COLOR_BUFFER_BIT
    GL_DEPTH_BUFFER_BIT
    GL_STENCIL_BUFFER_BIT
void glClear(GLbitfield mask); 

安装清除为哪个暗许值,可以由此上面包车型大巴函数来设置,上边包车型地铁多少个函数分别对应着地点的多少个掩码

// GL_COLOR_BUFFER_BIT 颜色
void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat  alpha);
// GL_DEPTH_BUFFER_BIT 深度
void glClearDepthf(GLfloat depthf);
// GL_STENCIL_BUFFER_BIT 模版
void glClearStencil(GLint s);

/* mode: 指定要绘制的图元,我们绘制两个三角形,这里用GL_TRIANGLES
count: 要绘制的“顶点数量”
type:指定的顶点索引的存储的值的类型
indices: 指向顶点索引的数组指针。*/

void glDrawElements(GLenum mode, GLsizei count, GLEnum type, const GLvoid *indices);

图片 12

渲染操作

OpenGL ES context

Context 封装了配备OpenGL ES保存在一定平台的数据结构新闻。因为OpenGL
ES是一个状态机,那意味在八个前后相继中布局之后就能够一贯保留这几个值,直到程序修改了这几个值。上下文音信只怕被保存在CPU所决定的内部存款和储蓄器中,也也许在GPU所主宰的内部存款和储蓄器中。OpenGL
ES Context的里边贯彻依据于差异的嵌入式系统和GPU硬件,所以OpenGL
ES提供了行业内部的ANSI C语言函数来与Context交互。OpenGL ES
Context会追踪用于渲染的帧缓存,一会追踪用于几何数据、颜色等的缓存。

图片 13iosOpenGl

iOS操作系统不辅助直接待上访谈front frame buffer和back frame
buffer,有操作系统来操作,这样的话方便随时使用Core Animation
Compositor来支配展现的结尾外观。

以此也很好通晓,因为core
animation是贰个单独的经过,不独有要生成我们友好使用里面包车型客车layer,还要调节app之间的切换,所以那是个系统的职业,没须要暴流露来。

layer保存了富有绘制操作的结果。比如,iOS提供了目的有效的在layer上制图录制,在layer上制图淡入淡出的图片。layer
content也能够用Core Graphics来绘制,也可以用OpenGL ES直接绘制。不过Core
Animation Compositor使用的是OpenGL ES来治本GPU,混合图层和贾环frame
buffer的。所以整个通过Core Animation的绘图最终都会涉嫌OpenGL ES。

GitHub传送门

https://github.com/weixin1/OpenGLES-Learn

缓存的变通、开端化和删除,供给消耗费时间间来一起图形管理器和CPU。

OpenGL ES函数

  • EAGLContext:封装八个特定于有个别平台的OpenGL ES上下文 实例。
    EAGL 可能是 Embedded Apple GL

  • EnclaveGBA颜色:红玉绿和发光度。(Red、Green、Blue、Alpha)

  • glBufferData方法中,GL_STATIC_DRAW告诉上下文,缓存中的内容符合复制到GPU调整的内部存储器,因为很少对其张开更动;GL_DYNAMIC_DRAW则表示数据会频仍修改,以不相同的法门来管理。

  • 帧缓存或然有除了像素颜色渲染缓存之外的别的叠合缓存(比方说深度测验),他们能够通过在glClear()函数中制订不一致的参数来打消。

  • glVertextAttribPointer()第多个参数表示小数点一定数据是还是不是足以被改成。

  • viewDidUnload在视图被卸载时候调用,能够在此删除OpenGL
    ES缓存。(和dealloc不相同)

  • CAEAGLLyaer是CoreAnimation提供的正规层类之一,与OpenGL
    ES的帧缓存分享它的像素颜色客栈。

  • context presentRenderbuffer:GL_RENDERBUFFEWrangler让上下文调度外观并应用CoreAnimation合成器把帧缓存的像素颜色渲染缓存与其余连锁层混合起来。

  • glViewport()
    函数用来支配渲染至帧缓存的子集。(设置视口调换的视口大小)

  • 视图重新调治大小的时候,layoutSubviews会被调用。

  • CADisplayLink的新闻为重新渲染三个现象提供了优质的触发器,渲染速度大于突显刷新速度是萧条。

  • GLKBaseEffect会生成直接在GPU上运维的GLSL。

着色器

GLKit提供的GLKBaseEffect是对OpenGL ES中的着色器的卷入。
下边的代码创设GLKBaseEffect,何况把GLKBaseEffect的纹理功能张开,然后将GLKTextureInfo赋值给GLKBaseEffect的纹理

图片 14

GLKBaseEffect

缓存

GPU和CPU都有投机占领的内部存储器区域,OpenGL
ES为四个内部存款和储蓄器区域间的数据交流定义了缓存的定义。缓存是指图形管理器能够调节和保管的总是的RAM。大约全部程序提供给GPU的数量都应西当放入缓存中。为缓存提供数占领如下7个步骤:

  1. Generate-> glGenBuffers()–伏乞OpenGL ES生成graphics
    processor调节的独步天下标识。
  2. Bind-> glBindBuffer()–告诉OpenGL ES使用缓存管理接下去的演算。
  3. Buffer Data-> glBufferData() or glBufferSubData()–告诉OpenGL
    ES为当下绑定的buffer分配并开始化丰盛多的接连内部存款和储蓄器(常常是从CPU调节的内部存款和储蓄器复制数据到GPU调节的内存)。
  4. Eable or Disable -> glEnableVertexAttribArray() or
    glDisableVertexAttribArray()–告诉OpenGL
    ES在接下去的渲染中是还是不是接纳缓存中的数据。
  5. Set Pointer -> glVertexAttribPointer()–告诉OpenGL ES
    buffer里的数据类型和会见buffer数据的任何内部存款和储蓄器偏移量。
  6. Draw -> glDrawArrays() or glDrawElements()–告诉OpenGL
    ES使用当前绑定的和能够应用的缓存来渲染部分依旧全体场景。
  7. Delete -> glDeleteBuffers()–告诉OpenGL
    ES去删除在此之前生成的缓存和假释相关联的能源。

流程

CAEAGLLyaer是CoreAnimation提供的正儿八经层类之一,与OpenGL
ES的帧缓存分享它的像素颜色商旅。

光线

  • GPU首先为每一个三角形的终端举办光线总计,再把结果开展插值,得出每个片元的末段颜色。
  • OpenGL ES的灯的亮光模拟包罗:情状光、漫反射光、镜面反射光。
  • 唯有种种光源的情形光部分才会照射到三角形的背后。

光明与几何图形互相效用的重中之重:总计出各样几何物体照射和散落出来多少光线。通过计算每个三角形与光的取向的垂直角度。

  • 矢量积:左手腕则。
    VectorA × VectorB 的矢量积 和 B × A 是来势相反的。
  • 光明总结依赖于表面法向量。法向量也是单位向量。

在GLKBaseEffect的灯的亮光开启后,电灯的光决定了渲染的颜料;常量的颜料和终点的颜色将被忽略。(constantColor属性仅适用于渲染单调不发光的物体)

  • 对于立体表面来说,法线是有偏向的:一般的话,由立体的中间针对外界的是法线正方向,反过来的是法线负方向。
  • 缩放对灯的亮光有机密的影响:二个法向量被缩放后,就可能不再是叁个单位向量。
    GL基特的GLKBaseEffect类生产的GLSL会按需正规法向量。

安装纹理贴图

咱俩把一张图片加载成为要渲染的纹路,由于纹理坐标系是跟手提式无线话机彰显的Quartz
2D坐标系的y轴正好相反,纹理坐标系使用左下角为原点,往上为y轴的正在,往右是x轴的正在,所以须要安装一下GLKTextureLoaderOriginBottomLeft
GLKit中使用GLKTextureInfo意味着纹理对象。

图片 15

纹理

坐标种类及转变

在原先使用3D马克斯(制作3D模型的软件)的时候就能够有成都百货上千的坐标系可以挑选,在做游戏的时候也是足以选取世界坐标恐怕是本地坐标,原本是OpenGL规定的正统。

图片 16坐标系转变

对实体的每种点做矩阵转换正是对全体实体的展开运动、缩放、旋转。OpenGL封装好了转移的矩阵,只须求大家传入退换的值就可以调换对应的矩阵。与iOS里面包车型大巴CoreGraphics或许是CALayer的transform矩阵转换是大同小异的。列举一下常用的三种转移:

  • 围绕三个点旋转:1)平移到所急需的团团转大旨。2)施加所必要的旋转。3)使用与第一步相反的平移值平移回来
  • 围绕三个点缩放:1)平移到所须要的缩放核心。2)施加想要的缩放。3)使用与第一步相反的平移值平移回来

透视投影是以贰个”平截投体“,例下图所示:

图片 17平截投体

其安装的代码如下所示(所传颂的品质正是规定平截投体的轻重的):

self.baseEffect.transform.projectionMatrix = GLKMatrix4MakeFrustum( -1.0 , //left 1.0 , //right -1.0, //bottom 1.0, //top 1.0, //near 60.0); //far

剩下的还也有动画、读取模型、特效那些剧情,那部分从未有过稳重的达成demo,而是大约看了眨眼间间,近日看了二十30日游相关的内容,这一个部分感到正是极其为十七日游和3D定制的,和应用类的ios开采有个别靠不上,所以这里等日后再深造。动画正是在单位时间内对稳定做矩阵变化,骨骼动画便是拟订父节点,父节点发生矩阵变化的时候一样也要对子节点做转换,那样的话就能有联合浮动的意义了。因为传递到GPU的都以定位消息,那么模型其实正是顶点新闻的文书,读取的经过正是抽出顶点、纹理等新闻。

5.创办设置上下文

GLKView *view = (GLKView *)self.view;

// 设置view的上下文

view.context = [[EAGLContext
alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];

// 设置当前上下文

[EAGLContext setCurrentContext:view.context];

纹理

纹理

二个用来保存图像颜色的OpenGL ES缓存。
渲染进度中的取样只怕会导致纹理被拉伸、压缩、翻转等。

图表展现

不易于,经过地点这么多步骤,我们算是把一张图片突显到了手提式有线电话机荧屏上,来看一下结出。可是,那唯有是OpenGL
ES万里长征的率先步,继续加油啊!

图片 18

渲染结果

CPU & GPU

CPU能够做到每秒十亿次的演算,但是它只好够每秒读写内部存款和储蓄器两亿次,所以要在各种数据上实践5个也许越多的演算,不然的话管理器的质量会处于次优状态,这种景色称为“数据饥饿”。同样,GPU上更引人瞩目,GPU每秒试行数十亿次不过每秒只可以访谈内存2亿次。所以GPU总是受限于内部存款和储蓄器的拜见品质上,而且普通须求在每块数据上试行10~叁19回运算才不会耳闻则诵总体的图纸输出。

4.扬言二个GLKBaseEffect 实例对象,并起初化属性。

GLKBaseEffect类提供了模拟OpenGL ES
1.1照明和阴影模型提供的相当多表现的着色器,包蕴材料,照明和纹理。
基本功效允许最多两个光和三个纹理应用于场景。

GLKBaseEffect会调换直接在GPU上运维的Shading Language
程序。GLKBaseEffect是工程师静心于接纳的机能和图表概念,而没有须要学习Shading
Language。

@property (nonatomic, strong) GLKBaseEffect *baseEffect;

//开首化着色器

self.baseEffect = [[GLKBaseEffect alloc]init];

// 二个开关

self.baseEffect.useConstantColor = GL_TRUE;

// 设置三角形颜色

self.baseEffect.constantColor = GLKVector4Make(0.5f, 0.5f, 1.0f,
1.0f);

首先个参数是GL_TEXTURE_2D

视口坐标

帧缓存中的像素地点叫做视口坐标。视口调换的结果是装有绘制的几何图形都被拉伸以适应荧屏尺寸。

渲染上下文

先来看一下前后相继中定义的品质:

图片 19

概念的属性.png

EGL连接了OpenGL ES与地点原生窗口(譬喻iOS系统)。Apple提供了投机的EGL的API,正是EGAL,EAGLContext纵使属于EGAL
EAGLContext是渲染上下文,OpenGL ES
必需有三个可用的上下文技能绘制,因为多个应用程序也许成立多个EAGLContext,所以大家必要关联特定的EAGLContext渲染表面,这一步称为“设置当前上下文

开创EAGLContext,成立的时候须求钦赐EAGLRenderingAPI类型,EAGLRenderingAPI取值类型有:kEAGLRenderingAPIOpenGLES1kEAGLRenderingAPIOpenGLES2kEAGLRenderingAPIOpenGLES3,分别对应着OpenGL ES 1.0OpenGL ES 2.0OpenGL ES 3.0,这里我们采取2.0。

图片 20

创建EAGLContext

图片 21

安装当前上下文

设置controller的日前上下文是刚刚创制的EAGLContext,设置颜色缓冲区的格式为RGBA8888的格式

图片 22

安装当前view的上下文和颜色缓冲区格式

CPU & GPU

图片 23流程图

CPU可以完结每秒十亿次的演算,可是它只好够每秒读写内部存款和储蓄器两亿次,所以要在各种数据上施行5个也许越来越多的演算,不然的话管理器的性质会处于次优状态,这种场所称为“数据饥饿”。同样,GPU上更明显,GPU每秒施行数十亿次不过每秒只好访问内部存款和储蓄器2亿次。所以GPU总是受限于内部存款和储蓄器的看望质量上,並且普通须要在每块数据上实行10~33遍运算才不会潜濡默化总体的图样输出。

效果图

图片 24

透视(perspective)

glTexImage2D

  • 先是个参数是GL_TEXTURE_2D
  • 其次个参数用于钦定MIP贴图的起来细节品级,若无采纳MIP必得尽管0
  • 其多个参数是点名纹理缓存每一个纹素须要保留的信息数据,对于iOS设备,有GL_RGB和RL_RGBA
  • 第四、三个参数钦点图像的肥瘦和冲天,必得是2的幂
  • 第七个 明确纹理纹素的界限大小,OpenGL ES中三翻五次被设置为0
  • 第1个钦定开首化缓存所用的图像数据中的每一种像素要保存的消息,在OpenGL
    ES中与inernalFormat
  • 第多个 纹素的位编码类型
  • 第七个 像素颜色数据的指针
<a name=”fenced-code-block”>启用通用顶点属性</a>
 /*
  index:指定通用顶点数据的索引,这个值的范围从0到支持的最大顶点属性数量减1
  功能:用于启用通用顶点属性
*/
void glEnableVertexAttribArray(GLuint index);

纹理

若是一贯动用GLKit提供的措施来起初化纹理的话是特别轻便点的,首先依照CGImage对象生成二个GLKTextureInfo对象,然后将该目的的Target和name赋值给baseEffect对象的照拂属性就能够了。在备选渲染的时候配置定位的读取准则就足以了。假若不行使GLKit的话,供给自身手动生成、绑定和安排纹理,与变化缓存类似。

  • glGenTexture(1,&id)生成纹理。
  • glBindTexture(GL_ TEXTURE_2D, id),绑定纹理。
  • glTexImage2D(GL_ TEXTURE,0,GL_RGBA,width,height,0,GL_ RGBA,GL_
    UNSIGNED_BYTE, [imageData bytes]),将图片数据保存成纹理
  • glTextParameteri(GL_ TEXTURE_2D, GL _ TEXTURE_ MIN_
    FILTER,GL_LINEA奇骏)配置纹理的体现。只要是纹理的高低大于或低于图形大小,纹理的布局形式。GL_LINEAWrangler表示的是取颜色的艺术是取相近的混合色,那样的纹理是模糊和潜移暗化的。

当纹理总括出二个一心不透明的fragment color的时候,会一贯沟通调frame
buffer中的color render buffer中对应的pixel
color。假如存在不透明的话就必要混合。通过glEnable来拉开混合。glBlendFunc(sourceFactor,destinationFactor)来安装混合函数。在每帧渲染的长河中需求替换baseEffect中的Target和name,然后[baseeffect
prepareToDraw]会共同状态,那样的话就能够绘制八个纹理了。GLKit提供了多种纹理的渲染,能够一向给baseEffect钦点多少个纹理,并且钦赐混合格局,就可以间接混合两种纹理。这也直接能够看出CoreAnimation的层设计也是以此为基础的。

OpenGL ES的电灯的光模拟包蕴:情形光、漫反射光、镜面反射光。

教程

OpenGLES入门教程1-Tutorial01-GLKit
OpenGLES入门教程2-Tutorial02-shader入门
OpenGLES入门教程3-Tutorial03-三维调换
OpenGLES入门教程4-Tutorial04-GLKit进级
OpenGLES进级教程1-Tutorial05-地球明亮的月
OpenGLES进级教程2-Tutorial06-光线
OpenGLES进级教程3-Tutorial07-粒子效果
OpenGLES晋级教程4-Tutorial08-帧缓存

“启用顶点数组” 和 “钦点顶点属性”

先来讲一下终极属性,顶点数据也叫顶点属性,内定各个终端的数额,每一种终端的多少足以每个终端挨个设置,正是顶点数组,也得以用一个常量设置于具有的巅峰,便是常量顶点属性。比如,绘制四个青莲的三角,可以钦定多少个常量顶点属性来安装三角形的上上下下3个极点,不过结合三角形的3个极端的岗位坐标不一致,可以选拔终端数组来钦点。
笔者们地方已经定义了终点数组:

//启用顶点地点(坐标)数组,以前说过opengl是状态机,需求哪些动静就开动什么动静
glEnableVertexAttribArray(GLKVertexAttribPosition);

 GLfloat vertexs[] = {
        -0.5, -0.5, 0,     0.0, 0.0,   //左下
        -0.5,  0.5, 0,     0.0, 1.0,   //左上
         0.5,  0.5, 0,     1.0, 1.0,   //右上
         0.5, -0.5, 0,     1.0, 0.0,   //右下
    };

选用完CocosCreator做了三个跑酷类的简易游戏之后,对图像渲染之类的比较感兴趣,以前学习过CoreAnimation之后,把iOS里面的进度领会了弹指间,不过并从未尖锐明白到GPU的开始和结果。OpenGL
ES正是查漏补缺吧。

glTexParameteri参数

投影转变

视锥体的近平面不能够用z地方小于0,固然是十分小的z的值也是有标题。
从近平面到远平面的离开限制会炫彩为深度缓存中的深度范围,当GPU总结保存在深度缓存中的值时,大幅度大概过小的近平面距离会产生数学舍入固有误差
OpenGL
ES使用一个名字为视域的几何图形来调整三个气象生成的片元是或不是会显得在最终的渲染结果中。
OpenGL ES私下认可为指入荧屏的负的Z坐标轴,GLKMatrixMakeFrustum()
产生三个指入显示器的蕴藏正的Z坐标轴的视域(view volume)。

多种纹理

MIP贴图

高细节的纹理,沿着S、T轴存款和储蓄越来越多的纹素,收缩GPU取样的数额增加渲染质量,但会扩充内部存款和储蓄器。

GL_TEXTURE_WRAP_T表示V坐标超越了T坐标

为缓存提供数据

1、生成(Generate),为缓存生成独占鳌头的标记符。
2、绑定(Bind),分明接下去运算使用的缓存。
3、缓存数据(Buffer
Data),为绑定的内部存款和储蓄器分配并显示丰裕的内部存款和储蓄器,把CPU调节的内存数据复制到分配的内部存款和储蓄器。
4、启用也许禁止(Enable、Disable),鲜明在接下去的渲染是不是接纳缓存。
5、设置指针(Set Pointer),鲜明缓存中数量的门类和数指标偏移值。
6、绘图(Draw),绘制部分依旧全体场景。
7、删除(Delete),删除生产的缓存並且释放能源。

缓存的改换、最先化和删除,需求消耗费时间间来一齐图形管理器和CPU。
GPU在剔除贰个缓存在此之前必需等待缓存相关的运算停止,要是频仍变动和删除缓存,GPU未有足够时间开展渲染。

变换

光栅化

转移几何样子数据为帧缓存中的颜色像素,叫做点阵化(rasterizing),也叫光栅化。
种种颜色像素叫做片元(fragment)。

第四、四个参数钦命图像的肥瘦和可观,必得是2的幂

数量饥饿

CPU长于运算,读写内存非常慢,当CPU的性能因为等待内部存款和储蓄器读写而处于次优状态时,这种次优状态就称为数据饥饿。

视图重新调治大小的时候,layoutSubviews会被调用。

深度测验

  • 每便渲染一个片元,片元的纵深(片元与视点之间的偏离)被总括出来并与深度缓存中为片元地点保存的值实行相比:选取深度值更加小(更就像视点)的片元来,替换在像素颜色渲染缓存中对应地点的水彩和深度缓存的呼应深度值。

  • 深度缓存为GPU提供了二个存放总括出来深度值的缓存,并且用来调控像素颜色渲染缓存中片元的交流。
    GL基特别支部持19人和十几人来保存深度值的吃水渲染缓存。

  • 纵深抵触(Z-fighting),多少个片元的纵深特别周围,深度缓存未有假设的快慢来差距,最后的片元颜色常常在大概之间往来闪烁,创制三个可知的打扰。

  • 不采纳GLKit协理,管理一个OpenGL ES深度缓存必要的步子:
    1、Generate(生成)—— 生成不二法门的标志符
    2、Bind(绑定)—— 明确使用的缓存
    3、Configure Storage (配置存款和储蓄) —— 钦赐大小
    4、 Attach(附加) —— 附加到二个帧缓存

与三个Core
Animation分享内部存款和储蓄器的像素颜色渲染缓存在层调解大时辰会活动调节大小。别的缓存,举例深度缓存,不会活动调治大小
能够在layoutSubviews方法里面删除现存的深度缓存,并成立三个新的与像素颜色渲染缓存的新尺寸相相配的深浅缓存。

视锥体的近平面无法用z地点小于0,纵然是十分小的z的值也许有题目。

变换

八个坐标系之间转移顶点坐标。

  • 核心转移
    四个基本转移
    平移(translation)
    旋转(rotation)
    缩放(scale)
    透视(perspective)

GPU在剔除贰个缓存从前必得等待缓存相关的运算甘休,假诺再三退换和删除缓存,GPU未有丰硕时间展开渲染。

纵深缓存为GPU提供了三个存放总计出来深度值的缓存,何况用来决定像素颜色渲染缓存中片元的置换。

GPU首先为各类三角形的极端进行光线总计,再把结果举行插值,得出每一种片元的最终颜色。