Uz rad je priložen program koji se razvijao tijekom rada na temi, s pripadajućim izvornim kodom. Korišten je jezik C++ uz OpenGL kao grafičko sučelje. Teksture su nacrtane koristeći poseban grafički program.
Program učitava 3D-model iz datoteke i generira prikaz uz mogućnost korisnikovog mijenjanja pogleda i promjene parametara prikaza.
Odabran je Wavefrontov OBJ-format datoteke modela kao glavni format. S obzirom da obrada složenih modela može potrajati i do pola minute, izvedena je mogućnost snimanja već obrađenih modela u vlastiti format s nastavkom NPR. Kasnije se takva ulazna datoteka može otvoriti umjesto izvorne OBJ-datoteke bez čekanja na obradu.
Uz program je priloženo nekoliko primjera modela u OBJ-formatu, koji se mogu slobodno koristiti u akademske svrhe.
Rješenje je namijenjeno Microsoft Windows platformi s uobičajenom podrškom za OpenGL u vidu biblioteka opengl32.dll i glu32.dll, koje su priložene uz operacijski sustav, ili njihovih zamjena. Poželjno je da računalo ima suvremenu grafičku karticu, zbog naglaska na radu s teksturama.
Pri pokretanju programa moguće je navesti ime ulazne datoteke kao parametar. Ona se može i kasnije odabrati putem izbornika Datoteka → Otvori ili pak dovući mišem iz drugih programa i ispustiti na radnu površinu. Obrađena datoteka može se snimiti za kasnije brzo učitavanje putem izbornika Datoteka → Snimi.
Izgled radnog prozora prikazan je na slici 5.1.
Slika 5.1. Glavni prozor programa
Na alatnoj traci na raspolaganju su korisničke opcije:prikaz smjerova zakrivljenosti izračunatih u vrhovima; koristi se crvena boja za vektor smjera u pojedinom vrhu
prikaz normala trokuta i normala vrhova; koristi se plava boja za normale vrhova i zelena boja za normale trokuta
uključenje face cullinga, za rasterećenje prikaza kod vrlo složenih modela
unos graničnog iznosa oštrog kuta, koji će se utvrđivati postojanje pregibâ na modelu; preporuka je kut od 90 stupnjeva ili veći
različiti stilovi crtačkih tehnika za oponašanje
Rotiranje učitanog modela se izvodi prevlačenjem lijevom tipkom miša preko radne površine, dok se kotačićem na mišu prikaz zumira u željenoj mjeri. Prevlačenje desnom tipkom miša pomiče model, odnosno pogled u stranu.
Korisniku su na raspolaganju i tipke gore/dolje/lijevo/desno za rotiranje modela preko tipkovnice, kao i tipka Escape za brzi izlazak iz programa.
Ako tijelo nije ispravno iscrtano, pogotovo nakon što se uključi face culling, preporuka je uključiti prikaz normala i provjeriti da li su sve normale usmjerene van tijela. Ako nisu, pripadni poligoni su orijentirani u smjeru suprotnom od kazaljke na satu. Program ne podržava takvu orijentaciju poligona.
Drugi problemi s pogrešnim iscrtavanjem modela koji imaju uzroke u samim modelima mogu biti kada se više točaka preklapa na istom mjestu, odnosno kad se više poligona preklapa u istoj ravnini. Takvi slučajevi mogu se pak brzo ispraviti u nekom 3D editoru.
Dijagram razvijenih C++ razreda prikazan je na slici 5.2.
Slika 5.2. Dijagram razredâ
Svaki razred pohranjen je u vlastitoj .cpp datoteci, s pripadnom .h datotekom. U tablici 5.1 dan je kratak opis svake od njih.Tablica 5.1. Organizacija izvornog koda po datotekama
Datoteke | Opis funkcionalnosti |
---|---|
vektor.cpp
vektor.h |
Razred Vektor, koji implementira vektor kao geometrijski element |
kvaternion.cpp
kvaternion.h |
Razred Kvaternion, koji služi za rotacije vektora |
matrica.cpp
matrica.h |
Razred Matrica, potreban za matrične izračune oko normalnih zakrivljenosti |
vrh.h |
Razred Vrh je jednostavna nadgradnja razreda Vektor, predstavlja element poligona |
trokut.cpp
trokut.h |
Razred Trokut predstavlja poligon 3D-mreže |
predmet.cpp
predmet.h |
Razred Predmet predstavlja jedan objekt u sceni |
prostor.cpp
prostor.h |
Razred Prostor predstavlja scenu, i sadrži cjelokupan opis prostora |
program.cpp
program.h datoteka.cpp |
Razred Program je glavni program, rasterećen svih nebitnih poslova; dio posvećen čitanju datoteka modela je izdvojen u zasebnu datoteku |
mfcprogram.cpp
mfcprogram.h |
Razred MFCProgram predstavlja tipični program za MS Windowse; iz njega je deriviran razred Program |
mfcprozor.cpp
mfcprozor.h |
Razred MFCProzor ostvaruje glavni prozor aplikacije u MS Windowsima |
mfctraka.cpp
mfctraka.h |
Razred MFCTraka je alatna traka na glavnom prozoru |
mfcploha.cpp
mfcploha.h |
Razred MFCPloha predstavlja radnu površinu u sredini prozora |
Slike tekstura (mipmape) pohranjene su u svojim zasebnim mapama.
Zbog optimizacije prikaza, stapanje tekstura je vlastoručno programirano u jedinicama za sjenčanje, u jeziku GLSL. Koristi se mogućnost procesora vrhova i fragmenata da sami utvrde koje točno teksture treba kombinirati na bilo kojem mjestu na poligonu, bez da moraju izvoditi bilo kakve nepotrebne poslove. Ranije je izračun bio moguć u samo tri krajnja vrha na pojedinom poligonu, pa je nužno bilo stapati šest tekstura na svakom poligonu kako bi oni u konačnici imali ispravne prijelaze između krajnjih nijansi.
U ostvarenom mehanizmu glavni program daje na raspolaganje procesoru vrhova sve teksture i položaj izvora svjetla putem uniformnih varijabli, te standardnim putem normalu interpoliranu između tri vrhova poligona za određenu točku na poligonu. Procesor vrhova prosljeđuje procesoru fragmenata prostorne koordinate dotične točke, danu normalu i koordinate tekstura. Procesor fragmenata dobivenim podacima izračuna intenzitet osvjetljenja i odredi potrebne teksture koje treba stopiti, te izračuna konačnu boju kao zbroj najviše dviju tekstura.
Program za procesor vrhova u GLSL-u je sljedeći:
varying vec3 vrh, normala; void main () { gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1; gl_TexCoord[2] = gl_TextureMatrix[2] * gl_MultiTexCoord2; gl_TexCoord[3] = gl_TextureMatrix[3] * gl_MultiTexCoord3; gl_TexCoord[4] = gl_TextureMatrix[4] * gl_MultiTexCoord4; normala = gl_Normal; vrh = vec3 (gl_Vertex); gl_Position = ftransform(); }
Program za procesor fragmenata:
uniform sampler2D tex1, tex2, tex3, tex4, tex5; uniform vec3 svjetlo; varying vec3 vrh, normala; void main () { vec4 boja1 = texture2D (tex1, gl_TexCoord[0].st); vec4 boja2 = texture2D (tex2, gl_TexCoord[1].st); vec4 boja3 = texture2D (tex3, gl_TexCoord[2].st); vec4 boja4 = texture2D (tex4, gl_TexCoord[3].st); vec4 boja5 = texture2D (tex5, gl_TexCoord[4].st); float intenzitet = max (0.0, dot ( normalize (svjetlo - vrh), normalize (normala))) * 4; float razina = floor (intenzitet); float ostatak = intenzitet – razina; if (razina <= 0) gl_FragColor = boja2 * ostatak + boja1 * (1.0 – ostatak); else if (razina == 1) gl_FragColor = boja3 * ostatak + boja2 * (1.0 – ostatak); else if (razina == 2) gl_FragColor = boja4 * ostatak + boja3 * (1.0 – ostatak); else if (razina == 3) gl_FragColor = boja5 * ostatak + boja4 * (1.0 – ostatak); else gl_FragColor = boja5; }
Rješenje je razvijeno u Microsoft Visual Studiju 2008, sa statički povezanim MFC-bibliotekama i uključenom punom podrškom za Unicode. Pri povezivanju se koriste standardne biblioteke opengl32.lib i glu32.lib, a za proširenja OpenGL-a 2.0 standardna datoteka glext.h.
Svi resursi aplikacije, uključujući bitmape za teksture, uključeni su u sam projekt i moraju biti povezani u konačnu izvršnu datoteku.