通过纹理函数(glTexEnv*())可以把纹理图像的颜色与物体表面的原先的颜色进行混合
当我们指定纹理数据时,其第三个参数internalformat可以简化为6种格式
基本内部格式 | 所提取的源颜色(R,G,B,A) |
GL_ALPHA | (0,0,0,A) |
GL_LUMINANCE | (L,L,L,1) |
GL_LUMINANCE_ALPHA | (L,L,L,A) |
GL_INTENSITY | (I,I,I,I) |
GL_RGB | (R,G,B,1) |
GL_RGBA | (R,G,B,A) |
void glTexEnvf (GLenum target, GLenum pname, GLfloat param);
如果target是GL_TEXTURE_FILTER_CONTROL pname必须是GL_TEXTURE_LOD_BIAS,param是个浮点数表示mipmap细节层的偏移量
target是GL_TEXTURE_ENV情况下 |
GL_TEXTURE_ENV_MODE | GL_DECAL,GL_REPLACE,GL_BLEND,GL_MODULATE,GL_ADD或GL_COMBINE |
GL_TEXTURE_ENV_COLOR | 包含4个浮点值的RGBA数组 |
GL_REPLACE,GL_MODULATE,GL_DECAL纹理函数 |
s表示纹理的源颜色 f表示新的片段值 c表示用GL_TEXURE_ENV_COLOR分配的颜色值 如果没有下标,表示最终计算所得的颜色 |
GL_REPLACE | GL_MODULATE | GL_DECAL | |
GL_ALPHA | C=Cf A=As | C=Cf A=AsAf | 未定义 |
GL_LUMINANCE | C=Cs A=Af | C=CfCs A=Af | 未定义 |
GL_LUMINANCE_ALPHA | C=Cs A=As | C=CfCs A=AsAf | 未定义 |
GL_INTENSITY | C=Cf A=Cs | C=CfCs A=AsAf | 未定义 |
GL_RGB | C=Cs A=Af | C=CfCs A=Af | C=Cs A=Af |
GL_RGBA | C=Cs A=As | C=CfCs A=AsAf | C=Cf(1-As)+CsAs A=Af |
GL_BLEND,GL_ADD 纹理函数 |
GL_BLEND | GL_ADD | |
GL_ALPHA | C=Cf A=AfAs | C=Cf A=AsAf |
GL_LUMINANCE | C=Cf(1-Cs)+CcCs A=Af | C=Cf+Cs A=Af |
GL_LUMINANCE_ALPHA | C=Cf(2-Cs)+CcCs A=AfAs | C=Cf+Cs A=AsAf |
GL_INTENSITY | C=Cf(3-Cs)+CcCs A=Af(1-As)+AcAs | C=Cf+Cs A=Af+As |
GL_RGB | C=Cf(4-Cs)+CcCs A=Af | C=Cf+Cs A=Af |
GL_RGBA | C=Cf(5-Cs)+CcCs A=AfAs | C=Cf+Cs A=AfAs |
#include "header.h" #define checkImageWidth 16 #define checkImageHeight 16 GLubyte checkImage[checkImageWidth][checkImageHeight][4]; int texName; enum InternalFormat { alpha='a', luminance='b', luminance_alpha='c', intensity='d', rgb, rgba }; enum Env { ADD='A', BLEND='B', REPLACE='R', MODULATE='M', DECAL='D' }; void makeImage() { int i,j; for ( i=0;i<checkImageWidth;i++) { for (j = 0; j < checkImageHeight; j++) { if(j%2==0) { checkImage[i][j][0]=255; checkImage[i][j][1]=0; checkImage[i][j][2]=0; checkImage[i][j][3]=100; }else { checkImage[i][j][0]=0; checkImage[i][j][1]=255; checkImage[i][j][2]=0; checkImage[i][j][3]=200; } } } } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glBlendFunc(GL_SRC_ALPHA,GL_ZERO); glBindTexture(GL_TEXTURE_2D,texName); glEnable(GL_BLEND); glBegin(GL_QUADS); glTexCoord2i(0,0); glVertex2i(-100,-100); glTexCoord2i(4,0); glVertex2i(100,-100); glTexCoord2i(4,4); glVertex2i(100,100); glTexCoord2i(0,4); glVertex2i(-100,100); glEnd(); glFlush(); } void init() { GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; glClearColor(0.5,0.5,0.5,1); glClearDepth(1.0); makeImage(); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glShadeModel(GL_SMOOTH); glGenTextures(1,&texName); glBindTexture(GL_TEXTURE_2D,texName); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable(GL_TEXTURE_2D); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-200,600,-300,300,-100,100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key,int x,int y) { switch(key) { case alpha: glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); glBlendFunc(GL_SRC_ALPHA,GL_ZERO); glBindTexture(GL_TEXTURE_2D,texName); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); break; case luminance: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); glBindTexture(GL_TEXTURE_2D,texName); glEnable(GL_TEXTURE_2D); glDisable(GL_BLEND); break; case luminance_alpha: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); glBlendFunc(GL_SRC_ALPHA,GL_ZERO); glBindTexture(GL_TEXTURE_2D,texName); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); break; case rgba: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); glBlendFunc(GL_SRC_ALPHA,GL_ZERO); glBindTexture(GL_TEXTURE_2D,texName); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); break; case rgb: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); glBlendFunc(GL_SRC_ALPHA,GL_ZERO); glBindTexture(GL_TEXTURE_2D,texName); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); break; case ADD: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); break; case MODULATE: //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); break; case DECAL: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); break; case BLEND: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); break; } glutPostRedisplay(); } void mouse(int button,int state,int x,int y) { } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA|GLUT_DEPTH); glutInitWindowSize(800,600); glutInitWindowPosition(100,100); glutCreateWindow("纹理函数"); glewInit(); init(); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutReshapeFunc(reshape); glutMouseFunc(mouse); glutMainLoop(); }