La documentation Android dit:
Il y a des situations où le contexte de rendu EGL sera perdu. Cela se produit généralement lorsque l'appareil se réveille après s'être endormi. Lorsque le contexte EGL est perdu, toutes les ressources OpenGL (telles que les textures) associées à ce contexte sont automatiquement supprimées. Afin de continuer à rendre le rendu correctement, un moteur de rendu doit recréer toutes les ressources perdues dont il a encore besoin. La méthode onSurfaceCreated (GL10, EGLConfig) est un moyen pratique de le faire.
Mais devoir recharger toutes les textures dans le contexte OpenGL est à la fois pénible et nuit à l'expérience de jeu de l'utilisateur lorsqu'il ressaisit l'application après une pause. Je sais que "Angry Birds" évite en quelque sorte cela, je cherche des suggestions sur la façon d'accomplir la même chose?
Je travaille avec l’Android NDK r5 (version CrystaX.) J'ai trouvé le piratage possible, mais j’essaie d’éviter de créer une version complète du SDK personnalisé.
Réponses:
L'île de réplication dispose d'une version modifiée de GLSurfaceView qui traite ce problème (et fonctionne avec les versions antérieures d'Android). Selon Chris Pruett :
Edit: Je viens de réaliser que vous avez déjà posté le lien vers un hack similaire. Je ne pense pas qu'il existe une solution intégrée avant le nid d'abeilles. Replica Island est un jeu populaire fonctionnant sur de nombreux appareils. L'implémentation et les commentaires de Chris peuvent être utiles.
la source
J'aimerais ajouter une autre réponse à cela qui m'a été transmise un an ou deux en arrière par Chris Pruett (Replica Island, Wind-Up Knight, etc.). C'est particulièrement utile ici en 2013, car setPreserveEglContextOnPause (true) ne semble pas fonctionner avec la version 4.3. (Je peux me tromper à ce sujet mais c'est ainsi que je vois les choses lorsque je met à jour le code du jeu pour la dernière fois en 2011).
L'essentiel est de détacher votre GLSurfaceView de la hiérarchie des vues de votre activité onPause (). Etant donné que ce n'est pas dans la hiérarchie de la vue au moment où onPause () est exécuté, le contexte n'est jamais détruit.
Donc, votre activité onPause () devrait ressembler à ceci:
Et vous restaurez votre GLSurfaceView dans la hiérarchie non pas de onResume () mais de onWindowFocusChanged ():
Notez que vous n’appelez jamais onPause () et onResume () de GLSurfaceView et qu’il s’agit du SDK GLSurfaceView officiel, aucune version alternative piratée n’est requise.
la source
<rant> J'ai passé énormément de temps sur ce problème, j'ai essayé de nombreuses solutions différentes et aucune ne fonctionnait jusqu'à aujourd'hui, je pense que c'est l'une des décisions de conception les plus terribles que j'ai jamais vues, mais venant de l'équipe Android, je ne suis pas vraiment surpris. </ rant>
La solution consiste donc à déplacer le membre eglContext vers le haut et à le rendre statique (global) afin qu'il ne soit pas détruit. Il vous suffit ensuite de vérifier s'il est nul ou non avant de le recréer.
Jusqu'à présent, cette solution semble fonctionner pour nous, et peu importe si elle tombe en panne sur les appareils 2005.
la source
Utilisez l'API en nid d'abeille. Il existe une option qui préserve votre contexte OGL. Sinon, vous devez recharger votre contexte. Ce n'est pas difficile ni douloureux.
Vous devez comprendre qu'il existe deux cas (Android 2.1):
Remarque: les anciens gpus android ne prennent pas en charge le contexte multiple. Ainsi, le contexte opengl est perdu lorsque vous passez à une autre application => aucune solution disponible (vous pouvez bidouiller pour préserver votre contexte lors d'une pause à l'écran).
Remarque 2: la fonction HoneyComb est setPreserveEGLContextOnPause
la source
Certaines des réponses fournies ici sont raisonnables pour les premières utilisations d’OpenGL ES sur Android. Les premiers appareils GLES ne prenaient en charge qu'un seul contexte. GLSurfaceView a donc été conçu pour éliminer de manière agressive l'état. Convaincre GLSurfaceView de faire autrement n'est pas facile.
Pour les versions plus récentes d'Android (probablement tout ce qui utilise GLES 2.x), la meilleure solution consiste à utiliser un SurfaceView standard et à gérer vous-même vos EGL et vos threads. Vous pouvez trouver plusieurs exemples de GLES utilisés avec un SurfaceView brut dans Grafika , notamment une bibliothèque de classes simples pour la création et la destruction de contextes EGL.
C'est toujours une bonne pratique de décharger l'état lorsqu'une application passe en arrière-plan, mais pour l'exemple de Chris Pruett - où l'application était toujours au premier plan, mais où l'activité hébergeant GLSurfaceView a été modifiée - rien ne sert de rien de se déchirer dans le contexte.
la source