Forum de la communauté SFML

Aide => Graphique => Discussion démarrée par: math77 le Août 21, 2013, 07:58:38 pm

Titre: 2D isométrique, VertexArray
Posté par: math77 le Août 21, 2013, 07:58:38 pm
Bonjour,

Ayant lu la plupart des sujets présent sur ce forum et d'autres concernant la manière la moins coûteuse en performances d'afficher un grand nombre de tile, j'aimerai vous poser quelques questions :)

J'ai lu que les VertexArray sont beaucoup plus rapides que les RenderTexture ou Sprites normaux : mais la limite est que l'on ne peut utiliser qu'une seule texture.
Le problème est que on ne peut pas faire un grand tileset regroupant toutes les tuiles possibles (non supporté par les cartes graphiques plus anciennes) et que je ne peux pas mettre plusieurs VertexArray par couche (car sinon les tuiles ne se superposent pas dans le bon ordre et le résultat est horrible).
L'autre solution était de faire un VertexArray par couche, mais là encore, je prévois beaucoup de tiles différents, et je ne peux pas savoir quels tiles vont être mis sur la map (par l'éditeur de map), donc je ne peux pas prévoir de tileset... :/

Auriez vous des réponses ? Et pour ceux qui ont déjà rencontrés ce type de problème pouvez-vous m'éclaircir ? :)

Merci beaucoup
Titre: Re : 2D isométrique, VertexArray
Posté par: Laurent le Août 21, 2013, 10:22:44 pm
Citer
sinon les tuiles ne se superposent pas dans le bon ordre et le résultat est horrible
Tes tuiles se superposent ?
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 21, 2013, 11:48:15 pm
Oui ce sont des tuiles qui peuvent etre avec un peu de relief et donc elles ont une profondeur (fausse 3D) :)

Exemple : https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcT73qRSV4Fn0ovkG-pDQ9h1LvChSc2kOb5T4ZdPpMlbHXrou9oR2N9aADf1NQ

Et si j'utilise un vertexArray par tuile différente, certaines qui sont derrière normalement se retrouveront devant et vice versat :/
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 22, 2013, 03:44:17 pm
Voila en image le problème :

Une map basique :

(http://img4.hostingpics.net/pics/715781tilemap1.png)

Si je fais un VertexArray par texture, cela me donne ça :

Pour la pierre :

(http://img4.hostingpics.net/pics/481979tilemap2.png)

Pour l'eau :

(http://img4.hostingpics.net/pics/388408tilemap3.png)

Et au final j'aurai ça comme résultat (pas bon, l'eau est par dessus le bloc) :

(http://img4.hostingpics.net/pics/819306tilemap4.png)

Le problème étant que je ne sais pas quel bloc l'utilisateur posera sur la map (avec l'éditeur de map) et donc je ne peux pas prévoir de tileset spécial pour le sol...

Merci d'avance :)
Titre: Re : 2D isométrique, VertexArray
Posté par: Laurent le Août 22, 2013, 03:56:37 pm
Là j'avoue que je n'ai pas de solution miracle, c'est un cas compliqué à gérer.

Simple curiosité, tu as combien de tuiles différentes en tout ?
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 22, 2013, 04:01:06 pm
Pour l'instant pour les tuiles de sol, j'en ai une quinzaine environ, mais je compte en faire encore plus ;)

Sinon j'ai pensé à faire des RenderTexture de par exemple 800px par 800px et les coller les unes contre les autres, pour ce qui est statique, cela permet de charger qu'une fois et apres juste afficher la RenderTexture, et lorsque on se déplace, rajouter une RenderTexture, etc.

Est-ce une bonne idée ? :)
Titre: Re : 2D isométrique, VertexArray
Posté par: Laurent le Août 22, 2013, 04:10:53 pm
Citer
Pour l'instant pour les tuiles de sol, j'en ai une quinzaine environ, mais je compte en faire encore plus
Même si tu en as plus, ça ne tient pas dans une texture de 1024x1024 ?

