OpenGL学习二十:纹理函数

本文介绍了OpenGL中的纹理函数(glTexEnv*()),包括如何使用这些函数来调整纹理图像与3D模型表面颜色的混合效果。文章详细解释了六种基本内部格式的作用,并展示了不同纹理函数(如GL_REPLACE、GL_MODULATE等)对纹理颜色的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过纹理函数(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_MODEGL_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_ALPHAC=Cf A=AsC=Cf A=AsAf未定义
GL_LUMINANCEC=Cs A=AfC=CfCs A=Af未定义
GL_LUMINANCE_ALPHAC=Cs A=AsC=CfCs A=AsAf未定义
GL_INTENSITYC=Cf A=CsC=CfCs A=AsAf未定义
GL_RGBC=Cs A=AfC=CfCs A=AfC=Cs A=Af
GL_RGBAC=Cs A=AsC=CfCs A=AsAfC=Cf(1-As)+CsAs A=Af
GL_BLEND,GL_ADD 纹理函数

  GL_BLEND GL_ADD
GL_ALPHAC=Cf A=AfAsC=Cf A=AsAf
GL_LUMINANCEC=Cf(1-Cs)+CcCs A=AfC=Cf+Cs A=Af
GL_LUMINANCE_ALPHAC=Cf(2-Cs)+CcCs A=AfAsC=Cf+Cs A=AsAf
GL_INTENSITYC=Cf(3-Cs)+CcCs A=Af(1-As)+AcAsC=Cf+Cs A=Af+As
GL_RGBC=Cf(4-Cs)+CcCs A=AfC=Cf+Cs A=Af
GL_RGBAC=Cf(5-Cs)+CcCs A=AfAsC=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();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寻找幸存者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值