26

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

No i mam wersję, która generuje maski/offsety na blitterze. :) Tyle, że u mnie wychodzi... wolniej. :O (z wyliczeń wynika, że powinno być szybciej, a nie jest :( ). I teraz widzę dwa wytłumaczenia: pierwsze bardziej prawdopodobne, że Cyprian zrobił to inaczej, drugie mniej prawdopodobne, że pomylił zrzuty ekranów :P
W każdym razie u mnie generowanie tablicy przebiega w pięciu cyklach (być może Cyprian tutaj lepiej sobie to wymyślił):
1. Generowanie wyANDowanych wartości współrzędnych dla offsetów
2. Generowanie wyANDowanych wartości dla masek
3. Generowanie offsetów
4. i 5. Generowanie masek.
Przy okazji wpadłem na kolejną optymalizację :D (Przy dużych trójkątach zejdzie jakieś 5 scanlinii). Jak wszystko połączę w całość, zamieszczę odpowiedni kod.

27

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

Ha! Po chwili (dłuższej :P) zastanowienia wiem już Cyprian, na czym polega twoja optymalizacja. :) Na razie jawi mi się w dwóch przejściach blittera nad wyliczonymi współrzędnymi. Kusi mnie, żeby zrobić swoją wersję... :P

28

(3 odpowiedzi, napisanych Software, Gry - 16/32bit)

No właśnie. Nie dopisałem, że na PC też coś może być :)

29

(3 odpowiedzi, napisanych Software, Gry - 16/32bit)

Panowie (a być może Panie :P). Potrzebuję czegoś, co wyeksportuje mi obiekty 3d do pliku tekstowego (współrzędne, ściany, kolory itd.). Pomożecie?

30

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

Cyprian napisał/a:

Widzę jeszcze miejsce na optymalizację, np. aktualnie generowanie nowej tablicy leftEdge/rightEdge/leftMask/rightMask wymaga inicjalizacji dla każdego wielokąta osobno. gdyż odbywa się ono pomiędzy "compute_triangle_dx" a "fill_triangle".

Można by spróbować wykonać tylko jedną inicjalizację dla wszystkich wielokątów. Czyli wykonać "compute_triangle_dx" dla wszystkich wielokątów, potem tylko jedna inicjalizacja BLiTTERa, a następnie dla każdego wielokąta generowanie nowej tablicy leftEdge/rightEdge/leftMask/rightMask. No i na koniec "fill_triangle" dla każdego wielokąta.

Jak zaczniemy bawić się kostką, to będzie można wspomniane optymalizację do kodu dorzucić :)

31

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

@Cyprian - Jeszcze trochę, to sobie kod wydrukuję i zacznę się do niego modlić :P
@MKM - fajne pomysły, fajny design - ogólnie gratulacje :)

32

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

Aaa właśnie. Czy "Takeover" (grupa Lamers) nie jest między innymi autorstwa naszego szanownego kolegi MKMa? :)

33

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

Ładne. :D , ale te vectory na początku szacuję na jakieś 2 ramki przy naszych prockach :P

34

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

W najbardziej krytycznej czasowo części kodu dużo miejsca na optymalizację już nie było, a zawsze będzie 3 linie mniej :)

35

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

Trudno określić w procentach, ile czasu będzie zajmował clipping, ale dla każdej krawędzi wykonywane jest kilka porównań i zapis do tablicy krawędzi - więc nie są to wartości porażające. W razie konieczności wyliczenia przecięcia krawędzi z oknem obcinającym dodatkowo wykonywane jest jedno dzielenie, jedno mnożenie, 3 move'y, 3 sub'y i jeden add. Ogólnie nie jest źle - a mam pomysł, jak pozbyć się mnożenia i dzielenia :) (i to bez tablicy). Oczywiście, jeśli okno jest malutkie (albo trójkąt bardzo duży) może zdarzyć się, że obcinanie będzie robione dla każdej krawędzi, czyli 4 razy.

36

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

No ciekawy jestem, co z twojego pomysłu wyjdzie. Clipping oczywiście nie jest zawsze potrzebny, ale biorąc pod uwagę szybkość działania wypełniania warto było się i nad tym problemem pochylić :) - tym bardziej, że pomysłowe użycie pozwoli uzyskać ciekawe "demkowe" efekty :D

37

(31 odpowiedzi, napisanych Programowanie - 16/32bit)

