

#1
Posté 04 March 2013 - 00:39 AM
Pour la réalisation d'un jeu 2D, j'ai de grands atlas de 2048*2048 chargés dans le GPU.
J'aimerai dynamiquement les modifier. uploadFromBitmapData est assez lourd et oblige de conserver un bitmapData de 2048*2048 en RAM pour tout réuploader au GPU. pas le pied :/
molehill ne permettant pas d'uploader une partie de texture (pfffff) me suis dit que j'allais faire un setRenderToTexture(atlas) et simplement dessiner ce que je veux modifier a l'endroit voulu. Seulement voila, molehill ne permet pas de faire de drawTriangles sans avoir fait un clear() apres un setRenderToTexture. Du coup la texture est effacée. Obligé de créer une texture temporaire de 2048*2048 en GPU et en prime de faire draw de 2048*2048 pour réafficher l'atlas de base.... c'est trop lent pour être utilisé en temps réel.
J'ai fais pas mal de recherches mais je n'ai pas trouvé grand chose. Est-ce possible de contourner ce probleme ? faire un clear() en jouant avec les mask pour ne pas perdre l'atlas ?
#2
Posté 04 March 2013 - 02:51 AM
Je ne vois pas de solution à ton problème sans passer par uploadFromBitmapData...
Que veux tu modifier exactement ? Si tu veux modifier les couleurs par exemples, il serait plus judicieux de faire ça au niveau du FragmentShader, en AGAL
#3
Posté 04 March 2013 - 09:11 AM
Imagine un atlas déja bien chargé, j'ai besoin d'y ajouter un ou plusieurs nouveaux sprites. Cela peut être du texte ou un élément graphique. Du coup pour ajouter seulement 30*30 pixels je suis obligé de redessiner/uploader tous l'Atlas... :s
#4
Posté 04 March 2013 - 10:47 AM

#5
Posté 04 March 2013 - 12:55 PM
Oui c'est ce que je fais, mais du coup j'y perd en CPU, car je ne peux pas faire un seul et unique drawTriangle. Je suis obligé de changer de texture plusieurs fois. C'est domage :s
#6
Posté 04 March 2013 - 15:01 PM
En fait je ne comprend pas bien pourquoi tu as besoin que ce soit à ce point optimisé - mais je me représente peut etre mal ce que tu veux faire - . Le changement de texture se fera lors d'un évènement ponctuel non?
#7
Posté 04 March 2013 - 16:24 PM
clear();
setTextureAt() // l'atlas
... // select vertexBuffer (qui contient les infos des triangles et la position de la texture dans l'atlas)
drawTriangles() // en une seule fois
present();
En faisant juste ça, je peux afficher des milliers de sprites à chaque frame en bouffant 0% de CPU.
Si je me retrouve avec des multiples atlas de texture, je suis obligé de boucler et de faire plusieurs setTextureAt() et drawTriangles();
Donc si je veux afficher une centaine de sprites dont la texture est générée dynamiquement (donc ici dans des atlas différents), je suis donc obligé de faire une centaine de setTextureAt puis drawTriangles à chaque frame :/
#8
Posté 06 March 2013 - 01:06 AM
Si tu veux diminuer le nombre de changements de texture et le nombre de draw calls dans le program opengl il te "suffit" pour Ça de créer ce que l'on appelle un batch.
Cad que tu vas regrouper les triangles à afficher en fonction ( par exemple ) des critères ci-dessous:
1 - La transparence
2 - La texture
3 - le shader utilisé
Ça te créera des groupes de rendus et diminuera le nombre de changements de textures et de draw calls.
Je ne sais pas si j'ai été assez clair ????
#9
Posté 06 March 2013 - 10:18 AM
thot, le 06 March 2013 - 01:06 AM, dit :
Le GPU oui, mais le CPU sur téléphone mobile sous air lui, il aime pas trop les boucles for() !!
Aujourd'hui j'arrive justement bien à faire un seul drawTriangle pour tous les sprites placés dans un seul atlas de texture. Le soucsi c'est si je dois ajouter des sprites dynamiquement. C'est là que j'aimerai simplement "updater" l'atlas dans le GPU sans devoir le reuploader intégralement. Mais je ne peux pas a cause de ce clear().. je suis obligé de faire des textures uniques et donc faire pleins de drawTriangles précédé par des setTextureAt.
Mon fps à 60 avec un seul drawTriangles et 1000 sprites a l'écran, chutte méchament quand le cpu doit boucler sur les textures uniques...
#10
Posté 06 March 2013 - 11:42 AM
Note: Il n'y a pas que les drawtriangles qui coutent cher au GPU le changement de texture coute aussi bien cher, essaie de désactiver tout ce qui est "rendu" dans ton code et check le fps, s'il est à 60 c'est que le bottleneck se situe au niveau du GPU et non au niveau du CPU. Dans les deux cas, tu as peut etre un problème d'architecture au niveau du code, mais ce que je dis est purement spéculatif et c'est pour ça que le code est le bienvenu

