计算机图形学 实验6 《纹理映射》

计算机图形学 实验6 《纹理映射》

一、实验目的

学习真实感图形绘制技术。

二、实验内容

1、读取或生成纹理图像数据;
2、将纹理图像映射到物体表面。

三、实验方法

要使用纹理映射,我们必须做以下三件事情:在OpenGL中装入纹理,为顶点提供纹理坐标(为了把纹理映射到顶点),用纹理坐标在纹理上执行一个采样操作,得到一个像素颜色。OpenGL支持 1D, 2D, 3D, cube等等多种纹理,使用glEnable(GL_TEXTURE_2D)开启2D纹理功能,使用glDisable(GL_TEXTURE_2D)关闭纹理,默认情况下纹理是关闭的。

四、实验步骤

1、准备纹理,这里准备的是棋盘纹理,结果存储在纹理数组中;
2、确定纹理映射的对象,这里选取一个抛物面;
3、将制作好的纹理通过glTexImage2D等等函数映射到指定对象(抛物面)上。

五、实验结果

实验输出图(以抛物面为基础绘制,上图橙色部分是后期画上去的边界)



六、实验结论

使用函数glGenTextures(N, &textureID)来分配N个纹理编号,使用glTexParameteri来设置常用的4个纹理参数,这些参数包括了当前纹理图像大小/小于模型目标时扩展纹理的处理方式。
关键代码:

#define	checkImageWidth 64
#define	checkImageHeight 64

GLuint        m_texName[2];         //纹理名称
GLubyte checkImage[checkImageHeight][checkImageWidth][3];
GLubyte image1D[checkImageWidth][3];

GLfloat diffuseMaterial[4] = { 0.5, 0.5, 0.5, 1.0 };

double parabolicSurf[36][10][3];	//用于绘制抛物面结构:36==>圆周36等分 10==>半径方向9等分 3==>坐标x、y、z
double vertexNormal[36][10][3];    //法向量:消除马赫带

// 在相应的display函数当中调用这个函数
void DrawTextureGraph()
{
	glGenTextures(2, m_texName);//向系统申请2个整数

	glBindTexture(GL_TEXTURE_2D, m_texName[0]);//用这个整数表示某个纹理图片
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);

	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_MAG_FILTER,GL_LINEAR);
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

	/*指定纹理图片位置(在内存中存放的位置)*/
	glTexImage2D(GL_TEXTURE_2D,0,				//texture type,level 纹理类型:二维,纹理级别:0级(分级是为了防止放大失真)
		         GL_RGB,						//internal format 数据以RGB存储
		         64, 64, 0,						//width,height,border	宽,高,边框(0,没有边框)
				 GL_RGB, GL_UNSIGNED_BYTE,		//format,type 数据的内部存储格式
				 checkImage);					//棋盘作为纹理图像,纹理绑定


	//一维纹理
	glBindTexture(GL_TEXTURE_1D, m_texName[1]);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);

	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB,
		         64, 0,							//width,border
				 GL_RGB, GL_UNSIGNED_BYTE,
				 image1D);
    
	int flag = 2;
	if(flag==2) 
    {
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
		glEnable(GL_TEXTURE_2D);
	}
	else if(flag==1) 
    {
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);//GL_MODULATE);
		//glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
		//GLfloat coeff[]={1.0, 0.0, 0.0, 0.0};
		//glTexGenfv(GL_S, GL_OBJECT_PLANE, coeff);	//自动生成一维纹理
		glEnable(GL_TEXTURE_1D);
	}
	else 
    {
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_TEXTURE_1D);
	}

	glBegin(GL_QUADS);//每个小块看成是四边形
	flag = 2;
	if(flag == 2)		//二维纹理
	{
		// 下面的代码用于绘制抛物面,可以用其他图形的绘制代替之,部分函数(如Normal函数)的实现这里省略
		for(int a = 0; a < 36; a++) 
        {
			for(int r = 0; r < 9; r++) 
            {
				double n[3];
				
				Normal(parabolicSurf[a][r], parabolicSurf[a][r + 1], parabolicSurf[(a + 1)%36][r + 1], n);
				glNormal3dv(n);
				glTexCoord2d(parabolicSurf[a][r][0]/2.0 + 0.5, parabolicSurf[a][r][1]/2.0 + 0.5);
				glVertex3dv(parabolicSurf[a][r]);
				glTexCoord2d(parabolicSurf[a][r + 1][0]/2.0 + 0.5, parabolicSurf[a][r + 1][1]/2.0 + 0.5);
				glVertex3dv(parabolicSurf[a][r + 1]);
				glTexCoord2d(parabolicSurf[(a + 1)%36][r + 1][0]/2.0 + 0.5, parabolicSurf[(a + 1)%36][r + 1][1]/2.0 + 0.5);
				glVertex3dv(parabolicSurf[(a + 1)%36][r + 1]);
				glTexCoord2d(parabolicSurf[(a + 1)%36][r][0]/2.0 + 0.5, parabolicSurf[(a + 1)%36][r][1]/2.0 + 0.5);
				glVertex3dv(parabolicSurf[(a + 1)%36][r]);
			}
		}
	}
}

七、实验小结

使用gltextImage2D函数根据指定的纹理参数生成一个2D纹理,第一个参数为指定的目标,可以使用GL_TEXTURE_2D,第二个参数为“多重细节层次”,不考虑多重纹理的话设置为零,第三个参数表示RGB数据存储的格式,这里使用GL_RGB,第四、五个参数是二维纹理像素的宽度和高度,第六个参数是纹理边框的大小,不使用纹理边框设置为零,第七个核第八个参数是数据格式和数据保存形式,第九个参数是保存了纹理图像的内参块地址。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值