Uff.. znalazłem w końcu trochę (dużo :P) wolnego czasu i zaimplementowałem wspomniany przeze mnie wcześniej algorytm obcinania wielokątów. O ile sam algorytm (Sutherland-Hodgman) nie jest zbyt skomplikowany, to już odpowiednia implementacja w assemblerze nie była zupełnie banalna (chociaż ilościowo kodu nie jest dużo). Implementacja obcina wielokąt do zadanego parametrycznie okna, wykorzystując strategię "dziel i zwyciężaj" - czyli skomplikowany problem dzieli na kilka mniejszych  - w tym wypadku obcinanie następuje dla każdej krawędzi okna osobno. Dzięki takiemu rozwiązaniu można obcinać np. tylko po krawędziach poziomych lub pionowych :). Procedurę clippingu przeniosłem do osobnego pliku, w programie głównym jest tylko kilka zmian w stosunku do procedury rysowania wielokątów wypukłych bez obcinania. Mam pomysł (chyba), jak zmniejszyć dosyć kosztowne czasowo liczenie przecięcia krawędzi z oknem obcinającym (teraz jest między innymi jedno mnożenie i jedno dzielenie), ale zostawiam to sobie na później (tablica nie wchodzi raczej w grę ze względu na jej rozmiar). Jak zwykle komentarze mile widziane :P Myślę, że kolejnym krokiem będzie jakiś obracający się sześcian, a później może obiecany wcześniej glenz :D

38

(6 odpowiedzi, napisanych Programowanie - 16/32bit)

Fajnie jest po tylu latach przypominać sobie stare rzeczy, szczególnie assemblera (zawsze miałem słabość do Motoroli :P). Przy okazji można wiele rzeczy zrobić lepiej (jednak doświadczenie znacznie większe) no i sporo rzeczy wynieść - cały czas 4 planowe wypełnianie na blitterze zaproponowane przez Cypriana robi na mnie wielkie wrażenie.
Edit: W wolnym czasie usiądę w takim razie do obcinania wielokątów. Zadanie nie jest zupełnie banalne, kilka rzeczy muszę sobie przemyśleć. Oczywiście najlepszy dla naszych potrzeb będzie algorytm wymyślony przez Sutherlanda-Hodgmana, ale warto uprościć go do postaci prostokąta obcinającego (oryginalnie jest to dowolny wielokąt) i tylko dla wielokątów wypukłych.

39

(6 odpowiedzi, napisanych Programowanie - 16/32bit)

Zanim zabiorę się za wektory, potrzebuję jeszcze obcinania wielokątów. Ktoś może zajmował się już tematem, czy będę musiał sam przysiąść i sobie napisać? :)

40

(6 odpowiedzi, napisanych Programowanie - 16/32bit)

Można w ramach ćwiczeń i glenza zrobić. :) Efekt jest w zasadzie bardzo prosty do realizacji. Trzeba ściany na różnych planach wyrysować i odpowiednio kolory w palecie ustawić.

41

(6 odpowiedzi, napisanych Programowanie - 16/32bit)

No i stało się! Matki krzyczą, dzieci płaczą, amigowcy pomstują. :P Wrzucam fillera dla DOWOLNEGO wielokąta wypukłego. Jedyne o czym trzeba pamiętać, to żeby współrzędne były podawane w kierunku przeciwnym do ruchu wskazówek zegara. Procedura nie musi nawet sortować wierzchołków, wystarczy, że wyznaczy sobie yMin i yMax. Dane określające wielokąt wyglądają np. tak:

pentaCoords                    
    dc.w    5-1 - ilość wierzchołków - 1
    dc.w    100,0 - wierzchołki
    dc.w    0,100
    dc.w    130,199
    dc.w    260,190
    dc.w    319,80
    dc.w    100,0 - wierzchołek zamykający, taki sam jak pierwszy

Edit: Tak naprawdę, to można podawać współrzędne również w kierunku zgodnym z ruchem wskazówek zegara, ale sugeruje przeciwny... :)

42

(50 odpowiedzi, napisanych Programowanie - 16/32bit)

Na początku miałem wersję z negacją, ale trzeba było odpowiednio reagować na ujemne dxy i zrezygnowałem z tego na rzecz szybszego kodu... :)

43

(50 odpowiedzi, napisanych Programowanie - 16/32bit)

Przy liczeniu współrzędnych linii korzystam z addx.l , dzięki czemu kod liczący wygląda tak:

    move.w    d0,(a6)+
    addx.l    d2,d0

