2 紋理纏繞
前面提到,紋理座標應位於0-1之間。那麼當紋理座標大於這個值會出現什麼情況呢?
我們可以對OpenGL進行設定,以決定當紋理座標不位於這一區間時應採取的操作。我們可以指定兩種操作:GL_CLAMP和GL_REPEAT。對於GL_CLAMP,超出紋理座標的地區會使用紋理映像的邊界顏色來代替,6.4-2所示。
而GL_REPEAT方式則是對紋理座標進行重設而得到重複的映像。觀察圖6.4-3,你就能很容易地發現這一點。
可以調用glTexParameter設定纏繞方式:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,WrapMode);//在s方向上的纏繞方式
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,WrapMode);//在t方向上的纏繞方式
其中,WrapMode可取GL_CLAMP或者GL_REPEAT。
4.紋理對象
建立和使用文理對象
在OpenGL中,我們使用glGenTextures建立紋理對象:
glGenTextures(Count:Integer;TexObjs:Pointer);
其中,Count是我們要建立的紋理數目,當我們只想建立一個紋理時,只需調用
var Texture:GLUint;
...
glGenTextures(1,@Texture);
這樣,Texture變數中就儲存了我們建立的紋理的ID號。
建立之後,我們使用glBindTexture將建立的紋理綁定到當前紋理。這樣所有的紋理函數都將針對當前紋理。
glBindTexture(Texture:GLUint);
這樣,我們就可以調用glTexParameter、glTexImage2D等函數來設定這個紋理對象了。
刪除紋理對象
在紋理資源使用完畢後(一般是程式退出或情境轉換時),一定要刪除紋理對象,釋放資源。
調用
glDeleteTextures(Count:Integer;TexObj:Pointer);
來刪除紋理對象。例如
glDeleteTextures(1,@Texture);
5. 多貼圖紋理
多貼圖紋理(Mip Mapping)為一個紋理對象產生不同尺寸的映像。在需要時,根據繪製圖形的大小來決定採用的紋理等級或者在不同的紋理等級之間進行線性插補。使用多貼圖紋理的好處在於消除紋理躁動。這種情況在所繪製的景物離觀察者較遠時常常發生(6.6-1和6.6-2)。由於多貼圖紋理現在的渲染速度已經很快,以至於和普通紋理沒有什麼區別,我們現在一般都使用多貼圖紋理。
|
|
| 圖6.6-1 GL_LINEAR濾鏡下的遠景 |
圖6.6-1 使用多紋理貼圖的遠景 |
使用多貼圖紋理並不麻煩。首先,我們需要建立不同等級(尺寸)的紋理圖片。我們需要調用n次glTexImage2D函數,產生不同等級的紋理貼圖。例如:
glTexImage2D(GL_TEXTURE_2D,0,3,8,8,0,GL_RGB,GL_UNSIGNED_BYTE,Pixels);
glTexImage2D(GL_TEXTURE_2D,1,3,4,4,0,GL_RGB,GL_UNSIGNED_BYTE,Pixels);
glTexImage2D(GL_TEXTURE_2D,2,3,2,2,0,GL_RGB,GL_UNSIGNED_BYTE,Pixels);
glTexImage2D(GL_TEXTURE_2D,3,3,1,1,0,GL_RGB,GL_UNSIGNED_BYTE,Pixels);
這些函數調用的第二個參數表示當前紋理的等級。0級的解析度最大。之後,每一級的解析度是上一級解析度的一半。這樣的函數調用應一直進行下去,直至映像的高度和寬度都為1。
但有時候,這樣做總並不是很方便。我們可以藉助一個glu函數幫我們自動產生這些多貼圖紋理。只需要把產生紋理映像的函數調用由glTexImage2D改為gluBuild2DMipMaps即可:
gluBuild2DMipMaps(GL_TEXTURE_2D,3,Bit.Width,Bit.Height,0,GL_RGB,GL_UNSIGNED_BYTE,Pixels);
此外,還必須把紋理的濾鏡改為MIP_MAP濾鏡。例如:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);