[ glorius @ 30.11.2009. 17:18 ] @
Pokusavam da nadjem najbolji nacin da uradim GUI sistem za meni ekrane i za ingame ekrancice ( Inventory, .... ) , uzecu GUI Diabla kao referencu.
Put kojim sam krenuo je koriscenje ID3DXSprite + IDirect3DTexture9 ali...

D3DXCreateTextureFromFile i D3DXCreateTextureFromFileEx su funkcije koje automatski proveravaju da li hardver podrzava NON_POW_2 i ako ne podrzava, ova funkcija zaokruzi dimenzije teksture na nearest POW_2. Iznenadio sam se kada sam video da moj 8600GT ne podrzava jer sam mislio da je ovaj feature uveden jos i pre ove generacije kartica tako da iscrtavanje ID3DXSprite u screen space nije moguce iskoristiti za moj GUI iz pomenutih razloga.

Ja sam uspeo da uradim iscrtavanje 2D slika pomocu blittovanja direktno na Back Buffer ali onda ne mogu da koristim Alpha Blending i jos neke mogucnosti koje ima DirectX-ov Sprite interface. Znaci, potreban mi je nacin da iscrtavam sliku na ekran posle svih 3D iscrtavanja i da to GUI iscrtavanje podrzava Alpha Blending ( koristeci alpha iz postojece slike ). Video sam da ljudi forsiraju ID3DXSprite interfejs u nekim njihovim primerima i ne spominju POW_2 problem i to me jos vise zbunjuje... Any ideas?



[Ovu poruku je menjao glorius dana 30.11.2009. u 20:37 GMT+1]
[ tosa @ 01.12.2009. 08:11 ] @
Ja bih ti savetovao da izbegnes D3DX API i da odradis to kao i ostatak iscrtavanja - jedina razlika je kada se crta i kakva projekcija se koristi.
Drugo, nema razloga da GUI elementi budu u odvojenim teksturama. Vecina igara sve potrebno za GUI napakuje u par tekstura i radi samo sa
nenormalizovanim koordinatama u istim. Tako mozes da imas elemente kakve zelis. Jos nesto, ne savetujem razvijanje GUI biblioteke, bar ne
preterano komplikovane, jer je to stvar koja se potpuno menja za svaku igru - dakle sednes i malo hakujes i eto :)

[ glorius @ 01.12.2009. 12:51 ] @
Aha.... Znaci, ako sam te razumeo, moglo bi da se uradi sa screen quads? Onda bih mogao da dobijem i zanimljive efekte koriscenjem shadera itd...

Ovo pitanje je vise vezano za in game GUI ( ne toliko za menije ). Sto se tice Menu GUI-ja, ne planiram nista kompleksno....

Prvenstveno sam zeleo da izbegnem POW_2 problem i zato sam mislio da iscrtavam blittovanjem i da izbegnem kreiranje tekstura.
U radu sa screen quads bih morao da podesavam texture coordinates da bi izgledalo kako treba, ako me razumes. Primer iz Diabla: kada uzmes bocicu healt-a misem, ona prelazi u svoju 2D verziju, ta bocica je mozda dimenzija 30 x 60, meni bi onda textura trebala da bude 64x64, screen quad dimenzija 30x60 i texture coordinate bi onda trebale da se koriguju da ne bi doslo do izduzivanja slicice bocice. Lakse bi mi bilo kada bi textura bila 30 x 60... Isto je i za slicne iteme koji bi se nalazili u inventaru, mini-map itd....
[ tosa @ 01.12.2009. 13:26 ] @
Da, bas tako, koriscenjem neke primitive dobijas mogucnost da ti GUI bude sastavni deo pajplajna i da deli iste mogucnosti kao i, recimo, mesh renderer.
Jasno mi je da bi ti bilo lakse da svaki element ima svoju teksturu u zeljenim pixel dimenzijama ali to je generalno lose resenje zbog dosta toga: vise menjanja
teksture - sporo, gubis memoriju na sistemima koji ne podrzavaju egzoticne dimenzije tekstura (sto je i vise nego zastupljen slucaj), vise DrawPrimitive poziva
mada je ovo ozbiljan problem samo na PC-u.

[ glorius @ 01.12.2009. 13:53 ] @
A da i ne spominjemo menjanje rezolucije sa fixnim velicinama textura posto je i to jedan od problema koji, za iole ozbiljniju igru, mora biti resen....

Po meni, resenje je onda da se napravi mali editor koji ce sluziti za pravljenje quadova, ucitavanje tekstura i podesavanja texture coordinates, velicine quada, ... i da se sve to exportuje i da se na dalje koristi.

Hvala puno na pomoci :)
[ Dark Icarus @ 22.12.2009. 23:38 ] @
D3DXSprite nudi većinu mogućnosti koje nudi i crtanje preko quadova. Posle D3DXSprite::Begin() zoveš SetRenderState (i kompaniju) kao što bi radio da rendaš preko quadova. Kada crtaš preko D3DXSprite-a svejedno moraš da ga projektuješ/translejtuješ na ekran tako da kad ga već provlačiš kroz transformacione matrikse možeš da mu obezbediš x, y, i z koordinatu, rotaciju, scaling... Ukratko D3DXSprite se u svemu ponaša kao da si ih nacrtao preko quadova sa Transformed-Lit verteksima (i verovatno je tako interno i implementiran). Ja sam sa D3DXSprite 9 izvukao alpha blending, fog, stencil testing, pixel shadere, aditivni blending, blur, bloom, itd. itd. bez i jednog eksplicitno deklarisanog verteksa.

Naravno ne kažem da je D3DXSprite bolji ili lošiji od "ručnih" quadova, sve zavisi od toga šta ti treba. Svakako je manje fleksibilan.

POW_2 problem je nešto što koliko vidim nije standardizovano rešeno u DX9 i bolje da se ne oslanjaš na to. Svakako je najbolje i najkompatibilnije rešenje da sve teksture koje koristiš budu power of 2 u obe dimenzije, pa da preko maski i blitovanja odrediš transparentne delove, ili još bolje (i optimizovanije!), da deklarišeš "blit regiju" za teksture. Tako npr. ako imaš teksturu dimenzije 200x150, "raširi" je (makar i u MS paintu) na 256x256 i učitaj je normalno (preko D3DXCreateTextureFromFileEx radiće sasvim lepo) i onda "objasni" D3Du da renderuje samo prvih 200x150 piksela. Da bi to uspelo moraćeš uz svaku teksturu da držiš još neke podatke i da prilikom blitovanja manipulišeš source rect-om i dest rect-om, ali to bar nije teško napraviti, a isplati se, jer onda možeš, kao što reče tosa, da naguraš i 200 različitih sprajtova u jednu teksturu i blituješ šta ti treba sa nje, a što manje menjanja tekstura to bolje.

Ako ti se ne radi preko blit regija, lakša alternativa bi bila da pošto resizeuješ teksturu (na ^2 dimenzije, u Paintu) transparentne delove filuješ određenom bojom (obično je to 0xffff00) i onda prilikom učitavanja D3DXCreateTextureFromFileEx procedurom kao ColorKey odrediš tu boju. I ova metoda zasniva se na blitovanju.