DirectX9 empty project Szécsi László
Visual Studio Első indításkor C++ választása
Project létrehozása Microsoft DirectX SDK (August 2008) telepítése Start Menu \ Microsoft DirectX SDK (August 2008)\ Sample browser Empty project (C++) July 2004 telepítése (D: vagy saját home) NEM a DX10 empty project project name: GraphGame
Próba Build Run eredmény: include hiba megoldás: Project properties/ C/C++/General/ Additional include directories + >\include
Próba Build Run eredmény: linkelési hiba megoldás: Project properties/ Linker/General/ Additional library directories + >\lib\x86
Próba Build Run eredmény: üres kék képernyő
Nézzük a kódot! GraphGame.cpp-ben vannak: Callback függvények események kezelésére paraméterként kapják: IDirect3DDevice9 interface
Class View / right click / New Folder “Lab1” Class View / right click / Add Class C++/C++ class Class Name: EngineInterface inline ebből fogjuk majd a laborokon az aktuális effektet megvalósító osztályt származtatni Hozzunk létre saját OO interfacet FILEEngineInterface.hOPnew classCLASSEngineInterface
Drag&Drop Class View drag & drop EngineInterface -> Lab1
class EngineInterface{ protected: LPDIRECT3DDEVICE9 device; … ez mindig kelleni fog Device referencia FILEEngineInterface.hOPnew memberCLASSEngineInterface
töröljük: EngineInterface(void); ~EngineInterface(void); Gyári konstruktor és destruktor nem kell FILEEngineInterface.hOPdel methodCLASSEngineInterface
public: EngineInterface(LPDIRECT3DDEVICE9 device) {this->device = device;} virtual HRESULT createManagedResources() {return S_OK;} virtual HRESULT createDefaultResources() {return S_OK;} Eseménykezelő metódusok FILEEngineInterface.hOPnew methodCLASSEngineInterface
virtual HRESULT releaseManagedResources() {return S_OK;} virtual HRESULT releaseDefaultResources() {return S_OK;} Eseménykezelő metódusok FILEEngineInterface.hOPnew methodCLASSEngineInterface
virtual void animate (double dt, double t){} virtual void processMessage ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){} virtual void render(){} Eseménykezelő metódusok FILEEngineInterface.hOPnew methodCLASSEngineInterface
EngineInterface kész
Class view, Add Class, C++ class: Class name: Lab1HLSL Base class: EngineInterface Implementáló osztály létrehozása FILELab1HLSL.h ~.cppOPnew classCLASSLab1HLSL
GraphGame.cpp: #include "EngineInterface.h" #include "Lab1HLSL.h" EngineInterface* engine = NULL; amíg nem hoztuk létre legyen NULL Globális eseménykezelő objektum FILEGraphGame.cppOPnew variableCLASS::
OnD3D9CreateDevice: engine = new Lab1HLSL(pd3dDevice); return engine-> createManagedResources(); OnD3D9DestroyDevice: engine-> releaseManagedResources(); delete engine; Példány létrehozás és felszabadítás FILEGraphGame.cppOPedit codeCLASS::
OnD3D9ResetDevice: return engine-> createDefaultResources(); OnD3D9LostDevice: engine-> releaseDefaultResources(); Reset és Lost esemény FILEGraphGame.cppOPedit codeCLASS::
OnFrameMove: if(engine) engine->animate (fElapsedTime, fTime); OnFrameRender: if(engine) engine->render(); a többit töröljük MsgProc: if(engine) engine->processMessage (hWnd, uMsg, wParam, lParam); Többi esemény FILEGraphGame.cppOPedit codeCLASS::
Az alap kész van Most már implementálhatjuk amit akarunk a Lab1HLSL-ben
class Lab1HLSL : public EngineInterface { public: Lab1HLSL(void); ~Lab1HLSL(void); Lab1HLSL gyári konstruktor/destruktor nem kell FILELab1HLSL.hOPdel methodCLASSLab1HLSL
Lab1HLSL::Lab1HLSL(void) { } Lab1HLSL::~Lab1HLSL(void) { } Az implementációja sem FILELab1HLSL.cppOPdel implCLASSLab1HLSL
class Lab1HLSL : public EngineInterface { public: Lab1HLSL(LPDIRECT3DDEVICE9 device); Új Lab1HLSL konstruktor FILELab1HLSL.hOPnew methodCLASSLab1HLSL
Lab1HLSL::Lab1HLSL(LPDIRECT3DDEVICE9 device) :EngineInterface(device) { } és az implementációja FILELab1HLSL.cppOPmethod implCLASSLab1HLSL
class Lab1HLSL : public EngineInterface { public: HRESULT createDefaultResources(); HRESULT releaseDefaultResources(); void render(); Implementálandó metódusok FILELab1HLSL.hOPnew methodCLASSLab1HLSL
class Lab1HLSL : public EngineInterface { LPDIRECT3DVERTEXBUFFER9 vertexBuffer; Vertex buffer referencia FILELab1HLSL.hOPnew memberCLASSLab1HLSL
HRESULT Lab1HLSL::createDefaultResources(){ device->CreateVertexBuffer( 4 * sizeof(D3DXVECTOR3), D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_DEFAULT, &vertexBuffer, NULL); //... Vertex buffer létrehozása FILELab1HLSL.cppOPmethod implCLASSLab1HLSL METHODcreateDefaultResources
//... D3DXVECTOR3* vertexData; vertexBuffer->Lock(0, 0, (void**)&vertexData, D3DLOCK_DISCARD); vertexData[0] = D3DXVECTOR3(-1.0f, 1.0f, 0.0f); vertexData[1] = D3DXVECTOR3(1.0f, 1.0f, 0.0f); vertexData[2] = D3DXVECTOR3(-1.0f, -1.0f, 0.0f); vertexData[3] = D3DXVECTOR3(1.0f, -1.0f, 0.0f); vertexBuffer->Unlock(); Vertex buffer feltöltése FILELab1HLSL.cppOPmethod implCLASSLab1HLSL METHODcreateDefaultResources
HRESULT Lab1HLSL:: releaseDefaultResources() { vertexBuffer->Release(); return S_OK; } Vertex buffer felszabadítása FILELab1HLSL.cppOPmethod implCLASSLab1HLSL METHODreleaseDefaultResources
void Lab1HLSL::render(){ HRESULT hr; device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0); //... Rajzolás: kép törlése FILELab1HLSL.cppOPmethod implCLASSLab1HLSL METHODrender
//... device->BeginScene(); device->SetStreamSource(0, vertexBuffer, 0, sizeof(D3DXVECTOR3)); device->SetFVF(D3DFVF_XYZ); device->DrawPrimitive (D3DPT_TRIANGLESTRIP, 0, 2); device->EndScene(); } Rajzolás: pipeline indítása FILELab1HLSL.cppOPmethod implCLASSLab1HLSL METHODrender
próba fekete téglalap, lefedi a viewportot (változtasuk meg a csúcskoordinátákat, hogy ne fedje le, próba, aztán vissza)
shaderek Effect (.fx) file HLSL függvények pass: render state és shaderek technique: pass lista + globális változók (uniform paraméterek minden shadernek)
effect interface ID3DXEffect interface magasabb szintű absztrakció a device felett a device „párja” lesz alapműveletekhez a devicehoz fordulunk pl. shader paraméterek beállítása az effecten keresztül
Solution exporer/Add new item/Utility/text file File name: Lab1HLSL.fx Új effect file FILELab1HLSL.fxOPnew fileCLASSN/A
float4 vsIdle( in float4 pos : POSITION ) : POSITION { return pos; } HLSL Vertex shader FILELab1HLSL.fxOPnew funcFUNCvsIdle
float4 psWhite() : COLOR0 { return float4(1, 1, 1, 1); } HLSL Pixel shader FILELab1HLSL.fxOPnew funcFUNCpsWhite
technique white{ pass ExamplePass{ ZEnable = TRUE; VertexShader = compile vs_2_0 vsIdle(); PixelShader = compile ps_2_0 psWhite(); } Technique definíció FILELab1HLSL.fxOPnew techniqueFUNC::
class Lab1HLSL : public EngineInterface { LPD3DXEFFECT effect; Effect referencia FILELab1HLSL.hOPnew memberCLASSLab1HLSL
HRESULT Lab1HLSL::createDefaultResources() { D3DXCreateEffectFromFile(device, L"Lab1HLSL.fx", NULL, NULL, 0, NULL, &effect, NULL); Effect létrehozása.fx file alapján hibaell. nélkül FILELab1HLSL.cppOPadd codeCLASSLab1HLSL METHODcreateDefaultResources
HRESULT Lab1HLSL:: releaseDefaultResources() { effect->Release(); Effect felszabadítás FILELab1HLSL.cppOPadd codeCLASSLab1HLSL METHODreleaseDefaultResources
device->BeginScene(); effect->SetTechnique("white"); UINT a; effect->Begin(&a, 0); effect->BeginPass(0); //... Rajzolás shaderekkel FILELab1HLSL.cppOPadd codeCLASSLab1HLSL METHODrender
device->SetStreamSource(0, vertexBuffer, 0, sizeof(D3DXVECTOR3)); device->SetFVF(D3DFVF_XYZ); device->DrawPrimitive (D3DPT_TRIANGLESTRIP, 0, 2); effect->EndPass(); effect->End(); device->EndScene(); Rajzolás shaderekkel FILELab1HLSL.cppOPadd codeCLASSLab1HLSL METHODrender
próba fehér téglalap
class Lab1HLSL : public LabInterface { LPD3DXMESH mesh; Mesh referencia FILELab1HLSL.hOPnew memberCLASSLab1HLSL
HRESULT Lab1HLSL::createDefaultResources() { D3DXLoadMeshFromX(L"helix.x", 0, device, NULL, NULL, NULL, NULL, &mesh); Mesh létrehozása.x file alapján FILELab1HLSL.cppOPadd codeCLASSLab1HLSL METHODcreateDefaultResources
HRESULT Lab1HLSL:: releaseDefaultResources() { mesh->Release(); Mesh felszabadítása FILELab1HLSL.cppOPadd codeCLASSLab1HLSL METHODreleaseDefaultResources
device->SetStreamSource(0, vertexBuffer, 0, sizeof(D3DXVECTOR3)); device->SetFVF(D3DFVF_XYZ); device->DrawPrimitive (D3DPT_TRIANGLESTRIP, 0, 2); mesh->DrawSubset(0); Mesh rajzolása (négyszög helyett) FILELab1HLSL.cppOPdel/add codeCLASSLab1HLSL METHODrender
float4 vsIdle( in float4 pos : POSITION ) : POSITION { return float4(pos.xzy * 0.1, 1); } Átméretezés FILELab1HLSL.fxOPedit codeFUNCvsIdle