前面已经提到过,载入一幅纹理所需要的时间是比较多的。因此应该尽量减少载入纹理的次数。如果只有一幅纹理,则应该在第一次绘制前就载入它,以后就不需要再次载入了。这点与glDrawPixels函数很不相同。每次使用glDrawPixels函数,都需要把像素数据重新载入一次,因此用 glDrawPixels函数来反复绘制图象的效率是较低的(如果只绘制一次,则不会有此问题),使用纹理来反复绘制图象是可取的做法。
但是,在每次绘制时要使用两幅或更多幅的纹理时,这个办法就行不通了。你可能会编写下面的代码:
glTexImage2D( /* ... */ )// 载入第一幅纹理
// 使用第一幅纹理
glTexImage2D( /* ... */ )// 载入第二幅纹理
// 使用第二幅纹理
// 当纹理的数量增加时,这段代码会变得更加复杂。
在绘制动画时,由于每秒钟需要将画面绘制数十次,因此如果使用上面的代码,就会反复载入纹理,这对计算机是非常大的负担,以目前的个人计算机配置来说,根本就无法让动画能够流畅的运行。因此,需要有一种机制,能够在不同的纹理樱销型之间进行快速的切换。
纹理对象正是脊猜这样一种机制。我们可以把每一幅纹理(包括纹理的像素数据、纹理大小等信息,也包括了前面所讲的纹理参数)放到一个纹理对象中,通过创建多个纹理对象来达到同时保存多幅纹理的目的。这样一来,在第一次使用纹理前,把所有的纹理都载入,然后在斗神绘制时只需要指明究竟使用哪一个纹理对象就可以了。
使用纹理对象和使用显示列表有相似之处:使用一个正整数来作为纹理对象的编号。在使用前,可以调用glGenTextures来分配纹理对象。该函数有两种比较常见的用法:
GLuint texture_ID
glGenTextures(1, &texture_ID)// 分配一个纹理对象的编号
或者:
GLuint texture_ID_list[5]
glGenTextures(5, texture_ID_list)// 分配5个纹理对象的编号
零是一个特殊的纹理对象编号,表示“默认的纹理对象”,在分配正确的情况下,glGenTextures不会分配这个编号。与glGenTextures对应的是glDeleteTextures,用于销毁一个纹理对象。
在分配了纹理对象编号后,使用glBindTexture函数来指定“当前所使用的纹理对象”。然后就可以使用glTexImage*系列函数来指定纹理像素、使用glTexParameter*系列函数来指定纹理参数、使用glTexCoord*系列函数来指定纹理坐标了。如果不使用 glBindTexture函数,那么glTexImage*、glTexParameter*、glTexCoord*系列函数默认在一个编号为0的纹理对象上进行 *** 作。glBindTexture函数有两个参数,第一个参数是需要使用纹理的目标,因为我们现在只学习二维纹理,所以指定为 GL_TEXTURE_2D,第二个参数是所使用的纹理的编号。
使用多个纹理对象,就可以使OpenGL同时保存多个纹理。在使用时只需要调用glBindTexture函数,在不同纹理之间进行切换,而不需要反复载入纹理,因此动画的绘制速度会有非常明显的提升。典型的代码如下所示:
// 在程序开始时:分配好纹理编号,并载入纹理
glGenTextures( /* ... */ )
glBindTexture(GL_TEXTURE_2D, texture_ID_1)
// 载入第一幅纹理
glBindTexture(GL_TEXTURE_2D, texture_ID_2)
// 载入第二幅纹理
// 在绘制时,切换并使用纹理,不需要再进行载入
glBindTexture(GL_TEXTURE_2D, texture_ID_1)// 指定第一幅纹理
// 使用第一幅纹理
glBindTexture(GL_TEXTURE_2D, texture_ID_2)// 指定第二幅纹理
// 使用第二幅纹理
提示:纹理对象是从OpenGL 1.1版开始才有的,最旧版本的OpenGL 1.0并没有处理纹理对象的功能。不过,我想各位的机器不会是比OpenGL 1.1更低的版本(Windows 95就自带了OpenGL 1.1版本,遗憾的是,Microsoft对OpenGL的支持并不积极,Windows XP也还采用1.1版本。据说Vista使用的是OpenGL 1.4版。当然了,如果安装显卡驱动的话,现在的主流显卡一般都附带了适用于该显卡的OpenGL 1.4版或更高版本),所以这个问题也就不算是问题了。
接着建一个文件夹,把你要用到的图像放到你的程序文件中。用到纹理 *** 作和加载图像 *** 作:以下是两个枝纳主要函数voidbaisic::Ground(){glPushMatrix()glEnable(GL_TEXTURE_2D)glBegin(GL_QUADS)glTexCoord2f(1.0f,1.0f)glVertex3f(-80.0f,0.0f,-80.0f)glTexCoord2f(0.0f,1.0f)glVertex3f(80.0f,0.0f,-80.0f)glTexCoord2f(1.0f,0.0f)glVertex3f(-80.0f,0.0f,80.0f)glTexCoord2f(0.0f,0.0f)glVertex3f(80.0f,0.0f,80.0f)glDisable(GL_TEXTURE_2D)glPopMatrix()}intbaisic::Load(char*fliename,GLuint&texture){AUX_RGBImageRec*pImage=NULLpImage=auxDIBImageLoad(fliename)if(pImage==NULL)returnfalseglGenTextures(1,&texture)glBindTexture(GL_TEXTURE_2D,texture)gluBuild2DMipmaps(GL_TEXTURE_2D,4,pImage-&gtsizeX,pImage-&gtsizeY,GL_RGB,GL_UNSIGNED_BYTE,pImage-&gtdata)free(pImage-&gtdata)free(pImage)returnTRUE}至于贴图的角猛饥没度问题:你用旋转函数glRotatef()函数即可.窗口是3d的里面距窗口还有一定的距离,你可以把Z坐标设置为0;X,Y坐肢丛标设置成窗口大小就好了;很久没编写OpenGL程序了,有些东西忘了,我有个这样的程序,想要的话,给我邮箱传给你;欢迎分享,转载请注明来源:内存溢出
评论列表(0条)