opengl纹理.docx
- 文档编号:23957781
- 上传时间:2023-05-22
- 格式:DOCX
- 页数:14
- 大小:18.05KB
opengl纹理.docx
《opengl纹理.docx》由会员分享,可在线阅读,更多相关《opengl纹理.docx(14页珍藏版)》请在冰豆网上搜索。
opengl纹理
AUX_RGBImageRecauxRGBImageLoad等函数意义分类:
opengl学习笔记2012-07-2614:
00416人阅读评论
OpenGL可以把纹理映射到指定的图形的表面上。
简单一点的,就是给平面映射纹理,比如一个四边形,一个长方体的6个面,都关于将一个位图作为纹理映射到某个或者多个面上,可以学习JeffMolofee的OpenGL系列对于指定的多个纹理,要根据自己的需要映射到不同的面上,需要对位图创建一个数组,用来存储位图的名称,然后在初始化Op成多个纹理存储到一个纹理数组中,接着就可以指定绘制的某个面,对该指定的面进行纹理
下面,在的JeffMolofee教程的第六课的基础上,实现对6个面分别进行不同的纹理映射准备工作就是制作6幅不同的位图,如图所示:
关键代码及其说明如下。
创建全局纹理数组GLuinttexture[6];//创建一个全局的纹理数组,用来存储将位图转换之后得到的纹理,对应于立方
加载位图文件加载位图,也就是把位图读取到内存空间,实现纹理的创建,加载位图的函数说明一下
AUX_RGBImageRec*LoadBMP(char*Filename)//根据位图文件的名称进行加载{
FILE*File=NULL;//文件指针if(!
Filename)//如果没有指定位图文件名称就返回NULL{
returnNULL;}
File=fopen(Filename,"r");//根据指定的位图文件名称,打开该位图文件if(File)//如果位图文件存在{fclose(File);//因为只是需要判断问题是否存在,而不需要对位图文件进行写操作,所以关闭位}returnNULL;//位图文件加载失败就返回NULL}
returnauxDIBImageLoad(Filename);//其实,只需要一个真正存在的位图文件的名称,实现加载位图文上面实现加载位图的函数中,AUX_RGBImageRec是glaux.h中定义的类型,该类型的定义如下/*
**RGBImageStructure*/
typedefstruct_AUX_RGBImageRec{GLintsizeX,sizeY;unsignedchar*data;}AUX_RGBImageRec;首先,AUX_RGBImageRec类型是一个RGB图像结构类型。
该结构定义了三个成员:
sizeX——图像的宽度;sizeY——图像的高度;data;——图形所包含的数据,其实也就是该图形在内存中的像素数据的一个指针。
AUX_RGBImageRec类型的变量描述了一幅图像的特征。
上述函数中,调用了glaux.h库文件中的auxDIBImageLoad函数,其实它是一个宏,函数原型为auxRGBImageLoadW(LPCWSTR在该库文件中找到它的定义,如下所示:
/*AUX_RGBImageRec*APIENTRYauxRGBImageLoad(LPCTSTR);*/#ifdefUNICODE#defineauxRGBImageLoadW#else
#defineauxRGBImageLoadA#endif
AUX_RGBImageRec*APIENTRYauxRGBImageLoadA(LPCSTR);AUX_RGBImageRec*APIENTRYauxRGBImageLoadW(LPCWSTR);#ifdefUNICODE#defineauxDIBImageLoadW#else
#defineauxDIBImageLoadA#endif
AUX_RGBImageRec*APIENTRYauxDIBImageLoadA(LPCSTR);AUX_RGBImageRec*APIENTRYauxDIBImageLoadW(LPCWSTR);宏auxDIBImageLoad实现的功能就是:
根据指定的位图名称,将该位图的信息加载到内存中,以便用来
创建纹理并加载纹理用于创建并加载纹理的函数为LoadGLTextures,实现如下所示:
intLoadGLTextures()//根据加载的位图创建纹理{
intStatus=FALSE;//指示纹理创建是否成功的标志AUX_RGBImageRec*TextureImage[6];//创建一个纹理图像数组,这里指定数组大小为memset(TextureImage,0,sizeof(void*)*6);//初始化纹理图像数组,为其分配内存char*pictures[]={//创建一个位图名称数组,对应6幅位图"Data/No
1.bmp","Data/No
2.bmp","Data/No
3.bmp","Data/No
4.bmp","Data/No
5.bmp",
"Data/No
6.bmp"
};
for(inti=0;i<6;i++)//遍历位图名称数组,根据位图名称分别生成{{
Status=TRUE;glGenTextures(1,&texture[i]);//为第i个位图创建纹理if(TextureImage[i]=LoadBMP(pictures[i]))//加载位图i成功,修改状态标志变量Status为glBindTexture(GL_TEXTURE_2D,texture[i]);//将生成的纹理的名称绑定到指定的纹理glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[i]->sizeX,TextureImage[i]->sizeY,0,GL_RGB,GL_UNSIGNED}
if(TextureImage[i])//释放位图数组占用的内存空间{if(TextureImage[i]->data){free(TextureImage[i]->data);}free(TextureImage[i]);}}
returnStatus;//创建纹理并加载,返回成功或者失败的标志Status}
上述函数是创建和加载纹理的核心实现。
1、glGenTextures函数其中,调用了glGenTextures函数,查看MSDN可以看到,声明如下所示:
voidglGenTextures(GLsizein,
GLuint*textures);
函数参数的含义:
n——生成的纹理的名称的个数;textures——生成的纹理名称所存储位置的指针,也就是一个纹理数组的内存地址,或者说是数组首元
函数被调用,会生成一系列纹理的名字,并存储到指定的数组中。
2、glBindTexture函数实现了将调用glGenTextures函数生成的纹理的名字绑定到对应的目标纹理上。
该函数
voidglBindTexture(GLenumtarget,GLuinttexture);
函数参数的含义:
target——纹理被绑定的目标,它只能取值GL_TEXTURE_1D或者GL_TEXTURE_2D;texture——纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用。
3、glTexImage2D函数调用glTexImage2D函数,用来指定二维纹理图像。
该函数的声明如下所示:
voidglTexImage2D(GLenumtarget,GLintlevel,
函数参数的含义:
GL_COLOR_INDEX、GL_R
ED、GL_GREEN、GL_BLU
E、GL_ALPH
A、GL_REXT、GL_LUMINAN
CE、GL_LUMINANCE_ALPHA,具体含义可以参考MSDN;type——像素数据的数据类型,取值可以为GL_UNSIGNED_BYTE,GL_BYTE,GL_BITMAP,GL_UNSIGNED_SHORT,GL_SHORFLOAT;
pixels——内存中像素数据的指针。
4、glTexParameteri函数或者glTexParameterf函数用来设置纹理参数,声明如下所示:
voidglTexParameterf(GLenumtarget,GLenumpname,GLfloatparam);
voidglTexParameteri(GLenumtarget,GLenumpname,GLintparam);
函数参数的含义:
target——目标纹理,必须为GL_TEXTURE_1D或GL_TEXTURE_2D;pname——用来设置纹理映射过程中像素映射的问题等,取值可以为:
GL_TEXTURE_MIN_FILTER、GL_TEXTURE_MAG_FILTEWRAP_T,详细含义可以查看MSDN;param——实际上就是pname的值,可以参考MSDN。
另外,该类函数还有两个:
voidglTexParameterfv(GLenumtarget,GLenumpname,constGLfloat*params);
voidglTexParameteriv(GLenumtarget,GLenumpname,constGLint*params);
上述程序中调用如下:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);功能就是实现线形滤波的功能,当纹理映射到图形表面以后,如果因为其它条件的设置导致纹理不能更好地显示的时候,进行过
掉显示不正常的纹理像素。
纹理映射过程纹理映射的过程是在DrawGLScene函数中实现的,也就是在绘制图形的过程中,直接进行我呢里映射,或者称为,为指定的平面
intDrawGLScene(GLvoid){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(
0.0f,
0.0f,-
5.0f);glRotatef(xrot,
1.0f,
0.0f,
0.0f);glRotatef(yrot,
0.0f,
1.0f,
0.0f);
glRotatef(zrot,
0.0f,
0.0f,
1.0f);
//FrontFaceglBegin(GL_QUADS);glTexCoord2f(
0.0f,
0.0f);glVertex3f(-
1.0f,-
1.0f,
1.0f);glTexCoord2f(
1.0f,
0.0f);glVertex3f(
1.0f,-
1.0f,
1.0f);glTexCoord2f(
1.0f,
1.0f);glVertex3f(
1.0f,
1.0f,
1.0f);glTexCoord2f(
0.0f,
1.0f);glVertex3f(-
1.0f,
1.0f,
1.0f);glEnd();
//BackFaceglBegin(GL_QUADS);glTexCoord2f(
1.0f,
0.0f);glVertex3f(-
1.0f,-
1.0f,-
1.0f);glTexCoord2f(
1.0f,
1.0f);glVertex3f(-
1.0f,
1.0f,-
1.0f);glTexCoord2f(
0.0f,
1.0f);glVertex3f(
1.0f,
1.0f,-
1.0f);glTexCoord2f(
0.0f,
0.0f);glVertex3f(
1.0f,-
1.0f,-
1.0f);glEnd();
//TopFaceglBegin(GL_QUADS);glTexCoord2f(
0.0f,
1.0f);glVertex3f(-
1.0f,
1.0f,-
1.0f);glTexCoord2f(
0.0f,
0.0f);glVertex3f(-
1.0f,
1.0f,
1.0f);glTexCoord2f(
1.0f,
0.0f);glVertex3f(
1.0f,
1.0f,
1.0f);glTexCoord2f(
1.0f,
1.0f);glVertex3f(
1.0f,
1.0f,-
1.0f);glEnd();
//BottomFaceglBegin(GL_QUADS);glTexCoord2f(
1.0f,
1.0f);glVertex3f(-
1.0f,-
1.0f,-
1.0f);glTexCoord2f(
0.0f,
1.0f);glVertex3f(
1.0f,-
1.0f,-
1.0f);glBindTexture(GL_TEXTURE_2D,texture[0]);//选择第一个纹理texture[0],进行贴纹glBindTexture(GL_TEXTURE_2D,texture[1]);//选择第二个纹理texture[1],进行贴纹glBindTexture(GL_TEXTURE_2D,texture[2]);//选择第三个纹理texture[2],进行贴纹glBindTexture(GL_TEXTURE_2D,texture[3]);//选择第四个纹理texture[3],进行贴纹glTexCoord2f(
0.0f,
0.0f);glVertex3f(
1.0f,-
1.0f,
1.0f);glTexCoord2f(
1.0f,
0.0f);glVertex3f(-
1.0f,-
1.0f,
1.0f);glEnd();
//RightfaceglBegin(GL_QUADS);glTexCoord2f(
1.0f,
0.0f);glVertex3f(
1.0f,-
1.0f,-
1.0f);glTexCoord2f(
1.0f,
1.0f);glVertex3f(
1.0f,
1.0f,-
1.0f);glTexCoord2f(
0.0f,
1.0f);glVertex3f(
1.0f,
1.0f,
1.0f);glTexCoord2f(
0.0f,
0.0f);glVertex3f(
1.0f,-
1.0f,
1.0f);glEnd();
//LeftFaceglBegin(GL_QUADS);glTexCoord2f(
0.0f,
0.0f);glVertex3f(-
1.0f,-
1.0f,-
1.0f);glTexCoord2f(
1.0f,
0.0f);glVertex3f(-
1.0f,-
1.0f,
1.0f);glTexCoord2f(
1.0f,
1.0f);glVertex3f(-
1.0f,
1.0f,
1.0f);glTexCoord2f(
0.0f,
1.0f);glVertex3f(-
1.0f,
1.0f,-
1.0f);glEnd();
xrot+=
0.3f;yrot+=
0.2f;
zrot+=
0.4f;returnTRUE;}
glBindTexture(GL_TEXTURE_2D,texture[4]);//选择第五个纹理texture[4],进行贴纹glBindTexture(GL_TEXTURE_2D,texture[5]);//选择第六个纹理texture[5],进行贴纹因为,通过前面的过程,已经将位图加载并创建和加载纹理成功,纹理数组已经存在于内存之中,调用上述函数实现纹理映射,
立方体的指定的面上。
上述函数中调用了glTexCoord2f函数,设置纹理坐标,该函数的声明如下所示:
voidglTexCoord2f(GLfloats,
GLfloatt
);
glTexCoord2f的第一个参数是X坐标,当s=
0.0f时是纹理的左侧,s=
0.5f时是纹理的中点,s=
1.0f时是纹理的右侧。
glTexC纹理的底部,t=
0.5f是纹理的中点,t=
1.0f是纹理的顶部。
上述函数在为前面那个面映射纹理的时候调用如下:
//FrontFaceglBindTexture(GL_TEXTURE_2D,texture[0]);glBegin(GL_QUADS);glTexCoord2f(
0.0f,
0.0f);glVertex3f(-
1.0f,-
1.0f,
1.0f);glTexCoord2f(
1.0f,
0.0f);glVertex3f(
1.0f,-
1.0f,
1.0f);glTexCoord2f(
1.0f,
1.0f);glVertex3f(
1.0f,
1.0f,
1.0f);glTexCoord2f(
0.0f,
1.0f);glVertex3f(-
1.0f,
1.0f,
1.0f);glEnd();
其中:
glTexCoord2f(
0.0f,
0.0f);表示将纹理texture[0]的左下角坐标(
0.0f,
0.0f)映射到立方体前面那个面的顶点(-glTexCoord2f(
1.0f,
0.0f);表示将纹理texture[0]的右下角坐标(
1.0f,
0.0f)映射到立方体前面那个面的顶点(1glTexCoord2f(
1.0f,
1.0f);表示将纹理texture[0]的右上角坐标(
1.0f,
1.0f)映射到立方体前面那个面的顶点(glTexCoord2f(
0.0f,
1.0f);表示将纹理texture[0]的左上角坐标(
0.0f,
1.0f)映射到立方体前面那个面的顶点(-这样,纹理texture[0]就被映射到了立方体前面那个面上。
纹理映射结果为了使立方体能够运动起来,对立方体进行累的旋转变换,而且,定义了三个全局变量
GLfloatxrot;//沿着x旋转的变量GLfloatyrot;//沿着y旋转的变量GLfloatzrot;//沿着z旋转的变量初始化都为0,然后,在每次调用DrawGLScene函数的时候,改变x、y、z的分量值,在DrawGLScenexrot+=
0.3f;yrot+=
0.2f;
zrot+=
0.4f;在DrawGLScene函数中还要执行旋转变换:
glRotatef(xrot,
1.0f,
0.0f,
0.0f);glRotatef(yrot,
0.0f,
1.0f,
0.0f);
glRotatef(zrot,
0.0f,
0.0f,
1.0f);每次重绘都在改变旋转轴,所以我们绘制的立方体能够动起来,看到各个进行纹理映射的面的效果
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- opengl 纹理