1. 建立紋理映像 OpenGL要求紋理的高度和寬度都必須是2的n次方大小,只有滿足這個條件,這個紋理圖片才是有效。 一旦擷取了像素值,我們就可以將這些資料傳給OpenGL,讓OpenGL產生一個紋理貼圖: glGenTextures(1,@Texture); glBindTexture(GL_TEXTURE_2D,Texture); glTexImage2D(GL_TEXTURE_2D,0,3,Bit.Width,Bit.Height,0,GL_RGB,GL_UNSIGNED_BYTE,Pixels); glGenTextures和glBindTexture函數用於建立和綁定紋理對象,glTexImage2D函數將Pixels數組中的像素值傳給當前綁定的紋理對象,於是便建立了紋理。glTexImage函數的參數分別是紋理的類型,紋理的等級,每個像素的位元組數,紋理映像的寬度和高度,邊框大小,像素資料的格式,像素值的資料類型,像素資料。 2. OpenGL中的貼圖方式 OpenGL為我們提供了三種紋理——GL_TEXTURE_1D、GL_TEXTURE_2D和GL_TEXTURE_3D。它們分別表示1維紋理、2維紋理和3維紋理。無論是哪一中紋理,使用方法都是相同的:即先建立一個紋理對象和一個儲存紋理資料的n維數組,在調用glTexImageN D函數來傳入相應的紋理資料。除此之外,我們可以一些函數來設定紋理的其他特性。 2.1 設定貼圖模式 OpenGL提供了3種不同的貼圖模式:GL_MODULATE,GL_DECAL和GL_BLEND。預設情況下,貼圖模式是GL_MODULATE,在這種模式下,OpenGL會根據當前的光照系統調整物體的色彩和明暗。第二種模式是GL_DECAL,在這種模式下所有的光照效果都是無效的,OpenGL將僅依據紋理貼圖來繪製物體的表面。最後是GL_BLEND,這種模式允許我們使用混合紋理。在這種模式下,我們可以把當前紋理同一個顏色混合而得到一個新的紋理。我們可以調用glTexEnvi函數來設定當前貼圖模式: glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,TextureMode); 其中TextureMode就是想要設定的紋理模式,可以為GL_MODULATE,GL_DECAL和GL_BLEND中的任何一種。 另外,對於GL_BLEND模式,我們可以調用 glTexEnvfv(GL_TEXUTRE_ENV,GL_TEXTURE_ENV_COLOR,@ColorRGBA); 其中,ColorRGBA為一個表示RGBA顏色的4維數組。 2.2 紋理濾鏡 在紋理映射的過程中,如果圖元的大小不等於紋理的大小,OpenGL便會對紋理進行縮放以適應圖元的尺寸。我們可以通過設定紋理濾鏡來決定OpenGL對某個紋理採用的放大、縮小的演算法。 調用glTexParameter來設定紋理濾鏡。如: glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILETER, MagFilter);//設定放大濾鏡 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, MinFilter); //設定縮小濾鏡 上述調用中,第一個參數表明是針對何種紋理進行設定,第二個參數表示要設定放大濾鏡還是縮小濾鏡。第三個參數表示使用的濾鏡。可以為下面的值之一:
| 表6.3-1 可使用的紋理濾鏡 |
| 濾鏡 |
描述 |
| GL_NEAREST |
取最鄰近像素 |
| GL_LINEAR |
線性內部插值 |
| GL_NEAREST_MIPMAP_NEAREST |
最近多貼圖等級的最鄰近像素 |
| GL_NEAREST_MIPMAP_LINEAR |
在最近多貼圖等級的內部線性插值 |
| GL_LINEAR_MIPMAP_NEAREST |
在最近多貼圖等級的外部線性插值 |
| GL_LINEAR_MIPMAP_LINEAR |
在最近多貼圖等級的外部和內部線性插值 |
3 紋理映射 3.1 紋理座標 要使用當前的紋理繪製圖元,我們必須在繪製每個頂點之前為該頂點指定紋理座標。只需調用 glTexCoord2d(s:Double;t:Double); 函數即可。其中,s、t是對於2D紋理而言的s、t座標。對於任何紋理,它的紋理座標都如同圖6.4-1所示的那樣:
對於任何紋理,無論紋理的真正大小如何,其頂端(左上方)的紋理座標恒為(0,0),右下角的紋理座標恒為(1,1)。也就是說,紋理座標應是一個介於0到1之間的一個小數。 例如,下面的代碼將使用當前紋理繪製一個三角形: glBindTexture(Tex); glBegin(GL_TRIANGLES); glTexCoord2d(0,0); glVertex3f(-10,-10,0); glTexCoord2d(0,1); glVertex3f(-10,10,0); glTexCoord2d(1,1); glVertex3f(10,10,0); glEnd(); |