játékfejlesztés.hu
FórumGarázsprojectekCikkekSegédletekJf.hu versenyekKapcsolatokEgyebek
Legaktívabb fórumozók:
Asylum:    5448
FZoli:    4892
Kuz:    4455
gaborlabor:    4449
kicsy:    4304
TPG:    3402
monostoria:    3284
DMG:    3172
HomeGnome:    2919
Matzi:    2520

Pretender:    2498
szeki:    2440
Seeting:    2306
Geri:    2188
Orphy:    1893
Joga:    1791
Bacce:    1783
MaNiAc:    1735
ddbwo:    1625
syam:    1491
(C++) DirectX programozás 16. - Direct3D 5. (Z-buffer) 2006.06.09 17:33


Z-buffer

Ha több testet jelenítünk meg, óhatatlanul belefutunk abba a problémába, hogy jó lenne, ha a hátsó testeket az elülső testek eltakarnánk. Ezt a problémát DirectX-ben a z-buffer oldja meg.

Gondoljuk meg, hogy legegyszerűbben úgy tudnánk megoldani a takarást, hogy a nézőpontból mindig hátulról előre renderelnénk, de ez túl bonyolúlt, bár megoldható. Régen ráadásul így is csinálták. Ma a legegyszerűbb módszer, hogy a rajzterületünkhöz egy buffert rendelünk, amely lényegében egy két dimenziós tömb, és pont akkora, mint a front bufferünk, azaz a rajzterületünk. Így a képünk minden pixeléhez tartalmaz egy mélységinformációt. Azaz azt, hogy a rajzterületünkre eddig levetült pixelnek mi a mélysége. Ezért egy kép előállításánál mindig először a lehető legnagyobb értékre(tehát a „legtávolabbi” értékre) állítjuk a z-buffer minden elemét, majd minden pixel renderelésénél megnézzük a pixelhez a z-bufferben tárolt értéket. Ha az nagyobb, mint az aktuális pixel mélysége, akkor kicseréljük a pixelt, majd beírjuk az új z értéket. Ha az aktuális pixel mélysége nagyobb, mint a beírt érték, akkor nem teszünk semmit.

A z-buffer egyébként MINDEN takarási feladatot megold, hiszen például egymást metsző testekre is megoldja a takarást, míg a hátúlról-előre renderelés itt dilemmába ütközik, hiszen mindkettő a másik előtt van…

Nézzük akkor a z-buffer létrehozását illetve használatát. Előrebocsájtom, könnyű lesz.

Létrehozásához semmi nem kell, csupán az eszközünk létrehozásánál az eszközleírót be kell állítani, hogy az eszközhöz rendeljen egy front buffer méretű z-buffert. Ez így tudjuk megtenni:

d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.EnableAutoDepthStencil = true;

Nyilván a második azt mondja, hogy legyen z-buffer, az első pedig azt, hogy milyen formátumú legyen. Jelenleg minden pixelhez egy 16 bites tárolót rendelünk(D3DFMT_D16). Ez lehetne akár 32 bites is(D3DFMT_D32). Így már létrehozhatjuk az eszközünket, automatikusan generálni fog hozzá egy z-buffert.

Természetesen a renderelési beállításoknál ennek a buffernek a használatát engedélyezni kell:

lpD3D_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

A D3DZB_TRUE párja nyilván a D3DZB_FALSE. Ezzel már működik is a z-bufferünk. Csupán mint mondtam, minden egyes képkocka elkészítésénél a legnagyobb értékre kell beállítani. Ezt a

lpD3D_Device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0x00000000,1.0f,0);

parancs végzi, amit már ismerünk. Ez most feketére törli a képernyőt, majd a z-buffert 1.0 értékre állítja, ugyanis ezen értéket 0.0-tól 1.0-ig lehet állítani. Ebből 1.0 a legnagyobb beállítható érték (a hátsó vágósík).

Ezután a forgó négyzetet illetve a hátteret mindegy milyen sorrendben rendereljük, hiszen mindig a forgó négyzet lesz elöl. Ez z-buffer nélkül nem lenne így.

A példa azt is bemutatja, hogyan lehet több testet renderelni különböző textúrákkal.

d3d4.exe


2006. február 15.

Crusader


Kapcsolódó linkek:

A cikksorozat további részei:

Értékelés: 0

Új hozzászólás
HomeGnome          2006.08.01 07:04
Hoppá! Köszi hogy szóltál, az .exe-ket ideiglenesen leszedtem...
szombatha          2006.08.01 02:35
az exék virustalanitására jobban oda kellene figyelni!!!! A mellékelt exe virusos !!!!!!!!!!!!!!!!!!!!!