DirectX 圖形介面指南(6) (轉)

worldblog發表於2007-12-12
DirectX 圖形介面指南(6) (轉)[@more@]

指南五:使用紋理對映:namespace prefix = o ns = "urn:schemas--com::office" />

 

儘管光照和材質大大增加了場景的真實感,但沒有比在表面上新增紋理更能增加真實感的了。紋理能夠被想象為一層緊緊包裝在表面的貼紙。你能在一個立方體上放置一層木質紋理使它看起來就象用木頭製成的一樣。本 Texture 例程將在 指南四:建立和使用光照 中構造的圓柱上新增一幅類似香蕉的紋理。此指南介紹的內容包括如何載入紋理,設定紋理,與呈遞帶有紋理的物體。

 

本指南採用以下步驟實現紋理:

 

·第一步:定義一個定製頂點格式

·第二步:初始化螢幕幾何

·第三步:演示場景

注意:Texture 示例的路徑為:

(SDK )SamplesMultimediaDirect3DTutorialsTut05_Textures.

 

注意:除了 Texture 示例不建立材質和光照以外,Texture 工程中的示例程式碼與 Lights 工程的幾乎完全一樣。本“使用紋理對映”指南僅僅關注於有關於紋理的獨特程式碼,而並不重複有關初始化 Microsoft Direct3D,處理 Microsoft 訊息,演示,或清理的內容。關於這些工作的資訊,見:指南一:建立裝置

 

本指南使用自定義頂點和頂點緩衝區顯示幾何物體。關於選擇一個自定義頂點格式並頂點緩衝的更多資訊,見:指南二:演示頂點

 

本指南採用矩陣進行幾何變換。關於矩陣和變換的更多資訊,參見:指南三:使用矩陣

 

第一步:定義一個定製頂點格式

 

在使用紋理以前,必須使用包含紋理座標的自定義頂點格式。紋理座標告訴 Microsoft Direct3D 在物件上如何將紋理定位於每個頂點上。紋理座標範圍從 0.0 到 1.0,(0.0, 0.0) 的位置代表紋理貼圖的左上角而 (1.0, 1.0) 代表紋理貼圖的右下角。

 

以下示例程式碼說明了 Texture 例程是如何透過設定它的自定義頂點格式來包含紋理座標的。

 

struct CUSTOMVERTEX

{

  D3DXVECTOR3 position; // The position.

  D3DCOLOR  color;  // The color.

  FLOAT  tu, tv;  // The texture coordinates.

};

 

// The custom FVF, which describes the custom vertex structure.

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)

 

關於紋理座標的進一步資訊,參見 SDK: Texture Coordinates 一章。

 

現在自定義頂點格式已經準備好了,下一步將是載入一幅紋理並建立一個圓柱體,見 第二步:初始化螢幕幾何

 

第二步:初始化螢幕幾何

 

在繪製之前,Texture 例程 InitGeometry,一個程式自定義的用於建立一幅紋理並初始化圓柱體的幾何引數。

 

紋理是由基於的影像構造的。以下示例程式碼使用 D3DXCreateTextureFromFile 從 Banana.bmp 檔案建立一幅紋理並用它覆蓋圓柱的表面。

 

if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "Banana.bmp",

  &g_pTexture ) ) )

  return E_FAIL;

 

D3DXCreateTextureFromFile 接受的第一個引數是一個指向 Microsoft Direct3D 裝置的指標,這個裝置將用於繪製紋理。第二個引數是一個指向 ANSI 字串的指標,它指定用於建立紋理的檔名。本例程指定從此檔案:“Banana.bmp” 來裝載影像。第三個引數是一個指向紋理指標的地址。

 

當這個類似香蕉的紋理被裝載並準備好之後,下一個步驟是建立圓柱體。以下示例程式碼用一個圓柱體填充頂點緩衝區。注意每一點都具備了紋理座標 (tu, tv)。

 

for( D i=0; i<50; i++ )

{

  FLOAT theta = (2*D3DX_PI*i)/(50-1);

 

  pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0, co(theta) );

  pVertices[2*i+0].color  = 0xffffffff;

  pVertices[2*i+0].tu  = ((FLOAT)i)/(50-1);

  pVertices[2*i+0].tv  = 1.0f;

 

  pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0, cosf(theta) );

  pVertices[2*i+1].color  = 0xff808080;

  pVertices[2*i+1].tu  = ((FLOAT)i)/(50-1);

  pVertices[2*i+1].tv  = 0.0f;

}

 