#11
Posté 06 March 2013 - 12:17 PM
Ce qui est clair c'est que sur mobile, le CPU est tres tres vite a genoux

Il n'y a pas grand chose à mesurer. L'appli n'a q'un seul enterFrame qui (en simplifiant) clear(), draw() et present(). Le CPU ne fait donc rien et l'appli tourne à 60 fps avec pas loin de 2000 sprites à l'ecran animés qui bougent.
Apres ya pas de magie, faire des boucles pour changer de textures, faire des calculs de position pour indiquer le bon IndexBuffer ça bouffe forcement du CPU.
Ce clear() est donc tres problematique. J'ajoute aussi que pour modifier un Atlas directement côté GPU, je suis obligé de creer une texture temporaire de 2048*2048 pour redessiner l'atlas de base (effacé par le clear()) pour au final dessiner le sprite dans l'atlas. Je me retrouve aussi avec un manque de RAM niveau GPU...
#12
Posté 06 March 2013 - 13:35 PM
#13
Posté 06 March 2013 - 14:20 PM
#14
Posté 06 March 2013 - 14:41 PM
J'ai essayé Minko oui, c'est une vrai cata pour les perfs :/. En fait j'ai ecris mes propres shaders qui integrent la notion de vitesse et d'accelleration d'un sprite. En gros je met dans le vertexBuffer, la position, la vitesse et l'accel du sprite à un instant t. A chaque frame, je fais le fameux drawTriangles() mais avant ça j'indique au shader via les programConstant le temps écoulé. Le shader fait donc les calculs et affiche le sprite au bon endroit.
Du coup je peux faire déplacer un millier de sprites à l'ecran à 60 fps sur une trajectoir en cloche par exemple. j'ai donc un effet de gravité intégralement géré par le GPU.
Minko me permet pas de faire ça, il faut modifier frame par frame chacun des prites pour dessiner, ou alors il faut ecrire son shader sois même. C'est exactement ce que j'ai fais mais avec mon framework qui ne gere que ça.
#15
Posté 06 March 2013 - 14:52 PM
Sinon oui en effet c'est plutot cool de gérer ce que tu peux gérer via le GPU.
PS: Quel est le téléphone "référence" pour ton framework ?
#16
Posté 06 March 2013 - 21:37 PM
Pour en avoir fait pas mal, la 3D n'a pas les mêmes contraintes. En 2D on doit afficher en haute qualité des sprites sur 4 vertex. En 3D on peut faire de la repetition de texture sur de grandes surfaces et on s'arrange pour avoir un seul drawTriangles qui affiches des objets de centaines de vertex. La qualité des textures n'est pas la même non plus.
Attention, dans mon cas je n'ai aucun soucis de perf niveau GPU. Mes shaders gerent les deplacements, les animations frames/frames, les rotations, les vitesses, les accelerations (position, rotation, echelle, alpha), les teintes etc... ça marche tres bien.
Par contre niveau CPU je dois optimiser un max, la gestion des collisions bouffe déja pas mal. C'est pour ça que je dois être pointilleux sur les perfs. D'autants que sur mobile, la conso batterie est importante à prendre en compte.
#17
Posté 07 March 2013 - 11:27 AM
1 utilisateur(s) li(sen)t ce sujet
0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)