Zdecydowanie najszybsze, co można wymyślić... :D

Tablica zrobiona jest pod wzór: t = (x2-x1)/(y2-y1), gdzie dx może mieć wartość ujemną. Nie chciałem ograniczać się do, jak to fajnie nazwałeś "życiowych trójkątów", ale wyliczyć wszystkie możliwe wartości, a to daje 2*320*200*4 bajtów. :P

Oczywiście jeśli nie są potrzebne wielkie trójkąty można zmodyfikować tablicę pod swoje potrzeby. :)

44

(50 odpowiedzi, napisanych Programowanie - 16/32bit)

Zgodnie z obietnicą zamieszczam kolejne rozwinięcie wypełniania. Połączyłem procedurę generowania współrzędnych i wypełniania trójkąta w jedną zbiorczą funkcję, 't' jest teraz odczytywane z tablicy, dzięki czemu w kodzie nie ostało się żadne dzielenie. :D Minusem rozwiązania jest prawie pół megowa tablica i 4 sekundowy czas jej generowania. Pomimo wszystko proponuję wykorzystać tą inkarnację kodu do dalszych modyfikacji.

45

(50 odpowiedzi, napisanych Programowanie - 16/32bit)

No ciekawy jestem, co udało ci się jeszcze wymyślić, bo mało miejsca zostało na optymalizację... :P

46

(50 odpowiedzi, napisanych Programowanie - 16/32bit)

Ok. Chyba pójdziemy dalej. Co byście powiedzieli gdybyśmy małymi krokami doszli do jakiegoś ładnego, kręcącego się obiektu? :D Kolejną rzeczą, którą warto zrobić jest rozszerzenie procedury na rysowanie czworokątów (a może nawet wszystkich wielokątów wypukłych? :P). Jeśli to się uda, będzie można (w razie konieczności) dodać clipping (algorytm Sutherland-Hodgman). W wolnej chwili pochylę się nad problemem - przy obecnym stanie kodu chyba nie powinno to być zbyt trudne. Prawdopodobnie połączę procedury generowania współrzędnych i rysowania w jedną wspólną prockę (będzie przejrzyściej) - kilka instrukcji też pewno wyleci. Dodatkowo można wrzucić w tablicę kod wyliczający t, czyli (x2-x1)/(y2-y1), dzięki czemu pozbędziemy się dzielenia i przesuwania bitów. Uff..

47

(50 odpowiedzi, napisanych Programowanie - 16/32bit)

Wrzucam wersję z zoptymalizowanym wypełnianiem dla linii mniejszych od 16 pixeli. Chyba powoli dochodzimy do ściany, wykorzystanie blitterowego 'skew' do generowania masek (jak sugerował Cyprian) może być kosztowne inicjalizacyjnie (chyba, że czegoś nie widzę/nie wiem).

48

(50 odpowiedzi, napisanych Programowanie - 16/32bit)

Zgadza się. Kolor jest inicjowany raz na trójkąt, ale dzięki temu mamy do dyspozycji 12 wolnych linii halftonów i możliwość rezygnacji z tablicy lineOPów, więc szybkościowo wychodzi bardzo podobnie. Tak, czy inaczej twoje ujemne dstYInc otworzyło mi oczy na wiele spraw :D za co oczywiście serdecznie ci dziękuję. :)

49

(50 odpowiedzi, napisanych Programowanie - 16/32bit)

Wydaję mi się, że dla linii mniejszych od 16 punktów (i mieszczących się w tym samym offsecie ekranu) będzie można wypełniać tylko jedno słowo, zamiast obecnych dwóch. Będzie trzeba dorobić oddzielną tablicę kolorów dla halftonów (też 4 linie) i stosować ją razem ze zerowym dstYInc. Sprawdzę, jak znajdę trochę czasu.

50

(50 odpowiedzi, napisanych Programowanie - 16/32bit)

Zmiana na poszczególne plany była w zasadzie banalna. Znacznie uprościłem halftony - teraz potrzebne są tylko 4 linie, nie jest potrzebna tablica blitterLineOP, wyliczenie dstYInc to teraz:

    add.w    d3,d3
    move.w    blitDstYIncTab(pc,d3.w),dstYinc(a6)    

Kurde. Panowie. Mamy RAKIETĘ :D a chyba można jeszcze trochę zakombinować :)