Autor Wątek: Ogromny terrain - jak wczytywać / traktować dane?  (Przeczytany 2261 razy)

Offline Montjet

  • Użytkownik

# Wrzesień 09, 2015, 15:04:17
Powoli przybieram się do programowania terenu.
Zastanawiam się jak go renderować -

1. Wczytać całą mapę (ogromna) - czy nie jest to szalony pomysł?
     lub
2. Renderować ograniczoną przestrzeń, tak by kamera zawsze była na środku tej przestrzeni - a wysokości mapy przesuwać wzg. kolejnych wierzchołków terenu?*

* Tylko jak takie coś uzyskać?
Użyć zmienne jednorodne?
A może na nowo aktualizować wysyłane do shader'a wierzchołki? -
glBindBuffer(GL_ARRAY_BUFFER, Mesh::Buffers[Mesh::POSITION_VB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Positions[0]) * Positions.size(), &Positions[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(POSITION_LOCATION);
glVertexAttribPointer(POSITION_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, 0);
Albo jeszcze inaczej?
Ważne dla mnie są FPS'y.

ps.
Mapa będzie rozrastała się wraz z aktualizacjami - nowe lokacje etc.
Dodatkowo użyję teselacji do zwiększania szczegółowości terenu wokół kamery.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline timus

  • Użytkownik

  • +1
# Wrzesień 09, 2015, 15:40:45
Najprościej podzielić teren na chunk'i o określonej wielkości np. 100x100 jednostek + do pamięci wczytywać teren o wielkości np. 9x9 chunk'ów względem kamery + renderować tylko chunk'ie widoczne przez kamerę + LOD'owanie dalszych chunk'ów terenu.

Offline Kos

  • Użytkownik
    • kos.gd

  • +1
# Wrzesień 09, 2015, 16:12:52
1. Wczytać całą mapę (ogromna) - czy nie jest to szalony pomysł?

A ile waży cała mapa? Albo się mieści cała w pamięci (wtedy niezbyt szalony) albo się nie mieści (wtedy to żaden pomysł :)).

Offline Montjet

  • Użytkownik

# Wrzesień 09, 2015, 16:29:31
@Kos
Tego jeszcze nie wiem, bo ta mapa jeszcze nie istnieje - po prostu taką mam wizję, powiedzmy coś jak w Skyrim.

@timus
W sumie to by chyba przeszło - przy ładowaniu danych mógłbym kontrolować liczbę FPS (tak by wczytywały się dane po kawałku).

Offline deadeye

  • Użytkownik

  • +2
# Wrzesień 09, 2015, 20:04:34
przy ładowaniu danych mógłbym kontrolować liczbę FPS (tak by wczytywały się dane po kawałku).
ty chyba mylisz wczytywanie danych z wyświetlaniem? możesz wczytać np kilkaset chunków, ale fps powinieneś kontrolować przez wyświetlanie albo ukrywanie odległych chunków, w pamięci wciąż je możesz trzymać.

Offline CheshireCat

  • Użytkownik

  • +1
# Wrzesień 09, 2015, 22:01:01
Renderować ograniczoną przestrzeń, tak by kamera zawsze była na środku tej przestrzeni - a wysokości mapy przesuwać wzg. kolejnych wierzchołków terenu?*

Jeżeli teren jest funkcyjny a wysokości reprezentujesz na równoodległej siatce, to pewnie możesz tak to rozwiązać.

Proponuję drzewo czwórkowe chunków terenu o eksperymentalnie dobranym rozmiarze.

Offline JasonVoorhees

  • Użytkownik
    • The Immortal Life of the Son of Jay

  • +2
# Wrzesień 10, 2015, 11:11:01
A ile waży cała mapa? Albo się mieści cała w pamięci (wtedy niezbyt szalony) albo się nie mieści (wtedy to żaden pomysł :)).
Takie podejście mieli twórcy Carmageddon Reincarnation. Poziom się ładuje bardzo długo do pamięci... Dopiero jak proces z grą zajmuje ~2GB, trasa się pokazuje. Pewnie na szybszym dysku szybciej wszystko by się ładowało. Ale w stosunku do poprzednich części Carmageddona, przegięli ;)

Offline Montjet

  • Użytkownik

# Wrzesień 10, 2015, 12:44:53
Dobra, jeszcze jedno pytanko: Jak renderować trójkąty?
GL_TRANGLE_STRIP - Najpierw wyrenderować kolumnę, odciąć i znowu renderować kolejną kolumnę (nie będą miały połączenia ze sobą kolumny)?
Czy może stworzyć indeksy? (pseudokod):
for(i < width - 1)
for(j < height - 1)
// 1'st triangle:
triangle[2*(i + j * (width))] = { i + j * (width), // 1'st vert
i + (j + 1) * (width), // 2'nd vert
i + 1 + (j + 1) * (width) // 3'rd vert
    };
// 2'nd triangle:
triangle[2*(i + j * (width)) + 1] = { i + j * (width) + 1, // 1'st vert
i + (j + 1) * (width), // 2'nd vert
i + 1 + (j + 1) * (width) // 3'rd vert
    };

#edit
Wyznaję ideę - kto pyta, ten nie błądzi - także sorki jeśli pytania wydają się błahe.

Offline Oti

  • Użytkownik

  • +1
# Wrzesień 10, 2015, 14:26:15
Ważne są dwie rzeczy-aby wierzchołków było jak najmniej(karta ma mniej liczenia) i aby draw calli było jak najmniej(żeby rzadziej 'przeszkadzać' karcie graficznej przez przesyłanie do niej danych z zasobów procesora). Z tych powodów wydaje mi się, że najlepsze jest renderowanie indeksowanych trójkątów-wierzchołków masz minimium, bo dokładnie tyle ile potrzeba, żaden nie musi być zduplikowany.

Triangle strip ma tę wadę, że część wierzchołków jest duplikowanych i dodatkowo masz masę draw calli(chyba, że jakoś sprytnie posortujesz wierzchołki, żeby zachować ciągłość, ale nie przychodzi mi do głowy dobry pomysł na to, ale to i tak nie rozwiązuje problemu duplikacji wierzchołków).
« Ostatnia zmiana: Wrzesień 10, 2015, 14:29:11 wysłana przez Oti »

Offline Krzysiek K.

  • Moderator
    • DevKK.net

  • +1
# Wrzesień 10, 2015, 15:27:05
Cytuj
Czy może stworzyć indeksy?
Ja bym polecał indeksy. Raz, że sporo to ułatwia przy LOD (możesz wyświetlać niepełnego quada i poprawiać połączenia), a dwa, że możesz później zoptymalizować kolejność bez zmiany całego kodu.

Cytuj
Triangle strip ma tę wadę, że część wierzchołków jest duplikowanych i dodatkowo masz masę draw calli(chyba, że jakoś sprytnie posortujesz wierzchołki, żeby zachować ciągłość, ale nie przychodzi mi do głowy dobry pomysł na to, ale to i tak nie rozwiązuje problemu duplikacji wierzchołków).
Triangle strip nie wyklucza indeksów. Do tego w nowszych API indeksowany triangle strip pozwala na rysowanie dowolnie wielu osobnych triangle stripów jednym draw callem (primitive restart).