Vendredi 11 Juillet 2008
[XNA] Hardware Accelerated TileMap Engine
Cette fois, rien de très particulier je me suis juste amusé à coder un rendu de tilemap entièrement accéléré par la carte graphique :p
C'est fou ce qu'on peut faire avec des pixels shader, quand même :D

Bon, j'explique quand même un peu plus le pourquoi du comment c'est bien (et aussi pourquoi c'est mal tant qu'à faire).
Afin d'afficher un tilemap sur une carte graphique moderne, il y a basiquement deux choix:

Le premier, c'est d'afficher les tiles 1 par 1 comme des sprites (méthode bizarrement proposée dans la plupart des tuto "xna tilemap" par exemple).
Le second est de dessiner dans une texture (sur le GPU) le tilemap.

Dans le premier cas, on doit dessiner tous les tiles un par un à chaque image, et lors des redimensionnements / rotations, des trous peuvent devenir visibles entre les tile (à plus forte raison avec le multisampling activé ) et il est fort possible que les textures bavent (effet secondaire du filtrage bilinéaire).
Dans le second cas on peut dessiner dans la texture avec le CPU (ce n'est pas forcément si lent qu'on pourrait le penser, regardez la vitesse des émulateurs ;) ), ou bien avec le GPU en dessinant les tile 1 par 1 comme au dessus. Dans tous les cas il ne faudra pas rafraichir la texture à chaque image, donc on gagne en performance, en revanche on perd en mémoire (pour un jeu 2D ce n'est pas important)

Bon j'avoue, je n'ai même pas essayé de dessiner les tile moi-même dans une texture, j'ai fait encore plus rusé... Mais c'est peut-être plus lent en fait (ahem :D )

Globalement, un tilemap est un tableau d'entiers contenant une référence sur des tile, et si on y réfléchit bien, un tile est une sorte de gros pixel. Donc ce que j'ai fait c'est de passer ce tableau d'entiers directement à la carte graphique pour qu'elle se charge de tout dessiner.
Il suffit d'utiliser cette magnifique fonctionnalité (obsolète ? non !) qu'est le Point Sampling (autrement dit le redimensionnement du pauvre), et on se retrouve avec plein de gros carrés de la bonne taille qu'il ne reste qu'à remplir.

Pour optimiser le shader, j'adresse les tiles en lignes et colonnes (maximum 255x255), de la manière dont ils sont stockés dans la texture. Il reste juste à trouver un format de texture adapté pour stocker des pixels de deux octets, L8A8 par exemple (Luminance 8 bits Alpha 8 bits).

Ensuite le shader est vraiment très simple:
float4 TileMapPixelShader(float2 mapCoord: TEXCOORD0) : COLOR
{
return tex2D(TileSampler, (255 * tex2D(DataSampler, mapCoord).xw + frac(MapSize * mapCoord)) / TileSetSize);
}
(Hé oui c'est du HLSL, j'ai arrêté de coder les shader en ASM #tsss# )
Je vous passe les explications de pourquoi ça marche malgré les erreurs "évidentes" de calculs dans certains cas (qui ne se produisent jamais en mapping 1:1)
Il n'y a qu'un truc qui n'est pas optimal dans ce shader je vous laisse deviner ce que c'est, pour ceux qui s'intéressent à ce genre de choses :p

Au final je dois allouer: 1 render target et une texture par tilemap à dessiner, plus éventuellement un z-buffer si les dimensions du rendu sont supérieures à celles de l'écran (il me semblait qu'on pouvait s'en passer, mais je dois encore vérifier ça)
Alors ça consomme beaucoup de mémoire, mais le CPU ne fait vraiment pas grand chose, et les transferts sur le bus graphique sont minimisés. (A priori les performances dépendent essentiellement du fillrate de la carte graphique)

Ensuite on peut utiliser ces magnifiques textures et y appliquer n'importe quel effet kikoololesque en commençant simplement par les mises à l'échelle et rotations, jusqu'aux effets de vague et autres joyeusetés =)

Enfin voilà, je pense que je vais pouvoir utiliser ça pour faire un petit jeu dont j'ai eu l'idée.

Je vous met quelques images et un lien pour télécharger comme d'habitude, mais bon c'est juste un tilemap animé (6 calques de 16x16 tiles de 16x16 pixels) qui tourne ;)

img
img

[ #cookie# Télécharger] (XNA 3.0 redist inclus)

Posté à
23:18
 par GoldenCrystal - | Programmation

6. GoldenCrystal à 16:20 13/07/2008 -
Verdict: en fait c'est juste que ta version de DirecX n'est pas à jour :p
(oué c'est con mais au moins c'est pas de ma faute :D )

5. GoldenCrystal à 16:04 13/07/2008 -
Ah tiens c'est étrange comme bug, je vais faire quelques tests pour voir d'où ça peut venir (peut-être simplement une exception toute bête qui est transformée en erreur fatale... ^^)
Après c'est juste un tilemap pourri donc les images parlent d'elles-même :D

4. JackosKing à 13:09 13/07/2008 -
TileMapDemo a cessé de fonctionner -> poubelle direct

3. squalyl à 23:09 12/07/2008 -
dommage :(

2. Zephyr à 15:58 12/07/2008 -
pas seulement, faut installer un autre truc... exit donc, comme d'hab ^^

1. squalyl à 13:43 12/07/2008 -
grr, dot net deux needed, tant pis!

Pseudo :

Adresse mail : (optionnel)

Site web : (optionnel)

Veuillez entrer la somme de sept et un :
Message :


 RSS  - ©yNBlogs 2004