通过纹理函数(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细节层的偏移量
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_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();
}