Citer
Sinon j'ai pensé à faire des RenderTexture de par exemple 800px par 800px et les coller les unes contre les autres, pour ce qui est statique, cela permet de charger qu'une fois et apres juste afficher la RenderTexture, et lorsque on se déplace, rajouter une RenderTexture, etc.
Ca marche oui, mais attention à ne pas saturer ta mémoire graphique si tu as de grands niveaux.
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 22, 2013, 04:16:24 pm
Euh mes textures font environ 90 par 60, donc je peux en mettre beaucoup mais j'ai lu que certaines cartes graphiques ne supportent que 512*512 :/

Mais l'autre problème c'est qu'elles ne font pas toutes la même taille donc pour faire un tileset c'est assez compliqué.

Ou sinon j'avais pensé, créer le tileset au moment du chargement de la map, avec uniquement les tiles présents sur la map (ça devrait passer niveau quantité) mais je ne suis pas sur que ça marche :/

Sinon entre les renderTextures de 800*800 et les VertexArray, qu'est ce qui est le plus performant ? :)
Titre: Re : 2D isométrique, VertexArray
Posté par: Laurent le Août 22, 2013, 04:23:17 pm
Citer
j'ai lu que certaines cartes graphiques ne supportent que 512*512
Dans ce cas ne prévois pas de RenderTexture de 800x800 :P

Honnêtement je ne suis pas sûr que les cartes ne supportant que 512x512 soient encore très présentes. On peut sans doute relever un peu le niveau à 1024x1024 de nos jours.

Citer
Mais l'autre problème c'est qu'elles ne font pas toutes la même taille donc pour faire un tileset c'est assez compliqué.
C'est gérable. Il suffit d'ajouter la taille des tuiles, soit dans un fichier séparé soit encodé dans un pixel à côté de chaque tuile.

Citer
Ou sinon j'avais pensé, créer le tileset au moment du chargement de la map, avec uniquement les tiles présents sur la map (ça devrait passer niveau quantité)
L'utilisateur ne peut pas mettre une tuile de chaque sorte sur sa carte ?

Citer
mais je ne suis pas sur que ça marche
Pourquoi pas ?

Citer
Sinon entre les renderTextures de 800*800 et les VertexArray, qu'est ce qui est le plus performant ?
Ca c'est une question sans réponse. Les vertex arrays sont toujours conseillés de manière générale, mais après si tu veux comparer les performances ça dépend trop de chaque contexte.
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 22, 2013, 04:30:20 pm
Citer
L'utilisateur ne peut pas mettre une tuile de chaque sorte sur sa carte ?
En fait dans l'éditeur de map l'utilisateur choisit ses tiles (qui seront rangés par catégorie donc séparés)
Ensuite dans le jeu, son personnage se déplace dessus.

Je pensais sinon au chargement de la map (dans le jeu) assembler les tiles présent sur la map dans un tileset avec la méthode que tu viens de dire dans une RenderTexture, puis utiliser cette RenderTexture comme tileset pour afficher la map avec les VertexArrays. Est-ce possible ? :)

Mais pour l'autre méthode, on appelle tous les draw() qu'une seule fois ou presque puisqu'après on a juste à afficher la RenderTexture, cela peut faire gagner en performances ? :)
Titre: Re : 2D isométrique, VertexArray
Posté par: Laurent le Août 22, 2013, 04:53:04 pm
Citer
Je pensais sinon au chargement de la map (dans le jeu) assembler les tiles présent sur la map dans un tileset avec la méthode que tu viens de dire dans une RenderTexture, puis utiliser cette RenderTexture comme tileset pour afficher la map avec les VertexArrays. Est-ce possible ?
J'avais bien compris. Oui c'est possible.

Citer
Mais pour l'autre méthode, on appelle tous les draw() qu'une seule fois ou presque puisqu'après on a juste à afficher la RenderTexture, cela peut faire gagner en performances ?
Ca dépend par rapport à quoi ;)
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 22, 2013, 05:01:32 pm
Par rapport à l'autre méthode plus haute :)

