Skocz do zawartości

Grafiki w png i jpg - wielkość kontra szybkość


hgter

Rekomendowane odpowiedzi

Witajcie

 

<AKTUALIZACJA>Działa wariant, w którym stworzyłem oddzielny sprite dla każdego zdjęcia i dałem do oddzielnego texture group. I ram pozostaje mały a zdjęcia przełączają się dużo szybciej. Jedyną wadą jest olbrzymi plik wynikowy.

W związku z tym problem kompresji staje się kluczowy. Jak zmniejszyć sprity na dysku? Czy one musza być zapisywane w png? Czy to nie może być jpg? A jeżeli nie to w jaki sposób sprawić aby były tak małe jak jpg?</AKTUALIZACJA>

 

 

<AKTUALIZACJA2>Jeszcze na to muszę spojrzeć: http://gmc.yoyogames.com/index.php?showtopic=669935. Ktoś może korzystał?</AKTUALIZACJA2>

 

 

<AKTUALIZACJA3>To jest po prostu śmieszne. Ok zmniejszyłem rozmiar przez jakąś stronę. Plik png ma 947kb. Podmieniam w GM (przez nadpisanie w katalogu). Po kompilacji plik zwiększa swój rozmiar do 1348kb. Ten sam plik w lepszej jakości w jpg ma 265kb czyli jest 5 razy mniejszy tyle, że przeklęte add_sprite jest za wolne (i zużywa masę ramu). Serio poradźcie coś.<AKTUALIZACJA3>

 

 

 

Z góry uprzedzam, że moja wiedza odnośnie kwestii związanych z pytaniem jest mała, więc z wdzięcznością przyjmę krytykę.

 

W projekcie na androida, którym się teraz bawię mam mieć dużo grafik (zdjęć) w stosunkowo dużej rozdzielczości: 1720x1080.

Miałem je w png i początkowo dodawałem je po prostu jako sprity. Tylko jak łatwo się domyślić wielkość apk nie była fajna.

Przekonwertowałem je do jpg (jakość wyszła super a wielkość parę razy spadła), ale po dodaniu jako sprite GM i tak konwertował je do wielgaśnych png.

W kolejnym podejściu dodałem je w Included Files jako jpg i ładuję sobie przez sprite_add.

I było fajnie. Apk jest mały, zdjęcia się wczytują. Tyle, że teraz pracując dalej wyszło, że chciałbym w miarę szybko zmieniać zmieniać zdjęcia wyświetlone na ekranie. I tu pojawił się kłopot. Bo sprite_add okazało się bardzo wolne.

 

Da się je jakoś przyspieszyć?

 

Mogę sobie oczywiście na początku wczytać w pętli wszystkie grafiki do pamięci, ale wtedy wychodzi mi na oko 16mb na zdjęcie po wczytaniu (jak rozumiem GM wpycha moje zdjęcia wtedy każde do oddzielnego texture pages?).

 

Gdzieś wyczytałem, że można kompresować png trzymane przez GM w katalogu sprites. Czy to może mi pomóc? Jak będzie wyglądały kwestie prędkości, wielkości w apk i wielkości w ramie? Początkowo uznałem, że mi nic nie da bo GM przechowuje spirty w formie rozpakowanej w pamięci czyli w moim przypadku na każdy sprite pójdzie oddzielne texture pages ile by nie zajmowały na dysku. Ale teraz zastanawiam się jak GM decyduje, które Texture Group wczytuje. Czy jedynym kryterium jest przypisanie do targetu i GM wczyta zawsze wszystkie Texture Group czy można jakoś je aktywować i deaktywować np. między roomami? Bo może jeżeli da się nie załadowywać tylko część Texture Group to może przełączania między nimi będzie szybsze niż sprite_add?

 

 

Jeżeli da się coś tu ugrać to czy znacie jakieś sensowne narzędzia do kompresji tych png? Bo spróbowałem jakiegoś stratnego z netu (na stronie) i co prawda png jest mały, ale jakość jest śmieszna.

 

 

I jeszcze jedno pytanie:

sprite_add wydaje się nie przejmować ustawieniami wielkości texture pages. Bo zmieniłem sobie testowo na 1024x1024 i po wczytaniu przez sprite_add mojego zdjęcia w debugerze i tak mam je w texture page 2048x2048 (myślałem, że je przeskaluje).

 