每一個頂點包括位置,顏色,以及紋理座標。上面的例程給每一點設定了紋理座標並使此紋理能夠平滑的包裹在圓柱體周圍。

 

現在紋理和頂點緩衝區已經準備好用於演示了,現在能夠呈遞和著色圖形了,參見 第三步:演示場景

 

第三步:演示場景

 

在場景幾何被初始化之後,應該是繪製場景的時候了。為了繪製一個帶有紋理的物體,使用的紋理必須要設定成當前紋理中的一個。下一步將是設定紋器的狀態。紋理儲存器狀態使你能夠定義一個或者多個紋理被呈遞的方式。比如說,你能將多個紋理混合在一起。

 

現在 Texture 示例開始設定需要使用的紋理。以下程式碼段使用 IDirect3DDevice8::SetTexture 設定 Microsoft Direct3D 裝置用於繪製的紋理。

 

g_pd3dDevice->SetTexture( 0, g_pTexture );

 

SetTexture 接受的第一個引數是設定紋理儲存器的標示符。一個裝置能夠支援八個已初始化的紋理,所以這兒的最大值是 7。本 Texture 示例僅僅使用一個紋理並且把它設定在儲存器 0。第二個引數是一個指向紋理物件的指標。在這兒,Texture 示例使用由它的程式自定義函式 InitGeometry 建立的紋理。

 

以下程式碼片設定紋理儲存器狀態的值,透過呼叫 IDirect3DDevice8::SetTextureStageState 方法。

 

g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,  D3DTOP_MODULATE );

g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );

g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,  D3DTOP_DISABLE );

 

SetTextureState 的第一個引數是需要改變狀態的儲存器的。本示例程式碼改變位於儲存器 0 的紋理,所以這兒置為 0。下一個引數是要設定的紋理狀態。關於所有有效的紋理狀態以及它們的意義,見 "SDK: D3DTEXTURESTAGESTATETYPE"。再下一個引數是設定為此紋理狀態的引數。你放置這兒的值應取決於你要改變的紋理儲存器狀態。

 

在設定完每個紋理儲存器狀態的合適值之後,這個圓柱體可以被呈遞了,現在紋理將被新增在它的表面上。

 

使用紋理座標的其他方法是使它們自動的生成。這是用一種紋理座標索引 (TCI) 實現的。TCI 使用一個紋理矩陣來變換 (x,y,z) TCI 座標為 (tu, tv) 紋理座標。在 Texture 例程中,位於攝像機空間中的頂點位置被用來產生紋理座標。

 

第一步是建立用於轉換的矩陣,示範在以下程式碼片段中:

 

D3DXMATRIX mat;

mat._11 = 0.25f; mat._12 = 0.00f; mat._13 = 0.00f; mat._14 = 0.00f;

mat._21 = 0.00f; mat._22 =-0.25f; mat._23 = 0.00f; mat._24 = 0.00f;

mat._31 = 0.00f; mat._32 = 0.00f; mat._33 = 1.00f; mat._34 = 0.00f;

mat._41 = 0.50f; mat._42 = 0.50f; mat._43 = 0.00f; mat._44 = 1.00f;

 

在矩陣建立好之後,它必須透過呼叫 IDirect3DDevice8::SetTransfo來設定它,如以下程式碼段所示:

 

g_pd3dDevice->SetTransform( D3DTS_TEXTURE0, &mat );

 

D3DTS_TEXTURE0 標誌告訴 Direct3D 應用此變換到位於紋理儲存器 0 的紋理。本示例的下一步是設定其他的儲存器狀態值,以得到所需的效果。這些處理在以下程式碼段中。

 

g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );

g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERACEPOSITION );

 

紋理座標被設定後,現在此場景已準備好被呈遞了。注意到現在的座標是自動設定到圓柱上的。這樣精確的設定使幾何物體被演示時紋理好象是覆蓋在繪製的螢幕上。

 

關於紋理的更多資訊,見 SDK: Texture 一章。

 

本指南已經向你說明了如何給表面新增紋理。指南六:使用Mesh模型 將告訴你如何應用Mesh模型呈遞複雜的幾何形體。

 

指南六:使用Mesh模型 見本文第七部分)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992159/,如需轉載,請註明出處,否則將追究法律責任。

相關文章