OpenGL纹理(经典).doc
OpenGL纹理 目 录12.1 基本步骤12.2 纹理定义12.3 纹理控制12.4 映射方式12.5 纹理坐标 在三维图形中,纹理映射(Texture Mapping)的方法运用得很广,尤其描述具有真实感的物体。比如绘制一面砖墙,就可以用一幅真实的砖墙图像或照片作为纹理贴到一个矩形上,这样,一面逼真的砖墙就画好了。如果不用纹理映射的方法,则墙上的每一块砖都必须作为一个独立的多边形来画。另外,纹理映射能够保证在变换多边形时,多边形上的纹理图案也随之变化。例如,以透视投影方式观察墙面时,离视点远的砖块的尺寸就会缩小,而离视点 较近的就会大些。此外,纹理映射也常常运用在其他一些领域,如飞行仿真中常把一大片植被的图像映射到一些大多边形上用以表示地面,或用大理石、木材、布匹等自然物质的图像作为纹理映射到多边形上表示相应的物体。纹理映射有许多种情况。例如,任意一块纹理可以映射到平面或曲面上,且对光亮的物体进行纹理映射,其表面可以映射出周围环境的景象;纹理还可按不同的方式映射到曲面上,一是可以直接画上去(或称移画印花法),二是可以调整曲面颜色或把纹理颜色与曲面颜色混合;纹理不仅可以是二维的,也可以是一维或其它维的。本章将详细介绍OpenGL纹理映射有关的内容:基本步骤、纹理定义、纹理控制、映射方式和纹理坐标等。12.1 基本步骤纹理映射是一个相当复杂的过程,这节只简单地叙述一下最基本的执行纹理映射所需的步骤。基本步骤如下:1)定义纹理、2)控制滤波、3)说明映射方式、4)绘制场景,给出顶点的纹理坐标和几何坐标。注意:纹理映射只能在RGBA方式下执行,不能运用于颜色表方式。下面举出一个最简单的纹理映射应用例子:例12-1 简单纹理映射应用例程(texsmpl.c) #include "glos.h"#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h> void myinit(void);void makeImage(void);void CALLBACK myReshape(GLsizei w, GLsizei h);void CALLBACK display(void); /* 创建纹理 */#define ImageWidth 64#define ImageHeight 64GLubyte ImageImageWidthImageHeight3; void makeImage(void) int i, j, r,g,b; for (i = 0; i < ImageWidth; i+) for (j = 0; j < ImageHeight; j+) r=(i*j)%255; g=(4*i)%255; b=(4*j)%255; Imageij0 = (GLubyte) r; Imageij1 = (GLubyte) g; Imageij2 = (GLubyte) b; void myinit(void) glClearColor (0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); makeImage(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* 定义纹理 */ glTexImage2D(GL_TEXTURE_2D, 0, 3, ImageWidth, ImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, &Image000); /* 控制滤波 */ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); /* 说明映射方式*/ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); /* 启动纹理映射 */ glEnable(GL_TEXTURE_2D); glShadeModel(GL_FLAT); void CALLBACK display(void) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* 设置纹理坐标和物体几何坐标 */ glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421); glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421); glEnd(); glFlush(); void CALLBACK myReshape(GLsizei w, GLsizei h) glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -3.6); void main(void) auxInitDisplayMode (AUX_SINGLE | AUX_RGBA); auxInitPosition (0, 0, 500, 500); auxInitWindow ("Simple Texture Map"); myinit(); auxReshapeFunc (myReshape); auxMainLoop(display); 图12-1 简单纹理映射以上程序运行结果是将一块纹理映射到两个正方形上去。这两个正方形都是按透视投影方式绘制,其中一个正对观察者,另一个向后倾斜45度角。图形的纹理是由函数makeImage()产生的,并且所有纹理映射的初始化工作都在程序myinit()中进行。由glTexImage2d()说明了一个全分辨率的图像,其参数指出了图像的尺寸、图像类型、图像位置和图像的其它特性;下面连续调用函数glTexParameter*()说明纹理怎样缠绕物体和当象素与纹理数组中的单个元素(texel,暂称纹素)不能精确匹配时如何过滤颜色;接着用函数glTexEnv*()设置画图方式为GL_DECAL,即多边形完全用纹理图像中的颜色来画,不考虑多边形在未被纹理映射前本身的颜色;最后,调用函数glEnable()启动纹理映射。子程序display()画了两个正方形,其中纹理坐标与几何坐标一起说明,glTexCoord*()函数类似于glNormal*()函数,不过它是设置纹理坐标,之后任何顶点都把这个纹理坐标与顶点坐标联系起来,直到再次调用 glTexCoord*()改变当前纹理坐标。12.2、纹理定义12.2.1 二维纹理定义的函数 void glTexImage2D(GLenum target,GLint level,GLint components,GLsizei width, glsizei height,GLint border,GLenum format,GLenum type, const GLvoid *pixels);定义一个二维纹理映射。其中参数target是常数GL_TEXTURE_2D。参数level表示多级分辨率的纹理图像的级数,若只有一种分辨率,则level设为0。参数components是一个从1到4的整数,指出选择了R、G、B、A中的哪些分量用于调整和混合,1表示选择了R分量,2表示选择了R和A两个分量,3表示选择了R、G、B三个分量,4表示选择了R、G、B、A四个分量。参数width和height给出了纹理图像的长度和宽度,参数border为纹理边界宽度,它通常为0,width和height必须是2m+2b,这里m是整数,长和宽可以有不同的值,b是border的值。纹理映射的最大尺寸依赖于OpenGL,但它至少必须是使用64x64(若带边界为66x66),若width和height设置为0,则纹理映射有效地关闭。参数format和type描述了纹理映射的格式和数据类型,它们在这里的意义与在函数glDrawPixels()中的意义相同,事实上,纹理数据与glDrawPixels()所用的数据有同样的格式。参数format可以是GL_COLOR_INDEX、GL_RGB、GL_RGBA、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_LUMINANCE或GL_LUMINANCE_ALPHA(注意:不能用GL_STENCIL_INDEX和GL_DEPTH_COMPONENT)。类似地,参数type是GL_BYPE、GL_UNSIGNED_BYTE、GL_SHORT、 GL_UNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_FLOAT或GL_BITMAP。参数pixels包含了纹理图像数据,这个数据描述了纹理图像本身和它的边界。12.2 一维纹理定义的函数void glTexImage1D(GLenum target,GLint level,GLint components,GLsizei width,GLint border,GLenum format,GLenum type,const GLvoid *pixels);定义一个一维纹理映射。除了第一个参数target应设置为GL_TEXTURE_1D外,其余所有的参数与函数TexImage2D()的一致,不过纹理图像是一维纹素数组,其宽度值必须是2的幂,若有边界则为2m+2。12.3、纹理控制OpenGL中的纹理控制函数是void glTexParameterifv(GLenum target,GLenum pname,TYPE param);控制纹素映射到片元(fragment)时怎样对待纹理。第一个参数target可以是GL_TEXTURE_1D或GL_TEXTURE_2D,它指出是为一维或二维纹理说明参数;后两个参数的可能值见表12-1所示。 参数值GL_TEXTURE_WRAP_SGL_CLAMPGL_REPEATGL_TEXTURE_WRAP_TGL_CLAMPGL_REPEATGL_TEXTURE_MAG_FILTER GL_NEARESTGL_LINEARGL_TEXTURE_MIN_FILTER GL_NEARESTGL_LINEARGL_NEAREST_MIPMAP_NEARESTGL_NEAREST_MIPMAP_LINEARGL_LINEAR_MIPMAP_NEARESTGL_LINEAR_MIPMAP_LINEAR 表12-1 放大和缩小滤波方式12.3.1 滤波一般来说,纹理图像为正方形或长方形。但当它映射到一个多边形或曲面上并变换到屏幕坐标时,纹理的单个纹素很少对应于屏幕图像上的象素。根据所用变换和所用纹理映射,屏幕上单个象素可以对应于一个纹素的一小部分(即放大)或一大批纹素(即缩小)。下面用函数glTexParameter*()说明放大和缩小的方法: glTexParameter*(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);glTexParameter*(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);实际上,第一个参数可以是GL_TEXTURE_1D或GL_TEXTURE_2D,即表明所用的纹理是一维的还是二维的;第二个参数指定滤波方法,其中参数值GL_TEXTURE_MAG_FILTER指定为放大滤波方法,GL_TEXTURE_MIN_FILTER指定为缩小滤波方法;第三个参数说明滤波方式,其值见表12-1所示。若选择GL_NEAREST则采用坐标最靠近象素中心的纹素,这有可能使图像走样;若选择GL_LINEAR则采用最靠近象素中心的四个象素的加权平均值。GL_NEAREST所需计算比GL_LINEAR要少,因而执行得更快,但GL_LINEAR提供了比较光滑的效果。12.3.2 重复与约简纹理坐标可以超出(0, 1)范围,并且在纹理映射过程中可以重复映射或约简映射。在重复映射的情况下,纹理可以在s,t方向上重复,即:glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);若将参数GL_REPEAT改为GL_CLAMP,则所有大于1的纹素值都置为1,所有小于0的值都置为0。参数设置参见表12-1。12.4、映射方式在本章的第一个例程中,纹理图像是直接作为画到多边形上的颜色。实际上,可以用纹理中的值来调整多边形(曲面)原来的颜色,或用纹理图像中的颜色与多边形(曲面)原来的颜色进行混合。因此,OpenGL提供了三种纹理映射的方式,这个函数是:void glTexEnvifv(GLenum target,GLenum pname,TYPE param);设置纹理映射方式。参数target必须是GL_TEXTURE_ENV;若参数pname是GL_TEXTURE_ENV_MODE,则参数param可以是GL_DECAL、GL_MODULATE或GL_BLEND,以说明纹理值怎样与原来表面颜色的处理方式;若参数pname是GL_TEXTURE_ENV_COLOR,则参数param是包含四个浮点数(分别是R、G、B、A分量)的数组,这些值只在采用GL_BLEND纹理函数时才有用。12.5、纹理坐标12.5.1 坐标定义在绘制纹理映射场景时,不仅要给每个顶点定义几何坐标,而且也要定义纹理坐标。经过多种变换后,几何坐标决定顶点在屏幕上绘制的位置,而纹理坐标决定纹理图像中的哪一个纹素赋予该顶点。并且顶点之间的纹理坐标插值与基础篇中所讲的平滑着色插值方法相同。纹理图像是方形数组,纹理坐标通常可定义成一、二、三或四维形式,称为s,t,r和q坐标,以区别于物体坐标(x, y, z, w)和其他坐标。一维纹理常用s坐标表示,二维纹理常用(s, t)坐标表示,目前忽略r坐标,q坐标象w一样,一半值为1,主要用于建立齐次坐标。OpenGL坐标定义的函数是:void gltexCoord1234sifdv(TYPE coords);设置当前纹理坐标,此后调用glVertex*()所产生的顶点都赋予当前的纹理坐标。对于gltexCoord1*(),s坐标被设置成给定值,t和r设置为0,q设置为1;用gltexCoord2*()可以设置s和t坐标值,r设置为0,q设置为1;对于gltexCoord3*(),q设置为1,其它坐标按给定值设置;用gltexCoord4*()可以给定所有的坐标。使用适当的后缀(s,i,f或d)和TYPE的相应值(GLshort、GLint、glfloat或GLdouble)来说明坐标的类型。注意:整型纹理坐标可以直接应用,而不是象普通坐标那样被映射到-1, 1之间。12.5.2 坐标自动产生在某些场合(环境映射等)下,为获得特殊效果需要自动产生纹理坐标,并不要求为用函数gltexCoord*()为每个物体顶点赋予纹理坐标值。OpenGL提供了自动产生纹理坐标的函数,其如下:void glTexGenifv(GLenum coord,GLenum pname,TYPE param);自动产生纹理坐标。第一个参数必须是GL_S、GL_T、GL_R或GL_Q,它指出纹理坐标s,t,r,q中的哪一个要自动产生;第二个参数值为GL_TEXTURE_GEN_MODE、GL_OBJECT_PLANE或 GL_EYE_PLANE;第三个参数param是一个定义纹理产生参数的指针,其值取决于第二个参数pname的设置,当pname为GL_TEXTURE_GEN_MODE时,param是一个常量,即GL_OBJECT_LINEAR、GL_EYE_LINEAR或GL_SPHERE_MAP,它们决定用哪一个函数来产生纹理坐标。对于pname的其它可能值,param是一个指向参数数组的指针。下面是一个运用自动产生纹理坐标函数的实例:例12-1 纹理坐标自动产生例程(texpot.c)#include "glos.h"#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h> void myinit(void);void makeStripeImage(void);void CALLBACK display(void);void CALLBACK myReshape(GLsizei w, GLsizei h); #define stripeImageWidth 64GLubyte stripeImage3*stripeImageWidth; void makeStripeImage(void) int j; for (j = 0; j < stripeImageWidth; j+) stripeImage3*j = 255; stripeImage3*j+1 =255-2*j; stripeImage3*j+2 =255; /* 参数设置 */ GLfloat sgenparams = 1.0, 1.0, 1.0, 0.0; void myinit(void) glClearColor (0.0, 0.0, 0.0, 0.0); makeStripeImage(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage1D(GL_TEXTURE_1D, 0, 3, stripeImageWidth, 0, GL_RGB, GL_UNSIGNED_BYTE, stripeImage); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, sgenparams); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_1D); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glFrontFace(GL_CW); glCullFace(GL_BACK); glMaterialf (GL_FRONT, GL_SHININESS, 64.0); void CALLBACK display(void) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); glRotatef(25.0, 1.0, 0.0, 0.0); auxSolidTeapot(1.5); glPopMatrix (); glFlush(); void CALLBACK myReshape(GLsizei w, GLsizei h) float a=3.5; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (-a, a, -a*(GLfloat)h/(GLfloat)w, a*(GLfloat)h/(GLfloat)w, -a, a); else glOrtho (-a*(GLfloat)w/(GLfloat)h, a*(GLfloat)w/(GLfloat)h, -a, a, -a, a); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); void main(void) auxInitDisplayMode (AUX_SINGLE | AUX_RGBA); auxInitPosition (0, 0, 500, 500); auxInitWindow (" Teapot TextureMapping"); myinit(); auxReshapeFunc (myReshape); auxMainLoop(display);以上程序运行结果是在屏幕上显示一个带条状纹理的茶壶。其中用到了前面所讲的一维纹理映射定义,以及本节的纹理坐标自动产生。OPENGL的纹理2008-11-07 15:28在3D图形中,纹理映射是广泛使用的。纹理映射也是相当复杂的过程:一 定义纹理二 控制滤波三 说明映射方式四 绘制场景给出顶点的纹理坐标和几何坐标注意!纹理映射只能在RGBA模式下使用,不适用于颜色索引模式 1.纹理定义void glTexImage2D( GLenum target, GLint level, GLint components,GLsizei width, GLsizei height, GLint border,GLenum format, GLenum type, const GLvoid *pixels );定义一个二维纹理映射。target是常数 GL_TEXTURE_2Dlevel表示多级分辨率的纹理图象的级数。若只有一种分辨率,level为0。components是从1到4的整数,1:选择R;2:选择R A;3:选择R G B;4:选择R G B A;width height是纹理的尺寸。format和type描述映射格式和数据类型。它们与前面讲的glDrawPixels()中GL_NEAREST_MIPMAP_NEARESTGL_NEAREST_MIPMAP_LINEARGL_LINEAR_MIPMAP_NEARESTGL_LINEAR_MIPMAP_LINEAR2.1 滤波原始纹理图象是个方形图象,把它映射到奇形怪状的物体上,一般不可能图象上的一个象素对应屏幕的一个象素。因此局部放大缩小时,就要定义合适的滤波方式(以2D为例):void glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);void glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);前者是放大滤波(GL_TEXTURE_MAG_FILTER),后者是缩小滤波(GL_TEXTURE_MIN_FILTER);另外,GL_NEAREST是利用最坐标最靠近象素中心的纹理元素,这有可能使图样走型,但计算速度快;GL_LINEAR利用线形插值,效果好但计算量大。 2.2重复与缩限纹理映射可以重复映射或者缩限映射,重复映射时纹理可以在自己的坐标S T方向重复。对于重复映射:void glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);void glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);参数GL_REPEAT改为GL_CLAMP,则缩限,所有大于1的纹理元素值置为1。所有小于0的纹理元素值置为0。0的纹理元素值置为0。 3. 映射方式处理纹理本身图案颜色和物体本身颜色的关系:void glTexEnvifv(GLenum target,GLenum pname,TYPE param);target必须是GL_TEXTURE_ENV; pname是GL_TEXTURE_ENV_MODE,则param可以是 GL_DECAL GL_MODULATE或GL_BLEND,说明纹理值与原来颜色不同的处理方式。pname是GL_TEXTURE_ENV_COLOR,则参数param是包含4个浮点数(R、G、B、A)的数组。这些值只在采用GL_BLEND纹理函数时才采用。 4. 纹理坐标坐标的定义:纹理图象是方形的,纹理坐标可定义成s,t,r,q坐标,仿照齐次坐标系的x,y,z,w坐标。void glTexCoord1234sifdv(TYPE coords);设置当前纹理坐标,此后调用glVertex*()所产生的顶点都赋予当前的纹理坐标。 5. 坐标自动产生有时不需要为每个物体顶点赋予纹理坐标,可以使用void glTexGenif(GLenum coord,GLenum pname,TYPE param);coord为:GL_S GL_T GL_R或GL_Q,指明哪个坐标自动产生pname为GL_TEXTURE_GEN_MODE时param为常数:GL_OBJECT_LINEAR GL_EYE_LINEAR或GL_SPHERE_MAP,它们决定用哪个函数来产生纹理坐标 pname为GL_OBJECT_PLANE或GL_EYE_PLANE,param时一个指向参数数组的指针。 先请看一个简单的例子:/sample.cpp#include "glos.h"#include <GL/gl.h>#include <GL/glaux.h>#include "windows.h"void myinit(void);void CALLBACK display(void);void CALLBACK reshape(GLsizei w,GLsizei h); /创建纹理图象的子程序#define TEXTUREWIDTH 64#define TEXTUREHEIGHT 64GLubyte TextureTEXTUREWIDTHTEXTUREHEIGHT3;void makeTexture(void)void makeTexture(void)int i,j,r,g,b;for(i=0;i<TEXTUREWIDTH;i+)for(j=0;j<TEXTUREHEIGHT;j+)r=(i*j)%255;g=(4*i)%255;b=(4*j)%255;Textureij0 =(GLubyte)r;Textureij1 =(GLubyte)g;Textureij2 =(GLubyte)b; void myinit(void)auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);auxInitPosition(0,0,500,500);auxInitWindow("sample1");auxInitWindow("sample1");glClearColor(0.0,0.0,0.0,0.0);glClear(GL_COLOR_BUFFER_BIT); /创建纹理图象的原始数据保存在Texture中makeTexture();glPixelStorei(GL_UNPACK_ALIGNMENT,1); /定义二维纹理glTexImage2D(GL_TEXTURE_2D,0,3,TEXTUREWIDTH,TEXTUREHEIGHT,0,GL_RGB,GL_UNSIGNED_BYTE,&Texture000);/控制滤波glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); /说明映射方式glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); /这个应该很熟了,启用纹理模式glEnable(GL_TEXTURE_2D);glEnable(GL_TEXTURE_2D);/ glShadeModel(GL_FLAT); void CALLBACK reshape(GLsizei w,GLsizei h) glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();/定义立体视景体gluPerspective(60.0,1.0*(GLfloat)w/(GLfloat)h,1.0,30.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glTranslatef(0.0,0.0,-3.6); void CALLBACK display(void)glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glBegin(GL_QUADS);/绘制四边形/先绘制正方形,用来显示实际未变形的纹理图样/先绘制正方形,用来显示实际未变形的纹理图样glTexCoord2f(0.0,0.0);glVertex3f(-2.0,-1.0,0.0);glTexCoord2f(0.0,1.0);glVertex3f(-2.0,1.0,0.0);glTexCoord2f(1.0,1.0);glVertex3f(0.0,1.0,0.0);glTexCoord2f(1.0,0.0);glVertex3f(0.0,-1.0,0.0); /绘制一个不规则四边形,用来显示纹理是如何随物体形状而变形的。glTexCoord2f(0.0,0.0);glVertex3f(0.0,-1.0,0.0);glTexCoord2f(0.0,1.0);glVertex3f(0.0,1.0,0.0);glTexCoord2f(1.0,1.0);glVertex3f(1.41421,1.0,-1.41421);glTexCoord2f(1.0,0.0);glVertex3f(1.41421,-1.0,-1.41421);glEnd(); glFlush();void main(void)myinit(); auxReshapeFunc(reshape);auxMainLoop(display);/end of sample从例子来看,除了纹理的定义和控制比较麻烦和不容易理解外,其应用是十分方便的。只须从纹理的坐标系选出合适点附在实际物体顶点上即可。对于复