Lekcija 2: Kreiranje objekata u 3D prostoru
Druga aplikacija nije puno promijenjena od prve, i kao što sam već rekao, trudit ću se da radim što manje korake. Najbitnija promjena u odnosu na prvi tutorial je ta što je dodana još jedna nova klasa, CPloha, koja sadrži sve potrebno da nacrtamo jednu jednostavnu plohu. No iako ovo nije značajna promjena, ona donosi nekoliko bitnih novina. Da prvo opišem novu klasu u programu. Klasa je držać koji sadržava 4 verteksa (točke), konstruktor, funkciju za iscrtavanje i još par manje važnijih stvari.
Ako se pitate šta znaće prve dvije linije u .h datotekama, objasniti ću ih.
|
#if !defined(AFX_PLOHA_H__687221F3_ACFF_4D66_97DB_88AB70E0CA59__INCLUDED_) #define AFX_PLOHA_H__687221F3_ACFF_4D66_97DB_88AB70E0CA59__INCLUDED_
|
Ovo su naredbe kompajleru, i ne prevode se, a služe da pri višestrukom uključivanju iste header datoteke ne bi došlo do višestruke definicije nekih klasa i funkcija. Oni znače da ako kompajler nema definiranu varijablu (ovu dugačku riječ koja može biti proizvoljna) onda će je definirati i kompajlirati kod sve do #endif naredbe, inače, ako je header već pozvan iz neke druge datoteke, varijabla će biti definirana, i kompajler će preskočiti cijeli kod.
Nakon ovoga definiran je još jednan makro:
|
#define PLOHAFVF (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
|
Ovaj makro određuje format vertexa koji ćemo koristiti pri iscrtavanju plohe. DirectX manipulira vertexima pomoću ovakvih konstanti, i u dokumentaciji su opisana značenja pojedinih zastavice. Neke zastavice se ne mogu koristiti zajedno. PLOHAFVF govori da će se format vertexa sastojati od x,y i z koordinate, te još jedna varijabla koja govori da je vertex transformiran. Drugi dio vertex formata je difuzna komponenta boje koju određuje jedna DWORD(integer) vrijednost. Da bi koristili vertekse, moramo također kreirati strukturu koja je ista kao i navedeni vertex format. Ovo je također napravljeno u ploha.h datoteci:
|
struct CPlohaFVF { float x,y,z;//pozicija, odgovara flag-u D3DFVF_XYZ float rhw;//rhw komponenta, homogena kordinata DWORD color;//boja, odgovara flag-u D3DFVF_DIFFUSE };
|
Dakle, pri čitanju i pisanju vertexa, koristiti se struktura CPlohaFVF, a Direct3D-u će biti naznačeno kako ta struktura izgleda pomoću makroa PLOHAFVF. Načina na koji se ovo moguće napraviti je vrlo mnogo, ali kada bi ih sve navodio, ovaj članak razvukao bi se izvan dozvoljenih i zanimljivih granica, no sve flagove možete naći u dokumentaciji koja dolazi uz DirectX.
Idemo sada na opis metoda CPloha klase. Konstruktor ove klase podešava uređaj koji će se koristiti za iscrtavanje plohe, te puni njen spremnih vertexa. Vertexi se računaju u FillVertices metodi, i stavljaju se direktno u vertex buffer. Prije nego čitamo ili pišemo u vertex buffer, moramo ga prvo zaključati, a nakon obavljene operacije, moramo ga odključati, i tako omogućiti drugim procesima da ga koriste. Ovo se obavlja sa idućim naredbama
|
VertexBuffer->Lock(0,4*sizeof(CPlohaFVF),(void**)&pVertices,0)) VertexBuffer->Unlock(); |
Između ove dvije naredbe zadaje se položaj i oblik plohe koju crtamo.
Jedino što još ostaje je Render metoda. Render metoda će se pozivati stalno iz glavne petlje. U render metodi podešava se izvor podataka za uređaj koji će se koristiti za crtanje, format vertexa, te se naposljetku crta sama ploha.
|
D3DDevice->SetStreamSource(0,VertexBuffer,0,sizeof(CPlohaFVF)); D3DDevice->SetFVF(PLOHAFVF); D3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
|
Prva naredba podešava izvor inforamacija na vertex buffer trenutne plohe, druga naredba govori na koji način je on popunjen, a zadnja crta dva trokuta. Direct3D može crtati više vrsta primitiva: TriangleFan, TriangleStrip, TriangleList, LineStrip, LineList te PointList. TriangleStrip crta trokute tako da gleda svaki vertex dva puta, i druga točka jednog trokuta koristi se kao prva točka drugog itd.
Druga bitna promjena je samo ugrađivanje dvije nove varijable tipa CPloha u CScene objekt.
|
class CScene { public: bool Inicijaliziraj(HWND hWnd);//inicijalizacija scene void Petlja();//glavna petlja CScene();//konstructor virtual ~CScene();//destructor private: HRESULT InicijalizirajObjekte();//Inicijalizacija objekata u sceni HRESULT InicijalizirajD3D(HWND hWnd);//inicijalizacija grafike void Render();//redendiranje objekata LPDIRECT3D9 D3DObject;//pointer na interface objekta LPDIRECT3DDEVICE9 D3DDevice;//pointer na interface uredaja CPloha *Ploha1;//Prva ploha u sceni --dodano CPloha *Ploha2;//druga ploha u sceni --dodano };
|
Ova dva objekta inicijalizirati ćemo u CScene::Inicijaliziraj(); proceduri pozivajući njihove konstruktore.
|
Ploha1=new CPloha(D3DDevice,100.,100.,D3DCOLOR_XRGB(255,255,255)); Ploha2=new CPloha(D3DDevice,200.,200.,D3DCOLOR_XRGB(255,0,0));
|
Nakon ovoga, plohe je još samo potrebno nacrtati, a to se obavlja unutar Render metode scene koja se poziva stalno iz glavne petlje.
|
Ploha2->Render();//renderiraj bijelu plohu Ploha1->Render();//renderiraj crvenu plohu
|
Izgled druge aplikacije

Made by:Mll