1.OpenGLES提供了一个为几何图形中的每个顶点设置不同颜色的方法。
2.纹理可以控制一个渲染的三角形中的每个像素的颜色。
3.纹理是一个用来保存图像的颜色元素值的OpenGLES缓存。
4.当用图像初始化一个纹理缓存之后,在这个图像中的像素变成了纹理中的一个纹素。与像素类似,纹素保存颜色数据。
5.纹理坐标系为S、T、R轴。3D纹理就是一个层饼,一个在拥有R、S和T轴沿着R轴堆叠的多个2D纹理的层饼。
6.帧缓存的像素坐标位置叫做视口(viewport)坐标。
7.一个场景中的每个几何坐标的转换都要耗费一打的矢量数学运算,但是GPU经常会在每秒执行10亿次的矢量运算。与内存读取相比,这个速度是如此之快,以至于这个转换在实际的应用中几乎不会产生性能影响。
8.在每个顶点的X、Y、Z坐标被转换为视口坐标后,GPU会设置转换成三角形内的每个像素颜色。转换几何形状数据数据为帧缓存中的颜色像素的渲染步骤叫做点阵化(rasterzing),每个颜色像素叫做片元(fragment)。当OpenGLES没有使用纹理时,GPU会根据包含该片元的对象的顶点的颜色来计算每个片元的颜色。当设置了使用纹理后,GPU会根据在当前绑定的纹理缓存中的纹素来计算每个片元的颜色。
9.程序需要制定怎么对齐纹理和顶点,以便让GPU知道每个片元的颜色由哪些纹素确定。这个对齐的过程叫做映射(mapping)。
10.U----->S,V------>T。
11.渲染过程中的取样可能会导致纹理被拉伸、压缩、甚至翻转。
12.
glTexParameterf(self.target, parameterID, value);
void glTexParameterf (GLenum target,GLenum pname,GLfloat param);函数来配置每个绑定的纹理,以便让OpenGLES知道怎么处理可用纹素的数量与需要被着色的片元的数量不匹配问题。
GL_TEXTURE_MAG_FILTER 表示纹素不够
GL_TEXTURE_MIN_FILTER表示片元不够
GL_LINEAR展示线性插值
GL_NEAREST展示最邻近差值取样模式
13.MIP贴图是一个为纹理存储多个细节级别的技术。可以减少GPU取样的数量来提高渲染的性能,但是使用MIP贴图会使每个纹理需要的内存增加1/3。
14.
SceneVertex定义了顶点坐标和纹理坐标。
vertices数组初始化了纹理坐标和位置坐标。
15.
GLKTextureInfo*textureInfo = [GLKTextureLoader textureWithCGImage:imageRef options:nil error:NULL];
这个方法接收一个CGImageRef使得图像的数据源可以是任何Core Graphics支持的形式。
GLKTextureLoader会自动调用glTexParameteri()方法来为创建的纹理缓存设置OpenGLES取样和循环模式。
16.手动实现一个GLKTextureLoader
AGLKTextureLoader
AGLKTextureInfo是一个封装了纹理缓存的有用信息的简单类,例如相应的OpenGLES纹理缓存的标识符以及纹理的图像尺寸。
AGLKTextureLoader的实现展现了Core Graphics 和 OpenGLES的整合,提供了与GLKit中GLKTextureLoader相似的功能。
glGenTextures()和glBindTextures()函数与用于顶点缓存的命名方式相似的函数的工作方式相同。
void glTexImage2D (GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid* pixels);
函数复制图片像素的颜色数据到绑定的纹理缓存中。
第一个参数是用于2D纹理的GL_TEXTURE_2D.
第二个参数用于指定MIP贴图的初始细节级别。如果不用MIP,则是0.
第三个参数internalFormat,用于指定在纹理缓存内每个纹素需要保存的信息的数量。iOS设备分GL_RGB,GL_RGBA两种。
第四个和第五个参数用来指定图像的宽度和高度。高度和宽度需要是2的幂。
第六个参数border一直用来确定围绕纹理的纹素的一个边界大小,但是在OpenGLES中总是被设置为0。
第七个参数format用于指定初始化缓存所使用图像数据中的每个像素需要保存的信息。这个参数总是和internalFormat相同。
第八个参数用于指定缓存中的纹素数据所使用的位编码类型。GL_UNSIGNED_BYTE可提供最佳最佳色彩质量,但是它的每个纹素中每个颜色元素的保存需要一字节的存储空间。不管为为每个颜色元素保存的位数量是多少,颜色元素的强度最终都会被GPU缩放到0.0到1.0的强度之间。
第九个参数是一个要被复制到绑定的纹理缓存中的图片的像素颜色数据的指针。
CG函数把指定的cgImage拖入imageData指定的字节中。CG是把cgImage拖入一个适当大小的CG上下文中,这个过程的一个副作用是把图像的尺寸调整为2的幂。图像在绘制的过程中被反转了。反转Y 轴是必须的。
函数最后返回imageData和数据对应的宽度和高度。
17.
glEnable(GL_BLEND);
void glEnable (GLenum cap);
函数开启混合。
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
void glBlendFunc (GLenum sfactor,GLenum dfactor);
函数来设置混合函数。sfactor参数用于指定每个片元的最终颜色元素是怎样混合的。dfactor参数用于指定在目标帧缓存中已经存在颜色元素怎样影响混合。
源因子和目标因子是可以通过glBlendFunc函数来进行设置的。glBlendFunc有两个参数,前者表示源因子,后者表示目标因子。这两个参数可以是多种值,下面介绍比较常用的几种。
GL_ZERO: 表示使用0.0作为因子,实际上相当于不使用这种颜色参与混合运算。
GL_ONE: 表示使用1.0作为因子,实际上相当于完全的使用了这种颜色参与混合运算。
GL_SRC_ALPHA:表示使用源颜色的alpha值来作为因子。
GL_DST_ALPHA:表示使用目标颜色的alpha值来作为因子。
GL_ONE_MINUS_SRC_ALPHA:表示用1.0减去源颜色的alpha值来作为因子。
GL_ONE_MINUS_DST_ALPHA:表示用1.0减去目标颜色的alpha值来作为因子。
除 此以外,还有GL_SRC_COLOR(把源颜色的四个分量分别作为因子的四个分量)、GL_ONE_MINUS_SRC_COLOR、 GL_DST_COLOR、GL_ONE_MINUS_DST_COLOR等,前两个在OpenGL旧版本中只能用于设置目标因子,后两个在OpenGL 旧版本中只能用于设置源因子。新版本的OpenGL则没有这个限制,并且支持新的GL_CONST_COLOR(设定一种常数颜色,将其四个分量分别作为 因子的四个分量)、GL_ONE_MINUS_CONST_COLOR、GL_CONST_ALPHA、 GL_ONE_MINUS_CONST_ALPHA。另外还有GL_SRC_ALPHA_SATURATE。新版本的OpenGL还允许颜色的alpha 值和RGB值采用不同的混合因子。但这些都不是我们现在所需要了解的。毕竟这还是入门教材,不需要整得太复杂~
举例来说:
如果设置了glBlendFunc(GL_ONE, GL_ZERO);,则表示完全使用源颜色,完全不使用目标颜色,因此画面效果和不使用混合的时候一致(当然效率可能会低一点点)。如果没有设置源因子和目标因子,则默认情况就是这样的设置。
如果设置了glBlendFunc(GL_ZERO, GL_ONE);,则表示完全不使用源颜色,因此无论你想画什么,最后都不会被画上去了。(但这并不是说这样设置就没有用,有些时候可能有特殊用途)
如 果设置了glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);,则表示源颜色乘以自身的alpha 值,目标颜色乘以1.0减去源颜色的alpha值,这样一来,源颜色的alpha值越大,则产生的新颜色中源颜色所占比例就越大,而目标颜色所占比例则减 小。这种情况下,我们可以简单的将源颜色的alpha值理解为“不透明度”。这也是混合时最常用的方式。
如果设置了glBlendFunc(GL_ONE, GL_ONE);,则表示完全使用源颜色和目标颜色,最终的颜色实际上就是两种颜色的简单相加。例如红色(1, 0, 0)和绿色(0, 1, 0)相加得到(1, 1, 0),结果为黄色。
注意:
所 谓源颜色和目标颜色,是跟绘制的顺序有关的。假如先绘制了一个红色的物体,再在其上绘制绿色的物体。则绿色是源颜色,红色是目标颜色。如果顺序反过来,则 红色就是源颜色,绿色才是目标颜色。在绘制时,应该注意顺序,使得绘制的源颜色与设置的源因子对应,目标颜色与设置的目标因子对应。不要被混乱的顺序搞晕了。
纹理混合这块揭示了iOS Core Animation技术的基本原理。每个Core Animation层使用一个对应的openGLES的像素颜色渲染缓存来保存像素颜色数据。每个层的像素颜色数据作为一个openGLES纹理缓存,并且纹理缓存会使用glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)函数来与后帧缓存混合在一起。
18.多重纹理方法:
第一张图片是3_4例子,是多通道渲染。很多有用的可视效果可以通过片元颜色与像素颜色渲染缓存中现存的颜色相混合来实现,但是这个技术有两个主要的缺点:每次显示更新时几何图形必须要被渲染一到多次,混合函数需要从像素颜色渲染缓存读取颜色数据以便于片元颜色混合。然后结果被写回帧缓存。当带有透明度数据的多个纹理层叠时,每个纹理的像素颜色渲染缓存的颜色会被再次读取、混合、重写。
内存访问限制了性能,因此多通道渲染是次优的。
多重纹理方法:所有现代的GPU都能够同时从至少两个两个纹理缓存中取样纹素。GLKit的GLKBaseEffect类同时支持两种纹理。执行纹素取样和混合的硬件组件叫做一个纹理单元或者取样器。
GLintiUnits;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &iUnits);
如果应用中需要超过两个以上的纹理单元,在确定一个单独的通道中可以结合多个纹理之前,需要使用以上的代码。
多重纹理另外一个配置选项,来自3_5例子:
GLKEffectPropertyTexture的envMode属性用于配置混合模式。
GLKTextureEnvModeModulate模式会让所有的为灯光和其他效果计算出来的颜色与从一个纹理取样的颜色相混合。
与3_4加载相同的两个纹理,但是不再明确地启动与帧缓存的像素颜色渲染缓存的混合。
第二个self.baseEffect.texture2d1.envMode=GLKTextureEnvModeDecal;模式会使用一个于glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);类似的方程式来混合第二个和第一个纹理。
19.自定义纹理:
3_6例子,一个用GLKBaseEffect生成的glsl语言实现绘制正方体。
另一个用自定义的shading language.