OGL纹理颜色组合函数glTexEnvf

OGL纹理函数就是对纹理颜色,多边形片段本身的颜色(指定的,或是来自光照得到的多边形顶点颜色),环境颜色 等颜色进行组合的函数。在OGL 2.0以后基本用Fragment Shader可编程来实现颜色的组合。但是了解传统的固定管线的纹理颜色组合函数对于正确的编写Fragment Shader是很有好处的。
可以通过glTexEnvf函数来指定纹理函数。
函数原型:
glTexEnvf (GLenum target, GLenum pname, GLfloat param);
例如:glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
target可以是:GL_TEXTURE_ENV, GL_TEXTURE_FILTER_CONTROL

1.如果target是GL_TEXTURE_FILTER_CONTROL ,pname必须是GL_TEXTURE_LOD_BIAS

param是一个浮点值作为mipmap时候纹理层级的定位用的偏移参数。

2.如果target是GL_TEXTURE_ENV,且pname是GL_TEXTURE_ENV_MODE

那么param必须是GL_REPLACE,GL_DECAL,GL_MODULATE; GL_ADD, GL_BLEND,GL_COMBINE颜色组合操作类型之一,或者GL_TEXTURE_ENV_COLOR直接提供一个色调进行组合颜色。

1)颜色操作的格式:

纹理数据有6种基本格式,GL_ALPHA,GL_LUMINANCE,GL_LUMINANCE_ALPHA,GL_INTENSITY, GL_RGB, GL_RGBA,或者其它格式类似GL_LUMINANCE6_ALPHA2,GL_R3_G3_B2为纹理成分指定分辨率, 但是纹理计算最终是在RGBA模式下进行的,会对上述颜色成分进行提取,提取规则见OGL RED BOOK page 282.

纹理颜色组合主要是两方面的颜色,Cf来自fragment的颜色(主要来自顶点指定的颜色,或顶点指定的法向量得到的光照颜色,或者来自光照贴图的颜色),Cs来自纹理插值映射后的纹理单元的颜色。
还有一个来自GL_TEXTURE_ENV_COLOR指定的环境颜色,该颜色主要是环境色调也属于Cf。

2)颜色的组合方法:

1)替换GL_REPLACE ,主要用途有GL_DECAL地表贴花,绘制不透明的物体。
2)标量乘以颜色各个分量, 主要用途有绘制透明度的物体。
3)颜色加法,各个分量的颜色分别对应相加,主要用途有高光效果,容易太强烈。
4)颜色乘法,各个分量的颜色分别对应相乘,主要用途有光照后和纹理颜色的混合。
GL_DECAL是贴花,GL_RGB模式下是直接用纹理颜色替换, GL_RGBA模式下:Cs*As+Cf*(1-As),alpha值是As。

3)纹理组合函数:

target是GL_TEXTURE_ENV下,使用了GL_COMBINE,那么启用了纹理组合函数。例如:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
那么就可以为混合设置混合函数,设置混合函数的参数,还可以对参数进行过滤选择。
设置可编程纹理组合器函数
在启用了纹理组合器后,glTexEnvf(GL_TEXTURE_ENV, pname, param)中设置的纹理组合函数,pname可以是GL_COMBINE_RGB表示对颜色成分进行操作,也可以是GL_COMBINE_ALPHA表示对alpha成分进行操作。
参数类型为arg0, arg1, arg2:
// arg0
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
// arg0 + arg1
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
// arg0 + arg1 - 0.5
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED);
// arg0 - arg1
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT);
// arg0*arg2 + arg1*(1-arg2)
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
设置混合函数参数来源和过滤操作:
GL_SOURCEi_Color, 其中i代表上述混合函数的参数,Color代表RGB或ALPHA;说明第几个参数的颜色成分的来源。
参数来源的类型parameter:
GL_PREVIOUS是当前片段内的颜色(也就是之前光照,Color或是多重纹理映射前面级别的纹理混合后得到的结果),
GL_TEXTURE说明颜色来源于当前纹理,GL_TEXTUREi多重纹理映射下指定是第i层级的纹理,GL_CONSTANT是GL_TEXTURE_ENV_COLOR指定的颜色。
GL_PRIMARY_COLOR是指进行纹理处理之前的光栅化片断得到的颜色。

GL_OPERANDi_Color,其中i代表上述混合函数的参数,Color代表RGB或ALPHA;说明对传入的颜色成分进行的过滤操作。
参数操作类型parameter:
GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA或GL_ONE_MINUS_SRC_ALPHA。
例如:
static GLfloat constColor[4] = {0.0, 0.0, 0.0, 0.0};
constColor[3] = 0.2; // alpha值赋值了0.2
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);
glBindTexture(GL_TEXTURE_2D, texName[0]);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
// 插值模式的混合函数
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);

glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
// 多级纹理中的前一个操作中fragmentColor, 这里只有一个层级纹理,所以是
// fragmentColor
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

// 用常量颜色,但是这里取alpha值为颜色值
glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
混合操作的含义是:
texColor*(0.2, 0.2, 0.2) + fragmentColor*(0.8, 0.8, 0.8);

对颜色进行缩放:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 1.0);
glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);

3.如果target是GL_POINT_SPRITE,并且pname是GL_COORD_REPLACE

那么把param参数设置为GL_TRUE那么可以启用围绕一个点块纹理的坐标进行迭代。
使用点块纹理:
glPointSize(10.0);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
// 点块纹理的的s坐标规定从左向右为[0,1], t坐标可以设置,这里设置为左下角为0,右上角1.
glPointParameter(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
glEnable(GL_POINT_SPRITE);

你可能感兴趣的:(OpenGL图形学)