Számítógépes grafika DirectX 6. gyakorlat
Emlékeztető Múlt órán megvilágítással foglalkoztunk Per vertex Per pixel
Tartalom Mesh-ek Indexelt primitívek
Összetett modellek Gyakorlatban elég ritkán készítjük el kóddal a programunkban használt modelleket Maya, 3D Studio Max, LighWave és hasonló modellezőprogramok biztosítanak számunkra is használható formátumba történő exportálást
Mesh Egy ilyen összetett modellt az ID3DXMESH interfészen keresztül és néhány D3DX-beli függvénnyel könnyen kezelhetünk Egy ilyen mesh tárolja a modellt alkotó csúcspontokat, anyagjellemzőket és textúrákat
Mesh-ek felépítése Megvalósítástól elvonatkoztatva tekinthetünk rájuk mint erőforrások és attribútumok közös tárolójára Erőforrások: Textúrák Anyagjellemzők (material-ok) Attribútumok: Pozíció adatok Szomszédsági adatok
Mesh-ek konkrétan Az előzőeket a következőkkel tárolja: Vertex buffer Index puffer Attribútum puffer Az attribútumok a mesh egy-egy csúcspontjának tulajdonságait írják le
1. példa Mesh
Mit csinálunk? A múlt órai per pixel megvilágítós kódunkba írunk bele ( egoldasok/PerPixel.zip ) egoldasok/PerPixel.zip Ezt készítjük el: _Meshes.zip _Meshes.zip
DXMyApp.h class CDXMyApp : public CDXAppBase {... private: LPD3DXMESH m_pMesh;... };
CDXMyApp::CDXMyApp() { m_pVB = NULL; m_pTexture = NULL; m_pMesh = NULL; m_angle = 0; m_dist = 0; }
CDXMyApp:: InitDeviceObjects() HRESULT CDXMyApp::InitDeviceObjects() { D3DXCreateSphere(m_pD3DDevice, 1, 32, 32, &m_pMesh, 0); return S_OK; }
D3DXCreateSphere HRESULT D3DXCreateSphere( LPDIRECT3DDEVICE9 pDevice, FLOAT Radius, UINT Slices, UINT Stacks, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency ); pDevice: érvényes device interfész mutató
D3DXCreateSphere HRESULT D3DXCreateSphere( LPDIRECT3DDEVICE9 pDevice, FLOAT Radius, UINT Slices, UINT Stacks, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency ); Radius: létrehozandó gömb sugara
D3DXCreateSphere HRESULT D3DXCreateSphere( LPDIRECT3DDEVICE9 pDevice, FLOAT Radius, UINT Slices, UINT Stacks, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency ); Slices: felbontás a főtengely körül
D3DXCreateSphere HRESULT D3DXCreateSphere( LPDIRECT3DDEVICE9 pDevice, FLOAT Radius, UINT Slices, UINT Stacks, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency ); Stacks: felbontás a főtengely mentén
D3DXCreateSphere HRESULT D3DXCreateSphere( LPDIRECT3DDEVICE9 pDevice, FLOAT Radius, UINT Slices, UINT Stacks, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency ); ppMesh: eredmény gömb
D3DXCreateSphere HRESULT D3DXCreateSphere( LPDIRECT3DDEVICE9 pDevice, FLOAT Radius, UINT Slices, UINT Stacks, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency ); ppAdjacency: szomszédossági adatok, lehet NULL
CDXMyApp::Render() D3DXMATRIXA16 matWorld; D3DXMatrixTranslation(&matWorld,0,2,0); D3DXMatrixTranspose(&matWorld, &matWorld); cgD3D9SetUniformMatrix(m_CGparam_world, &matWorld); m_pMesh->DrawSubset(0);
Egyéb mesh-es konstruktorok HRESULT D3DXCreateTeapot( LPDIRECT3DDEVICE9 pDevice, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency );
Egyéb mesh-es konstruktorok HRESULT D3DXCreateTorus( LPDIRECT3DDEVICE9 pDevice, FLOAT InnerRadius, FLOAT OuterRadius, UINT Sides, UINT Rings, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency );
Egyéb mesh-es konstruktorok HRESULT D3DXCreateCylinder( LPDIRECT3DDEVICE9 pDevice, FLOAT Radius1, FLOAT Radius2, FLOAT Length, UINT Slices, UINT Stacks, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency );
Egyéb mesh-es konstruktorok HRESULT D3DXCreateBox( LPDIRECT3DDEVICE9 pDevice, FLOAT Width, FLOAT Height, FLOAT Depth, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency );
Feladat Pattogtassuk a labdát a piramis tetején! Az Y tengely mentén 2 egységnyit utazzon felfelé, aztán induljon vissza lefelé és a piramis „csúcsáról” pattanjon vissza Ne csak pattogjon, hanem forogjon is a saját tengelye körül a gömb! Változzon folyamatosan a gömb színe is!
Feladat Miközben egy gömb pattog a piramis tetején az előbbieknek megfelelően, az Y = 3 síkban 10 teáskanna forogjon a piramis csúcspontja körüli 4 sugarú körön! Ne csak a piramis körül forogjanak, hanem egy tetszőleges tengelyük körül is A teáskannák színei külön-külön változzanak!
Mesh-ek betöltése fájlból Tervező rendszerekben készített modellek betöltése D3DX library segít benne Ezt készítjük el: _LoadMesh.zip _LoadMesh.zip
DXMyApp.h class CDXMyApp : public CDXAppBase {…{… private: LPD3DXMESH m_pMesh; D3DMATERIAL9* m_pMeshMaterials; LPDIRECT3DTEXTURE9* m_pMeshTextures; DWORD m_dwNumMaterials; HRESULT LoadMesh(); VOID UnloadMesh();... };
CDXMyApp::CDXMyApp() {... m_pMesh = NULL; m_pMeshMaterials = NULL; m_pMeshTextures = NULL; m_dwNumMaterials = 0;... }
CDXMyApp::LoadMesh() HRESULT CDXMyApp::LoadMesh() { LPD3DXBUFFER pD3DXMtrlBuffer; D3DXLoadMeshFromX( TEXT("modell.x"), D3DXMESH_DEFAULT, m_pD3DDevice, NULL, &pD3DXMtrlBuffer, NULL, &m_dwNumMaterials, &m_pMesh )...
D3DXLoadMeshFromX HRESULT D3DXLoadMeshFromX( LPCTSTR pFilename,...) pFilename: betöltendő meshfájl neve
D3DXLoadMeshFromX HRESULT D3DXLoadMeshFromX(... DWORD Options,...) Options: betöltési opciók (D3DXMESH): D3DXMESH_VB_SYSTEMMEM, MANAGED, stb: létrejövő vertexbuffer memóriaosztálya D3DXMESH_VB_WRITEONLY, DYNAMIC, stb: felhasználási mód Index bufferekre hasonlók D3DXMESH_SYSTEMMEM, stb: VB és IB is ez lesz
D3DXLoadMeshFromX HRESULT D3DXLoadMeshFromX(... LPDIRECT3DDEVICE9 pD3DDevice,...) pD3DDevice: érvényes device mutató
D3DXLoadMeshFromX HRESULT D3DXLoadMeshFromX(... LPD3DXBUFFER* ppAdjacency,...) ppAdjacency: kimeneti tároló a modell szomszédsági adatainak rögzítésére Lehet NULL is
D3DXLoadMeshFromX HRESULT D3DXLoadMeshFromX(... LPD3DXBUFFER* ppMaterials,...) ppMaterials: kimeneti tároló a modell anyagainak (anyagok tömbje)
D3DXLoadMeshFromX HRESULT D3DXLoadMeshFromX(... LPD3DXBUFFER* ppEffectInstances,...) ppEffectInstance: kimeneti tároló az effektekhez
D3DXLoadMeshFromX HRESULT D3DXLoadMeshFromX( DWORD* pNumMaterials,...) pNumMaterials: a modell által használt anyagok száma
D3DXLoadMeshFromX HRESULT D3DXLoadMeshFromX( LPD3DXMESH * ppMesh,...) ppMesh: kimeneti mesh-ünk
CDXMyApp::LoadMesh()... D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer-> GetBufferPointer(); m_pMeshMaterials = new D3DMATERIAL9[m_dwNumMaterials]; if( m_pMeshMaterials == NULL ) return E_OUTOFMEMORY;...
CDXMyApp::LoadMesh()... m_pMeshTextures = new LPDIRECT3DTEXTURE9[m_dwNmMtrls]; if( m_pMeshTextures == NULL ) return E_OUTOFMEMORY;...
CDXMyApp::LoadMesh()... for (DWORD i=0; i<m_dwNMtrls; i++) { m_pMeshMaterials[i] = d3dxMaterials[i].MatD3D; m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse; m_pMeshTextures[i] = NULL;...
CDXMyApp::LoadMesh() if(d3dxMaterials[i].pTextureFilename !=NULL) { D3DXCreateTextureFromFileA( m_pD3DDevice, d3dxMaterials[i].pTextureFilename, &m_pMeshTextures[i] ); } } // ciklus vége pD3DXMtrlBuffer->Release(); return S_OK; }
CDXMyApp::UnloadMesh() VOID CDXMyApp::UnloadMesh() { if ( m_pMesh != NULL ) { m_pMesh->Release(); m_pMesh = NULL; } if( m_pMeshMaterials != NULL ) delete[] m_pMeshMaterials;...
CDXMyApp::UnloadMesh() if( m_pMeshTextures ) { for( DWORD i = 0; i < m_dwNumMaterials; i++ ) { if( m_pMeshTextures[i] ) { m_pMeshTextures[i]->Release(); m_pMeshTextures[i] = NULL; } delete[] m_pMeshTextures; } } // ReleaseDeviceObjects vége
HRESULT CDXMyApp:: Render()... D3DXMATRIXA16 matWorld, matScale; D3DXMatrixTranslation(&matWorld, 0, 2, 0); D3DXMatrixScaling(&matScale, 0.02f, 0.02f, 0.02f); matWorld = matScale * matWorld ; D3DXMatrixTranspose(&matWorld, &matWorld); cgD3D9SetUniformMatrix(m_CGparam_world, &matWorld);...
HRESULT CDXMyApp:: Render() for ( DWORD i=0; i<m_dwNumMaterials; i++ ) { cgD3D9SetUniform( m_CGparam_mat_emissive, &m_pMeshMaterials[i].Emissive ); cgD3D9SetUniform( m_CGparam_mat_ambient, &m_pMeshMaterials[i].Ambient ); cgD3D9SetUniform( m_CGparam_mat_diffuse, &m_pMeshMaterials[i].Diffuse ); cgD3D9SetUniform( m_CGparam_mat_specular, &m_pMeshMaterials[i].Specular ); cgD3D9SetUniform( m_CGparam_mat_specular_power, &m_pMeshMaterials[i].Power ); cgD3D9SetTexture( m_CGparam_texture, m_pMeshTextures[i]); m_pMesh->DrawSubset( i ); }
Feladat Körözzön az űrhajó a piramis körül! Az orra nézzen mindig a körpálya érintője felé Legyen 60 fokban megdöntve a hossztengelye mentén
Feladat 30 űrhajó körözzön a piramis körül!