Czy da się jakoś prosto wczytać plik jpg w Include File, ale do przeskalowanej wielkości i żeby GM przechowywał je na jednej texture page?

 

Bo obejście to mogę jakoś napisać: narysuję do surface o wymiarach texture page kilka przeskalowanych spritów jeden obok drugiego i zrzucę surface do sprita a potem będę rysował odpowiedni kawałek. Wychodzi mi, że jak użyję skali 0.55 to mi wejdzie 6 na jedną texture page 2048x2048. Już się nie mogę doczekać błędów przy pisaniu.

Odnośnik do komentarza
Udostępnij na innych stronach

Ciężko o jednolitą odpowiedź, ponieważ to pytanie na kilka frontów, ale postaram się pomóc:

Po wczytaniu do vRAM grafika zawsze będzie zajmować tyle samo. Różnice możesz tylko odczuć w ilości wygenerowanych texture page'y (oraz tego ile z nich jest wczytanych na raz do pamięci)

Korzystająć z wbudowanych rozwiązań, możesz zmniejszyć zużycie pamięci korzystając z draw_texture_flush, które wyrzuci z pamięci wszystkie wczytane tekstury. Wczytujesz je na nowo poprzez ich rysowanie, ale musisz pamiętać, że przed pierwszym rysowaniem może być chwila lagu na wczytanie zasobu, więc najlepiej wczytać taki zasób do surface na jakimś czarnym ekranie, zanim będzie w ogóle potrzebny.

 

CO do rozszerzenia które znalazłeś, z tego co mi wiadomo korzysta z niego Rock God Tycoon i jest bardzo wydajne, ale skomplikowane w użyciu. Jeżeli masz siły się z tym bawić to najprawdopodobniej najlepsze wyjście.

Odnośnik do komentarza
Udostępnij na innych stronach

Cześć.

Sytuacja wygląda tak. Grafiki wrzucone jako sprite i background będą wciśnięte na texturepages w GM. To też sprawia że żadna kompresja nie ma sensu ponieważ się ponownie kompresowane na texturepages. To też oznacza że przy wymiarach jakie podajesz każda grafika będzie na osobnym texturepages. To nie jest koniecznie złe rozwiązanie ale do tego wrócimy.

 

Wrzucanie grafik do included files i dodawanie ich przez sprite_add() sprawia że są dodawane jako osobne texturepages. Nie sprawdzałem nigdy ale możliwe jest że zachowują swoją kompresję... ale wręcz przeciwnie. Może GM musi re rozkompresować i wrzuca do pamięci jako nowy texturepages bez jakiejkolwiek kompresji... albo kompresuje swoim sposobem i dlatego jest to wolne.

Przy tym sposobie musisz umiejętnie operować na tych plikach. Wczytywanie ich i usuwanie ich za każdym razem gdy są potrzebne jest głupie powinny być wczytywane zanim będą potrzebne a usuwane gdy już na pewno nie będą potrzebne.

 

Ale wróćmy do domyślnego wrzucania grafik do sprite. GM zadba o to aby były zapisane w wygodny dla niego sposób i skompresuje je (słabo ale jednak). Nie pamiętam czy wszystkie zostają wczytane na początku gry, ale na pewno są wczytywane przy próbie ich użycia.

W GM Mamy dostępną funkcję draw_texture_flush() która usuwa z pamięci wszystkie texturepages. Ponowne użycie jakiejś sprawia jej natychmiastowe wczytanie. W ten sposób możesz kontrolować ich wczytywanie.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Kompresja tekstur w GMS2 ma przyjśc - ale w pamięci VRAM zawsze będzie to 32 bitowa grafika ARGB lub RGBA i nic na to nie poradzisz - to tak działa i już. Nie opłaca się zatem wrzucać do gry JPGów - zresztą GMS2 czy GMS1 i tak zapisują wszystko jako PNG.

Odnośnik do komentarza
Udostępnij na innych stronach

Ciężko o jednolitą odpowiedź, ponieważ to pytanie na kilka frontów, ale postaram się pomóc:

Po wczytaniu do vRAM grafika zawsze będzie zajmować tyle samo. Różnice możesz tylko odczuć w ilości wygenerowanych texture page'y (oraz tego ile z nich jest wczytanych na raz do pamięci)

Tak podejrzewałem.

 

CO do rozszerzenia które znalazłeś, z tego co mi wiadomo korzysta z niego Rock God Tycoon i jest bardzo wydajne, ale skomplikowane w użyciu. Jeżeli masz siły się z tym bawić to najprawdopodobniej najlepsze wyjście.

Teoretycznie nauka tego do prościutkiej gierki nie wygląda opłacalnie, ale jeżeli nie obejdę problemu inaczej może spróbuję - warto chyba znać na przyszłość.

 

 

Ale wróćmy do domyślnego wrzucania grafik do sprite. GM zadba o to aby były zapisane w wygodny dla niego sposób i skompresuje je (słabo ale jednak).

W związku z tym muszę jeszcze sprawdzić jak GM radzi sobie z wczytaniem przez add_sprite plików png, które utworzył sam. Bo jeżeli jest to szybsze niż jpg to może warto rozważyć rozwiązanie, w którym przy pierwszym uruchomieniu wczytuję wszystkie jpg jeden po drugim i zapisuję je na dysku przez save sprite. I potem korzystam z nich przez add_sprite. W ten sposób, co prawda gra będzie zajmowała sporo miejsca na dysku po instalacji, ale apk będzie mały. Czy jest jakiś sposób żeby sprawdzić ile wolnego miejsca ma użytkownik pod androidem? W razie problemu to też obejdę próbując najpierw zapisać coś większego niż sprity po "rozpakowaniu" i jeżeli się uda to dopiero puszę save_sprite.

 

Nie pamiętam czy wszystkie zostają wczytane na początku gry, ale na pewno są wczytywane przy próbie ich użycia.

 

Raczej tylko przy próbie bo w debugerze po pamięci było widać, że nie wczytał wszystkich spritów naraz.

 

Kompresja tekstur w GMS2 ma przyjśc - ale w pamięci VRAM zawsze będzie to 32 bitowa grafika ARGB lub RGBA i nic na to nie poradzisz - to tak działa i już. Nie opłaca się zatem wrzucać do gry JPGów - zresztą GMS2 czy GMS1 i tak zapisują wszystko jako PNG.

 

Nie opłaca się dawać jako sprity bo je przekonwertuje do png i tak. Ale jako include files już się opłaca o ile rozwiążę kwestię szybkości działania. Bo apk będzie 5 razy mniejszy nawet.

 

Ok. Mam trzy możliwe rozwiązania poza dodaniem zdjęć jako zwykłych sprites w edytorze:

 

1) Wczytać wszystko do pamięci (ponieważ w miejscu, gdzie potrzebuję szybkiego wczytywania mogę być niższej jakości to uda mi się przez surface wepchnąć 6 na jedną texture page)

 

2) Rozpakować jpg do png przy pierwszym uruchomieniu o ile ich wczytywanie jest szybsze.

 

3) Spróbować z rozszerzeniem.

 

 

Dzięki za wszelkie info.

Odnośnik do komentarza
Udostępnij na innych stronach

W HTML5 masz. Może dodatkowo jakby podmienić pngcrush na optipng to się zaoszczędzi więcej

 

Na początku pomyślałem, że to ciekawe info, ale u mnie nic nie zmienia bo mi zależy na androidzie. Ale tak się teraz zastanawiam jaka jest struktura apk od GM. Muszę sprawdzić wieczorem. Ciekawe czy podmieniając assety w apk całość się uruchomi.

Odnośnik do komentarza
Udostępnij na innych stronach

Dam Ci jeszcze jedno rozwiązanie: sprite_add() pozwala na pytanie URL do grafiki. Wtedy pobiera ja z internetu. Oczywiście trzeba pobieranie obsłużyć i sprawdzić czy się pobrało i użytkownik musi mieć internet, ale jest to jakieś rozwiązanie.

Odnośnik do komentarza
Udostępnij na innych stronach

