1. 纹理映射
纹理映射,简单的理解就是把一副图像映射到图形上的过程。比如一个图片像壁纸一样贴在物体的表面。这个技术可以从过年一个特殊类型标中的着色器中查询值,例如 颜色值。现在所有OpenGL着色阶段都有纹理映射,常用的阶段为处理片元的环境中。
2. 纹理
说完纹理映射,那什么是纹理呢?纹理图(简称纹理),通常是摄像机捕获的,也可以是程序中生成的,也可以是OpenGL以纹理代替显示设备为目标渲染的。纹理是2维的,但是OpenGL也支持许多其他类型的纹理,比如 1维、3维、立方体映射、缓冲纹理、数组纹理等。
纹理由纹素组成,通常包括颜色值。也有很多实用程序把纹理看作是可以在着色器中查询的表,用于所需要的任意目的。使用步骤如下:
• 创建一个纹理对象,为它加载纹素数据
• 为顶点增加纹理坐标
• 把纹理图与着色器中将要使用的纹理采样器关联
• 在着色器中使用纹理采样器来查询纹素值
3. 纹理基本类型
OpenGL支持许多类型的维数和布局可变的纹理对象,每个纹理对象表示组成完整纹理的一组图像。每个图像可以是纹素的1维、2维或者3维数组,并且很多图像可以放在另一个图像的顶部来形成mipmap金字塔。但并不是所有的纹理都可以表示纹理数组或者形成mipmap金字塔,比如矩形纹理对象、纹理缓冲。
另外纹理可以包括1维或者2维切片的数组,这样的纹理成为数组纹理,数组的每一个元素都是一个切片,立方体映射就是纹理数组的一个示例,它共有6个面(切片),立方体映射数组表示立方体映射纹理的数组,是6个面的整数倍。
纹理也可以用于2维和2维数组纹理的多重采样纹理类型表示多种采样表面。多重采样是一个用于抗锯齿的术语,其中每个像素被赋予多个独立的颜色,然后在渲染过程中合并这些颜色来生成最终的输出颜色。多重采样纹理对于每个纹素都有几个采样(典型值在2和8之间)。
4. 纹理绑定
纹理通过纹理单元绑定到OpenGL环境,其中纹理单元用命名为GL_TEXTURE0到GL_TEXTUREi的绑定点表示,这里i是实现支持的纹理单元的数组减一。许多纹理可以绑定到同样的环境,因为同一个环境可以支持多个不同的纹理单元。
// Uniform index.
enum
{
UNIFORM_Y,
UNIFORM_UV,
UNIFORM_ROTATION_ANGLE,
UNIFORM_RANGEOFFSET,
UNIFORM_COLOR_CONVERSION_MATRIX,
NUM_UNIFORMS
};
// 0 and 1 are the texture IDs of _lumaTexture and _chromaTexture respectively.
glUniform1i(uniforms[UNIFORM_Y], 0);
glUniform1i(uniforms[UNIFORM_UV], 1);
glUniform1f(uniforms[UNIFORM_ROTATION_ANGLE], 0);
glUniform1f(uniforms[UNIFORM_RANGEOFFSET], 0);
glUniformMatrix3fv(uniforms[UNIFORM_COLOR_CONVERSION_MATRIX], 1, GL_FALSE, _preferredConversion);
CVOpenGLESTextureRef _lumaTexture;
CVOpenGLESTextureCacheRef _videoTextureCache;
CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, _context, NULL, &_videoTextureCache);
//选择当前被纹理函数改变的纹理单元
glActiveTexture(GL_TEXTURE0);
//
CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
_videoTextureCache,
pixelBuffer,
NULL,
GL_TEXTURE_2D,
GL_RED_EXT,//GL_LUM
frameWidth,
frameHeight,
GL_RED_EXT,//GL_RED_EXT
GL_UNSIGNED_BYTE,
0,
&_lumaTexture);
//绑定纹理
glBindTexture(CVOpenGLESTextureGetTarget(_lumaTexture), CVOpenGLESTextureGetName(_lumaTexture));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
....
....
glActiveTexture(GL_TEXTURE1);
....
....
纹理一旦被绑定到环境中,着色器就可以使用采样器变量来访问,而采样器变量用匹配纹理的位数来声明。纹理位数(纹理目标)和对应采样器类型(必须在着色器中使用来访问纹理中的纹素)对应如下:
目标GL_TEXTUREi | 采样器类型 | 维度 |
---|---|---|
1D | sampler1D | 1D |
1D_ARRAY | sampler1DArrary | 1D数组 |
2D | sampler2D | 2D |
2D_ARRAY | sampler2DArrary | 2D数组 |
2D_MULTISAMPLE | sampler2DMS | 2D多重采样 |
2D_MULTISAMPLE_ARRAY | sampler2DMSArrary | 2D多重采样数组 |
3D | sampler3D | 3D |
CUBE | samplerCube | 立方体映射纹理 |
ARRAY | samplerCubeArray | 立方体映射数组 |
RECTANGLE | samplerRect | 2D矩形 矩形纹理对象(GL_TEXTURE_RECTANGLE)是2维纹理的特例,表示一个简单的纹素矩形,它没有mipmap并且不能表示纹理数组。 |
BUUFER | samplerBuffer | 1D缓存 缓冲纹理(GL_TEXTURE_BUFFER)表示任意纹素的1维数组,它没有mipmap,不能聚合数组。 它的存储是用一个缓冲对象来表示的。故缓冲纹理的上边界比普通的1维纹理大的多。 缓冲纹理使任意着色器阶段的数据访问(例如顶点数据)而不用把它拷贝进纹理图像成为可能。 |