Davnih Dana, kada se takt procesora još mjerio u megahercima, a assembler vladao svijetom, programiranje aplikacija zahtjevalo je detaljno poznavanje hardvera i to na najnizoj mogucoj razini. Samo kontroliranje unosa na tipkovnici je već bila znanost za sebe, no ujedno i sve druge stvari koje se danas uzimaju zdravo za gotovo. Svaka aplikacija je iznova morala rjesavati jedan te isti problem. Programeri su više vremena provodili pokušavajući natjerati odredeni komad hardvera da proradi na zadovoljavajući način, nego sto su provodili razvijajuci same aplikacije. Porast broja hardverskih komponenti zahtjevalo je dodatno programiranje kako bi se omogucila kompatibilnost sa hardverskim trzistem.
Tek su se pojavom prvih Windowsa počele stvari mjenjati. Od ključne vaznosti za Windowse i samu PC platformu je bilo olaksanje posla developerima, a i samim krajnim korisnicima. Dolazi do kreiranja prvih API-a (Applicattion Programing Interface), ljuski koje bi trebale olaksati komunikaciju s raznolikim hardverom na takav način da API komunicira sa hardverom, a programeri sa API-jom. Iz početka, svaki API je bio vrlo bugovit, slabo dokumentiran, no stvari su se počele polako mjenjati...
Razvijen unutar Microsofta tijekom 1994. I 1995. Godine, svjetlo dana je ugledao sa Windowsima 95 i DirectX API, verzija 2.0. Kako se razvijala tehnologija, razvijao se i DirectX. Postajao je sve kompleksnij, sve veci i fleksibilnij, ali i sve moćnij alat za komunikaciju sa hardverom. Sam DirectX se sastoji od nekoliko djelova, a to su:
DirectDraw – brine se za rasteziranu grafiku.
Direct3D – Zaslužen za 3D grafiku
DirectInput – Brine se za sve ulazne komponente (tipkovnica, joystick, miš, itd...
DirectSound – Zadužen za .waw datoteke
DirectMusic – Prošireni DirectSound koji i dalje koristi isti API za svoj rad.
DirectPlay – Brine se za mrežne protokole i kompletni MP doživljaj u igrama.
Što je to DirectX?
DirectX ( u nastavku DX) je application programing interface, tj. laički rečeno skup naredbi, metoda i funkcija koje kontroliraju hardver na najnižoj razini. Pojasnit cu ovo malo...
I sami znamo da postoji velik broj grafičkih kartica. One, u osnovi rade na približno iste stvari, ali svaka na svoj način. U takvoj situacij postoji nekoliko razina na kojima se upravlja radom tih kartica. Da, programeri mogu napraviti aplikaciju koja šalje instrukcije u točno tom obliku kakav zahtjeva pojedina grafička kartica. Ali, onda ta aplikacija nebi radila na drugoj grafičkoj kartici. Direct3D je jedna od razina kontrole hardvera koja rješava ovaj problem. Proizvođači grafikčkih kartica moraju se pobrinuti da njihov proizvod podržava DirectX. Recimo, korinsik pošalje odredeni zahtjev za iscrtavanje odredene geormetrije. Direct3D pripremi sve stvari potrebne za taj zahtjev i prosljedi ih najnizoj razini, samim driverima grafičke kartice. Direct3D ( u daljnem teksu D3D) je napravio sve to, eliminirajuci potrebu da to programer radi.
Napraviti aplikaciju koja će moći rasditi na tim svim karticama bilo bi nemoguće bez DirectX-a. Nemorate voditi čak ni brigu o kakvom se hardveru radi; Da li ce taj hardver biti u buducnosti ili je on sada na trzistu. Vi radte softver koji je DirectX kompatibilan, a DX ce se pobrinuti da on radi na različitom hardveru. U tu svrhu uvedena su dva sloja rada: HAL i HEL
Hardware Abstraction Layer (HAL) – koristi hardverske resurse za svoj rad, ukoliko ti isti resursi nisu dostupni (nema hardvera), koristi se Hardware Emulation Layer (HEL) koji emuliraja odredeni komad hardvera koji nedostaje.
Još jedna bitna stvar u DX. DX se razvijao i rastao, no njegova bitna osobina je backward compability; svaka nova verzija je unatrag kompatibilna sa starijom verzijom (iznimka DX10). Tako da aplikacije pisane recimo za, DX8.1 bez problema rade sa svim novijim revizijama i na proizvedenom hardveru.
Još jedna velika prekretnica u svjetu DX je dosla s verzijom DX8.1, koji je uveo shadere. Shaderi su u biti mali komadici koji kontroliraju na odredeni način da se obraduju pojedini vertexi/pixeli. Svaka verzija shadera donosi nesto novo, veci broj naredbi, prosirene registre...
Isprva su shaderi bili pisani u običnom, tekstualnom obliku, koje je kasnije DX prevodila u jezik poznat grafičkom hardveru. Jezik je bio sličan assembleru, sa nekim modifikacijama. Tada je na scenu stupa HLSL – odnosno High Level Shadnig Language, jezik koji je sličan C-u, ali samim time preglednij i jednostavnij. Princip, je opet doduše ostao isti. Napišete shader u HLSL-u, compiler pretovori kod u kod prepoznatljiv grafičkom hardveru i stvar je rješena. No, ono što je ogromna prednost HLSL-a je ta što možete birati za koju verziju shadera želite kompajlirati shader. Recimo, ako grafička podržava shadere 3.0, možete ga kompajlirati za tu verziju, no ako podržava samo 2.0 shader, možete isti taj shader kompajlirati u istoj toj verzij bez ikakvih modifikacija. Ponekad to nije moguće zbog ograničenja samog shadera, no ako se pripazi pri programiranju, moguće je ostvariti maksimalnu fleksibilnost shadera.
Kao što je rečeno, DX je započeo svoj život kao alat koji olaksava stvar programerima. Prednost DX nad ostalim API-ima je ta što on obuhvaća sve komponente koje ce ijednom prosječnom programeru zatrebati. No, nije ni DX bez grijeha. Glavni problem je što je to Microsoftov prizovod, što znači da ide samo na Windows i Xbox platformu. Tako da, ukoliko poželite izdati i svoju aplikaciju za Mac OS reciimo, morate posegnuti za OpenGL.
DirectX je s druge strane besplatan. Moguće ga je s neta skinuti, no isto tako je moguće i skinuti DX SDK (Software Development Kit) koji će vam učiniti programiranje s DX-om puno jednostavnije.
Kada je riječ o razvoju DX-a, Microsoft i proizvođači usko surađuju. Oni slušaju developere, slušaju sve prijedloge sto bi zeljeli u iducim verzijama. Recimo, shaderi su uvedeni zbog potrebe da dodatno kontroliraju procesiranje geometrije piskela, kao i zbog potrebe za većom fleksiblnošću hardvera. DX je u biti custom made.
Direct3D
Najzanimljivija komponenta DX-a je Direct3D, iz par razloga. Prvi je naravno, brutalno brz razvoj grafičkih karticai njihovih mogućnosti, koje naravno kontrolira Direct3D. Drugi razlof je najatraktivnij dojam koji ta komponenta zadužena za 3D grafiku ostavlja.
DirectX je implementiran preko COM (Component Object Model) objekata, i programeri koji rade u C++ koriste D3D direktno. Nije potrebno poznavanje COM-a da bi se radilo u D3D-u. Osnovni pojam
kod D3D-a je device. Preko D3D-a Create funkcije dobijemo pokazivač na D3D sučelje. Nakon što dobijemo sučelje, izabrat ćeno prozor koji želimo kontrolirati, te kreirati sam Device preko kojeg ćemo pristupati funkcijama koje želimo. Prvi i najbolnij korak je preden.
Prije nego što navalimo na D3D, potrebno je malo objasniti sam koncept 3D svjeta.
Zaslon Monitora, kao primarna izlazna jedinica, je naravno dvodimenzionalan. Emuliranje 3D prostora predsatvlja kompliciranu zadaću i potrebno mu je posvetiti dosta pažnje, a u cjelu priču je i upleteno dosta matematike. Uzmimo običnu točku koju smo postavili u naš neki imagirani 3D kordninatni sustav. Nazovimo tu točku Vertexom. Vertex čini osnovnu komponentu svakog 3D modela, to je obična točka koja je posavljena u neki 3D prostor. Njeno osnovno svojstvno je da ima poziciju koja se prikazuje 3D vektorom. Redovno, vertexi imaju još svojstava, no za sada ćemo se samo zadovoljiti sa svojstvom točne pozicije u prostoru.
Najosnovnij geometrijski model je trokut. On se sastoji od tri vertexa i služi kao osnovni gradevni element za sve naše modele. Znači, imamo neku imagiranu točku u nekom imagiranom 3D svjetu. U igru sada dolazi novi pojam; vertex buffer. Samo ime govori; Riječ je o memorij u koju se spremaju vertexi.
Direct3D je u jednu priču uveo još jedan zanimljiv koncept – kameru, odnosno oko onoga koji gleda tu točku. Podstavimo tu točku u ishodiste kordinatnog sustava i odmaknimo se malo od nje. Recimo da pozicija predstavlja poziciju našega oka, i početnu točku odakle se promatra. Bitne su 3 stvari: odakle gledamo, gdje gledamo, i u kojem smjeru gledamo. To su takozvani position, lookat, i up vektori i oni medusobno kombinirani čine svojevrsnu matricu. To je takozvana view matrica, prva od tri matrice koje su nam bitne u D3D. Ukoliko znamo ta 3 vektora, možemo postaviti kameru u bilo kojoj pozicij u nešem 3d svjetu, i promatrati ga. No, kada bismo promatrali samo preko view matrice, slika bi nam se deformirala ovisno o pozicij kamere i kutu pod kojim bisno gledali neko objekt.
Iz tih razloga je uvedena projection martica, koja popravlja persektivu i stavlja sliku ovisno o danim parametrima. Da bi kreirali jednostavnu projection matricu, potrebno je znati koja nam je najbliža točka koju vidimo, kao i udaljena. Još je samo potreban omjer našeg ekrana i to je to.
Nakon što smo uveli te dvije matrice, možemo bez problema postaviti u 3D prostor. Rezultirajuća slika na našem monitoru će biti zadovoljavajuća. Nakon što smo postavili matrice i napunili naš vertex buffer koordinatnim točkama, moramo još postaviti sve te parametre i spremni smo za crtanje naše prve točke!
Z-buffer
Z-buffer se naziva još i depth bufferom, i on sadrži podatke o dubini odnosno udaljenosti pojedninih elemenata ovisno od položaja našeg oka. Super, ali čemu on služi? Stara poslovica kaže: "najbrže se rendeira ono što se ne rendeira". Ukoliko se jedan objekt nalazi ispred drugogm, ovaj potonji se nevidi, nije li tako? Upravo ovdje leži razlog jedne od optimizacija igrara. Z-buffer je upravo stvoren u tu svrhu. Vi prosljedite geometriju na iscrtavanje, a nakon rasterizacije odreduje se jeli dubina koja se nalazi u Z-bufferu. Ukoliko je vidljiva, D3D je iscrtava na ekranu. Ukoliko nije vidljiva - grafička kartica ju jednstavno preskoči.
No, Z-Buffer ima još jednu zanimljivu osobinu. Naime, raspodjela gustoće dubine nije linearna. "Near plane" i "far plane" definirane su u projection matrici. Recimo, da smo za najbližu odabrali jedan metar, dok smo za najdulju odabrali 100 metara. Z-Buffer ima na raspolaganju 24bita. Tih 24 bita u našem slučaju nije linearno rasporedeno. Moderne igre pridaju posebnu pozornost detaljima koje su bliže oku, dok objekti u daljini jednostavno se gube na detaljima. Z-buffer je koncipiran na taj način da se u pravilu 90% njegovih mogućnosti 10% troši na dubine najbliže vama, kako bi se osigurala najbolja moguća kvaliteta.
Nemali broj grafičkih kartica kompresira z-buffer kako bi smanjile memorijsko zauzeće i prije svega ubrzale cjelu stvar. Ukoliko je z-buffer previše rastrgan, dolazi do suprotnog efekta: kompresija z-buffera uzrokuje usporenje. Doduše, na modernom hardveru to nije ništa strašno, no pametan programer broji svaku sitnicu.
Stigli smo do prvog djela.
Očekujte sutra nastavak - Sutra ćemo se pozabaviti shaderima!