glTexEnv

来源:互联网 发布:阿里云上海机房地址 编辑:程序博客网 时间:2024/06/09 13:48

1. 简介

glTexEnv用来设置纹理的环境参数,纹理环境参数主要控制纹理如何与片元颜色进行计算的。

2. 函数原型

void glTexEnvf( GLenum target,    GLenum pname,    GLfloat param);void glTexEnvi( GLenum target,    GLenum pname,    GLint param); void glTexEnvfv(   GLenum target,    GLenum pname,    const GLfloat * params);void glTexEnviv(    GLenum target,    GLenum pname,    const GLint * params);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

该函数是一个函数簇,根据具体的参数类型来决定使用哪个版本的函数。 
参数描述: 
1. target:设置操作的目标,可以设置为GL_TEXTURE_ENV, GL_TEXTURE_FILTER_CONTROL 或者GL_POINT_SPRITE 
2. pname:设置项 
3. param:对panme设置项的值

3. 详细描述

  1. 当纹理环境中的target设置为GL_TEXTURE_FILTER_CONTROL的时候,pname的值必须设置为 GL_TEXTURE_LOD_BIAS,当设置pname是GL_TEXTURE_LOD_BIAS的时候,它的值是用来设置MipMap纹理层级选择公式的一个参数,具体可以参考 OpenGL API 之glTexParameter

  2. 当纹理环境中target设置为GL_TEXTURE_ENV,panme设置为GL_TEXTURE_ENV_MODE时候,对应的param的取值包括:

param取值含义GL_ADD处理方式是片段颜色加上纹理采样的颜色GL_MODULATE片段颜色与纹理采样颜色相乘GL_DECAL见下图中的表GL_BLEND两者相混合,参考下图中的表GL_REPLACE纹理颜色完全取代片段颜色GL_COMBINE参考后面的论述

纹理的格式(参考OpenGL图像格式 )包括有以下几种

纹理的基本格式颜色成分CsAlpha成分AsGL_ALPHA(0, 0, 0, 0)AtGL_LUMINANCE(Lt,Lt,Lt)1GL_LUMINANCE_ALPHA(Lt,Lt,Lt)AtGL_INTENSITY(It,It,It)ItGL_RGB(Rt,Gt,Bt)1GL_RGBA(Rt,Gt,Bt)At

我们先用一个程序感性的了解一下这些参数对于程序表现的影响:

#pragma comment(lib, "glew32.lib")#pragma comment(lib, "freeglut.lib")#pragma comment(lib, "soil.lib")#include <stdio.h>#include <gl/glew.h>#include <gl/glut.h>#include <iostream>#include <gl/soil.h>int windowWidth = 0;int windowHeight = 0;bool leftMouseDown = false;float mouseX, mouseY;float cameraAngleX, cameraAngleY;float xRot, yRot;GLuint texID;void drawCube(){    glBindTexture(GL_TEXTURE_2D, texID);    glBegin(GL_QUADS);    glColor3f(1, 0, 0);    glTexCoord2d(0.0, 0.0);    glVertex3f(-1.0f, -1.0f, 1.0f);    glTexCoord2d(1.0, 0.0);    glVertex3f(1.0f, -1.0f, 1.0f);    glTexCoord2d(1.0, 1.0);    glVertex3f(1.0f, 1.0f, 1.0f);    glTexCoord2d(0.0, 1.0);    glVertex3f(-1.0f, 1.0f, 1.0f);    glEnd();}void SetupRC(){    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);    glEnable(GL_DEPTH_TEST);    glEnable(GL_TEXTURE_2D);    int imageWidth, imageHeight;    int channels;    glGenTextures(1, &texID);    glBindTexture(GL_TEXTURE_2D, texID);    unsigned char* imageDataA = SOIL_load_image("../Data/a.png", &imageWidth, &imageHeight,        &channels, SOIL_LOAD_AUTO);    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageDataA);    unsigned char* imageDataB = SOIL_load_image("../Data/b.png", &imageWidth, &imageHeight,        &channels, SOIL_LOAD_AUTO);    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageDataB);    unsigned char* imageDataC = SOIL_load_image("../Data/c.png", &imageWidth, &imageHeight,        &channels, SOIL_LOAD_AUTO);    glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageDataC);    unsigned char* imageDataD = SOIL_load_image("../Data/d.png", &imageWidth, &imageHeight,        &channels, SOIL_LOAD_AUTO);    glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA8, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageDataD);    unsigned char* imageDataE = SOIL_load_image("../Data/e.png", &imageWidth, &imageHeight,        &channels, SOIL_LOAD_AUTO);    glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA8, imageWidth, imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageDataE);    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 1);    //如果注释掉这行代码,会导致纹理失败,这主要是因为GL_TEXTURE_MIN_FILTER使用的默认值是    //GL_NEAREST_MIPMAP_LINEAR,但是代码中却没有设置MipMap,对于GL_TEXTURE_MAG_FILTER是否设置并不重要    //因为GL_TEXTURE_MAG_FILTER默认的取值就是GL_LINEAR    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    ///////////////////////////////////////////////////////////////    ///测试glTexEnv函数的表现    //GL_TEXTURE_ENV_MODE 取值:    //1. GL_REPLACE    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);    //2. GL_MODULATE(默认取值)    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);    //3. GL_ADD    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);    //4. GL_DECAL     //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);    //5. GL_BLEND    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);    //设置与片段颜色进行混合的颜色    //GLfloat blendColor[] = { 0.8, 0.5, 0.7, 0.5 };    //glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blendColor);    SOIL_free_image_data(imageDataA);    SOIL_free_image_data(imageDataB);    SOIL_free_image_data(imageDataC);    SOIL_free_image_data(imageDataD);    SOIL_free_image_data(imageDataE);    glBindTexture(GL_TEXTURE_2D, 0);}void RenderScene(void){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();    glTranslated(0, 0, -5);    glRotated(cameraAngleY*0.5, 1, 0, 0);    glRotated(cameraAngleX*0.5, 0, 1, 0);    drawCube();    glutSwapBuffers();}void ChangeSize(int w, int h){    windowWidth = w;    windowHeight = h;    if (h == 0)        h = 1;    glViewport(0, 0, w, h);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    gluPerspective(45.0, w*1.0 / h, 0.01, 1000.0f);    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();}void MouseFuncCB(int button, int state, int x, int y){    mouseX = x;    mouseY = y;    if (button == GLUT_LEFT_BUTTON)    {        if (state == GLUT_DOWN)        {            leftMouseDown = true;        }        else if (state == GLUT_UP)        {            leftMouseDown = false;        }    }}void MouseMotionFuncCB(int x, int y){    if (leftMouseDown)    {        cameraAngleX += (x - mouseX);        cameraAngleY += (y - mouseY);        mouseX = x;        mouseY = y;    }    glutPostRedisplay();}int main(int argc, char* argv[]){    glutInit(&argc, argv);    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);    glutInitWindowSize(800, 600);    glutCreateWindow("OpenGL");    glutReshapeFunc(ChangeSize);    glutDisplayFunc(RenderScene);    glutMouseFunc(MouseFuncCB);    glutMotionFunc(MouseMotionFuncCB);    GLenum err = glewInit();    if (GLEW_OK != err) {        fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));        return 1;    }    SetupRC();    glutMainLoop();    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197

