Comment charger les textures en OpenGL ES efficace

J'ai une connaissance de base de l'utilisation de OpenGL, surtout sur Android. Je suis de développer une application qui utilise OpenGL pour basculer entre le mode plein écran des images dans une voie rapide (car il est trop lent à l'aide de la normale Android-cadre).

Ce que j'ai trouvé, c'est que pour charger les textures, j'ai besoin de faire quelque chose comme:

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
_gl = gl;
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), _imageResourceId);
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();

Maintenant, étant donné que les images sont destinées à être en plein écran (et ils sont assez grand - 1024x1024), cela prend un certain temps, surtout depuis que j'ai besoin de charger 5 d'entre eux en même temps.

Donc j'ai besoin de vous poser quelques questions concernant les conseils de l'amélioration du code, en particulier à propos efficace de chargement (mais aussi en utilisant moins de mémoire si possible):

  1. si je décoder l'image bitmap de ne pas avoir de la transparence de pixels, à l'aide de la RGB_565 format, il va augmenter la vitesse de chargement des images pour OpenGL (ou de la phase de décodage)?
  2. l'entrée bitmap avoir une largeur et une hauteur qui sont des puissances de 2 ou je peux le laisser OpenGL ne prendre que la partie qu'il veut, qui aura cette règle? Je veux dire, je peux peut-être faire la texImage2D commande de ne prendre qu'une partie de l'image bitmap?
  3. je peux peut-être même de décoder seulement cette partie depuis le début (donc, si j'ai une énorme image de 10000x10000, je peux décoder seulement un 1024x1024 partie de, et de le donner à OpenGL)?
  4. est-il possible de charger et d'afficher seulement la première image, et à l'arrière-plan de charge du reste? J'ai entendu dire que vous ne pouvez pas envoyer les images à OpenGL dans un thread qui n'est pas celui qui le manipule. Est-il judicieux de les charger sur le onDrawFrame méthode de la GlRenderer, disons, la deuxième fois qu'il me demande?
  5. Je me souviens que j'ai entendu parler d'une astuce à propos de la fusion de plusieurs images en une seule image (l'un après l'autre, de gauche à droite), de sorte qu'elle peut avoir une certaine augmentation de la vitesse de la phase de décodage. Pas sûr quel est le nom de cette technique. Est-il encore possible pour OpenGL ES sur Android?
  6. est-il possible d'éviter de créer une occurrence de Bitmap et de laisser le décodage fait dans une plus moyen natif (NDK , peut-être)? Selon mes tests, le décodage d'un fichier PNG de taille 1024 x 1024 sur un émulateur prend environ 400ms-700ms, encore de l'envoyer à OpenGL prend environ 50ms-70ms.
  7. à l'aide de Procrank, j'ai découvert que l'OpenGL peut prendre beaucoup de mémoire. Est-il possible d'utiliser moins de mémoire? Peut-être mieux utiliser les textures types?
  8. depuis Android peut fonctionner sur plusieurs types d'appareils, est-il possible de mettre dans le manifeste d'une exigence de combien de mémoire est nécessaire pour l'application à exécuter, de sorte que les gens avec trop peu de mémoire ne sera pas en mesure de l'installer?

@Majid Max :

  1. donc c'est suffisant pour décoder cette façon, et de l'envoyer à OpenGL, ou devrais-je également définir quelque chose de spécial lors de l'envoi d'openGL?
  2. il n'existe pas une commande pour prendre partielle d'une partie de l'image bitmap?
  3. Je voulais dire, je peux décoder seulement une partie de la partie du fichier qui doit être stockée dans un bitmap, au lieu de l'ensemble de l'image bitmap?
  4. donc, la seule chose que je peux faire c'est de charger tout au début, et ensuite l'utiliser? Comment pourrait-il être? Comment faire des jeux de le manipuler? Je veux dire, ils montrent une étape après l'autre, même avec quelque chose qui ressemble à un OpenGL généré barre de progression. Ceci est très problématique.
  5. ce que je vais décrire est disponible sur le web. Par exemple, au lieu de chargement multitude de minuscules images, la page web contenant une seule image et des cartes de quelle partie de celui-ci devrait être indiqués, le cas. Un autre nom car il est les sprites. Exemple ici .
  6. Je vois. Je suppose que je doit appeler glDeleteTextures quand je vois il n'y a pas plus utilisé, non?
  7. comment dois-je faire? Que dois-je changer dans le code?
  8. ce qui se passe lorsque j'utilise beaucoup de mémoire? Est-il une chose telle que la RAM virtuelle (utilise la mémoire de stockage interne peut-être) quand il n'y a pas de libérer de la mémoire vive? J'en ai entendu parler sur Google IO vidéo, mais il semble qu'ils n'étaient pas sûrs de la réponse. Lien ici. Ils ont seulement dit s'attendre à plus de plantages quand une telle chose se produit.

@Majid Max :

1+2+3. ?

  1. cela pourrait fonctionner. Tu veux dire que je fais un nouveau thread qui va charger les images, puis d'envoyer les résultats à l'OpenGL thread qui va lier les textures de l'image bitmap? Je pourrais peut-être utiliser une approche similaire pour asyncTask, et l'utilisation publishprogress.
  2. c'est aussi une bonne chose. Avez-vous un lien que je devrais lire à ce sujet? Ou peut-être un fragment de code à modifier dans mon code?
  3. grâce.
  4. donc je pense que c'est la chose la plus facile à utiliser ETC1. Cependant, il ne prend pas en charge la transparence à tous, alors, selon ce lien, j'ai besoin d'utiliser une autre texture pour ça, mais je ne peux pas trouver un exemple pour cela.
  5. ce que je peux prendre de la mémoire disponible que je peux utiliser? Puis-je supposer, par exemple, que tous les appareils Android peut m'offrir de 200 mo de mémoire vidéo que je peux utiliser pour l'OpenGL?

OriginalL'auteur android developer | 2012-09-03