OPENGL紋理基礎

2021-07-29 14:59:18 字數 2636 閱讀 4584

//對於vbo道理是一樣的 

1. 紋理座標 

在繪製一條線段時,我們設定其中乙個端點為紅色,另乙個端點為綠色,則opengl會自動計算線段中其它各畫素的顏色,如果是使用glshademode(gl_smooth);,則最終會形成一種漸變的效果(例如線段中點,就是紅色和綠色的中間色)。

類似的,在繪製一條線段時,我們設定其中乙個端點使用

「紋理圖象中最左下角的顏色

」作為它的顏色,另乙個端點使用

「紋理圖象中最右上角的顏色

」作為它的顏色,則

opengl

會自動在紋理圖象中選擇合適位置的顏色,填充到線段的各個畫素(例如線段中點,可能就是選擇紋理圖象**的那個畫素的顏色)。

我們在模擬時,使用了「紋理圖象中最左下角的顏色」這種說法。但這種說法在很多時候不夠精確,我們需要一種精確的方式來表示我們究竟使用紋理中的哪個畫素。紋理座標也就是因為這樣的要求而產生的。以二維紋理為例,規定紋理最左下角的座標為

(0, 0)

,最右上角的座標為

(1, 1)

,於是紋理中的每乙個畫素的位置都可以用兩個浮點數來表示(三維紋理會用三個浮點數表示,一維紋理則只用乙個即可)。

使用gltexcoord*系列函式來指定紋理座標。這些函式的用法與使用glvertex*系列函式來指定頂點座標十分相似。例如:gltexcoord2f(0.0f, 0.0f);指定使用(0, 0)紋理座標。

2.紋理物件

前面已經提到過,載入一幅紋理所需要的時間是比較多的。因此應該儘量減少載入紋理的次數。如果只有一幅紋理,則應該在第一次繪製前就載入它,以後就不需要再次載入了。這點與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紋理單元

可以這樣簡單的理解為 顯示卡中有n個紋理單元 具體數目依賴你的顯示卡能力 每個紋理單元 gl texture0 gl texture1等 都有gl texture 1d gl texture 2d等,如下 cpp view plain copy print struct textureunit te...

openGL 紋理使用

最近找了點資料學習了下opengl 紋理的使用 先有個 整體把握,然後再去看大部頭中的細節講解,感覺這樣的學習方式好些 總結下紋理使用總體流程 1 啟用紋理 glenable gl texture 2d 2 載入紋理 3 紋理 的顯示 載入紋理 1 讀取紋理影象高寬和畫素資料到記憶體中,老版本 op...

openGL 紋理使用

總結下紋理使用總體流程 1 啟用紋理 glenable gl texture 2d 2 載入紋理 3 紋理 的顯示 載入紋理 1 讀取紋理影象高寬和畫素資料到記憶體中,老版本opengl需要考慮寬度和高度不是的整數次方 2 分配乙個新的紋理編號 glgentextures 1,texture id ...