Uzjel Opublikowano 12 Listopada 2016 Opublikowano 12 Listopada 2016 Hej. Wyświetlam na ekranie sporo instancji, każda składa się z maksymalnie sześciu grafik. Przy mapie 25x25 daje to 3750 wywołań draw. Nie mogę pozwolić na dezaktywacja instancji. Jakieś pomysły/dobre rady?
candy Opublikowano 12 Listopada 2016 Opublikowano 12 Listopada 2016 A możesz wrzucić jakiś obrazek jak to wygląda. Tak będzie nam łatwiej coś wymyślić.
Fervi_ Opublikowano 12 Listopada 2016 Opublikowano 12 Listopada 2016 Hej. Wyświetlam na ekranie sporo instancji, każda składa się z maksymalnie sześciu grafik. Przy mapie 25x25 daje to 3750 wywołań draw. Nie mogę pozwolić na dezaktywacja instancji. Jakieś pomysły/dobre rady? Nie wywołuj draw, problem solved xd Fervi Gdyby wywoływać draw co 2 klatkę to by robił przerwę czy zostawiał starego drawa?
I am Lord Opublikowano 12 Listopada 2016 Opublikowano 12 Listopada 2016 Hmmm może wyłączyć automatyczny draw, i rysować tylko te instancje które zmieniają swoją animację. I to na surface oczywiście.
Ignatus Opublikowano 12 Listopada 2016 Opublikowano 12 Listopada 2016 Pytanie z punktu widzenia amatora totalnego(zapewne głupie)- po co w ogóle używać draw do wyświetlania grafik instancji?Nie lepiej przypisać jej sprite i potem podmieniać
Fervi_ Opublikowano 12 Listopada 2016 Opublikowano 12 Listopada 2016 Pytanie z punktu widzenia amatora totalnego(zapewne głupie)- po co w ogóle używać draw do wyświetlania grafik instancji?Nie lepiej przypisać jej sprite i potem podmieniać Nie działa jeśli obiekt rysuje coś po evencie draw. Wtedy sprite nie jest wyświetlany, bo nawet nie wiem czemu xd Fervi
Ignatus Opublikowano 12 Listopada 2016 Opublikowano 12 Listopada 2016 To akurat rozumiem ale każdy obiekt musi coś rysować?Zawsze można wstawić jeden obiekt który będzie odpowiadać za event draw dla różnych obiektów (roboty z tym pewnie z miesiąc ale 1500 drawów nie będzie;p)
Exigo Opublikowano 12 Listopada 2016 Opublikowano 12 Listopada 2016 Pierwszy pomysł: Niewykluczone że Game Maker ma wbudowany sprite batching, więc można mu pomóc rysując wszystko "wszerz", a nie "w głąb". Szkopuł tkwi w tym, że obiekty nie mogą na siebie nachodzić (obiekty, nie sprite). Poniżej pseudokod który pokazuje jak rysujesz obecnie (dla porównania). for each object { draw sprite A draw sprite B draw sprite C } Poniżej pseudokod który może przyśpieszyć. for each object { draw sprite A } for each object { draw sprite B } for each object { draw sprite C } W pierwszym rozwiązaniu VBO resetuje się za każdym razem przed narysowaniem tekstury (zakładając że nie używasz atlasu tekstur), czyli masz 3750 draw calli. W drugim rozwiązaniu tekstura zmieniana jest jedynie tyle razy, ile masz tekstur (czyli wyjdzie coś koło ~kilkunastu draw calli). Nie mam benchmarka na potwierdzenie, ale w innych silnikach taka strategia działa, tylko że bardziej komplikuje kod (optymalizacje mają to do siebie że komplikują, kek). Drugi pomysł (nie wyklucza się z pierwszym): Jeśli obrazki nie są dynamiczne, możesz rysować planszę do surface i przerysowywać ją tylko wtedy, kiedy coś się na niej zmienia. Przełączanie bufora (surface_set_target i surface_reset_target) może mieć duży narzut, czyli nie możesz robić tego per obiekt w evencie draw, ale globalnie, raz na klatkę lub rzadziej (bo inaczej będą krótkie "przywieszki" podczas przerysowywania; będziesz miał 25x25 bind calli). Trzeci pomysł (też się nie wyklucza): napisz swój shader wycinając niepotrzebne rzeczy (np. z blending który jest podawany jako atrybut w defaultowym shaderze). Elo.
Uzjel Opublikowano 12 Listopada 2016 Autor Opublikowano 12 Listopada 2016 A możesz wrzucić jakiś obrazek jak to wygląda. Tak będzie nam łatwiej coś wymyślić. A surface'y? Mam złe doświadczenia z surfacami na Androidzie. Nie wiem jak jest teraz, ale pamiętam grę gnyska z czasów YoyoGames. Tam wszystko było robione na surfacach i widać było artefakty. Hmmm może wyłączyć automatyczny draw, i rysować tylko te instancje które zmieniają swoją animację. I to na surface oczywiście. Jak wyżej. Pytanie z punktu widzenia amatora totalnego(zapewne głupie)- po co w ogóle używać draw do wyświetlania grafik instancji?Nie lepiej przypisać jej sprite i potem podmieniać Jeżeli jedna instancja ma wyświetlać więcej grafik niż swoja własna :) Pierwszy pomysł: Niewykluczone że Game Maker ma wbudowany sprite batching, więc można mu pomóc rysując wszystko "wszerz", a nie "w głąb". Szkopuł tkwi w tym, że obiekty nie mogą na siebie nachodzić (obiekty, nie sprite). Poniżej pseudokod który pokazuje jak rysujesz obecnie (dla porównania). ... Dzięki exigo, zrobię testy. Szczególnie z optymalizacją atlasów. Spróbuję też z tilesetami. Największym kłopotem o którym wspomniałem jest Android.
Administratorzy gnysek Opublikowano 12 Listopada 2016 Administratorzy Opublikowano 12 Listopada 2016 1. tilesety ? 2. wszystkiemu dać visible = false i jako parenta objekt "drawable" i w tym jednym obiekcie: GML with(drawable) { draw_self(); }
Threef Opublikowano 13 Listopada 2016 Opublikowano 13 Listopada 2016 Ja bym tu zastosował 2 surface. Oba statyczne rysowane ponownie tylko w momencie zmian. Pierwsza zawierająca tła i wszystko nie animowane co jest rysowane pod grafikami wody. Drugi to wszytko nad. Możesz zrobić sobie jedna zmienną która sprawdza czy rysować od nowa czy używać wcześniej rysowanego surface. Pseudokod wyobrażam sobie tak: GML (create) surBackground=-4 surForeground=-4 doRedraw=true GML (step) if(jakis event ruchu w grze) { //jakies akcje doRedraw=true } GML (draw) if(!surface_exists(surBackground)) { surBackground=surface_create(512, 512) //2^n aby zapobiec glitchom } if(doRedraw=true) { surface_set_target(surBackground) for(var _x=0; _x<25; _x++) for(var _y=0; _y<25; _y++) { draw_sprite(tlo) draw_sprite(plecki) } surface_reset_target() } draw_surface(surBackground, 0, 0) draw_woda() if(!surface_exists(surForeground)) { surForeground=surface_create(512, 512) //2^n aby zapobiec glitchom } if(doRedraw=true) { surface_set_target(surForeground) for(var _x=0; _x<25; _x++) for(var _y=0; _y<25; _y++) { draw_sprite(blysk) draw_sprite(kontur) draw_sprite(kolor) } surface_reset_target() doRedraw=false } draw_surface(surForeground, 0, 0) Oczywiście przy tym każdy obiekt ma visible=false i rysowane jest wszystkie w tym jednym evencie. Wadą jest to że wciąż wykorzystuje to taką samą moc obliczeniową ale tylko w jednym momencie. Przez to może być czuć ten peak spadających FPS. Najgorzej jak będzie on w momencie odbioru inputu od gracza. Na przykład w czasie przeciągania.
I am vader Opublikowano 13 Listopada 2016 Opublikowano 13 Listopada 2016 Uzjel juz opisal sceptycyzm do surface'y. Poza tym to tymczasowe tekstury, moga zniknac z pamieci w kazdej chwili, np. po zminimalizowaniu gry.
Threef Opublikowano 13 Listopada 2016 Opublikowano 13 Listopada 2016 Wiec przyjrzyj się jak to działa. Tak jak powinno. Przy każdej próbie rysowania surface sprawdza czy on istnieje i go tworzy od nowa. Nie ma z tym żadnych problemów. Mam 2 gry które tak działają. Ale to jest optymalizacja FPS kosztem pamięci.
Administratorzy gnysek Opublikowano 14 Listopada 2016 Administratorzy Opublikowano 14 Listopada 2016 Ale na Androidzie surface działają chujowo.
Threef Opublikowano 14 Listopada 2016 Opublikowano 14 Listopada 2016 Ale na Androidzie surface działają chujowo. Zdarzyło mi się mieć tylko jeden przypadek na jednym telefonie. Gdy na surface rozmiaru chyba 128x32 próbowałem rysować przewijający się tekst. Gdy jakiś pixel rysował się na prawe krawędzi surface to nie był odpowiednio czyszczony i zostawiał ślady. draw_clear_alpha(0,0) nie pomagało. Ale pomogło zwiększenie rozmiaru surface do 256x32.
I am Lord Opublikowano 14 Listopada 2016 Opublikowano 14 Listopada 2016 ogolem to nie powinno sie robic prostokatnych no i rozmiar power of 2
Administratorzy gnysek Opublikowano 14 Listopada 2016 Administratorzy Opublikowano 14 Listopada 2016 Odpal application_surface to pogadamy o wydajności :)
Uzjel Opublikowano 14 Listopada 2016 Autor Opublikowano 14 Listopada 2016 Dziękuję wszystkim za odpowiedzi :) Na razie zoptymalizowałem atlasy, żeby zmniejszyć ilość texture swapów. Na początku na tej największe było prawie 2000 texture swapów swapów Pierwszym krokiem było wrzucenie do jednego atlasu wszystkich elementów rur i mapy Ilość swapów spadła do 300-400 Miałem jeszcze trzy przyciski na interfejsie które też dodałem do atlasu z rurami Ilość swapów spadła do 10-15, FPS się unormował ~40 na moim telefonie Pobawiłem się trochę w debugerze profilowaniem i znalazłem kilka słabych miejsc w stepie, co zmniejszyło ilość obliczeń Dopisałem też, żeby rury nie próbowały się rysować poza widzialnym obszarem co powinno przyspieszyć grę na wolnych telefonach, ale tylko w przypadku zooma
Administratorzy gnysek Opublikowano 14 Listopada 2016 Administratorzy Opublikowano 14 Listopada 2016 btw. z tego co widzę, gra powinna mieć raptem kilka spritów: - prosta rura - zakręcona rura - brzeg rury - pokrętło (białe) - kratkę (białą) - mieszacz (dwie klatki z tego co widzę) - pełny szary element Reszta powinna być rysowana za pomocą draw_sprite_ext z odpowiednim kolorem i obrotem. Jakby przerobić grę na tablicę, wystarczy jeden obiekt do zarządzania wszystkim (a więc i jeden event draw).
Uzjel Opublikowano 14 Listopada 2016 Autor Opublikowano 14 Listopada 2016 I tak jest, tylko że rura jest składana tak:
Threef Opublikowano 14 Listopada 2016 Opublikowano 14 Listopada 2016 W takim razie na prawdę miałeś chaos z tymi texture pages.
Uzjel Opublikowano 14 Listopada 2016 Autor Opublikowano 14 Listopada 2016 no tak, nic z nimi nigdy nie robiłem i grafiki rur były rozproszone w kilku/kilkunastu atlasach :)
Administratorzy gnysek Opublikowano 14 Listopada 2016 Administratorzy Opublikowano 14 Listopada 2016 Przecież takie grafiki co pokazałeś, to nie powinny zająć nawet pół jednej tekstury. Btw. z drugiej strony, jeśli kombinacji nie jest za wiele, szybciej może być jednak rysować gotowe sprite'y niż je nakładać, o ile zmieszczą się na jednej teksturze :)
I am Lord Opublikowano 14 Listopada 2016 Opublikowano 14 Listopada 2016 Pewnie animacja wody zapełnia atlas?
Administratorzy gnysek Opublikowano 16 Listopada 2016 Administratorzy Opublikowano 16 Listopada 2016 Musi tak być, bo te grafiki powyżej tego absolutnie nie zrobią.
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się