Dam Ci jeszcze jedno rozwiązanie: sprite_add() pozwala na pytanie URL do grafiki. Wtedy pobiera ja z internetu. Oczywiście trzeba pobieranie obsłużyć i sprawdzić czy się pobrało i użytkownik musi mieć internet, ale jest to jakieś rozwiązanie.

 

O, to bardzo fajne info. Dzięki.

Odnośnik do komentarza
Udostępnij na innych stronach

Nie wiem co tam masz za grafiki, ale w wielu przypadkach PNG < JPG - oczywiście mowa o JPG o zadowalającej jakości (80-90%).

 

Ogólnie bardzo się lubię z png, ale akurat tutaj niestety mam zdjęcia. I różnica zarówno w jakości jak i wielkości jest na korzyść jpg wyraźnie.

 

Co do problemu:

Na chwilę obecną rozwiązanie z użyciem texture page z wepchniętymi 6 pomniejszonymi zdjęciami na każdą, działa całkiem zadowalająco. Apk jest małe dzięki jpg w Include Files, działa znośnie pod względem szybkości a zużycie ramu jest akceptowalne póki co.

 

W dalszej perspektywie będę jeszcze pewnie bawił się tym rozszerzeniem, ale do tego projektu raczej odpuszczę.

 

Dzięki za wszystkie rady.

Odnośnik do komentarza
Udostępnij na innych stronach

Ogólnie bardzo się lubię z png, ale akurat tutaj niestety mam zdjęcia. I różnica zarówno w jakości jak i wielkości jest na korzyść jpg wyraźnie.

 

A PNG nie jest czasem bezstratne? Chyba, że mówimy o kompromisie między PNG, a JPG

 

Fervi

Odnośnik do komentarza
Udostępnij na innych stronach

A PNG nie jest czasem bezstratne? Chyba, że mówimy o kompromisie między PNG, a JPG

 

Rzeczywiście png powinno być bezstratne.

 

Natomiast na próbę korzystałem z https://tinypng.com/ i z tego co tam piszą to jednak robią to stratnie (przynajmniej oni). I efekt był różny - czasem okropny.

 

Gdy korzystałem z narzędzi lokalnych (PNGGauntlet i pngcrush) jakość była ok, ale pliki duże (w porównaniu do jpeg). Zresztą tak czy siak po kompilacji GM przekształcał je po swojemu i były jeszcze większe.

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

Rzeczywiście png powinno być bezstratne.

 

Natomiast na próbę korzystałem z https://tinypng.com/ i z tego co tam piszą to jednak robią to stratnie (przynajmniej oni). I efekt był różny - czasem okropny.

 

Gdy korzystałem z narzędzi lokalnych (PNGGauntlet i pngcrush) jakość była ok, ale pliki duże (w porównaniu do jpeg). Zresztą tak czy siak po kompilacji GM przekształcał je po swojemu i były jeszcze większe.

 

Wiem, ale spróbuj podmienić plik wykonywalny optipng na pngcrush. Może łyknie to GM i będą pliki wynikowe mniejsze

 

Fervi

Odnośnik do komentarza
Udostępnij na innych stronach

Wiem, ale spróbuj podmienić plik wykonywalny optipng na pngcrush. Może łyknie to GM i będą pliki wynikowe mniejsze

 

Nie wiem co masz na myśli. Próbowałem oba te narzędzia (PNGGauntlet wykorzystuje optipng). Brałem pliki png z folderu sprites i je kompresowałem. Po kompilacji ich wielkość rosła (choć nie tak bardzo jakby były tylko w GM obrabiane).

 

Patrzyłem też jak wygląda wnętrze apk w przypadku gm. Pliki z Include Files leżą sobie luzem w katalogu assets. Natomiast cała gra jest zawarta w jednym oddzielnym pliku "game.droid".

 

Myślałem, że nie za bardzo da się do tego dobrać. I tu czekała mnie 3 godzinna przygoda. Opisałem ją oddzielnie tutaj: https://forum.gmclan.org/index.php?showtopic=33346

 

 

Ale tak czy siak nie udało mi się na chwilę obecną znaleźć prostego sposobu na podmianę grafik w apk i exe już po kompilacji - to raczej jest możliwe, ale przekracza moje umiejętności.

Odnośnik do komentarza
Udostępnij na innych stronach

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ę
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...