Dokumentacja Androida mówi:
Istnieją sytuacje, w których kontekst renderowania EGL zostanie utracony. Zwykle dzieje się tak, gdy urządzenie budzi się po zaśnięciu. Gdy kontekst EGL zostanie utracony, wszystkie zasoby OpenGL (takie jak tekstury), które są powiązane z tym kontekstem, zostaną automatycznie usunięte. Aby zapewnić prawidłowe renderowanie, renderer musi odtworzyć utracone zasoby, których nadal potrzebuje. Metoda onSurfaceCreated (GL10, EGLConfig) jest wygodnym miejscem do tego.
Jednak ponowne ładowanie wszystkich tekstur w kontekście OpenGL jest zarówno uciążliwe, jak i utrudnia użytkownikowi grę po ponownym uruchomieniu aplikacji po przerwie. Wiem, że „Angry Birds” jakoś tego unika, szukam sugestii, jak to zrobić?
Pracuję z Androidem NDK r5 (wersja CrystaX.) Znalazłem ten możliwy hack do problemu, ale staram się uniknąć budowania całej niestandardowej wersji SDK.
Odpowiedzi:
Wyspa repliki ma zmodyfikowaną wersję GLSurfaceView, która rozwiązuje ten problem (i działa z wcześniejszymi wersjami Androida). Według Chrisa Pruetta :
Edycja: Właśnie zdałem sobie sprawę, że opublikowałeś już link do podobnego hacka. Nie sądzę, aby istniało jakieś wbudowane rozwiązanie przed budową plastra miodu. Replica Island to popularna gra działająca na wielu urządzeniach i może okazać się pomocna w implementacji Chrisa i komentarzach.
źródło
Chciałbym dodać kolejną odpowiedź na to pytanie, którą przekazał mi rok lub dwa lata temu Chris Pruett (wyspa repliki, Wind-Up Knight itp.). Jest to szczególnie przydatne tutaj w 2013 r., Ponieważ wydaje się, że setPreserveEglContextOnPause (true) nie działa na 4.3. (Mogę się mylić w tej sprawie, ale tak to wygląda teraz, kiedy aktualizuję kod gry ostatnio dotknięty w 2011 roku).
Zasadniczo sztuczka polega na odłączeniu GLSurfaceView od hierarchii widoku od działania onPause () Twojej aktywności. Ponieważ nie ma go w hierarchii widoków w momencie uruchomienia onPause (), kontekst nigdy nie zostaje zniszczony.
Więc twoja aktywność onPause () powinna wyglądać następująco:
I przywracasz GLSurfaceView do hierarchii nie z onResume (), ale z onWindowFocusChanged ():
Zauważ, że nigdy nie wywołujesz GLSurfaceView onPause () i onResume () i że jest to oficjalny SDK GLSurfaceView, nie jest wymagana żadna zhackowana wersja alternatywna.
źródło
<rant> Spędziłem dużo czasu na tym problemie, wypróbowałem wiele różnych rozwiązań i żadne nie działało do dziś, myślę, że jest to jedna z najstraszniejszych decyzji projektowych, jakie kiedykolwiek widziałem, ale pochodzący z zespołu Androida nie jestem naprawdę zaskoczony. </ rant>
Tak więc rozwiązaniem jest przesunięcie elementu eglContext w górę i ustawienie go w sposób statyczny (globalny), aby nie został zniszczony, a następnie po prostu musisz sprawdzić, czy jest on zerowy, zanim utworzysz go ponownie.
Do tej pory wydaje się, że to rozwiązanie działa dla nas i nie obchodzi nas, czy zepsuje się na urządzeniach z 2005 roku.
źródło
Użyj interfejsu API plastra miodu. Istnieje opcja zachowania twojego kontekstu OGL. W przeciwnym razie musisz ponownie załadować kontekst. To nie jest trudne ani bolesne.
Musisz zrozumieć, że istnieją dwa przypadki (Android 2.1):
Uwaga: stary Android Gpus nie obsługuje wielu kontekstów. Tak więc kontekst opengl zostaje utracony po przełączeniu na inną aplikację => brak dostępnego rozwiązania (możesz zhakować, aby zachować swój kontekst na ekranie pauzy).
Uwaga 2: Ustawiona jest funkcja HoneyCombPreserveEGLContextOnPause
źródło
Niektóre odpowiedzi tutaj są uzasadnione dla wczesnego użycia OpenGL ES na Androidzie. Pierwsze urządzenia GLES obsługiwały tylko jeden kontekst, więc GLSurfaceView został zaprojektowany do agresywnego odrzucania stanu. Przekonanie GLSurfaceView do zrobienia czegoś innego nie jest łatwe.
W przypadku nowszych wersji Androida (prawdopodobnie wszystko korzystających z GLES 2.x) najlepszą odpowiedzią jest użycie zwykłego SurfaceView i samodzielne zarządzanie EGL i zarządzanie wątkami. Możesz znaleźć wiele przykładów GLES używanych z prostym SurfaceView w Grafice , w tym bibliotekę prostych klas do tworzenia i niszczenia kontekstów EGL.
Nadal dobrą praktyką jest zwalnianie stanu, gdy aplikacja przechodzi w tło, ale na przykład od Chrisa Pruetta - gdzie aplikacja była nadal na pierwszym planie, ale działanie Hosting GLSurfaceView zostało wyłączone - nie ma żadnej wartości w rozdzieraniu w dół kontekstu.
źródło