Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: [Résolu] Problème de performance avec beaucoup de sprites à l'écran  (Lu 3994 fois)

0 Membres et 1 Invité sur ce sujet

Nikogram

  • Newbie
  • *
  • Messages: 39
    • Voir le profil
    • E-mail
Bonjour à tous.
Je me trouve face à un petit soucis de performance pour le jeu que je crée actuellement.

Mes sprites mesurent 40*34px. Mon jeu étant un jeu sandbox (comme Minecraft par exemple) en 2d isométrique, je dois afficher la map sous forme d'un ensemble de sprites sur tout l'écran (les sprites se superposent à certains endroits car ce sont des pseudo-cubes). Je me retrouve donc avec quelques milliers de sprites à afficher pour une résolution de 1680*945.
Quand je vais dans le gestionnaire de tache, ça m'indique que mon jeu prend 30% de mon processeur (i7 Q 720), ce qui est assez énorme quand même.

J'aimerais donc avoir quelques conseils pour optimiser mon jeu, car je ne vois pas comment faire autrement (j'ai bien fais attention à utiliser le draw() sur un minimum de sprite).
Car autrement je vais devoir limiter la zone de jeu pour les écrans avec une trop grande résolution, ce qui serait assez dommage sur les écrans Full HD par exemple.
Merci d'avance.
« Modifié: Janvier 04, 2013, 02:18:39 pm par Nikogram »

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : Problème de performance avec beaucoup de sprites à l'écran
« Réponse #1 le: Janvier 03, 2013, 08:43:30 pm »
Salut.

Tu prends soin de ne pas afficher les sprites qui sont en dehors de la vue ?
Tu peux peut-être utiliser un sf::VertexArray sinon.
30% de CPU, mais tu limites le nombre de frames ou a activé la v-sync ?
« Modifié: Janvier 03, 2013, 08:45:23 pm par G. »

Nikogram

  • Newbie
  • *
  • Messages: 39
    • Voir le profil
    • E-mail
Re : Problème de performance avec beaucoup de sprites à l'écran
« Réponse #2 le: Janvier 03, 2013, 08:56:18 pm »
Merci pour ta réponse rapide.

Je n'affiche bien que les pixels dans la vue, et j'ai limité le jeu à 60 fps.
Et sinon je ne vois pas vraiment en quoi sf::VertexArray pourrait m'aider. Ca permet d'afficher des lignes c'est bien ça ? Or les image de mes sprites ne sont pas composés de simples formes géométrique.

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : Problème de performance avec beaucoup de sprites à l'écran
« Réponse #3 le: Janvier 03, 2013, 10:10:07 pm »
Nonon pas seulement des lignes, mais aussi des triangles et des quadrilatères texturés. Ça peut vraiment améliorer les perfs d'une tilemap par exemple. Y'a des exemples sur les forums (peut-être seulement le forum anglais, je ne sais pas) et même sur le wiki il me semble. Je ne sais pas trop comment se gèrent les chevauchements avec un vertex array par contre...
Enfin dans tous les cas, le CPU finira bien par être utilisé. :p

Par "minecraft en 2D isométrique", tu parles bien un truc de ce genre ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème de performance avec beaucoup de sprites à l'écran
« Réponse #4 le: Janvier 03, 2013, 10:30:48 pm »
Les vertex array sont les briques bas niveau qui permettent de construire toutes les entités haut niveau que tu connais (sprite, text, shape). Donc si tu veux des performances maximales, c'est là qu'il faut attaquer. En gros, un vertex array te permet de regrouper tous les sprites qui utilisent la même texture, dans une seule grosse entité, dessinable en un seul appel. Et comme les performances sont directement proportionnelles au nombre d'appels à draw... ;)
Laurent Gomila - SFML developer

Nikogram

  • Newbie
  • *
  • Messages: 39
    • Voir le profil
    • E-mail
Re : Problème de performance avec beaucoup de sprites à l'écran
« Réponse #5 le: Janvier 04, 2013, 01:21:57 pm »
Ah d'accord, dans ce cas effectivement sf::VertexArray est essentiel.
Et oui G., je parle bien d'un jeu avec un affichage similaire à l'image.

