OGL纹理颜色组合函数glTexEnvf

原创 2016年08月30日 10:53:54
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);
版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/blues1021。

相关文章推荐

OpenGL中的贴图方式

http://apps.hi.baidu.com/share/detail/54807724 OpenGL为我们提供了三种纹理——GL_TEXTURE_1D、GL_TEXTURE_2D和GL_TEX...
  • abcdef8c
  • abcdef8c
  • 2012年03月02日 15:16
  • 13518

OpenGL学习二十:纹理函数

通过纹理函数(glTexEnv*())可以把纹理图像的颜色与物体表面的原先的颜色进行混合 当我们指定纹理数据时,其第三个参数internalformat可以简化为6种格式 基本内部格式 所提...

CString与char*互转、ANSI 和 UNICODE 编码及_T和L宏定义的介绍

1、简述之前在写MFC程序的时候经常会用到CString 字符串类型,自从转到Qt就转为用QString了,自然QString比CString好用多了。最近需要将CString 与 char* 进行互...

Unicode字符集下CString与char *转换 (解决中文乱码等)(转)

UniCode 下 CString 转 char* 的方法的文章有很多,但是大部分都是在互相转载,看了那么多资料,仍然没有解决乱码的问题,后来从一个论坛的一条回复里面找到了正确的方法,特此拿出来与大家...

15.1.4 可组合函数和对象

15.1.4 可组合函数和对象       创建可组合库的第二个选项,是构建一些函数或对象,表示声明性的规范,并可以执行。这限制了用组合对象所能做的操作,因为,操作是每个基元的一个固有部分...
  • hadstj
  • hadstj
  • 2011年12月12日 19:53
  • 382

OGL纹理坐标计算和纹理边框颜色环绕模式过滤方法

必须为物体分配顶点坐标和纹理坐标,顶点坐标决定在屏幕上的那个位置渲染那个顶点,纹理坐标决定了纹理图像中的那个纹理单元将分配给这个顶点( 光栅化时候顶点处理和像素处理汇合 ),然后插值纹理坐标,进行fr...

lambda高级进阶--组合函数

只有一个参数的函数可以将一个值转换成另一个值,如果你有2个这样的转换函数,那么在进行一个转换之后在进行第二个转换,其实也是一个中转换。 说到这里,先说一下我个人的一个习惯,我在写javaBean...

UVALive-7304 - Queue of Soldiers 【动态规划】【组合函数】【好题】

UVALive- 7304 - Queue of Soldiers 题目大意:士兵过山洞,必须以类似7 6 5 4 3 2 1顺序过。在第i个人之后,比i高的人都会被杀死,问如果要杀死k个人,有几种...

15 第十五章 创建可组合函数库

15 第十五章 创建可组合函数库   本章介绍 ■ 设计函数式连接符库 ■ 处理时变值 ■ 组合时变值与绘图 ■ 开发金融合同模型库       函数式...
  • hadstj
  • hadstj
  • 2011年12月09日 20:43
  • 403

11.2.3 测试组合函数

11.2.3 测试组合函数   在第11.1.2 节,我们讨论跟踪代码中的依赖关系时,使用的C# 方法,类似于上两个示例中的F# 函数,演示函数式编程使得更容易识别函数做什么,访问什么数据。这不仅...
  • hadstj
  • hadstj
  • 2015年01月11日 12:27
  • 540
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OGL纹理颜色组合函数glTexEnvf
举报原因:
原因补充:

(最多只允许输入30个字)