Skocz do zawartości

Optymalizacja wyświetlania dużej liczby obiektów


hgter

Rekomendowane odpowiedzi

Witajcie

 

Wybaczcie długi wstęp, ale po pierwsze chcę, aby było wiadomo skąd się bierze wszystko to z czym jest kłopot, a po drugie może robię coś niepotrzebnie a da się dużo prościej:

 

 

 

Pracuję nad prościutką gierką zręcznościową, w której będzie bardzo dużo poziomów (znaczy w teorii:). Całość wykorzystuje fizykę.

 

Do projektowania poziomów wstępnie użyłem standardowej metody. Czyli z pomocą rozciąganych obiektów tworzę szkielet poziomu (ściany, platformy itp.), a w drugim etapie ręcznie pokrywam te rozciągnięte obiekty ładnymi tilesami. I to działa. Obiektów jest mało i całość chodzi szybko.

 

ALE

 

Poziomów ma być dużo i niespecjalnie miło widzę to całe ręczne pokrywanie szkieletu. Chciałbym żeby obiekty (wstępnie w formie trójkątów prostokątnych) same pokrywały się grafiką, ale z zachowaniem tego, że są skalowane i obracane. Robię to tak: mam duży plik z tłem (wielkości okna) z jakąś tam teksturą. Etap wyliczania wierzchołków każdego obiektu z uwzględnieniem skalowania i obrotu poszedł bez problemu. Następnie wykorzystując Primitives (tilesów nie, bo tam może być chyba tylko kwadratowy fragment?) wyświetlam odpowiednie fragmenty tekstury w miejscu obiektu. Mógłbym to tak zostawić bo w sumie już działa. Ale chciałbym mieć możliwość stworzenia tych obiektów bardzo dużo. Czyli chciałbym mieć ciastko i zjeść ciastko: "samotailsujące" się obiekty, których może być bardzo dużo.

 

Wymyśliłem tak: niech każda instancja obiektu na początku przekazuje wyliczone własne trzy wierzchołki do zbiorczej tablicy a potem sama się usuwa. I to też działa (na chwilę obecną zajmuję się tylko wyświetleniem, ale dla fizyki zrobię podobnie, też przypiszę wiele fixtures do jednego obiektu). Uzyskuję jeden obiekt, który ma zarządzać wyświetlaniem. Ale tu pojawia się problem. Póki instancji trójkątów jest mało to całość działa, ale jak zwiększyłem ich ilość to po przekroczeniu pewnej granicy (dokładnie 333) wywala się wyświetlanie wszystkiego. Mam artefakty, inne obiekty niezależne się wyświetlają źle albo zupełnie nie. Robię to tak:

 

Ten kod wrzucony jest bezpośrednio w draw obiektu zarządzającego:

 

GML
draw_set_colour(c_white);

var tex = background_get_texture(tlo);

draw_primitive_begin_texture(pr_trianglelist, tex);

for (licz1 = 0; licz1 < global.ilosc_tiles; licz1 += 1)

{

c_x=global.tiles[licz1,1]

c_y=global.tiles[licz1,2]

w1_x=global.tiles[licz1,3]

w1_y=global.tiles[licz1,4]

w2_x=global.tiles[licz1,5]

w2_y=global.tiles[licz1,6]

draw_vertex_texture(c_x, c_y, c_x/1920, c_y/1200);

draw_vertex_texture(w1_x, w1_y, w1_x/1920, w1_y/1200);

draw_vertex_texture(w2_x, w2_y, w2_x/1920, w2_y/1200);

 

}

draw_primitive_end();

 

Tablica global.tiles przechowuje wcześniej wyliczone wierzchołki wszystkich obiektów.

 

 

Jak rozumiem jeżeli obiektów jest więcej niż 333 to kod w draw nie daje rady się wykonać? Zdaję sobie sprawę, że każdorazowe liczenie tego primitywu składającego się z tylu trójkątów jest głupotą - tym bardziej, że nic się nie zmienia. To są nieruchome obiekty czyli wystarczyłoby tylko raz opracować i potem wyświetlać. Tylko jak? Jak zrobić coś takiego:

 

