OpenGL ES 系列笔记二

字数 1324阅读 95

纹理:纹理是一个用来保存图像的颜色元素值的OpenGL ES缓存。

当一个图像初始化一个纹理缓存之后,在这个图像中的每一个像素变成了纹理中得一个纹素。纹素保存颜色数据,像素通常表示计算机屏幕上的一个实际的颜色点,因此,像素通常会被用作为一个测量单位,纹素存在于一个虚拟的没有尺寸的数学坐标系中。纹理坐标有一个命名为S轴和T轴的2D坐标,在一个纹理中无论有多少个纹素纹理的尺寸在S轴和T轴上永远都是0.0~1.0之间

在每个顶点的XYZ坐标转换为视口坐标后,GPU会设置转换生成三角形内的的每个顶点的每个像素的颜色,当OpenGL ES没有使用纹理时,GPU会根据每个包含了该片元对象的的顶点颜色来算每个片元的颜色,当绑定了纹理有,GPU会根据绑定的纹理计算出每个片元的颜色。

纹理映射

纹理和顶点如何对齐才能让GPU知道每个片元对应的纹素?

这个对齐的过程叫做映射,因为每个顶点除了有XYZ坐标,还会有UV坐标,每个U坐标会映射顶点在纹理中一个S轴上的位置,V则会映射到T轴上



当顶点都映射到纹理上,GPU就可以开始计算每个片元颜色了,但是并不是每次都会出现片元数 = 玟素数,这样就涉及到纹理的采样模式了

纹理采样:根据片元的纹理坐标到纹理图中提取对应位置的颜色

当出现片元与玟素个数不对应时,程序应该告诉OpenGL ES应该怎样去取样:

减小和放大过滤:

当用GL_LINEAR修饰GL_TEXTURE_MIN_FILTER,当出现玟素>片元的时候,就会从几个符合条件的玟素采用线性内插法混和玟素,从而得到片元的颜色。当使用GL_NEAREST修饰GL_TEXTURE_MIN_FILTER,如果出现纹素>片元 就会取距离UV坐标最近的一个纹素作为片元的颜色

而GL_TEXTURE_MAG_FILTER是使用在 纹素<片元的情况,当使用GL_LINEAR修饰GL_TEXTURE_MAG_FILTER时混合附近纹素作为片元的颜色,当使用GL_NEAREST时就会拾取与UV坐标最近的一个纹素并放大纹理。

越界过滤

当出现UV坐标的值小于0 或者大于1的时候,纹理坐标(0~1)就没有对应的坐标去匹配了,这时候可以设置另外两个属性去指定纹理的映射方式,此时有两个选择,要么尽可能多地重复纹理以填满映射到记得图形的整个UV区域,要么是取纹理边缘的元素去填充多出来的片元。

纹理加载


GLKTextureLoader的"-textureQWithCGImage:options:error:"方法会接收一个CGImageRef并创建一个新的包含CGImageRef的像素数据的OpenGL ES纹理缓存。GLKTextureLoader会自动调用上面定义的采样设置函数glTexParameteri()来设置取样和循环模式。

透明度、混合和多重纹理

当纹理计算出来一个完全不透明的最终片元颜色时,这个片元颜色会简单地替代任何在帧缓存的像素颜色渲染缓存内存在的对应的像素颜色。如果计算出来是半透明或者是全透明的,OpenGL ES就会使用一个混合函数来混合片元颜色与像素颜色缓存内对应的像素。通过glEnable(GL_BLEND)函数开启混合。然后通过glBlendFuns(sourceFactor,distinationFactor)来设置混合函数。最常用的代码组合

glEnable(GL_BLEND);

glBlendFunc(GL_SEC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

多重纹理混合

通过多次读写像素颜色渲染缓存来创建一个最终渲染像素的过程叫做多通道渲染。但是,由于内存收到限制,多通道渲染是次优的。可以选择更优秀的多重纹理方法。

所有当代的GPU有能够同时从至少两个纹理缓存中取样纹素,执行纹素取样的混合的硬件组件叫做一个纹理单元或者一个取样器,如果你的应用需要超过了两个纹理单元,在确定一个单独的通道中可以结合多喝个纹理之前,请使用以上代码。

多重纹理引入了另一个组合配置选项,GLKit的GLKEffercPropertyTexture类定义了三种常用的多重纹理模式:GLKTextureEnvModeReplace/GLKTextureEnvModeModelate/GLKTextureEnvModelDecalGLKEffectPropertyTexture默认使用GLKTextureEnvModeModelate模式会让所有灯光和其他效果计算出来的颜色与从一个取样的颜色相混合。

使用Shading Language自定义纹理使多重纹理更具有灵活性。

推荐阅读更多精彩内容