Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

ATmega128 - przeglądarka modeli 3D

ikko 26 Lip 2011 23:33 16206 44
  • #31 26 Lip 2011 23:33
    sweter_007
    Poziom 13  

    Witam. Fajny projekt. Ja lubię takie rzeczy. Kilka pytań.
    Na jakiego rodzaju liczbach przeprowadzane są operacje?
    Czy obroty zrobione na macierzach, czy jednak zwykłe funkcje (trygonometria)?
    Czy jest zaimplementowana obsługa kamery (FPP, poruszanie się, kąt widzenia itd.)?
    Czy engine jest w stanie rasteryzować wypełnione trójkąty(czyli wypełnione obiekty)?

    I jeszcze robię coś podobnego i mam problem. Najprościej tłumacząc:
    przesuwam po ekranie wypełniony kwadrat(grafika2D). Rysuję kwadrat, liczę nowe współrzędne, zamalowuję stary kwadrat i w pętli wszystko. I zamiast ładnie przesuwającego się kwadratu, jest on taki w "paski". Na komputerze nazwał bym to wyłączoną synchronizacją pionową monitora. Nawet przy przesuwaniu o 1 jednostkę(pixel)na sekundę. Jak wygląda u ciebie algorytm renderowania?
    Rysujesz->liczysz nowe wsp->zamalowujesz stare(czyścisz ekran) i tyle?

  • #32 27 Lip 2011 22:25
    ikko
    Poziom 11  

    sweter_007 napisał:
    Na jakiego rodzaju liczbach przeprowadzane są operacje?

    Większość obliczeń jest wykonywana na liczbach zmiennoprzecinkowych 32 bitowych.

    sweter_007 napisał:
    Czy obroty zrobione na macierzach, czy jednak zwykłe funkcje (trygonometria)?

    Skorzystałem z tradycyjnych wzorów na obrót trójwymiarowy wokół punktu.
    Funkcje trygonometryczne są tablicowane.

    sweter_007 napisał:
    Czy jest zaimplementowana obsługa kamery (FPP, poruszanie się, kąt widzenia itd.)?

    Obsługa kamery jest raczej prymitywna. Obejmuje teraz tylko poruszanie się w trzech wymiarach.
    Można też doimplementować obracanie kamerą kosztem dodatkowych obliczeń.

    sweter_007 napisał:
    Czy engine jest w stanie rasteryzować wypełnione trójkąty(czyli wypełnione obiekty)?

    Nie. Nie brałem tego pod uwagę ze względu na wyświetlacz, którego używam.
    Nie widzę sensu w kolorowaniu ścian na czarno.
    Po zamalowaniu wszystkich wielokątów model byłby czarny i nie za wiele byłoby widać. Z kolorowym wyświetlaczem nie byłoby tego problemu.
    Inną sprawą jest to, że wypełnianie trójkątów mocno spowolniło by renderowanie.

    sweter_007 napisał:
    Jak wygląda u ciebie algorytm renderowania?
    Rysujesz->liczysz nowe wsp->zamalowujesz stare(czyścisz ekran) i tyle?

    Tak. W dużym uproszczeniu tak to wygląda:
    Obliczanie -> rysowanie -> (opóźnienie) -> czyszczenie ekranu.

    Wcześniej, zamiast czyszczenia zamalowywałem poprzedni model, ale trwa to dłużej niż rysowanie przy niektórych modelach.
    Wyglądało to tak:
    Obliczanie nowych współrzędnych -> rysowanie wg nowych współrzędnych na czarno -> (opóźnienie) -> rysowanie wg starych współrzędnych na biało

  • #33 27 Lip 2011 23:39
    sweter_007
    Poziom 13  

    Dzięki za odpowiedź. W moich próbach z grafiką, również zamalowuję poprzednią klatkę starymi współrzędnymi. Tak jest szybciej. Gratuluje umiejętności obsługi plików *.obj Pozdr

  • #34 28 Lip 2011 16:41
    ikko
    Poziom 11  

    W ramach optymalizacji geometrii napisałem procedurę ukrywania niewidocznych krawędzi.
    Jest to implementacja back-face cullingu, czyli jednego z algorytmów usuwania niewidocznych ścian.
    Podczas rysowania wielokątów pomijane są te, które odwrócone są tyłem do kamery.
    Algorytm ustala czy wektor normalny danego wielokąta jest skierowany w kierunku do kamery.
    Jeśli iloczyn skalarny wektora normalnego i wektora kamery jest dodatni to wielokąt jest rysowany.

    Przyspieszyło to rendering o 170% - 200% w zależności od modelu.

    Oto kilka zdjęć:
    ATmega128 - przeglądarka modeli 3D ATmega128 - przeglądarka modeli 3D ATmega128 - przeglądarka modeli 3D ATmega128 - przeglądarka modeli 3D ATmega128 - przeglądarka modeli 3D ATmega128 - przeglądarka modeli 3D

  • #36 11 Sie 2011 14:58
    ikko
    Poziom 11  

    Myślę, że nie. Wiem, że pozbycie się liczb zmiennoprzecinkowych przyspieszyło by obliczenia i myślałem wstępnie o tym. Odstraszała mnie zmiennoprzecinkowa trygonometria i obawa przed "pokaleczeniem" modeli przy zbyt niskiej rozdzielczości liczb.
    Powinienem gdzieś pomiędzy normalizacją (wstępnym skalowaniem i centrowaniem) a renderowaniem zastosować konwersję liczb z 32bit na 16bit lub nawet 8bit.

  • #37 11 Sie 2011 21:27
    sweter_007
    Poziom 13  

    W moim engine używam 8:8 fixed point. Nie ma mowy o "pokaleczeniu" obiektów przy takiej rozdzielczości. Zastosowanie reprezentacji stało pozycyjnej ma same plusy: znacznie mniejszy plik wynikowy(*.hex), brak powolnych mnożeń zmiennoprzecinkowych, zastąpienie funkcji round() poprzez przesunięcia bitowe, mniejsze zużycie pamięci sram. W grafice trójwymiarowej(na AVR) ,podczas obrotów czy skalowania nie jest ważne np. ósme miejsce po przecinku. Przy rasteryzacji obiektów i tak tracimy tą informację. Większej rozdzielczości wymaga się(właściwie aż się prosi, -1<=sin<=1)przy funkcjach trygonometrycznych, gdzie możemy przeznaczyć więcej bitów na część ułamkową podnosząc dokładność obliczeń.
    Poza tym, poradził bym koledze zastosowanie macierzy. Na początku może być ciężko jak się jest na bakier z matematyką(to nie ja:D). Ale po przygotowaniu wszystkiego po prostu poezja, czyli łączenie przekształceń. I dla przykładu: Obracanie punktów wokół 3 osi XYZ. Używając na chłopski rozum funkcji trygonometrycznych, na każdy punkt przypada 12 mnożeń. Przygotowując macierz XYZ używamy 16 mnożeń oraz 9 mnożeń na każdy punkt. Czyli dla 1000 punktów: wersja tryg. 12*1000=12000 mnożeń, wersja macierz 16 + 9*1000=9016 mnożeń. Im więcej składamy przekształceń, tym więcej zyskujemy.

  • #38 12 Sie 2011 19:07
    ikko
    Poziom 11  

    Dodałem bufor ramki, który zniwelował nieco uciążliwe migotanie.
    Dostosowałem algorytm rysowania punktu do rysowania w buforze.
    Cały model po przeliczeniu wierzchołków renderuje się w buforze znajdującym się w zewnętrznej pamięci XRAM. Gdy już cały bufor jest gotowy, następuje skopiowanie go do pamięci wyświetlacza. To taki mini double buffering. Większość pisałem w asemblerze opierając się na bibliotece GLCD.LIB.
    Z pomiarów czasu rysowania wynikło, że rysowanie w pamięci GLCD i w zewnętrznym XRAMie trwa tyle samo.
    Podmienienie bufora czyli skopiowanie z XRAM do pamięci w GLCD trwa 40ms a całość przyspieszyła o 100ms na cykl renderowania.
    Bufor zawiera każdy piksel na wyświetlaczu więc również tekst i obramowanie.

    Film przedstawia wersję z back-face cullingiem.


    Link

  • #39 12 Sie 2011 23:09
    leonow32

    Poziom 29  

    To działa na 16MHz? Próbowałeś podkręcić procesor np. do 20MHz? Kiedyś bawiłem się w podkręcania i przy 20 nie stwierdziłem żadnych problemów. Przy 24MHz UART zaczynał szwankować ale i tak procek chodził w miarę stabilnie. Kiedyś w EP rozkręcili ATmegę32 nawet do 48MHz, ale z generatora a nie samym kwarcem i ów generator nie ruszał od razu z dużą prędkością, ale stopniowo się rozpędzał.

  • #40 15 Sie 2011 21:04
    ikko
    Poziom 11  

    Cytat:
    Próbowałeś podkręcić procesor np. do 20MHz?

    Zanim o tym pomyślę wolałbym raczej przyspieszyć działanie programu.
    Spróbuję np. pozamieniać niektóre mnożenia na przesunięcia bitowe lub zmniejszyć liczbę operacji na liczbach zmiennoprzecinkowych. Algorytmy rysowania linii i stawiania punktu w buforze chcę oprzeć na asemblerze (zamiast bascomowych komend Line czy Pset napisałem własne).

    Co do samego podkręcania to nie wiem czy zewnętrzny RAM nadąży.
    Zauważam też sporadyczne niestabilności w działaniu programu czyli pojawiające się "krzaki" na wyświetlaczu (w miejscach z tekstem) lub autoreset (rzadziej).
    Wydaje mi się, że może mieć to związek z monitorem i szumami zasilania.
    Przy zasilaniu bateryjnym to nie występuje.

  • #41 15 Sie 2011 22:34
    leonow32

    Poziom 29  

    Jeżeli procesor Ci się resetuje to przy każdym starcie programu dobrze jest odczytać rejestr MCUCSR gdzie jest zapisane źródło ostatniego sygnału reset. Po odczytaniu należy ten rejestr wyzerować (patrz dokumentacja str. 54). Jeżeli procesor się resetuje, a w MCUCSR nie jest niż zapisane, wówczas nastąpił skok do adresu zero.

  • #42 19 Sie 2011 17:46
    ikko
    Poziom 11  

    michalko12 napisał:
    W tym przypadku buforować wystarczy tylko okno z grafiką co spowoduje mniejsze zapotrzebowanie na RAM i znacznie ograniczy potrzebny czas na wygenerowanie takiego ekranu i jego wyświetlenie.

    Zrobiłem dodatkowy bufor na okno z renderowanym modelem (wymiary: 120x120). Wciągnąłem go do wewnętrznego RAMu co trochę przyspieszyło rysowanie. Prędkość samego odświeżania takiego buforka wynosi 37 FPS.

    sweter_007 napisał:
    Przygotowując macierz XYZ używamy 16 mnożeń oraz 9 mnożeń na każdy punkt.

    Można zejść nawet to 7 mnożeń na punkt. W projekcie nie wykorzystuję jednak rotacji wokół 3 osi. Modele takie jak domki, meble lub zwierzątka nie wyglądałyby zbyt korzystnie obrócone do góry nogami, dlatego ostatecznie obracam obiekty wokół jednej osi. Do tego wystarczają 3 mnożenia. Przyspieszyło mi to obliczenia o 230%.

    leonow32 napisał:
    Jeżeli procesor Ci się resetuje to przy każdym starcie programu dobrze jest odczytać rejestr MCUCSR gdzie jest zapisane źródło ostatniego sygnału reset.

    Dopisałem pułapkę wskazującą źródło resetu za pomocą diod LED. Przyda się.

  • #43 08 Gru 2011 15:22
    ADI-mistrzu
    Poziom 30  

    Jak wygląda obecna praca nad projektem?

  • #44 10 Gru 2011 13:07
    ikko
    Poziom 11  

    ADI-mistrzu napisał:
    Jak wygląda obecna praca nad projektem?

    Równolegle do tego projektu pracowałem nad czymś innym. Tytułowy projekt uśpiłem po osiągnięciu zadowalającej mnie płynności.
    Programowanie tej konstrukcji wiele mnie nauczyło i zamierzam wykorzystać część tej wiedzy w przyszłych projektach.

    Stworzyłem listę możliwych modyfikacji ale nie zainspirowały mnie jeszcze na tyle bym którąś wybrał.
    Wymienię niektóre.

    Renderowanie każdej klatki z pierwszego obrotu modelu do pliku BMP, zapisywanie jej na karcie pamięci i późniejsze odtwarzanie animacji w pętli z serii plików BMP. Podobną (szybszą) opcją miało być wczytywanie całej animacji z plików BMP do pamięci RAM i jej odtwarzanie z RAMu.
    Po wstępnych próbach porzuciłem pomysł. Małym obiektom to tylko przeszkodziło a te duże nie przyspieszyły znacznie.

    Przełożenie całości na język C. Mam zamiar w przyszłości przepisać całość w języku C i porównać wydajność i wielkość kodu (gdy wystarczająco dobrze opanuję ten język).

    Prosta gra 3D z wieloma modelami jednocześnie.

    Narzędzie do modelowania 3D z podstawowych obiektów z możliwością zapisu modelu końcowego jako plik OBJ (najbardziej mnie kusi właśnie ten modeler).


    Gdybym miał...
    Interesują mnie przeróżne algorytmy graficzne i przetwarzanie obrazu.
    Poimplementowałbym sobie teksturowanie, cieniowanie, antyaliasing, wykrywanie krawędzi itp.
    Niestety widzę tu ograniczenia ze strony wyświetlacza monochromatcznego.
    Może kiedyś stworzę podobną platformę graficzną z wyświetlaczem kolorowym i czymś szybszym od 16MHz (jakiś ARM).

  • #45 10 Gru 2011 14:03
    jacynka84
    Poziom 26  

    Najnowszy Bascom obsługuje również xmega z mniejszą ilością pinów, przez co łatwiejsze jest lutowanie, a xmege też możesz w bascom opisać, ale działa nawet na 42Mhz z takim Lcd jak twój, czemu się nie przesiądziesz ?? Tyle mocy :))
    I do tego sprzętowa szyna na SDRAM, mam takie kostki KM616 co do 50Mhz chyba mogą chodzić, spróbuj czegoś takiego.