home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1997 #3 / amigamamagazinepolishissue03-1 / ma_1995 / 08 / ami021.txt < prev    next >
Text File  |  1997-04-07  |  7KB  |  169 lines

  1. /**** ELA, NAJPRAWDOPODOBNIEJ TRZEBA ZMIENIÊ LEAD, BO JESTEM PEWIEN,
  2. ÛE WYWALË MU CONAJMNIEJ POÎOWË OBRAZKÓW. -Raf ****/
  3.  
  4. Jak ulepszyê procedurë?
  5. -----------------------
  6.  
  7. CIENIOWANIE
  8.  
  9. <lead>Do dzisiejszego odcinka przygotowaîem "nieco" ilustracji. A
  10. zajmiemy sië oôwietlaniem i cieniowaniem ruchomych obiektów.
  11.  
  12. <a>Miklesz/ Damage
  13.  
  14. <txt>Na poczâtek parë zaîoûeï przydatnych przy rysowaniu ôcian.
  15. Bëdziemy rysowaê czworokâtnâ ôcianë, wyznaczonâ przez punkty
  16. (0,1,2,3). Musimy jeszcze zaîoûyê jedno. Kolejne punkty ôciany
  17. zawsze "przebiegajâ" w jednym kierunku (np.: w kierunku wskazówek
  18. zegara). Pierwszâ rzeczâ, jakâ musimy zrobiê, bëdzie znalezienie
  19. najwyûszego (majâcego najmniejszâ wspóîrzëdnâ Y) punktu. Zaîóûmy,
  20. ûe bëdzie on miaî numer 0. Kiedy juû to wiemy, îatwo moûna
  21. zauwaûyê, ûe nasza figura bëdzie ograniczona z lewej strony
  22. nastëpujâcymi krawëdziami (posuwajâc sië od góry): 0-3 i 3-2. Z
  23. prawej bëdâ to 0-1 i 1-2. Wiemy, ûe Dy (wysokoôê caîej figury,
  24. liczona po osi Y) jest równa:
  25.  
  26. <l>Dy=Y2-Y0
  27.  
  28. <txt>Pozostaje nam wiëc przetablicowaê sobie obie (lewâ i prawâ)
  29. krawëdzie. Kaûdâ liczymy w dwóch etapach (lewâ: 0-3 i 3-2, prawâ:
  30. 0-1 i 1-2). Jak szybko wyliczyê wszystkie punkty odcinka?
  31. Przemnaûanie wszystkich wartoôci nie naleûy do najlepszych metod.
  32. Natomiast wyliczenie krótkiego wektora i dodawanie go do
  33. kolejnych punktów spowoduje powstawanie sporych przekîamaï,
  34. wynikajâcych ze staîoprzecinkowoôci procesora gîównego. Nie chcë
  35. byê posâdzony o pisanie tekstów za pomocâ funkcji Copy i Paste,
  36. ale poniewaû wspominaîem o metodzie, pozwalajâcej rozwiâzaê nasz
  37. problem juû kilka miesiëcy temu, to pozwolë sobie przedstawiê jâ
  38. raz jeszcze:
  39.  
  40. <sr>Wyliczanie krawëdzi
  41.  
  42. <txt>Caîâ krawëdú moûemy potraktowaê jako funcjë N-elementowâ,
  43. przyporzâdkowujâcâ kaûdemu elementowi (Yi) z osi Y, wartoôê (Xi)
  44. z osi X. Braliômy to juû przy okazji omawiania wektorów
  45. teksturowanych. Podajë wzór:
  46.  
  47. <l>I - Indeks
  48.  
  49. N - Liczba punktów
  50.  
  51. X0 - Wspóîrzëdna X punktu (0,0)
  52.  
  53. Xn - Wspóîrzëdna X punktu (N,0)
  54.  
  55. Xi - Wspóîrzëdna X punktu (I,0)
  56.  
  57. Y0 - Wspóîrzëdna Y punktu (0,0)
  58.  
  59. Yn - Wspóîrzëdna Y punktu (N,0)
  60.  
  61. Yi - Wspóîrzëdna Y punktu (I,0)
  62.  
  63.  
  64. Xi=(Xn-X0)/N*I+X0
  65.  
  66. Yi=(Yn-Y0)/N*I+Y0
  67.  
  68. <txt>Jak jednak dokonywaê wszelkich mnoûeï i dzieleï liczb
  69. zmiennoprzecinkowych? Jeûeli mamy koprocesor matematyczny, to
  70. problem z gîowy, lecz co wtedy, gdy nie jesteômy wîaôcicielami
  71. FPU? Pozostaje nam jedynie symulacja liczb zmiennoprzecinkowych
  72. na liczbach staîoprzecinkowych. Zacznë od przykîadu, którego
  73. bezpoôrednio nie moûna by byîo wykorzystaê w asemblerze, z uwagi
  74. na mnoûenie przez potëgi liczby 10, a nie 2. My jednak
  75. procesorami nie jesteômy, wiëc 10 wyglâda dla nas trochë
  76. przyjaúniej.
  77.  
  78. Przypuôcmy, ûe chcemy pomnoûyê liczbë 12,34 przez 56,78.
  79. Normalnie procesor gîówny obciâîby wszystko to, co po przecinku,
  80. i otrzymalibyômy 12 x 56 = 672. Jest to oczywiôcie niezgodne z
  81. prawdziwym wynikiem, wynoszâcym 12,34 x 56,78 = 700,6652.
  82. Przypuôêmy, ûe jeszcze bîâd rzëdu +1/-1 byîby dopuszczalny, ale
  83. pomyîka o prawie 1/10 wyniku, to juû powaûna sprawa. A caîoôê
  84. wyglâda jeszcze groúniej, kiedy musimy póúniej zsumowaê kilka
  85. bîëdnie wyliczonych wartoôci! Ale jest sposób na otrzymywanie
  86. dokîadniejszych wyników. Najpierw nasze dwie wartoôci pomnóûmy
  87. przez 100 (czyli przesuïmy przecinek na koniec cyfry). Otrzymamy
  88. 1234 i 5678. Teraz spokojnie mnoûymy obie liczby przez siebie,
  89. otrzymujâc w wyniku 7006652. Nastëpnie caîoôê dzielimy przez
  90. 100000 (liczba zer jest oczywiôcie sumâ miejsc, o które
  91. przesunëliômy wczeôniej przecinek). Wynik: 700,6652, czyli po
  92. odjëciu zer, równe 700. Bîâd wyniósî 0,6652. Jest to znacznie
  93. mniej niû jeden procent caîoôci, a to chyba dokîadnoôê
  94. wystarczajâca, aby nasza wektorówka wyglâdaîa estetycznie.
  95.  
  96. Pozostaje pytanie, jak to wszystko mnoûyê w asemblerze? To
  97. proste, wszelkie operacje wykonujemy przy liczbach juû wczeôniej
  98. przemnoûonych przez jakâô potëgë dwójki, czego dokonujemy
  99. oczywiôcie nie przez MULa.b lecz przez przesuniëcia bitowe. Tu
  100. warto zwróciê uwagë, ûe im bardziej wczeôniej przeskalujemy
  101. wartoôci poczâtkowe, tym dokîadniejszych wyników moûemy póúniej
  102. oczekiwaê. Oczywiôcie tak prosto nie da sië uzyskaê samych liczb
  103. z wartoôciami po przecinku. Posiadajâc jedynie CPU, wartoôci
  104. takie uzyskaê moûemy jedynie w wyniku dzielenia przez siebie juû
  105. przeskalowanych liczb. Obecnie na 68EC020++ moûemy juû operowaê
  106. na QuadWordach, tak wiëc zakresów nam raczej nie zabraknie.
  107. Jeûeli zaô chodzi o przesuwanie bitowe, to polecam szybkâ
  108. instrukcjë SWAP.W, która w ekspresowy sposób z kaûdej liczby
  109. $0000abcd, zrobi nam przeskalowanâ $abcd0000. Naleûy pamiëtaê
  110. oczywiôcie, ûe wszelkie operacje na przeskalowanych wartoôciach
  111. muszâ mieê rozmiar dîugiego sîowa (.L), gdyû mniejsze rozmiary
  112. bëdâ dotyczyîy jedynie cyfr "po przecinku".
  113.  
  114. Kiedy juû wyliczymy sobie to, czego potrzebujemy, jednym SWAPem
  115. sprowadzamy liczbë "na ziemië", czyli obcinamy zera (w zasadzie
  116. to wysyîamy je "do góry", lecz przy dalszych operacjach na samym
  117. sîowie (.W) nie ma to juû znaczenia, choê czasami moûe warto i o
  118. tym pamiëtaê), a czëôê caîkowitâ otrzymujemy w dolnych szesnastu
  119. bitach rejestru. Kiedy wiëc podanâ przeze mnie metodâ wyliczymy
  120. wszystkie cztery krawëdzie i po poîâczeniu tablic otrzymamy dwie:
  121. lewâ i prawâ, wystarczy (jak to robi blitter) wypeîniê przestrzeï
  122. pomiëdzy nimi.
  123.  
  124. <sr>Cieniowanie ôcian
  125.  
  126. <txt>Na razie narysowaliômy ôcianë w jednym kolorze. A przecieû
  127. miaîo byê o cieniowaniu! Okazuje sië, ûe wystarczy juû jedem maîy
  128. kroczek. Dla uproszczenia przyjmujemy, ûe odlegîoôê danego punktu
  129. ôciany zaleûy od jego odlegîoôci od obserwatora, liczonej w osi
  130. Z. Dziëki temu, juû po wykonaniu rotacji, znamy jasnoôci
  131. naroûników. Wystarczy wyliczyê natëûenia na caîej ôcianie.
  132. Zaczniemy od wyliczenia jasnoôci kaûdego z punktów krawëdzi.
  133. Znowu skorzystamy z usîug proporcjonalnoôci i kiedy bëdziemy
  134. wiedzieli, ûe naroûnik 0 ma jasnoôê 255, a naroûnik 1 000, to
  135. kolor I tego punktu jest równy:
  136.  
  137. <l>Ci=(C1-C0)/N*I+C0
  138.  
  139. <txt>Oznaczenia indeksów pozostajâ takie same, jak we wzorze na X
  140. i Y. Znamy juû natëûenia wszystskich punktów dwóch krawëdzi
  141. lewych i dwóch prawych. Teraz, kiedy wypeîniamy ôcianë, musimy
  142. zadbaê o pîynne przejôcie jasnoôci od lewego do prawego brzegu.
  143. Jeûeli powiem, ûe znów wykorzystamy tu proporcjonalnoôê, to nikt
  144. juû chyba nie bëdzie zaskoczony. Sposób podany przeze mnie nie
  145. jest moûe idealny, ale powstajâce w wyniku jego dziaîania
  146. niedokîadnoôci przy cieniowaniu sâ bardzo maîe. W kaûdym razie
  147. metoda sië sprawdza w 100%, a trzeba zauwaûyê, ûe jest stosunkowo
  148. szybka!
  149.  
  150. <sr>Ilustracje
  151.  
  152. <txt>Tradycyjnie prezentujë kilka przykîadów demek wykorzystujâcych
  153. omawiane przeze mnie techniki. Ilustracja pierwsza pochodzâca z dema
  154. "Anahalonium Lewini" grupy Tristar Red Sector Incorporation, to
  155. przykîad zastosowania prostej metody oôwietlania do skomplikowanej
  156. figury, co daîo niezîy efekt koïcowy. Druga ilustracja przedstawia
  157. obraz ôcianki jaki moûna otrzymaê po zastosowaniu algorytmu,
  158. podanego przeze mnie. Jeûeli w wyniku dziaîania Waszej procedurki
  159. "wyszîo" wam coô podobnego, to znaczy, ûe jest wszystko OK!
  160.  
  161. <sr> Sîowo na niedziele
  162.  
  163. <txt>Jak widzicie, cieniowanie obiektów, to nie taka straszna
  164. "Magia Davida BlitterFielda". Nadmieniê jednak naleûy, ûe
  165. wykonanie DOBREJ procedury do oôwietlania, jest dosyê
  166. czasochîonne. Ûyczë udanych prób i wspaniaîych efektów. Udanego
  167. Gourauda! Za miesiâc opowiem, jak wykonaê "RealTime Emboss".
  168.  
  169.