home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1997 #3
/
amigamamagazinepolishissue03-1
/
ma_1995
/
04
/
ami038.txt
< prev
next >
Wrap
Text File
|
1997-04-06
|
10KB
|
209 lines
Jak ulepszyê procedurë? (odc. 6.)
---------------------------------
TEXTURED VECTORS
<lead>Ostatnio w kaûdym dobrym demie moûemy ujrzeê tzw.
wektorówki teksturowane, czyli majâce naîoûonâ na ôciany grafikë.
Jak stworzyê takie "cudo"?
<a>Miklesz/Damage
<txt>Sâ w zasadzie dwie metody. Pierwsza polega na odpowiednim
rysowaniu ôcian i specjalnym nanoszeniu na nie grafiki. Trzeba
jednak mieê na uwadze, ûe metoda ta wymaga trochë wiëkszego
wkîadu pracy, a omówië jâ w póúniejszych odcinkach, przy okazji
przedstawiania cieniowania ôcian (Gouraud). Natomiast drugi
sposób polega na obracaniu wszystkich punktów obrazka i rysowaniu
ich po kolei. Jest to sposób stosunkowo prosty, lecz niezbyt
szybki. Z uwagi na jego prostotë zajmë sië nim dzisiaj i
postaram sië dokîadnie go omówiê...
Wyobraúmy sobie, ûe chcemy obróciê "obrazek" o rozmiarach 16 x 16
pikseli (dla uproszczenia). Normalnie mamy 16 x 16 = 256 punktów
do przeliczenia. Nieprzyzwoicie duûo. Przy wiëkszych rozmiarach
to i Silicon nie da sobie rady. Ale jest na to rada, podam Wam
sposób, jak obliczajâc JEDEN punkt, moûemy poznaê pozycje
wszystkich punktów kwadratowego obrazka! Ale zacznijmy od
poczâtku...
Najpierw taka umowa: wszystkie punkty ponumerowane sâ od (0,0) do
(F,F). Da nam to klarowny obraz, który "dot" mam akurat na myôli.
Jak juû wspominaîem, rotujemy jeden punkt, ten o symbolu (0,0).
To juû 1/256 sukcesu! Zaraz bëdziemy juû znali dwa punkty.
Zauwaûmy, ûe punkt (F,0) moûemy otrzymaê, zamieniajâc wspóîrzëdne
(X,Y) punktu (0,0) ze sobâ, a nastëpnie negujâc Y. Radzë to sobie
przeanalizowaê na ukîadzie wspóîrzëdnych (jest to tzw. mirror
cheating). Nastëpnym krokiem bëdzie wyliczenie punktów na caîej
krawëdzi pomiëdzy (0,0) i (F,0). Poniewaû tak sië zîoûyîo, ûe
znamy liczbë punktów wchodzâcych w jej skîad i w naszym wypadku
wynosi ona 16, moûemy brakujâce wspóîrzëdne wyliczyê, korzystajâc
z proporcjonalnoôci. Wiëkszoôê z Was zrozumiaîa juû zapewne, o co
chodzi. Dla tych, którzy sië jeszcze z takim dziwadîem nie
spotkali, podajë wzór ogólny:
<r>
I -- indeks
N -- liczba punktów;
X0 -- wspóîrzëdna X punktu (0,0);
Xn -- wspóîrzëdna X punktu (N,0);
Xi -- wspóîrzëdna X punktu (I,0);
Y0 -- wspóîrzëdna Y punktu (0,0);
Yn -- wspóîrzëdna Y punktu (N,0);
Yi -- wspóîrzëdna Y punktu (I,0);
Xi=(Xn-X0)/N*I+X0
Yi=(Yn-Y0)/N*I+Y0
<txt>Nooo.... Teraz juû chyba wszystko jest jasne. Jak zapewne
zauwaûyliôcie, osiâgnëliômy juû 16 punktów i gwarantujë Wam, ûe
teraz pozostaje jedynie kilka dodawaï i odejmowaï, aby otrzymaê
wszystkie 256 punktów obrazka!
Zauwaûmy, ûe nasza krawëdú to 1/16 obrazka. Gdybyômy potraktowali
jâ jako linië i nastëpnie odpowiednio 15 razy skopiowali,
przesuwajâc za kaûdym razem o odpowiedni wektor, to
otrzymalibyômy peîny obrazek! No dobrze, ale skâd wiedzieê, o
jaki wektor przesuwamy? Nic trudnego... Wektor pomiëdzy punktem
(0,0) a (0,1) jest równy wektorowi pomiëdzy (0,0) i (1,0),
obróconemu w prawo o 90 stopni. Jak obróciê wektor o kât prosty,
juû wiecie (wykorzystamy do tego mirror cheating). Czynnoôê
kopiowania wspóîrzëdnych z translacjâ powtarzamy 15 razy i mamy
obrócone wszystkie punkty obrazka! Teraz wystarczy tylko nanieôê
to wszystko na ekran.
Na razie jedynie chwaliîem ten sposobik. Teraz coô o jego wadach.
Po pierwsze obojëtnie jak maîy obszar zajmowaîaby ôcianka na
ekranie, to i tak obliczamy wszystkie punkty obrazka úródîowego,
mimo ûe duûa ich czëôê sië pokryje. Po drugie kiedy z kolei
zaczniemy powiëkszaê ôcianë, zacznâ powstawaê "dziury". Dlatego
najlepiej wykorzystaê sposób podany przeze mnie do wszelkiego
rodzaju teksturowanych obiektów punktowych, majâcych wyraúne
oddzielone od siebie punkty. Trzeciâ wadâ jest sprawa
perspektywy, która musi byê, niestety, staîa dla caîej ôciany lub
czasami nawet dla caîego obiektu. Bywa, ûe wpîywa to ujemnie na
koïcowy efekt. Tak czy siak metoda jednak dziaîa, a przykîadem
jej wykorzystania mogâ byê, zrobione przeze mnie, trzy
teksturowane szeôciany, obracajâce sië w demie "Noxzema"/Damage.
Po tej dawce teorii na temat rotowania punktów, parë praktycznych
uwag. Jak zapewne zauwaûyliôcie, wektory, np. pomiëdzy (0,0) i
(1,0) oraz pomiëdzy (1,0) i (2,0), sâ sobie równe. Dlaczego wiëc
nie wyliczyê ich raz, a póúniej tylko powielaê? Moûna, ale
zauwaûcie, ûe najczëôciej nie majâ one wartoôci caîkowitej. W
zwiâzku z tym caîy obrazek przeskakiwaîby wyraúnie i trudno by
byîo uznaê jego drgawki za rotacjë. Oczywiôcie jeûeli mamy
koprocesor matematyczny, to problem z gîowy, lecz co wtedy, gdy
nie jesteômy wîaôcicielami FPU? Pozostaje nam jedynie symulacja
liczb zmiennoprzecinkowych na liczbach staîoprzecinkowych.
Zacznë od przykîadu, którego bezpoôrednio nie moûna by byîo
wykorzystaê w asemblerze, z uwagi na mnoûenie przez potëgi liczby
10, a nie 2. My jednak procesorami nie jesteômy, wiëc 10 wyglâda
dla nas trochë przyjaúniej. Ale moûe po kolei...
Przypuôêmy, ûe chcemy pomnoûyê liczbë 12,34 przez 56,78.
Normalnie procesor gîówny obciâîby wszystko to, co po przecinku,
i otrzymalibyômy 12 x 56 = 672. Jest to oczywiôcie niezgodne z
prawdziwym wynikiem wynoszâcym 12,34 x 56,78 = 700,6652.
Przypuôêmy, ûe jeszcze bîâd rzëdu +1/-1 byîby dopuszczalny, ale
pomyîka o prawie 1/10 wyniku to juû powaûna sprawa. A caîoôê
wyglâda jeszcze groúniej, kiedy musimy póúniej zsumowaê kilka
bîëdnie wyliczonych wartoôci! Ale jest sposób na otrzymywanie
dokîadniejszych wyników. Najpierw nasze dwie wartoôci pomnóûmy
przez 100 (czyli przesuïmy przecinek na koniec cyfry). Otrzymamy
1234 i 5678. Teraz spokojnie mnoûymy obie liczby przez siebie,
otrzymujâc w wyniku 7 006 652. Nastëpnie caîoôê dzielimy przez
100 000 (liczba zer jest oczywiôcie sumâ miejsc, o które
przesunëliômy wczeôniej przecinek, zresztâ chyba wszyscy
pamiëtamy to z podstawówki :-). Wynik: 7 006 652, czyli po
odjëciu zer, równe 700. Bîâd wyniósî 0,6652, jest to znacznie
mniej niû jeden procent caîoôci, a to chyba dokîadnoôê
wystarczajâca, aby nasza wektorówka wyglâdaîa estetycznie.
Pozostaje pytanie, jak to wszystko mnoûyê w asemblerze? To
proste, wszelkie operacje wykonujemy przy liczbach juû wczeôniej
przemnoûonych przez jakâô potëgë dwójki, czego dokonujemy
oczywiôcie nie przez MULa.b, lecz przez przesuniëcia bitowe. Tu
warto zwróciê uwagë, ûe im bardziej wczeôniej przeskalujemy
wartoôci poczâtkowe, tym dokîadniejszych wyników moûemy póúniej
oczekiwaê. Oczywiôcie tak îatwo nie da sië uzyskaê samych liczb z
wartoôciami po przecinku. Majâc jedynie CPU, moûemy uzyskaê takie
wartoôci jedynie w wyniku dzielenia przez siebie liczb juû
przeskalowanych. Obecnie na 68EC020++ moûemy juû operowaê na
QuadWordach, tak wiëc zakresów nam raczej nie zabraknie. Jeûeli
zaô chodzi o przesuwanie bitowe, to polecam szybkâ instrukcjë
SWAP.W, która w "ekspresowy" sposób z kaûdej liczby $0000abcd,
zrobi nam przeskalowanâ $abcd0000. Naleûy oczywiôcie pamiëtaê, ûe
wszelkie operacje na przeskalowanych wartoôciach muszâ mieê
rozmiar dîugiego sîowa (.L), gdyû mniejsze rozmiary bëdâ
dotyczyîy jedynie cyfr "po przecinku". Kiedy juû wyliczymy sobie
to, co potrzebujemy, jednym SWAP-em sprowadzamy liczbë "na
ziemië", czyli obcinamy zera (w zasadzie to wysyîamy je "do
góry", lecz przy dalszych operacjach na samym sîowie (.W) nie ma
to juû znaczenia, choê czasami moûe warto i o tym pamiëtaê), a
czëôê caîkowitâ otrzymujemy w dolnych szesnastu bitach rejestru.
Proste?
Jeûeli na razie nie mieliôcie zbyt dîugiego kontaktu z
teksturowanymi wektorówkami, to muszë uprzedziê, ûe ten typ
efektów naleûy do "raczej" czasochîonnych, i to zarówno w sensie
czasu poôwiëconego na napisanie procedury, jak i czasu
ekranowego, potrzebnego do narysowania wszystkich ôcian. One
Frame naleûy tu do rzadkoôci, a co bardziej skomplikowane obiekty
na wolniejszych maszynach poruszajâ sië niebywale wolno, mimo ûe
koder naprawdë wycisnâî z Amigi, co sië tylko daîo. Dla tych,
którzy jeszcze nie widzieli lub nie sîyszeli, podajë, ûe ostatnio
w demach zachodnich pojawiajâ sië obiekty teksturowane i przy
okazji na przykîad deformowane, cieniowane.
Przy okazji pragnë wyjaôniê, ûe wszelkiego rodzaju WolfSteiny i
Doomy sâ zazwyczaj (choê nie zawsze) wektorówkami. Te wszystkie
prostsze sâ zbliûone bardziej do tzw. Comanche'y (wszystkie te
nazwy pochodzâ oczywiôcie od gier pecetycznych, w których dany
efekt pojawiî sië po raz pierwszy). Zastanawiaê moûe fakt,
dlaczego to kompatybilni pierwsi zaczëli tworzyê takie rzeczy.
Jest to skutkiem nieposiadania przez koôci OCS, ECS i AGA trybu
chunky pixel. Operacje na bitplane'ach, jak wiadomo, choê
upraszczajâ tworzenie na przykîad "Glenz Vectorów", to
spowalniajâ stawianie pojedynczych punktów w duûej liczbie
kolorów. Teoretycznie nawet do oômiu razy. W tej sytuacji dopiero
pojawienie sië trybu chunky, czëôciowo emulowanego na Copperze,
oraz szybkich konwerterów "Chunky To Plannar" przyôpieszyîo
rozwój wszelkiej grafiki teksturowanej i cieniowanej.
Nim zakoïczë dzisiejszy odcinek, zabiorë jeszcze gîos w takiej
pewnej sprawie... Doszîy mnie sîuchy, ûe Szanowni Czytelnicy
zareagowali na mój cykl dotyczâcy asemblera. Z jednej strony
cieszë sië, gdyû znaczy to, ûe ktoô czyta, to co ja tam bazgrzë,
a to juû jest sukces. Z drugiej strony jednak okazaîo sië, ûe
Szanowni Czytelnicy zareagowali negatywnie... A to juû mniej
cieszy. A wîaôciwie, to wcale. Jednak nikt z Was nie zaproponuje
nic konstruktywnego, tylko mówicie (najczëôciej do sîuchawki), ûe
Wam sië nie podoba i juû. Jeûeli macie jakiô pomysî, to
powiedzcie, a nie tylko krytykujcie. Jeûeli chcecie, bym napisaî
np. o tunelach, to napiszë. Jeûeli jednak po prostu nie podoba
Wam sië cykl sam w sobie (lub moja osoba, co teû jest
prawdopodobne), to po prostu dam sobie spokój i po mnie ktoô inny
zacznie n-ty cykl pt. "Jak otworzyê okienko i napisaê w nim: Tu
byîem, Tony Halik" ;-) Czy jednak komuô sië to naprawdë przyda
przy kodowaniu dema?
Oglâdajâc najnowsze dema, dochodzi sië do wniosku, ûe
teksturowane wektory sâ domenâ nie tylko pecetów. Amiga, mimo
braku chunky pixel, radzi sobie nieúle z generowaniem takich
obiektów. Wam równieû ûyczë wspaniaîych "teksturowaïców". Juû
dziô zapowiadam, ûe w nastëpnym odcinku dogonimy niebieskiego w
kolejnej branûy... Wykonamy lot nad fraktalowymi górami,
rysowanymi, oczywiôcie, w czasie rzeczywistym!