计算机图形学 实验6 《纹理映射》
一、实验目的
学习真实感图形绘制技术。
二、实验内容
1、读取或生成纹理图像数据;
2、将纹理图像映射到物体表面。
三、实验方法
要使用纹理映射,我们必须做以下三件事情:在OpenGL中装入纹理,为顶点提供纹理坐标(为了把纹理映射到顶点),用纹理坐标在纹理上执行一个采样操作,得到一个像素颜色。OpenGL支持 1D, 2D, 3D, cube等等多种纹理,使用glEnable(GL_TEXTURE_2D)
开启2D纹理功能,使用glDisable(GL_TEXTURE_2D)
关闭纹理,默认情况下纹理是关闭的。
四、实验步骤
1、准备纹理,这里准备的是棋盘纹理,结果存储在纹理数组中;
2、确定纹理映射的对象,这里选取一个抛物面;
3、将制作好的纹理通过glTexImage2D
等等函数映射到指定对象(抛物面)上。
五、实验结果
实验输出图(以抛物面为基础绘制,上图橙色部分是后期画上去的边界)
![](https://img-blog.csdnimg.cn/1d780b853fe44c12a22d778bb9d88180.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAY3N1X2NhbmdrdWk=,size_18,color_FFFFFF,t_70,g_se,x_16#pic_center)
![](https://img-blog.csdnimg.cn/ce2acab6934d419488c43fbb188567dd.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAY3N1X2NhbmdrdWk=,size_18,color_FFFFFF,t_70,g_se,x_16#pic_center)
六、实验结论
使用函数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
,第四、五个参数是二维纹理像素的宽度和高度,第六个参数是纹理边框的大小,不使用纹理边框设置为零,第七个核第八个参数是数据格式和数据保存形式,第九个参数是保存了纹理图像的内参块地址。