2010-10-19 4 views
4

Je travaille sur un jeu et j'ai des problèmes de performance en dessinant une toile sur une autre avec drawImage. Selon le profileur de Chrome, je passe 60% de mon temps en seulement un appel drawImage et 10% dans le clearRect au-dessus ...HTML/Canvas - drawImage performance avec une autre toile

La toile source est d'environ 3000x3000 pour l'instant (ce qui est assez petit, je disons) et la toile de destination est 1024x768.

J'ai pensé qu'au lieu de dessiner toutes les tuiles; murs et ainsi de suite chaque boucle (ce qui me donne environ 15fps), qu'il serait probablement plus rapide de tous les dessiner sur une toile hors écran, puis dessiner sur ma toile principale, puis dessiner des entités, etc. . Cela me donne ~ 30fps mais ... est-ce le meilleur que je vais obtenir avec le rendu logiciel?

Mon rendre boucle est essentiellement:

ctx.clearRect(0, 0, 1024, 768); 

ctx.beginPath(); 
ctx.drawImage(map, cam.position.i, cam.position.j, 1024, 768, 0, 0, 1024, 768); 
ctx.closePath(); 

ctx.save(); 
ctx.translate(-cam.position.i, -cam.position.j); 
// draw entities, etc. 
ctx.restore(); 

Je ne peux pas vraiment penser quoi faire, autre que commencer à utiliser WebGL (pour tirer profit de son accélération matérielle) ou attendre les fournisseurs pour mettre en œuvre l'accélération matérielle pour le contexte 2d. Je préférerais ne pas faire l'un ou l'autre, cependant, toute contribution serait appréciée.

+2

Je ne suis pas sûr beginPath et closePath applique à drawImage. – kanaka

+0

Ah, je les ai utilisé pour les chemins avec lineTo/moveTo et avec drawImage. Je les ai juste enlevés et le framerate est à peu près le même mais merci quand même. – Xavura

+2

3000x3000 est gargantuesque, même 1024x768 est déjà lent avec le rendu logiciel, ou il utilise tout le processeur qu'il peut obtenir, d'après mon expérience, il n'y a pas grand-chose que vous pouvez faire jusqu'à ce que l'accélération matérielle arrive à toutes les extrémités. Vous pourriez envisager d'utiliser une approche basée sur HTML pour un jeu basé sur les tuiles. –

Répondre

1

Il est peut-être plus rapide d'utiliser getImageData pour chacun de vos "sprites" et de conserver des références aux tableaux imageData dans votre Javascript et d'utiliser putImageData pour le rendre dans votre canevas cible.

Vous pouvez toujours afficher vos sprites en utilisant un canevas source invisible et le getImageData sur chacun des carreaux/sprites. Il utiliserait plus de mémoire mais pourrait être plus rapide que drawImage avec un canevas source et destination.

2

Wow, c'est une grande toile hors écran. Le stockage juste pour le tampon est d'environ 36 Mo.

Je serais tentée d'utiliser de plus petits carreaux hors écran, par ex. 1024x124 et dessinez les visibles sur votre canevas principal. Pour économiser de la mémoire, vous ne pouvez créer que les tuiles visibles, puis en générer d'autres à mesure qu'elles deviennent visibles. (Et vous pouvez en disposer, ou même mieux recycler celles qui ne sont plus visibles).

Je ne crois pas que la réponse suggère que vous utilisez putImageData donnera de meilleures performances, comme l'expérience de l'intervenant ici indique: why-is-putimagedata-so-slow

Questions connexes