GL_MODULATE(默认取值) 
Modulate 
GL_REPLACE 
Replace 
GL_ADD 
ADD 
GL_BLEND 
BLEND 
这些最终表现的颜色是怎么计算的呢?实际上计算的公式参考下表: 
表中:【公式参数的简要说明:后缀是v表示最终输出的颜色(也就是我们上面看到的图片颜色),后缀是p表示是片段颜色(尚未应用纹理计算previous texture stage),后缀是s表示纹理图片的颜色(texture source color), 后缀是c表示我们需要通过GL_TEXTURE_ENV_COLOR设置的颜色, C表示颜色成分(RGB),A表示Alpha成分】

纹理格式最终颜色和Alpha成分结果GL_REPLACEGL_MODULATEGL_DECALGL_BLENDGL_ADDGL_ALPHACv =CpCp未定义CpCp Av =AsAs*Ap未定义As*ApAs*ApGL_LUMINANCE(或者1)Cv =CsCp*Cs未定义Cp(1Cs)+CcCsCp+Cs Av =ApAp未定义ApApGL_LUMINANCE_ALPHA(或者2)Cv =CsCp*Cs未定义Cp(1Cs)+CcCsCp+Cs Av =AsAs*Ap未定义As*ApAs*ApGL_INTENSITYCv =CsCp*Cs未定义Cp(1Cs)+CcCsCp+Cs Av =AsAs*Ap未定义Ap(1As)+AcAsAp+AsGL_RGB(或者3)Cv =CsCpCsCsCp(1Cs)+CcCsCp+Cs Av =ApApApApApGL_RGBA(或者4)Cv =CsCpCsCp(1As)+CsAsCp(1Cs)+CcCsC_p+C_s Av =AsApAsApApAsApAs

除了上述对纹理进行的操作外,OpenGL还支持更加复杂的纹理颜色操作方式,这种操作方式成为 纹理组合器。具体的方式如下:

为了使用纹理组合器,需要调用:

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  • 1
  • 1

接下来选择对颜色成分还是Alpha成分进行计算的算法选择,可以设置:

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);或者是Alpha的操作:glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

各种不同参数的含义 
TCB

参数中的Arg0、Arg1和Arg2需要使用下面的方式来设置: 
GL_SOURCEx_RGB,GL_SOURCEx_Alpha(x代表0,1,2),这些参数的取值如下:

取值含义GL_TEXTURE当前活动的纹理单元GL_TEXTUREx第x号纹理单元GL_CONSTANT使用GL_TEXTURE_ENV_COLOR设置的颜色值GL_PRIMARY_COLOR几何体片段的颜色GL_PREVIOUS来自上一个纹理单元最后计算出的颜色

例如我们需要设置公式中Arg0代表的是第0号纹理,那么需要调用:

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
  • 1
  • 1

除此之外,还可以对操作数做一些修改,使用GL_OPERANDx_RGB和GL_OPERANDx_ALPHA(x是0,1,2)来修改操作数,修改的方式包括:

操作数修改方式含义GL_SRC_COLOR颜色原RGB值GL_ONE_MINUS_SRC_COLOR1减去颜色原RGB值GL_SRC_ALPHA颜色原Alpha值GL_ONE_MINUS_SRC_ALPHA1减去颜色原Alpha值

通过上面的组合,模拟 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); 的效果:

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);    glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);    glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);    glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

上面这些内容简单点说就是通过设置一个等式的各个参数和操作符 
glTex

0 0
原创粉丝点击