230 likes | 318 Views
DirectX 10, en Gine – minimál 3d motor. ELTE-IK, Számítógépes grafika 2./haladó 2 . gyakorlat Klár Gergely. en Gine 3d „motor”. 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
E N D
DirectX 10,enGine – minimál 3d motor ELTE-IK, Számítógépes grafika 2./haladó 2. gyakorlat Klár Gergely
enGine3d „motor” • 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
Új osztály: Mesh • Egyszerű modellek tárolása/rajzolása • Vertex = pozíció+normál+2D tex. Koord • addVertex/addIndexfv.-k töltik fel • initBuffers hozza létre a DX-esvertex é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
Új osztály: Entity • 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
Új osztály: ObjParser • .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);
Manager konténerek SimpleApp.h • Textúrák, Mesh-ek és Entity-ktárolására • Név szerinti hivatkozás! • Automatikus felszabadítás! • Gyakorlatilag egy std::map + új cleanupfv. • OnDestroyDevice()-ban pucoljuk ki őket ReleasingManager<ID3D10ShaderResourceView> textures; DeletingManager<Mesh> meshes; DeletingManager<Entity> entities;
Textúrák betöltése SimpleApp::OnCreateDevice 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;
Mesh-ek betöltése SimpleApp::OnCreateDevice m = ObjParser::parse("media\\cube.obj"); m->initBuffers(_device); meshes["cube"] = m;
Entity-k SimpleApp::OnCreateDevice Entity *e = new Entity(_device, meshes["cube"], textures["green"], effect, dirLightTex); e->setWorld(0,0,0,0,0,0); entities["cube"] = e;
Rajzolás 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 worldmátrixát minden Entitytudja
Rajzolás - mátrixok 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 worldmátrixát minden Entitytudja
Rajzolás - mátrixok 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);
Nem rossz, de • Még jobb lenne, ha a képarány mindig jó lenne • Be lehetne járni a színteret • Megoldás: DXUTcamera/CFirstPersonCamera
Kamera objektum SimpleApp.h #include "DXUTcamera.h" … classSimpleApp : public DX10Framework { … CFirstPersonCamera camera; … };
Kamera init SimpleApp::OnCreateDevice D3DXVECTOR3 eye(0, 5, 10), at(0.0f, 0, 0.0f); camera.SetViewParams(&eye, &at); camera.SetScalers(0.01f, 5);
Képarány megtartás SimpleApp::OnResizedSwapChain HRESULT SimpleApp::OnResizedSwapChain( const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc) { floataspect = 1.0f * pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height; camera.SetProjParams(D3DX_PI / 4, aspect, 0.1f, 20); return S_OK; }
Eseménykezelők -> kamera SimpleApp::OnFrameMove camera.FrameMove(fElapsedTime); SimpleApp::MsgProc camera.HandleMessages(hWnd, uMsg, wParam, lParam);
Rajzolás „kamerával” SimpleApp::OnFrameRender 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);