Számítógépes grafika DirectX 7. gyakorlat
Emlékeztető Múlt órán mesheket és transzformációkat használtunk Most primitívkirajzoláshoz nézünk meg egy hasznos dolgot
Tartalom 1. Index pufferek 2. Függvénykirajzoló
Egy apró kényelmetlenség Az eddig megismert primitívjeink (triangle list/strip/fan stb) használatával néha túlságosan redundáns csúcsponttárolásr kényszerülünk Háromszöglistával például egy egyszerű kocka tárolására 36 csúcspont kell Ha mi adhatnánk meg, hogy milyen sorrendben történjen a csúcsok összekötése jelentős megtakarításokat érhetnénk el
Index buffer Ha indexelt primitíveket használunk, akkor két tárolónk van: Egy vertexbuffer a csúcspontoknak És egy indexbuffer, ami vertexbufferbeli indexeket tárol. A benne lévő sorrendben köti össze a csúcsokat a D3D primitívkirajzoláskor
2. példa Indexelt primitívek
Mit csinálunk? Egy kockát rajzolunk ki indexelt primitívek segítségével Ez lesz az eredmény:
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, uniform float4x4 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;... A CG Context a shader programjaink tárolója A CGprogram típusú változók a shadereink azonosítóit fogják tartalmazni, amiken keresztül tud kommunikálni az alkalmazásunk a shader programokkal A CGparameter típusú változók a shaderprogramjaink „paraméterei” (uniform típusú változók), amelyeknek értéket adhatunk az alkalmazásunkból (pl. az m_CGparam_color a kirajzolási színt fogja jelenteni)
DXMyApp.h... D3DXMATRIXA16 matProj; LPDIRECT3DVERTEXBUFFER9 m_pVB; LPDIRECT3DINDEXBUFFER9m_pIB; float m_angleY; static const DWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE; struct Vertex { D3DXVECTOR3 p; DWORD c; }; }
CDXMyApp::CDXMyApp() { m_pVB = NULL; m_pIB = NULL; }
HRESULT CDXMyApp:: InitDeviceObjects() { m_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE); CUSTOMVERTEX vertices[8];...
HRESULT CDXMyApp:: InitDeviceObjects() { Vertex vertices[] = { {D3DXVECTOR3(-1,-1,-1), 0xffff0000 }, {D3DXVECTOR3( 1,-1,-1), 0xff00ff00 }, {D3DXVECTOR3( 1, 1,-1), 0xff0000ff }, {D3DXVECTOR3(-1, 1,-1), 0xff808080}, };...
HRESULT CDXMyApp:: InitDeviceObjects()... if( FAILED( m_pD3DDevice-> CreateVertexBuffer( 8*sizeof(CUSTOMVERTEX), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pVB, NULL ) ) ) return E_FAIL;...
HRESULT CDXMyApp:: InitDeviceObjects()... VOID* pVertices; if( FAILED( m_pVB->Lock( 0, sizeof(vertices), &pVertices, 0 ) ) ) return E_FAIL; memcpy( pVertices, vertices, sizeof(vertices) ); m_pVB->Unlock();...
HRESULT CDXMyApp:: InitDeviceObjects()... WORD indices[] = {0,3,1, 3,2,1 }; m_pD3DDevice->CreateIndexBuffer( sizeof(indices)*sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pIB, NULL);...
IDirect3DDevice9:: CreateIndexBuffer HRESULT CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle ); Length: a létrehozandó indexbuffer mérete bájtban
IDirect3DDevice9:: CreateIndexBuffer HRESULT CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle ); Usage: felhasználási mód, most D3DUSAGE_WRITEONLY
IDirect3DDevice9:: CreateIndexBuffer HRESULT CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle ); Format: a buffer formátuma: D3DFMT_INDEX16, D3DFMT_INDEX32: 16 vagy 32 bites indexeket használunk
IDirect3DDevice9:: CreateIndexBuffer HRESULT CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle ); Pool: memóriaosztály
IDirect3DDevice9:: CreateIndexBuffer HRESULT CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle ); ppIndexBuffer: a kimeneti érték, egy indexbuffer interfészre mutató pointer címe
IDirect3DDevice9:: CreateIndexBuffer HRESULT CreateIndexBuffer( UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle ); pSharedHandle: kötelezően NULL
HRESULT CDXMyApp:: InitDeviceObjects()... m_pIB->Lock( 0, sizeof(indices), &pIndices, 0) ; memcpy( pIndices, indices, sizeof(indices) ); m_pIB->Unlock();...
CDXMyApp::InitDeviceObjects() m_CGcontext = cgCreateContext(); cgD3D9SetDevice( m_pD3DDevice ); CGprofile vertexProfile = cgD3D9GetLatestVertexProfile(); CGprofile pixelProfile = cgD3D9GetLatestPixelProfile(); const char **vertexOptions[] = { cgD3D9GetOptimalOptions( vertexProfile ), NULL, }; const char **pixelOptions[] = { cgD3D9GetOptimalOptions( pixelProfile ), NULL, }; Létrehozzuk a context-et és beállítjuk a CG-nek a device- unkat A shadereink txt fájlokban vannak, ezeket le kell fordítanunk. Itt a CG-n keresztül lekérdezzük az adott hardveren elérhető legújabb vertex és fragment shader verziókat Beállítjuk a shadereink fordítási paramétereit – a legújabb profilra akarunk fordítani
CDXMyApp::InitDeviceObjects()... m_CGprogram_vertex = cgCreateProgramFromFile( m_CGcontext, CG_SOURCE, "vs.cg", vertexProfile, "main", *vertexOptions );... Hogyan hozzuk létre a shadert: CG_SOURCE: forrásfájlból CG_OBJECT: lefordított objektum kódból 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" );... A D3D-nek megfelelő shader létrehozása a lefordított CG shaderekből A cgGetNamedParameter az első paraméterben megadott shaderből a második paraméterben megadott nevű, uniform változó azonosítóját adja vissza, hogy annak értékét a CG- n keresztül tudjuk a programunkból módosítani
CDXMyApp::InitDeviceObjects()... D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2, m_BBWidth/ (float)m_BBHeight, 0. 1f, 100); return S_OK; }
VOID CDXMyApp:: ReleaseDeviceObjects() { cgD3D9SetDevice(NULL); cgDestroyProgram(m_CGprogram_vertex); cgDestroyProgram(m_CGprogram_pixel); cgDestroyContext(m_CGcontext); if (m_pIB != NULL) { m_pIB->Release(); m_pIB = NULL; } if (m_pVB != NULL) { m_pVB->Release(); m_pVB = NULL; } }
VOID CDXMyApp::FrameUpdate() { D3DXMATRIXA16 matWorld; D3DXMATRIXA16 matView; D3DXMatrixIdentity(&matWorld); D3DXMatrixRotationY(&matWorld, m_angleY); D3DXVECTOR3 vEye(0, 4, 4); D3DXVECTOR3 vAt(0, 0, 0); D3DXVECTOR3 vUp(0, 1, 0);...
VOID CDXMyApp::FrameUpdate()... D3DXMatrixLookAtLH(&matView, &vEye, &vAt, &vUp); D3DXMATRIX worldViewProj = matWorld * matView * matProj ; D3DXMatrixTranspose(&worldViewProj, &worldViewProj); cgD3D9SetUniformMatrix( m_CGparam_worldViewProj, &worldViewProj ); } A cgD3D9SetUniformMatrix segítségével shadereink uniform float4x4 típusú paramétereinek adhatunk értéket, a második paraméterben megadott memóriacímen található tartalommal
VOID CDXMyApp::Render()... m_pD3DDevice->SetFVF(FVF); D3DXVECTOR4 vConstColor( 0.4f, 1.0f, 0.7f, 0.0f ); cgD3D9SetUniform( m_CGparam_color, &vConstColor ); cgD3D9BindProgram( m_CGprogram_vertex ); cgD3D9BindProgram( m_CGprogram_pixel ); m_pD3DDevice->SetStreamSource(0,m_pVB,0,sizeof(Vertex)); m_pD3DDevice->SetIndices( m_pIB ); m_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);... A cgD3D9SetUniform-mal egy shader uniform paraméternek adhatunk értéket (kivéve sampler-nek!) – az, hogy ez hány bájtnyi adat kell hogy legyen, a cgD3D9TypeToSize és cgGetParameterType segítségével kérdezhető le Aktiváljuk a vertex és fragment shadereinket
IDirect3DDevice9:: DrawIndexedPrimitive HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount); Type: kirajzolandó primitív típus
IDirect3DDevice9:: DrawIndexedPrimitive HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount); BaseVertex: a vertexpuffer hányadik eleme lesz a nullás indexű tag
IDirect3DDevice9:: DrawIndexedPrimitive HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount); MinIndex: legalacsonyabb vertex index érték, amit használunk a kirajzoláskor
IDirect3DDevice9:: DrawIndexedPrimitive HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount); NumVertices: felhasznált csúcspontok száma
IDirect3DDevice9:: DrawIndexedPrimitive HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount); StartIndex: indexpufferbeli offset
IDirect3DDevice9:: DrawIndexedPrimitive HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount); Type: kirajzolt primitívek száma
Feladat Készítsünk egy kockát!
Feladat Az egér fel/le mozgatásával az X tengely körül forogjon a kocka
Feladat Csináljunk egy „repülő kamerát” D3DXVec3Normalize( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV ) : egységvektorrá alakítja pV-t D3DXVec3Cross( D3DXVECTOR3 * pOut, CONST D3DXVECTOR3 * pV1, CONST D3DXVECTOR3 * pV2 ) : pOut = pV1 x pV2
Tartalom 1. Index pufferek 2. Függvénykirajzoló
Letölteni Innen: _Functions.zip _Functions.zip