Donc j'ai le choix :

1- j'affiche la couche avec un VertexArray qui prend comme texture le tileset créé par la RenderTexture.
2- je créé des RenderTexture pour toute la couche (et je la divise en partie de 1024 par 1024 par exemple^^) et une fois créé je n'ai plus qu'à les afficher jusqu'à ce que le perso bouge et la rebelotte, on recommence à créé des RenderTextures etc.

Quelle méthode semble la plus optimisée ? :)
Titre: Re : 2D isométrique, VertexArray
Posté par: Laurent le Août 22, 2013, 08:19:30 pm
Si tu peux faire quelque chose avec des vertex arrays, préfère le à la solution à base de RenderTexture.

Mais bon sinon faut tester, dans l'absolu ça se vaut.
Titre: Re : 2D isométrique, VertexArray
Posté par: Hypnéos le Août 23, 2013, 01:06:26 pm
Je ne sais pas si cela peut aider, mais les primitives d'un VertexArray sont rendues dans l'ordre dans lequel elles sont entrées.

donc, si tu enregistre les tuiles les plus éloignées de la caméra en premier, et les plus proches en dernier; elles devraient se superposer correctement.

Je ne suis pas sur à 100% du comportement d'openGL, mais je pense que ça devrait marcher...
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 23, 2013, 05:10:45 pm
@Laurent : Je vais essayer avec les VertexArray mais je ne suis pas sur du résultat :/

@Hypnéos : En fait ta méthode est bonne à partir du moment où un seul vertexArray affiche la meme couche. Quand il y en a plusieurs (par exemple 1 par texture), comme sur la photo, on ne peut pas afficher un bout du vertexArray puis un bout de l'autre etc., on doit forcément tout afficher d'un coup ...

 Donc du coup les mêmes tiles sont bien affichées, mais des qu'il y en a plusieurs, c'est là qu'il y a un problème :'(
Titre: Re : 2D isométrique, VertexArray
Posté par: Hypnéos le Août 23, 2013, 07:13:26 pm

Le nombre de textures est en effet un problème.
Est-ce que tu as déjà une idée du nombre de textures qu'il y aura à l'écran?

Tu pourrais rendre ton terrain par "bloc" de (par exemple) 8 cases de coté?
Et actualiser seulement les blocs qui ont changés (personnages qui se déplacent, etc)

Une solution plus ... complexe ... pourrait être d'utiliser un shader... avec un paramètre "distance depuis la 'camera' "
Malheureusement (*) sf::Vertex ne permet pas d'ajouter des paramètres supplémentaires, donc il faudrait en venir à des "hacks" tels que :


<note d'après relecture :>

Les points que j'ai abordés sont très vagues et très risqués.
Je tiens aussi à dire que je n'ai quasiment aucune expérience dans ces domaines.

@Laurent :  Est-ce que les renderTextures peuvent être modifiés pour avoir un composant GL_DEPTH ?
( J'ai essayé de rechercher sur le forum, mais j'ai reçu une 'Database error'  >_< )
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 23, 2013, 11:20:05 pm
Citer
Tu pourrais rendre ton terrain par "bloc" de (par exemple) 8 cases de coté?

Tu veux parler d'un système de "chunks", c'est-à-dire découper la map en zones de X blocks * X blocks ? :)

A vrai dire je ne sais pas combien de texture il y aura à l'écran, mais sachant qu'il y aura 3 couches, que la couche du sol sera entièrement remplie par des tiles, il doit y avoir un grand nombre.

Citer
Et actualiser seulement les blocs qui ont changés (personnages qui se déplacent, etc)

Actualiser les chunks visibles dans l'écran ? :) Mais en utilisant des VertexArrays ou une RenderTexture ?

Les VertexArrays ne peuvent prendre qu'une texture donc il faudrait que je crée le tileset dans une renderTexture puis que j'utilise cette dernière comme texture du VertexArray.