J'ai donc commencé à me renseigné sur les vertex array. Afficher des lignes est un jeu d'enfant, mais par contre je n'arrive pas à afficher une texture.
Voilà mon code de test :
sf::Texture textureCube;
textureCube.loadFromFile("Ressources/Entites normales/0.png");
sf::VertexArray lines(sf::LinesStrip, 5);
lines[0].position = sf::Vector2f(0, 0);
lines[1].position = sf::Vector2f(40, 0);
lines[2].position = sf::Vector2f(40, 34);
lines[3].position = sf::Vector2f(0, 34);
lines[4].position = sf::Vector2f(0, 0);
lines[0].texCoords = sf::Vector2f(0, 0);
lines[1].texCoords = sf::Vector2f(40, 0);
lines[2].texCoords = sf::Vector2f(40, 34);
lines[3].texCoords = sf::Vector2f(0, 34);
lines[4].texCoords = sf::Vector2f(0, 0);

fenetre.draw(lines, &textureCube);
Je vois bien que la texture se place aux bonnes coodonnées, mais elle n'est affichée que sur les lignes, pas à l'intérieur de mon carré. Comment je peux faire pour afficher la texture entièrement ?
Sinon j'ai du mal à voir comment faire pour afficher toute une map en un seul draw (ou plusieurs car j'ai différentes textures de cubes).

EDIT : c'est bon pour le remplissage avec la texture. Il suffisait de mettre Quads (et d'enlever le dernier vertex de l'array) au lieu de LinesStrip. Mais je vois toujours pas comment afficher plusieurs cubes en un draw.
« Modifié: Janvier 04, 2013, 01:28:57 pm par Nikogram »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème de performance avec beaucoup de sprites à l'écran
« Réponse #6 le: Janvier 04, 2013, 01:35:31 pm »
Si tu veux voir des carrés au lieu de lignes, change sf::LinesStrip en sf::Quads.

Pour afficher toute une map, c'est très simple, il suffit de mettre plus d'un quad dans ton vertex array.

sf::Texture textureCube;
textureCube.loadFromFile("Ressources/Entites normales/0.png");

sf::VertexArray quads(sf::Quads, width * height * 4);
for (int i = 0; i < width; ++i)
    for (int j = 0; j < height; ++j)
    {
        sf::Vertex* quad = &quads[(i + j * height) * 4];

        quad[0].position = sf::Vector2f(i * tile_width, j * tile_height);
        quad[1].position = sf::Vector2f((i + 1) * tile_width, j * tile_height);
        quad[2].position = sf::Vector2f((i + 1) * tile_width, (j + 1) * tile_height);
        quad[3].position = sf::Vector2f(i * tile_width, (j + 1) * tile_height);

        // même délire pour les coordonnées de texture...
    }

fenetre.draw(quads, &textureCube);

Attention à l'ordre des quads, si certains se chevauchent. Les derniers dans le vertex array seront les derniers affichés.
« Modifié: Janvier 04, 2013, 01:37:30 pm par Laurent »
Laurent Gomila - SFML developer

Nikogram

  • Newbie
  • *
  • Messages: 39
    • Voir le profil
    • E-mail
Re : Problème de performance avec beaucoup de sprites à l'écran
« Réponse #7 le: Janvier 04, 2013, 02:00:29 pm »
Merci bien ^^ J'en ai affiché 100*100 et effectivement ça consomme presque aucune ressource (bon y avait un bon lot qui sortait de l'écran quand même, peut-être que c'est pour ça). J'ai plus qu'à adapter ça à mon système de posiition de cubes.

J'ai une dernière petite question : ma map est composé de plusieurs types de blocs, ayant chacun leur texture. Donc ça peut donner quelque chose comme l'image de G.. Je me demande comment gérer ça en un seul draw, car si j'en fais plusieurs, il va y avoir des problème de positionnement (les cubes d'une certaine texture se retrouveront devant ou derrière tous les autres).
Y a t-il donc la posibilité de choisir une texture par quad ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème de performance avec beaucoup de sprites à l'écran
« Réponse #8 le: Janvier 04, 2013, 02:13:09 pm »
Tu ne peux utiliser qu'une seule texture par vertex array, pas moyen de faire autrement.

Mais ne peux-tu pas regrouper toutes tes images de cubes dans une seule texture ?
Laurent Gomila - SFML developer

Nikogram

  • Newbie
  • *
  • Messages: 39
    • Voir le profil
    • E-mail
Re : Problème de performance avec beaucoup de sprites à l'écran
« Réponse #9 le: Janvier 04, 2013, 02:18:06 pm »
Ah oui j'avais pas pensé à ça. Suffit de changer la valeur des texCoords en fonction de la texture du cube.
Merci  ;)