ELTE-IK, Számítógépes grafika 2./haladó 2. gyakorlat Klár Gergely
Sokkal kevesebb, mint egy igazi 3d engine Jóval több, mint a DX10Framework magában Feature-ök: ◦ Mesh osztály ◦ Entity osztály ◦.obj file-ok betöltése ◦ Manager konténerek ◦ Shader irányfényforráshoz
Egyszerű modellek tárolása/rajzolása Vertex = pozíció+normál+2D tex. Koord addVertex/addIndex fv.-k töltik fel initBuffers hozza létre a DX-es vertex és index buffert ◦ Ne felejtsétek el meghívni! createInputLayoutForTechnique hozza létre az input layout-ot ◦ Az Entity automatikusan meghívja! predraw – rajzolás előtti beállítások, amiket nem kell minden pass-ben újra kiadni. draw – a tényleges rajzolás hívás
Kb. = Mesh+World mátrix+rajzolás Az Entity a színtér egy eleme – pl. egy sakkfigura, játékos, láda, stb. Összefogja, a rajzoláshoz szükséges elemeket, amiket külön-külön töltünk be: ◦ Mesh ◦ Textúra ◦ Effekt ◦ Technika ◦ Pozíció ◦ Méret ◦ Elfogatás
.obj file -> Mesh betöltés Korlátai: ◦ Az.obj file-ban csak egyetlen objektum lehet ◦ Meg kell legyen adva normálvektor és textúra koordináta is minden csúcshoz ◦ Csak háromszög-lapok szerepelhetnek a file-ban Használata: #include "Mesh.h" #include "ObjParser.h„ … Mesh *m; m = ObjParser::parse("media\\sphere.obj"); m->initBuffers(_device);
Textúrák, Mesh-ek és Entity-k tárolására Név szerinti hivatkozás! Automatikus felszabadítás! Gyakorlatilag egy std::map + új cleanup fv. OnDestroyDevice()-ban pucoljuk ki őket ReleasingManager textures; DeletingManager meshes; DeletingManager entities; SimpleApp.h
D3DX10_IMAGE_LOAD_INFO loadInfo; ZeroMemory( &loadInfo, sizeof(D3DX10_IMAGE_LOAD_INFO) ); loadInfo.BindFlags = D3D10_BIND_SHADER_RESOURCE; loadInfo.Format = DXGI_FORMAT_BC1_UNORM; ID3D10ShaderResourceView *tmp; D3DX10CreateShaderResourceViewFromFile( _device, L"media\\green.png", &loadInfo, NULL, &tmp, NULL ); textures["green"] = tmp; SimpleApp::OnCreateDevice
m = ObjParser::parse("media\\cube.obj"); m->initBuffers(_device); meshes["cube"] = m; SimpleApp::OnCreateDevice
Entity *e = new Entity(_device, meshes["cube"], textures["green"], effect, dirLightTex); e->setWorld(0,0,0,0,0,0); entities["cube"] = e; SimpleApp::OnCreateDevice
entities["cube"]->draw(view, projection); Elvégzi a teljes rajzolást, de kéne ◦ view mátrix ◦ projection mátrix ◦ shader-nek átadni a szempozíciót Megj.: saját world mátrixát minden Entity tudja SimpleApp::OnFrameRender
entities["cube"]->draw(view, projection); Elvégzi a teljes rajzolást, de kéne ◦ view mátrix ◦ projection mátrix ◦ shader-nek átadni a szempozíciót Megj.: saját world mátrixát minden Entity tudja SimpleApp::OnFrameRender
D3DXVECTOR3 eye(0, 5, 10), at(0.0f, 0, 0.0f), up(0, 1, 0); D3DXMATRIX view, projection; D3DXMatrixLookAtLH(&view, &eye, &at, &up); D3DXMatrixPerspectiveFovLH(&projection, D3DX_PI / 4, 1.333f, 0.1f, 20); V(effect->GetVariableByName("eyePosition")->AsVector()-> SetFloatVector(eye)); entities["cube"]->draw(view, projection); SimpleApp::OnFrameRender
Még jobb lenne, ha a képarány mindig jó lenne Be lehetne járni a színteret Megoldás: DXUTcamera/CFirstPersonCamera
#include "DXUTcamera.h" … class SimpleApp : public DX10Framework { … CFirstPersonCamera camera; … }; SimpleApp.h
D3DXVECTOR3 eye(0, 5, 10), at(0.0f, 0, 0.0f); camera.SetViewParams(&eye, &at); camera.SetScalers(0.01f, 5); SimpleApp::OnCreateDevice
HRESULT SimpleApp::OnResizedSwapChain( const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc) { float aspect = 1.0f * pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height; camera.SetProjParams(D3DX_PI / 4, aspect, 0.1f, 20); return S_OK; } SimpleApp::OnResizedSwapChain
SimpleApp::OnFrameMove camera.FrameMove(fElapsedTime); SimpleApp::MsgProc camera.HandleMessages(hWnd, uMsg, wParam, lParam);
HRESULT hr; float clearColor[4] = { 0.176f, 0.196f, 0.667f, 0.0f }; const D3DXMATRIX& view = *camera.GetViewMatrix(); const D3DXMATRIX& projection = *camera.GetProjMatrix(); _device->ClearRenderTargetView(_defaultRenderTargetView, clearColor); _device->ClearDepthStencilView(_defaultDepthStencilView, D3D10_CLEAR_DEPTH, 1.0f, 0); V(effect->GetVariableByName("eyePosition")->AsVector()-> SetFloatVector((float*)camera.GetEyePt())); entities["cube"]->draw(view, projection); SimpleApp::OnFrameRender