采样器对象 Sampler Objects
如第8.22节所述,用于纹理处理的状态可以分为两类。GL纹理对象包括这两类状态。第一类表示维度和其他图像参数,第二类表示采样状态。此外,可以创建一个采样器对象,仅封装纹理对象的采样状态。
生成采样器对象
void glGenSamplers( sizei count, uint *samplers );
返回在samplers
中的count
个之前未使用的采样器对象名称。0
被GL保留,表示未将采样器绑定到采样器单元。
它们只有在首次用作BindSampler
、SamplerParameter
、GetSamplerParameter*
或IsSampler
函数的参数时才会获取状态。首次在这些函数中使用时,生成的采样器对象将使用表23.18中列出的所有状态和相同的初始值进行初始化。
创建采样器对象
void glCreateSamplers( sizei n, uint *samplers );
返回n个先前未使用的采样器名称,每个名称代表一个新的采样器对象,它是一个状态向量,包含表23.18中列出的所有状态和相同的初始值。
绑定采样器对象
void glBindSampler( uint unit, uint sampler );
当一个采样器对象绑定到一个纹理单元时,它的状态将覆盖绑定到该纹理单元的纹理对象的状态。如果采样器名称为零被绑定到一个纹理单元,那么当前绑定纹理的采样器状态将变为活动状态。一个采样器对象可以同时绑定到多个纹理单元。
unit
为绑定采样器的纹理单元的从零开始的索引,sampler
设置为从先前调用GenSamplers
返回的采样器对象的名称。
如果绑定成功,绑定的采样器对象的状态不会发生变化,并且任何先前绑定到该单元的绑定都将被中断。
如果在绑定到纹理单元的采样器对象中存在状态,在调用TexParameter*
为绑定到该单元的纹理进行调用时会被拒绝,实现的行为就好像纹理是不完整的一样。例如,如果绑定到纹理单元的采样器对象上设置了TEXTURE_WRAP_S
或TEXTURE_WRAP_T
为REPEAT
、MIRRORED_REPEAT
或MIRROR_CLAMP_TO_EDGE
,并且绑定到该单元的纹理是一个矩形纹理,则该纹理将被视为不完整。
不影响绑定到纹理单元的纹理类型的采样的采样器对象状态,比如对于矩形纹理的TEXTURE_WRAP_R
,不会影响完整性。
可以通过调用GetIntegerv
并将pname
设置为SAMPLER_BINDING
来查询当前绑定的采样器。当从纹理单元解绑采样器对象(通过将名称为零的采样器对象绑定到该单元)时,修改后的状态将再次被与绑定到该纹理单元的纹理对象相关联的采样器状态所替代。
多个采样器对象绑定
void glBindSamplers( uint first, sizei count, const uint *samplers );
将count
个现有的采样器对象绑定到从first
到first+count−1
编号的纹理图像单元。如果samplers
不是NULL
,则它指定了一个包含count
个值的数组,其中每个值必须为零或现有采样器对象的名称。如果samplers
为NULL
,则从first
到first+count−1
的每个受影响的纹理图像单元将被重置为没有绑定的采样器对象。
// 相当于
for (int i = 0; i < count; i++) {
if (samplers == NULL) {
BindSampler(first + i, 0);
} else {
BindSampler(first + i, samplers[i]);
}
}
设置采样器对象的每个参数
由采样器对象表示的参数是第8.10节中描述的参数的子集。通过调用以下函数之一设置采样器对象的每个参数:
void glSamplerParameter{if}( uint sampler, enum pname, T param );
void glSamplerParameter{if}v( uint sampler, enum pname, const T *param );
void glSamplerParameterI{i ui}v( uint sampler, enum pname, const T *params );
其中,sampler
是先前通过调用GenSamplers
保留的采样器对象的名称。pname
是要修改的参数的名称,param
是该参数的新值。pname
必须是表23.18中的采样器状态名称之一。
未在此处和表23.18中列出的纹理状态(在表23.16-23.17中列出)以及采样器状态中的纹理状态不是采样器状态的一部分,并保留在纹理对象中。数据转换按照第2.2.1节中指定的规则执行,但有以下例外:
- 如果使用
SamplerParameterIiv
或SamplerParameterIuiv
指定TEXTURE_BORDER_COLOR
的值,则它们不会被修改,并使用整数的内部数据类型存储。如果使用SamplerParameteriv
指定,它们将使用等式2.2将被转换为浮点数。否则,这些值不会被修改并以浮点数形式存储。
修改采样器对象的参数会影响到该采样器对象绑定到的所有纹理单元。调用TexParameter
对于绑定到活动纹理单元的采样器对象没有影响。它将修改绑定到该单元的纹理对象的参数。
删除采样器
void glDeleteSamplers( sizei count, const uint *samplers );
删除采样器对象后,其名称再次变为未使用状态。如果删除一个当前绑定到一个或多个纹理单元的采样器对象,就好像对每个绑定到采样器的纹理单元调用了一次BindSampler
函数,其中unit
设置为纹理单元,sampler
设置为零。
是否为采样器对象
boolean glIsSampler( uint sampler );
如果sampler
是先前从调用GenSamplers
返回的采样器对象的名称,则IsSampler
将返回TRUE
,否则返回FALSE
。零不是采样器对象的名称。