Pipeline Vertex shader Fragment shader
Transzformációs modul A modellünket a saját koordinátarendszerében adjuk meg Azonban a saját koordinátarendszerükben lévő modelleket egy közös, úgynevezett világ koordinátarendszerbe kell hozni Ezt különböző transzformációkkal – nagyítás, kicsinyítés, forgatás, eltolás – visszük végbe
Transzformációs modul Először közös koordinátarendszerbe helyezzük a színtér alkotóelemeit - ez a világ transzformáció Utána az aktuális nézőpontunknak megfelelően tovább transzformálódik a színtér - ez a nézet transzformáció Végül pedig létrejön a 3D-s színterünk 2D-s vetülete - ez a vetítési transzformáció
Transzformációs modul A transzformációs modul a fenti transzformációkat vektor-mátrix szorzásokkal valósítja meg A szorzásokat a DirectX végzi, nekünk FFP-nél csak meg kell mondani neki, hogy egy-egy konkrét transzformációt mely mátrixok valósítják meg Shaderekben pedig el kell végezni a szorzást a mul CG paranccsal
Transzformációk A transzformációkat 4x4-es mátrixokkal adjuk meg A D3DX utility könyvtárban két megvalósítás is van (az alap D3DMATRIX-on kívül) ezeknek: D3DXMATRIX D3DXMATRIXA16: a memóriába 16 bájtos egységekre illeszti a mátrixokat – ezt az Intel procik szeretik, sokat lendít a sebességen
Transzformációk Bármely affin transzformáció A mátrixa felírható egy N nyírás, egy S léptékezés, egy O origó körüli elforgatás és egy T eltolás mátrix szorzataként Figyeljünk azonban a sorrendre: A DirectX a mátrix-vektorszorzást balról jobbra végzi Vagyis a transzformált x’ pontot így kapjuk: x’=xA
Transzformációk Ezt mindenképpen jegyezzük meg, ugyanis általában a következőt szeretnénk csinálni a világban való elhelyezés során: 1.Nagyítani/kicsinyíteni a modellünket 2.Elforgatni a modellünket (orientációt beállítani) 3.Eltolni a modellünket a helyére a világban
Világtranszformáció A modell saját koordinátarendszeréből a világ koordinátarendszerbe térünk át
D3DX utility könyvtár A transzformációk mátrixát a D3DX függvényeinek segítségével állítjuk elő A következő lib és header fájlokra lesz szükség hozzájuk: #pragma comment(lib,"d3dx9.lib") #include
Mátrixműveletek D3DXMATRIX * D3DXMatrixIdentity( D3DXMATRIX * pOut ); A paraméterben kapott címen lévő mátrixot a 4x4- es egységmátrixszal tölti fel D3DXMATRIX m_id; D3DXMatrixIdentity(&m_id);
Mátrixműveletek D3DXMATRIX * D3DXMatrixMultiply( D3DXMATRIX * pOut, CONST D3DXMATRIX * pM1, CONST D3DXMATRIX * pM2 ); Az első paraméterben kapott címre kerül a második és harmadik helyen kapott mátrixok szorzata (balról jobbra szoroz) Előbb az M1, aztán az M2 transzformációt elvégző mátrix lesz az eredmény A D3DXMATRIX ‘*’ operátorát is használhatjuk
Mátrixműveletek D3DXMATRIX * D3DXMatrixRotationX( D3DXMATRIX * pOut, FLOAT Angle ); Az első paraméterben kapott mátrixot feltölti az X tengely körüli Angle radián nagyságú elforgatás mátrixával D3DXMatrixRotationY, D3DXMatrixRotationZ hasonló
Mátrixműveletek D3DXMATRIX * D3DXMatrixRotationYawPitchRoll( D3DXMATRIX * pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); Forgatásmátrixot készít, ami az Y tengely körül Yaw, az X körül Pitch, a Z körül pedig Roll szöggel forgat el
Mátrixműveletek D3DXMATRIX * D3DXMatrixTranslation( D3DXMATRIX * pOut, FLOAT x, FLOAT y, FLOAT z ); A paraméterben kapott mátrixot az (x,y,z) vektorral való eltolás mátrixa lesz
Mátrixműveletek D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); Balsodrású projekciós mátrixot épít, paramétereit lásd később
Mátrix-vektor műveletek D3DXVECTOR4 * D3DXVec3Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); A pV vektor homogén alakját transzformálja a pM mátrixszal Az eredmény 4 komponensű vektor lesz
Mátrix-vektor műveletek D3DXVECTOR3 * D3DXVec3TransformCoord( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); A pV vektor homogén alakját transzformálja a pM mátrixszal Az eredmény a homogén osztás utáni, w koordináta elhagyásával kapott vektor lesz
Vetítési transzformáció Tekinthetünk rá úgy, mint a kamera belső tulajdonságainak beállítására Mi most egy perspektív transzformációt fogunk beállítani
Vetítési transzformáció
D3DXMatrixPerspectiveFovLH D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); pOut: kimeneti mátrix
D3DXMatrixPerspectiveFovLH D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); fovy: radiánban mért látószög
D3DXMatrixPerspectiveFovLH D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); Aspect: a nézetmező szélesség:magasság aránya
D3DXMatrixPerspectiveFovLH D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); zn: közelsík távolsága, >0
D3DXMatrixPerspectiveFovLH D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); zf: távolsík távolsága
Nézet transzformáció Azt szeretnénk, hogy ne egy, vagy néhány adott objektum helyzete változzon, hanem az a hely, ahonnan nézzük a színteret Erre szolgál a nézeti transzformáció, elhelyezi a virtuális világban a szemlélőt D3DXMatrixLookAtLH: balsodrású koordinátarendszer nézeti transzformációját állítja elő nézőpont, nézett pont és felfelé mutató irány alapján
Nézet transzformáció vLookatPt vEyePt vUpVec X Y Z
VOID CDXMyApp ::Render() {... m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);...
Z-buffer Az ősosztályba bekerült D3DPRESENT_PARAMETERS struktúra feltöltésében is meg kell erről emlékeznünk: DXAppBase.cpp:... m_d3dpp.EnableAutoDepthStencil = TRUE; m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;...
Z-buffer A backbuffer felbontásának megfelelő nagyságú lesz Egy-egy eleme ( (x,y) pontbeli értéke) azt mondja meg, hogy az adott pixelben látható fragment milyen messze van
Culling A DirectX alapbeállítás szerint a hátrafelé néző lapokat nem veszi figyelembe rendereléskor Tehát amikor körbeforog a négyzetünk, az esetek felében nem látszik majd ha ezt így hagyjuk
Előre néző lap Egy háromszög előre néző lapja (front face) megkapható, ha ismerjük a háromszög 3 csúcspontját Egy háromszög előre néző lapja (front face) az, amelyiknek a normálvektora felől nézve a háromszög csúcsai az óra járásával megegyező irányban adottak a primitívmegadáskor
Front face
IDirect3DDevice9::SetRenderState HRESULT SetRenderState( D3DRENDERSTATETYPE State, DWORD Value ); State: melyik állapot beállításait akarjuk módosítani. Lehet például D3DRS_FILLMODE, D3DRS_LIGHTING, D3DRS_CULLMODE, stb. (Ld. D3DRENDERSTATETYPE)
IDirect3DDevice9::SetRenderState HRESULT SetRenderState( D3DRENDERSTATETYPE State, DWORD Value ); Value: az állapotváltozó új értéke. D3DRS_CULLMODE-nál ez lehet: D3DCULL_NONE: nincs eldobás D3DCULL_CW: óramutató járása szerint D3DCULL_CCW: azzal ellentétesen