zbiorczy_prymityw=blablabla

 

i w draw tylko:

 

GML
draw(zbiorczy_prymityw)

 

 

Będę zobowiązany za wskazówki.

 

PS Nie wiem czy to będzie istotne, ale ponieważ gra ma być na androida to mam application_surface_enable(false) - sam sobie zarządzam skalowaniem

 

 

PPS Walcząc z tym problemem póki co rozwiązałem to tak, że stworzyłem dwa zbiorcze obiekty. Jeden wyświetla tekstury dla instancji 1-300 a drugi 300-600 (można dodać kolejne) i to działa ok. Ale to straszna prowizorka - poza tym nadal jest bez sensu że w każdym stepie od zera rysuję całą scenę zamiast tylko wyświetlić wcześniej stworzoną. Ehh liczę na Was bo nie wiem jak to ugryźć a ta metoda ma sens. Przyrost wydajności w porównaniu do wyświetlania się każdego obiektu oddzielnie jest mniej więcej czterokrotny.

 

 

 

PPPS Kurde tak podejrzewałem, że surface będzie rozwiązaniem: http://forums.tigsource.com/index.php?topic=7441.0 (post 3).

 

 

ROZWIĄZANIE:

 

Mimo application_surface_enable(false) daje się wyświetlić stworzony surface (myślałem, że się wywali dlatego nie szedłem w tym kierunku).

 

Co ciekawe limit 333 instancji pozostał. Myślę, że to chodzi o to, że mam 3 punkty na każdą z 333 instancji czyli primitives może się składać z max 1000 punktów - ale nie mogę tego potwierdzić nigdzie. W każdym razie muszę tworzyć więcej primitives niż 1 jeżeli mam więcej obiektów niż 333. I o dziwo działa a wydajność na androidzie jest kosmiczna - kolejne 4-5 razy w porównaniu do rozwiązania z dwoma kontrolnymi obiektami (a na pc znowu odwrotnie - ale może to jakiś artefakt). Czyli ponad 16x! lepiej niż jeżeli po prostu wyświetlam primitives w każdej instancji oddzielnie! Jedyny problem jest na androidzie bo zablokowaniu i odblokowaniu ekranu moja piękna surface znika. Ale to pewnie do rozwiązania jest.

 

W sumie ponieważ sam sobie rozwiązałem problem (nadal po partyzancku, ale działa) to chyba powinienem usunąć cały wątek? Ale może komuś się przyda?

 

Używaj tagów [ gml ], aby kod był czytelny - Uzjel

Odnośnik do komentarza
Udostępnij na innych stronach

Nie jestem do konca pewien o co pytasz, ale z opisu wydaje mi sie, ze pomoze zaimplementowanie gotowego juz rozwiazania(ktore, co ciekawe, pojawilo sie w shotuboxie doslownie dzien temu)

http://gmc.yoyogames.com/index.php?showtopic=642829

Odnośnik do komentarza
Udostępnij na innych stronach

Dzięki, widziałem to wtedy:) - ale jednak chciałem mieć swoje rozwiązanie.

 

Fajnie to tam wyszło. Jest to mocno rozbudowane, bo u mnie tylko obiekty o stale zdefiniowanym kształcie są wypełniane teksturą, ale można je dowolnie skalować i obracać na etapie tworzenia poziomu.

 

Chodzi o to aby łatwo można było budować z klocków levele z ich automatycznym teksturowaniem. Reszta to tylko kwestia tego, że chciałem mieć możliwość użycia dużej ilości różnych obiektów przy zachowaniu znośnej wydajności.

 

Sorry, że niezrozumiale to opisałem.

 

PS Dzięki Uzjelu za poprawę formatowania kodu w poście - będę tak robił.

 

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ę...