2008-10-20 12 views
3

Je travaille sur un jeu de défilement 2D pour iPhone. J'ai un grand fond d'image, disons 480 × 6000 pixels, dont seule une partie est visible (exactement la valeur d'un écran, 480 × 320 pixels). Quelle est la meilleure façon d'obtenir un tel fond sur l'écran?Grand fond de défilement dans OpenGL ES

Actuellement, j'ai l'arrière-plan divisé en plusieurs textures (pour contourner la limite de taille de texture maximale) et dessiner l'arrière-plan entier dans chaque image comme une bande de triangle texturée. Le défilement se fait en traduisant la matrice modelview. La boîte à ciseaux est réglée sur la taille de la fenêtre, 480 × 320 pixels. Ce n'est pas destiné à être rapide, je voulais juste un code de travail avant d'arriver à optimiser. Je pensais que peut-être l'implémentation OpenGL serait assez intelligente pour éliminer la partie invisible de l'arrière-plan, mais selon un code de mesure que j'ai écrit, il faut 7 ms pour dessiner en moyenne et 84 ms au maximum. (Ceci est mesuré dans le simulateur.) Cela représente environ la moitié de la boucle de rendu entière, c.-à-d. assez lent pour moi.

Dessiner l'arrière-plan devrait être aussi facile que de copier quelque 480 × 320 pixels d'une partie de la VRAM à une autre, ou, en d'autres termes, de flamboyer rapidement. Quel est le meilleur moyen de se rapprocher d'une telle performance?

Répondre

4

C'est la façon rapide de le faire. Ce que vous pouvez faire pour améliorer les performances:

  • Essayez différents formats de texture. Vraisemblablement, les documents SDK ont des détails sur le format préféré, et vraisemblablement plus petit est meilleur.
  • Cull sur tout vous tuiles offscreen
  • Diviser l'image en plus petites textures

Je suppose que vous dessinez à 1: 1 niveau de zoom; est-ce le cas?

Édition: Oups. Ayant lu votre question plus attentivement, je dois offrir un autre conseil: Les synchronisations faites sur le simulateur ne valent rien.

+0

Merci, plus ou moins, je pensais que ce serait comme ça. Aujourd'hui, je vais enfin avoir un iPod pour tester, je vais exécuter le code sur le HW réel et voir ce qui se passe. – zoul

+1

Après avoir essayé le code sur l'appareil: Oui, les synchronisations effectuées sur le simulateur ne valent rien. – zoul

2

La solution rapide:

  • créer une matrice de géométrie des tuiles (quads de préférence), de sorte qu'il y ait au moins une rangée/colonne de carreaux hors écran sur tous les côtés de la zone visible.

  • Cartographier les textures de tous ces carreaux.

  • Dès qu'une case se trouve en dehors de la zone visible, vous pouvez libérer cette texture et en lier une nouvelle. Déplacez les tuiles en utilisant un modulo de la largeur de la tuile et de la hauteur des tuiles comme position (de sorte que la tuile se repositionne à sa position de départ quand elle a bougé exactement d'une longueur de tuile). N'oubliez pas de remapper les textures pendant cette opération. Cela vous permet d'avoir une très petite grille/très peu de mémoire de texture chargée à un moment donné. Ce que je suppose est particulièrement important dans GL ES.

Si vous avez de la mémoire à perdre et êtes toujours en proie à la vitesse de chargement lente (bien que vous ne devriez pas pour cette quantité de textures). Vous pouvez créer un moteur de streaming de texture qui précharge les textures dans une mémoire plus rapide (quelle qu'elle soit sur votre périphérique cible) lorsque vous atteignez une nouvelle zone.Le mappage en tant que textures va dans ce cas partir de cette mémoire plus rapide en cas de besoin. Assurez-vous simplement que vous êtes en mesure de le précharger sans utiliser toute la mémoire et n'oubliez pas de le relâcher dynamiquement lorsqu'il n'est pas nécessaire.

Voici un lien vers un moteur de tuiles GL (pas ES). Je ne l'ai pas utilisé moi-même donc je ne peux pas garantir sa fonctionnalité mais il pourrait être en mesure de vous aider: http://www.mesa3d.org/brianp/TR.html

+0

Je ne pense vraiment pas que la bibliothèque de rendu des carreaux est ce que l'affiche originale est après. Cette bibliothèque est destinée à rendre les scènes en énormes résolutions de pixels, plus que OpenGL ne le supporterait en un seul passage. – unwind

+1

Oui, la bibliothèque fait quelque chose de différent de ce dont j'ai besoin, mais diviser l'arrière-plan en plus petits carreaux pourrait être une bonne idée. (Merci.) – zoul

Questions connexes