Sinon je dessine des RenderTextures par chunks et je les "colle" les unes contre les autres", et une fois dessinées, je n'ai plus qu'à les afficher comme une image de fond fixe, je devrai par contre la refaire si la map change (lorsqu'on se déplace par exemple).

Citer
Une solution plus ... complexe ... pourrait être d'utiliser un shader... avec un paramètre "distance depuis la 'camera' "

Je n'y connais absolument rien en shader, je préfère éviter :D
Titre: Re : 2D isométrique, VertexArray
Posté par: Laurent le Août 23, 2013, 11:32:02 pm
Citer
@Laurent :  Est-ce que les renderTextures peuvent être modifiés pour avoir un composant GL_DEPTH ?
Oui.

Citer
J'ai essayé de rechercher sur le forum, mais j'ai reçu une 'Database error'
Cherche plutôt dans la doc :P
Et quand tu cherches sur le forum, pour éviter les erreurs, ne sélectionne pas tous les forums, cherche uniquement sur ceux qui sont pertinents.
Titre: Re : 2D isométrique, VertexArray
Posté par: Hypnéos le Août 23, 2013, 11:56:49 pm
Tu veux parler d'un système de "chunks", c'est-à-dire découper la map en zones de X blocks * X blocks ? :)
[...]
Actualiser les chunks visibles dans l'écran ? :) Mais en utilisant des VertexArrays ou une RenderTexture ?

Je pensait à quelque chose comme : VertexArray -> RenderTexture -> RenderWindow.
Pas la meilleure solution pour atteindre 60 FPS si on doit le répéter à chaque frame...

Je n'y connais absolument rien en shader, je préfère éviter :D

Sage décision, c'est une force puissante, mais difficile à maîtriser.
<insert Star-War quote>



Merci Laurent, j'avais oublié la doc  :-[.
Au fait, je n'ai pas vu de shaders dans les source; est-ce que je suis passé au-dessus, ou SFML n'en utilise pas ?
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 24, 2013, 01:11:21 am
Citer
Je pensait à quelque chose comme : VertexArray -> RenderTexture -> RenderWindow.
Pas la meilleure solution pour atteindre 60 FPS si on doit le répéter à chaque frame...

Mais en utilisant le systeme de chunk ? :)
Du genre : créer une renderTexture par chunk, la remplir au chargement de la map et aux déplacements du personnage, puis lorsque on ne bouge pas, on se contente d'afficher les renderwtectures déjà dans la mémoire ... donc très peu d'appels a draw() :)

Qu'en pensee vous ? :)
Titre: Re : 2D isométrique, VertexArray
Posté par: Hypnéos le Août 24, 2013, 01:47:15 am
C'est ce que je voulais dire; mais tu as l'air d'avoir mieux compris que moi  ;D

Ce qui me soucie, c'est que si tu veut faire la moindre animation, il faudra soit reconstruire le chunk, soit en faire une copie par frame d'animation.

C'est un prix cher pour avoir de l'eau animée.  :-\


Je vais voir si je peux faire quelque chose avec openGL...
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 24, 2013, 02:07:23 am
Parce que sinon ya aussi la méthode du je crée le tileset dans une rendertexture et je fais un vertexArray pour afficher la map :)

Seulement rapport difficulté gain en performance je ne sais pas laquelle vaut mieux :/

