以前已经把纹理的渲染给弄出来了,可是又遇到一个新的问题,那就是图元装配,好比说我已经把图片给显示出来了,可是呢,并无作到让它显示到具体的位置,而跟这个位置相关的则须要靠图元装配。编程
图元装配发生在顶点着色器处理图元顶点以后,在这一阶段,执行裁剪、透视分割和视口变换操做。而光栅化是将图元转化为一组二维片断的过程,这些片断由片断着色器处理,表明能够在屏幕上绘制的像素,发生在图元装配以后。函数
能够绘制图元的包括下面的函数:对象
其中这些函数能够绘制三角形、直线和点精灵。索引
支持的图元是GL_POINTS,点精灵对指定的每一个顶点绘制,点精灵一般用于将粒子效果看成点而非正方形绘制,从而实现高效渲染。点精灵是指定位置和半径的屏幕对齐的正方形,位置描述正方形的中心,半径用于计算描述点精灵的正方形的4个坐标,。游戏
OpenGL ES中有5个绘制图元的API调用,分别是文章开头谈到那5个,这里须要注意的是,前面3个是常规的非实例化绘图,后面两个才是实例化绘图。图片
glDrawArrays用元素索引为first到first+count-1的元素指定的顶点绘制mode指定的图元。须要注意的是,这里的count并不意味着越大绘制的就越多,这里仅仅是指顶点的个数,还须要看mode,是单独的仍是相连的。内存
若是你有一个由一系列顺序元素索引描述的图元,且几何形状的顶点不共享,则glDrawArrays很好用,可是,游戏或者其余3D应用程序使用的典型对象由多个三角形网格组成,其中的元素索引可能不必定按照顺序,顶点通畅在网格的三角形之间共享,则使用glDrawElements会比较好,这有不少缘由,例如说,因为顶点重用,顶点属性数据的尺寸也较小,这也致使较小的内存占用和内存带宽需求。变量
好比画一个由2个3角形组成的正方形,左上角坐标是l,t,右下角坐标是r,b
使用glDrawArrays绘制时,画2个三角形,须要这样传:
(l,t),(r,t),(l,b)
(r,t),(r,b),(l,b)
而用glDrawElements画的话能够这样
float coord[4][2]={{l,t},{r,t},{r,b},{l,b}};
绘制时:
0,1,3
1,2,3渲染
glDrawArrays传输或指定的数据是最终的真实数据,在绘制时效能更好
而glDrawElements指定的是真实数据的调用索引,在内存/显存占用上更节省。float
几何形状实例化很高效,能够用一次API调用屡次渲染具备不一样属性(例如不一样的变换矩阵、颜色或者大小)的一个对象。这一功能在渲染大量相似对象时颇有用,例如对人群的渲染,这将会下降了向OpenGL ES引擎发送许多API调用的CPU开销处理。
glDrawArraysInstanced
glDrawElementsInstanced
那若是咱们想访问其中的实例对象时怎么办呢?有两种方法,分别是使用函数glVertexAttribDivisor,还有就是使用内建输入变量gl_InstanceID做为顶点着色器中的缓冲区索引,以访问每一个实例的数据,不过前提是你使用的是几何形状实例化API调用,好比你使用的是非实例化绘图调用,那么gl_InstanceID将不会保存当前图元实例的索引。
使用图元重启后,能够在一次绘图调用中渲染多个不相连的图元,以前咱们绘制不相连的也就是使用glDrawArrays,这对于下降绘图API调用的开销是不利的。
咱们能够经过在索引列表中插入一个特殊索引来重启一个用于索引绘图调用(如glDrawElements、glDrawElementsInstanced 或 glDrawRangeElements)的图元,这个特殊索引是该索引类型的最大可能索引,(例如,索引类型为GL_UNSIGNED_BYTE为255,而GL_UNSIGNED_SHORT则为65535)。
注意,可使用代码去启用或者图元重启。
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
前面只是讲到图元的相关知识,从这里开始便进行到真正的图元装配。
在图元装配阶段,顶点着色器输出会依次经历:裁剪,透视分割,视口变换,才会到光栅化阶段。
(不得不说,仍是OpenGL 编程指南讲得更详细一些。。。)