1.18k likes | 1.33k Views
Számítógépes grafika. DirectX 4. gyakorlat. Emlékeztető. Múlt órán megnéztük a különböző memóriaosztályokat Utána elkezdtük a 3D-s alapokat, megnéztük mik a primitívek, a csúcspontok hol tárolódnak stb. Most áttekintjük a végső keretrendszerünket, a transzformációkat és a világítást.
E N D
Számítógépes grafika DirectX 4. gyakorlat
Emlékeztető • Múlt órán megnéztük a különböző memóriaosztályokat • Utána elkezdtük a 3D-s alapokat, megnéztük mik a primitívek, a csúcspontok hol tárolódnak stb. • Most áttekintjük a végső keretrendszerünket, a transzformációkat és a világítást
Tartalom • 1. Keretrendszer • 2. Transzformációk • 3. Textúrázás
Múlt órai programváz InitDeviceObjects ReleaseDeviceObjects FrameUpdate Render InitD3D CleanUpD3D
Végleges programváz FrameUpdate Render HandleInput InitDeviceObjects ReleaseDeviceObjects InitD3D CleanUpD3D
Tartalom • 1. Keretrendszer • 2. Transzformációk • 3. Textúrázás
Emlékeztető • A DirectX Graphics renderelő komponense a Direct3D Device • Tárolja a megjelenítést befolyásoló úgynevezett renderelési állapotokat • Három modulból áll: • transzformációs • megvilágító • és raszterizáló
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: • Nagyítani/kicsinyíteni a modellünket • Elforgatni a modellünket (orientációt beállítani) • 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:#pragmacomment(lib,"d3dx9.lib")#include <d3dx9.h>
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
1. példa Alap transzformációk
Mit csinálunk? • Tölstük le: http://people.inf.elte.hu/valasek/bevgraf/04/01_Transforms.zip • Kirajzolunk és egérrel forgatunk egy háromszöget a következő vertexformátummal: • struct CUSTOMVERTEX{ FLOAT x, y, z; DWORD color; };#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
Mit csinálunk • Definiálunk egy saját vertex formátumot • Felveszünk egy vertex buffer adattagot • Default pool-osként kezeljük, így InitDeviceObjects-ben hozzuk létre a VB-t • ReleaseDeviceObjects-ben pedig felengedjük • Render-ben pedig kirajzolunk • HandleInput-ban kezeljük az egeret • FrameUpdate-ben a transzformációkat állítjuk be
Vertex shader 1/2 struct vertexIn { float3 p : POSITION; float4 c : COLOR0; }; struct hvertexOut { float4 p : POSITION; float4 c : COLOR0; };
Vertex shader 2/2 hvertexOut main(vertexIn IN, uniformfloat4x4 worldViewProj ) { hvertexOut OUT; float4 v = float4(IN.p.x,IN.p.y,IN.p.z,1.0); OUT.p = mul( worldViewProj, v); OUT.c = IN.c; return OUT; }
Pixel shader 1/2 struct fragment { float4 p : POSITION; float4 c : COLOR0; }; struct pixel { float4 c : COLOR; };
Pixel shader 2/2 pixel main( fragment IN, uniform float4 cl ) { pixel OUT; OUT.c = cl; return OUT; }
DXMyApp.h class CDXMyApp :public CDXAppBase{ ... private: CGcontext m_CGcontext; CGprogram m_CGprogram_vertex; CGprogram m_CGprogram_pixel; CGparameter m_CGparam_color; CGparameter m_CGparam_worldViewProj; ...
DXMyApp.h ... D3DXMATRIXA16 matProj, matView, matWorld; LPDIRECT3DVERTEXBUFFER9 m_pVB; float m_angleY; staticconstDWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE; struct Vertex{ D3DXVECTOR3 p; DWORD c;}; }
CDXMyApp::CDXMyApp(void) CDXMyApp::CDXMyApp(void) { m_pVB = NULL; m_angleY = 0; }
CDXMyApp ::~CDXMyApp(void) CDXMyApp::~CDXMyApp(void) { }
CDXMyApp::InitDeviceObjects() HRESULT CDXMyApp::InitDeviceObjects() { Vertex vertices[] ={ { D3DXVECTOR3(0,1,0), 0xffff0000 }, { D3DXVECTOR3(1,-1,0), 0xff00ff00 }, { D3DXVECTOR3(-1, -1,0), 0xff0000ff } }; m_pD3DDevice->CreateVertexBuffer( sizeof(vertices), D3DUSAGE_WRITEONLY,FVF,D3DPOOL_DEFAULT, &m_pVB, NULL ); ...
CDXMyApp::InitDeviceObjects() ... void *pVertices = NULL; m_pVB->Lock(0,sizeof(vertices), &pVertices, 0 ); memcpy(pVertices, vertices,sizeof(quadVertices)); m_pVB->Unlock(); ...
CDXMyApp::InitDeviceObjects() m_CGcontext = cgCreateContext(); cgD3D9SetDevice( m_pD3DDevice ); CGprofile vertexProfile = cgD3D9GetLatestVertexProfile(); CGprofile pixelProfile = cgD3D9GetLatestPixelProfile(); constchar **vertexOptions[] ={ cgD3D9GetOptimalOptions( vertexProfile ),NULL,}; constchar **pixelOptions[] ={ cgD3D9GetOptimalOptions( pixelProfile ),NULL,};
CDXMyApp::InitDeviceObjects() Hogyan hozzuk létre a shadert:CG_SOURCE: forrásfájlbólCG_OBJECT: lefordított objektum kódból ... m_CGprogram_vertex = cgCreateProgramFromFile( m_CGcontext, CG_SOURCE, "vs.cg", vertexProfile, "main", *vertexOptions ); ... Context amibe rakjuk a shadert Fordítandó shader fájlneve Fordítási cél shader modell A shader belépési pontja Compiler opciók
CDXMyApp::InitDeviceObjects() ... m_CGprogram_pixel = cgCreateProgramFromFile( m_CGcontext, CG_SOURCE, "ps.cg", pixelProfile, "main", *pixelOptions ); ...
CDXMyApp::InitDeviceObjects() cgD3D9LoadProgram( m_CGprogram_vertex, TRUE, 0 ); cgD3D9LoadProgram(m_CGprogram_pixel, TRUE, 0 ); m_CGparam_worldViewProj = cgGetNamedParameter( m_CGprogram_vertex, "worldViewProj" ); m_CGparam_color = cgGetNamedParameter( m_CGprogram_pixel, "cl" ); ...
CDXMyApp::InitDeviceObjects() ... D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/2, m_BBWidth/(float)m_BBHeight, 0.1f, 100); return S_OK; }
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
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