Tkt si je faisais mes rendertextures ça serait pour le sol (et mon sol n'est pqs animé^^)
Titre: Re : 2D isométrique, VertexArray
Posté par: Lolilolight le Août 24, 2013, 01:41:34 pm
Ca dépend de ce que tu veux faire.

Si ton sol est statique et que l'ordre d'affichage est le même pour tout les vertexarray de ton tileset alors, une rendertexture ou une tilemap (si t'a pas besoin de faire du blending) feront l'affaire.

Sinon, si ton sol est dynamique par exemple si l'eau peut passer par dessus le bloc alors là, il va falloir que tu trie les VertexArray dans l'ordre avec lequel tu veux les afficher.

Et là y'a pas vraiment le choix je n'ai pas trouvé d'autre solution plus rapide que de dessiner tout vertexarray par vertexarray, j'avais trouvé une solution en rajoutant une composante z aux vertexarray pour le sol et actvier l'alpha test et le depth test mais comme il failait reconstruire la tilemap à chaque rendu bah, ça n'était pas vraiment mieux finalement que de dessiner tout un par un.

Ou alors faire un système qui, récupère la tile animée dans ta tile map et change son z order à chaque rendu..., mais je sais pas si c'est vraiment plus rapide que de créer un thread externe qui insère les tiles animé au bonne endroit dans ton vecteur de tiles triées. (chose que je fais pour mon framework.)
Et ça me pose vraiment problème car mes tiles ne sont pas en bloc comme toi, j'utilise de la transparence plutôt, mais si tes tiles n'ont pas de transparence tu pourrais passer directement par opengl je pense pour le dessin et jouer avec le zorder plutôt que de t'embêter avec la SFML qui n'est qu'une surcouche pour simplifié les choses mais qui n'est pas très optimisées pour certains cas bien précis car elle ne permet pas de faire assez de choses.

PS : se serait bien d'ajouter la possibilité de rajouté une composante z aux vertexarray dans une version future de la SFML, rajouté quelques primitives de synchronisation pour le multi-threading, rajouté la gesion du protocole SSL avec des socket SSL, etc...
Bref moi je le fais déja en modifiant pas mal SFML mais bon....
Titre: Re : 2D isométrique, VertexArray
Posté par: Laurent le Août 24, 2013, 02:22:13 pm
Citer
PS : se serait bien d'ajouter la possibilité de rajouté une composante z aux vertexarray dans une version future de la SFML, rajouté quelques primitives de synchronisation pour le multi-threading, rajouté la gesion du protocole SSL avec des socket SSL, etc...
C'est un peu hors-sujet ici, si tu veux en discuter tu peux ouvrir un (ou plusieurs) nouveau(x) sujet(s).
Titre: Re : 2D isométrique, VertexArray
Posté par: Hypnéos le Août 24, 2013, 02:57:27 pm
J'ai fait quelques test avec openGL; à moins que la carte ne soit très ( trèèèèèès ) complexe, SFML est une meilleure solution.

Pourrais-tu nous donner une approximation de ce qu'il y aura à l'écran dans le jeu final ?
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 24, 2013, 07:26:24 pm
Voici quelques images tirées de projets existant pour montrer à quoi pourra ressembler mes maps :

(http://d24.e-loader.net/EBKQQTOGa0.png)

(http://static.dofus.com/blog/img/articles/ld/devblog_comparatif_dofus2.jpg)

(https://lh3.googleusercontent.com/-XZE9uZ3VUKc/Tt0nwLB1VCI/AAAAAAAAAFw/iLl4P3qwrG8/w800-h800/se_05122011.png)

(http://www.steamoflethis.com/images/screenshots/1.png)

(http://blendman.free.fr/dev/pb/3arks_purebasic_03.jpg)



Ce ne sont que des exemples, mais il y aura 3 couches :

- sol
- décorations sur le sol (herbe, etc.)
- objets (maisons, arbres, etc.)
Titre: Re : 2D isométrique, VertexArray
Posté par: Hypnéos le Août 24, 2013, 08:15:19 pm
Merci, c'est très utile.
Je pensais à quelque chose de plus compliqué que nécessaire.  ;D

En me basant sur ces exemples, je crois que tu n'as pas à te faire de souci.
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 24, 2013, 09:01:32 pm
Merci :)

Quelle solution te parait la meilleur du coup ? :)
Titre: Re : 2D isométrique, VertexArray
Posté par: Hypnéos le Août 24, 2013, 09:29:17 pm
Si tu utilise un système de chunks, je ferais quelque chose comme :

Au chargement de la chunk :
Dessin de l'arrière plan dans un RenderTexture ( tiles + petit objects )

A l'affichage :
Dessiner l'arrière plan,
puis les objets en partant du plus éloigné.

Tu n'as pas besoin de trier les objets à chaque frame.
Les défauts ne sont aussi voyants qu'on pourrait le penser :
Regarde dans la 3ème image, le premier rocher dans la rivière à gauche du personnage.
Titre: Re : 2D isométrique, VertexArray
Posté par: Lolilolight le Août 25, 2013, 10:55:16 am
Tu n'as pas forcément besoin de faire de tri, il suffit juste d'utiliser 2 std::vector par exemple :

tiles[couche][tile]
 

Et ensuite t'a plus qu'à faire une boucle qui récupère tout et qui insère le tout dans un autre vecteur (ça s'appelle le tri par insertion et c'est plus rapide.)

for (int couche = 0; couche < tiles.size(); couche++) {
      for (int  tile  = 0; tile  < tiles[couche].size(); tile++) {
            tilesVisible.push_back(tiles[couche][tile]);
      }
}
 

Bref moi c'est comme ça que je fais mais en récupérant uniquement la partie du monde qui se trouve dans la vue.

Je n'ai pas trouvé de meilleur solution que de les dessiner une par une. (vu que j'utilise de la transparence le depth test ne marche pas.)

Mais pour toi, si tu n'utilises pas de transparence, alors oui il y a une meilleur solution et tu pourrais même dessiner tout d'un coup en donnant une composante z à tes vertexarray.

PS : je ne tiens pas vraiment à rouvrir un nouveau sujet pour discuter de ça pour l'instant je voulais juste dire que se serait bien mais c'est pas urgent vu que d'autres librairie le font déjà et puis je vais je pense ouvrir un sujet pour en discuter sur le forum Anglais.
Je disais juste ça si l'envie te venait un jour d'ajouté de nouvelles fonctionnalité à ta librairie.

Mais pour le sol animé le mieux est quand même je pense d'utiliser un shader ou peut être une texture 3D ???

PS 2 : tu m'as donné une idée je pense que je vais mixer les 2, tiles en bloc et tiles plates, ça pourrait être sympa!
Titre: Re : 2D isométrique, VertexArray
Posté par: Hypnéos le Août 25, 2013, 02:40:07 pm
La dernière fois que j'ai vérifié, le tri par insertion était toujours un tri  :P

Et "tiles[couche][tile]" est déjà trié, ou presque trié.

En même temps, pour N suffisamment petit, n'importe quel tri est rapide.
Titre: Re : 2D isométrique, VertexArray
Posté par: Lolilolight le Août 26, 2013, 11:45:39 am
Je ne vois pas en quoi utiliser une rendertexture serait plus rapide car tu dois quand même dessiner dans ta rendertexture avant de dessiner ta render texture, le seule truc qui marche vraiment pour améliorer la rapidité c'est la tile map. (et là tu peux dessiner tout d'un coup) mais c'est pas pratique pour les sols dynamiques ou si tes images contienne de la transparence ce qui est mon cas donc dans ce cas là le mieux reste un tri ou alors il faut utiliser un shader.
Je n'ai pas trouvé d'autre solution, si quelqu'un en a une je suis preneur.

PS : Mais de toute façon mon algorithme est assez rapide car :

-Je mets à jour les tiles à afficher dans un autre thread ce qui soulage la pile d'exécution du thread principal.
-Je fais déjà un pré-tri avec l'éditeur de map à chaque fois que j'ajoute ou que je supprime une tile.

Avec ça je tourne de manière rapide.

Ha oui et aussi avec la tehncique des tiles map tu es limité à une seule texture par couche.
Titre: Re : 2D isométrique, VertexArray
Posté par: math77 le Août 26, 2013, 03:06:21 pm
Bonjour,

Je vais finalement essayer les différents méthodes et comparer en termes de performances.

Avez-vous un moyen (a part le gestionnaire des taches) d'enregistrer la consommation moyenne de l'UC ? :)
Titre: Re : 2D isométrique, VertexArray
Posté par: Lolilolight le Août 27, 2013, 09:17:04 am
Non pas vraiment mais il doit exister des logiciels qui le font.