DirectX 入門 04 建立和使用光照

2021-04-12 17:47:12 字數 4109 閱讀 9676

原文在ms directx的幫助文件中:

directx graphics ->direct3d 9 ->tutorials and samples->tutorials->direct3d tutorials

->tutorial 4: creating and using lights

由於英文水平很菜有些語句翻譯不準確, 各位看了見諒, 如果有錯誤和不足之處歡迎指出.   (翻譯中有些語句我已經省去, 並加入了一些注釋, 為了養成一些習慣我對**進行了一點點地修改.)

正文:

direct3d光照使3d物件的真實感大大增加。當使用光照,場景中每乙個幾何物件將根據其位置和使用的光照型別被照亮。本例子介紹光照和材質兩個話題。

**路徑:

( sdk root)/samples/c++/direct3d/tutorials/tut04_lights

步驟1 -- 初始化場景中的幾何體

使用光照其中乙個要求是每乙個平面必須具有法線。因此,光照程式中使用與以往不同的頂點結構型別。新定義的頂點結構具有3d座標和平面法線。平面法線用於direct3d內部的光照計算。

structcustomvertex;

//自定義自由頂點格式(fvf)

#defined3dfvf_customvertex(d3dfvf_xyz | d3dfvf_normal)

定義了正確的頂點格式後,光照例子程式呼叫應用程式定義用於建立圓筒的函式initgeometry。首先需要建立頂點緩衝儲存儲存圓筒的頂點。

//建立頂點緩衝, g_pvb為頂點緩衝的介面指標 idirect3dvertexbuffer9*

if(failed(g_pd3ddevice->createvertexbuffer(50*2*sizeof(customvertex),

0,d3dfvf_customvertex),

d3dpool_default, &g_pvb, null) )

return e_fail;

下一步需要用圓筒的頂點資料填充頂點緩衝,注意以下**,對每乙個頂點計算其座標與法線向量。

customvertex* pvertices;

if( failed(g_pvb->lock(0, 0, (void**)&pvertices, 0) ) )

return e_fail;

//sin(x+y) = sin(x)*cos(y) + cos(x)*sin(y);

//cos(x+y) = cos(x)*cos(y) - sin(x)*sin(y);

float fdelta = (float)(2*d3dx_pi/(50-1));

float fdeltasin = sinf(fdelta);

float fdeltacos = cosf(fdelta);

float fsin = 0.0f;

float fcos = 1.0f;

float ftmpsin = 0.0f;

for(dword i=0; i<49; i++)

//防止出現累計誤差

pvertices[98].position = d3dxvector3(fsin, -1.0f, fcos);

pvertices[98].normal = d3dxvector3(fsin, 0.0f, fcos);

pvertices[99].position = d3dxvector3(0.0f, 1.0f, 1.0f);

pvertices[99].normal = d3dxvector3(0.0f, 0.0f, 1.0f);

使用圓筒座標填充頂點緩衝後,即可使用它進行渲染。但是,在渲染圓筒之前首先要設定場景中的材質與光源。

步驟二 --- 設定材質與光源

在direct3d中使用光照,你需要建立乙個或多個光源。要決定幾何物體反射的顏色,你需要建立用於渲染幾何物體的材質。渲染場景之前,光照程式呼叫設定材質和方向光源的函式setuplights。

建立材質:

材質規定幾何物體表面受到光照時反射的顏色。下段**使用d3dmaterial9結構建立乙個黃色的材質。

d3dmaterial9 material;

zeromemory(&material, sizeof( d3dmaterial9));

material.diffuse.r = material.ambient.r = 1.0f;

material.diffuse.g = material.ambient.g = 1.0f;

material.diffuse.b = material.ambient.b = 0.0f;

material.diffuse.a = material.ambient.a = 1.0f;

g_pd3ddevice->setmaterial( &material );

將材質的漫反射色和環境色設定為黃色。呼叫setmaterial函式將該材質用於direct3d裝置的場景渲染。setmaterial函式僅接受待設定材質的位址作為引數。呼叫該函式後,每乙個圖元使用剛設定的材質進行渲染,直到下一次呼叫setmaterial指定不同的材質。(因此,如果場景中包含多個不同材質的幾何體時,需要將幾何體按材質歸類後進行渲染。)

建立光源:

direct3d中具有三種可用的光源型別:

l點光源

l方向光源

l聚光燈

此例子三建立乙個方向光源(光線方向一致),改**使得光源方向隨時間不斷調整。

下一段**使用d3dlight9結構建立乙個方向光源。

d3dxvector3

vecdir;

d3dlight9

light;

zeromemory(&light, sizeof(d3dlight9));

light.type = d3dlight_directional;

//光源型別:方向光源

light.diffuse.r = 1.0f;

//設定光源漫反射色為白色。r, g, b取值[0.0f,1.0f]

light.diffuse.g = 1.0f;

light.diffuse.b = 1.0f;

//設定光源方向

vecdir = d3dxvector3( cosf(timegettime()/360.0f),

0.0f,

sinf(timegettime()/360.0f) );

//歸一化方向向量

d3dxvec3normalize( (d3dxvector3*)&light.direction, &vecdir );

light.range = 1000.0f;

//設定光源能照射到的最遠距離

呼叫d3dxvec3normalize歸一化指定光源方向的向量。

光照範圍指定該方向光源光照能影響的最遠距離。此成員不影響方向光源。

下面的**呼叫setlight設定光源。

g_pd3ddevice->setlight(0, true);

setlight函式的第乙個引數指定光源索引,(注意:如果該索引相關光源已存在,呼叫該函式將用新的光源覆蓋原有的光源。)第二個引數指定定義該光源的結構指標。

下面**開啟0號光源。

g_pd3ddevice->lightenable(0, true);

lightenable函式第乙個引數指定光源索引,第二個引數指定開啟光源(true)或關閉光源(false)。

下面**呼叫direct3d裝置介面的setrenderstate方法開啟光照計算。

g_pd3ddevice->setrenderstate(d3drs_lighting, true);

setrenderstate函式第乙個引數為需要改變裝置狀態變數,第二個引數設定該狀態的值。

最後再次呼叫setrenderstate開啟環境光(環境光使場景中每乙個物體接受相同環境光照)。

g_pd3ddevice->setrenderstate(d3drs_ambient, 0x00202020);

上面的**為場景設定灰色的環境光。

04 建立和管理表

資料庫物件 表 基本的資料儲存集合,行 列 檢視 相關的資料集合 序列 提供有規律的數值 索引 提高查詢效率 同義詞 給物件起別名 資料型別 命名規則 表名和列名 必須以字母開頭 必須在 1 30 個字元之間 必須只能包含 a z,a z,0 9,和 必須不能和使用者定義的其他物件重名 必須不能是o...

sparse image file的建立和使用

sparse file的檔案以sparse方式儲存,其優點是延遲分配磁碟空間,原理可模擬於可執行檔案中的.bss段。sparse file尤其適合作為虛擬機器的磁碟映像檔案。它僅保留一些建立時使用者指定的檔案大小資訊以及其他的metadata,使用allocation on demand的方式,用多...

04程序的建立和銷毀

通過fork 建立程序,通過返回的的pid進行區別父子程序,系統會拷貝父程序的堆疊到子程序中。getpid 獲取程序id getppid 獲取父程序id 通過exit exit 這兩個函式去結束程序,還有執行到函式最後一行,return 結束程序。狀態標誌位 exit success exit fa...