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

Auteur Sujet: [SFML 2.0]sf::Sprite getPixel  (Lu 6362 fois)

0 Membres et 1 Invité sur ce sujet

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
[SFML 2.0]sf::Sprite getPixel
« le: Avril 18, 2012, 02:14:57 pm »
Bonjour,

J'ai une questions sur les sf::Sprites.

Les sf::Sprites ne peuvent contenir plus que des sf::Textures et ils n'ont plus la méthode getPixel() or les Textures n'ont pas ces méthodes elles-aussi.

Il faut donc faire un getTexture() puis un copyToImage() pour enfin faire un getPixel().

Or, le getPixel est très utile pour détecter la collision de la souris avec des images où certaines zones sont transparentes (= pas de collision dessus).

Or la détection est une méthode appelée assez fréquemment, et le copyToImage() est une méthode assez lourde...

Existe-t-il une méthode plus légère?
Sachant qu'on ne sait pas forcément quelle image est dans un sf::Sprite...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #1 le: Avril 18, 2012, 02:17:01 pm »
Une indication est donnée dans la documentation de sf::Texture :

Citer
Since they live in the graphics card memory, the pixels of a texture cannot be accessed without a slow copy first. And they cannot be accessed individually. Therefore, if you need to read the texture's pixels (like for pixel-perfect collisions), it is recommended to store the collision information separately, for example in an array of booleans.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #2 le: Avril 18, 2012, 02:33:29 pm »
Donc à chaque sf::Texture, il va falloir que je fasse correspondre un tableau de booléen (= redondance d'informations) et ensuite à chaque sf::Sprite, il va falloir que je fasse correspondre un pointeur sur le tableau de booléen associé au sf::Texture qui sera "contenu" dans le sf::Sprite.

Pourquoi ne pas avoir laissé le getSprite() dans le sf::Sprite ou d'avoir laissé la possibilité de mettre des sf::Image dans les sf::Sprite, on aurait pas perdu grand chose et ça aurait tout de même simplifié pas mal de choses?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #3 le: Avril 18, 2012, 02:45:21 pm »
Avant c'était bien, c'était chouette, mais c'était très largement sous-optimisé. Il faut bien comprendre que sf::Image/sf::Sprite n'étaient pas magiques : pour permettre cette grande facilité d'utilisation il y avait des traitements inutiles et des informations dupliquées, et au final ça pénalisait les gens qui voulaient faire des trucs plus fins et optimisés.

Là c'est sûr, tu dois faire un peu plus de choses, mais au moins elles collent très exactement à tes besoins, ni plus ni moins.

Il faut bien prendre le temps de comprendre ce qu'impliquent les modifications qui ont été faites, et ce qu'impliquerait ce que tu suggères ; quand je vois "on aurait pas perdu grand chose" je pense que tu ne t'es pas assez penché sur la question ;)
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #4 le: Avril 18, 2012, 03:00:23 pm »
Les images contenues dans les sf::Textures sont stockées en mémoire comment?
Je suppose qu'ils ne sont pas stocké au format binaire rgba mais plutôt sous un format compressé ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #5 le: Avril 18, 2012, 03:07:00 pm »
Non, c'est du RGBA 32-bits classique. Mais comme la documentation l'indique, c'est stocké sur la carte graphique, les accès en lecture y sont donc lents et limités.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #6 le: Avril 18, 2012, 03:17:50 pm »
Donc pour construire mon tableau de collision, il vaut mieux enregistrer l'image temporairement dans une sf::Image puis à partir de la sf::Image faire une sf::Texture ou faire directement la sf::Texture puis passer par un sf::Image pour construire mon tableau?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #7 le: Avril 18, 2012, 03:25:22 pm »
Je dirais que ça a peu d'importance, étant donné que ça ne sera fait qu'une fois pendant l'initialisation. Si la second solution prend un pouillème plus de temps à s'exécuter personne ne le verra.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #8 le: Avril 20, 2012, 03:33:49 pm »
J'ai un peu réfléchis.

Pour les sf::Sprite qui n'ont pour image qu'une image directement chargée directement depuis un fichier, il suffit d'avoir un sf::Texture pour la source et un sf::Image pour les collisions (ou autres)

Mais un sf::Sprite peu aussi être composé (via sf::RenderTexture) de plusieurs images "basiques", pour les collisions cela deviens donc plus compliqué.

D'un côté, à partir des sf::Images, on peut faire des tableaux et essayer de "fusionner" les tableaux en même temps qu'on dessine sur une sf::RenderTexture.

Mais au final, n'est-il pas plus rapide (et plus simple) de faire une getTexture sur le sf::Sprite puis d'obtenir l'image à partir de la sf::Texture ?

Car certes l'accès aux données de la cartes graphiques sont lent, mais d'un autre côté on a plus à "fusionner" les tableaux de pixels nous même ce qui me semble tout de même plus lent qu'un accès en lecture sur la carte graphique.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #9 le: Avril 20, 2012, 03:41:49 pm »
C'est clair que tu ne vas pas t'amuser à créer toi-même le masque de collision d'une texture composée, ça n'a aucun intérêt comparé au fait de le générer automatiquement depuis la texture.

Comme je te l'ai dit, du moment que ce n'est fait qu'une fois, on se fout un peu du temps que ça prend ;)
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #10 le: Avril 20, 2012, 03:55:04 pm »
Dans des images composées, les éléments seront susceptibles de changer de place.

Donc ceci sera fait au maximum 60 fois par secondes.

Je dis bien au maximum car je pense mettre un booléen pour savoir si une modification a été effectuée dans l'image afin d'éviter des actions inutiles.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #11 le: Avril 20, 2012, 03:59:05 pm »
Dans quel cas as-tu besoin de recréer une texture 60 fois (max) par seconde, et de récupérer ses infos de collision ?

Peux-tu m'en dire plus sur ton cas d'utilisation ?
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #12 le: Avril 20, 2012, 05:02:11 pm »
C'est vrai que sauf circonstances extrêmes 60 fois par secondes est très improbable si on utilise un booléen pour savoir s'il y a eu des modifications ou non.

Le seul problème qu'il pourrait subvenir, c'est que la boucle d'affichage est exécutée toutes les 1/60 secondes minimum (et on essaye de s'y tenir au maximum) mais je pense que cela reste très large pour ce qu'on fait.

L'une des "circonstances extrêmes" que j'ai trouvé, c'est une de mes "fenêtres" ( élément graphique spécifique dessiné sur la sf::RenderWindow ) qui serait défini comme l'ensemble de ses éléments (ie pas de "fond", on dessine sur un rectangle transparent et tout ce qui est transparent ne ferait alors pas partie de la fenêtre).

(d'ailleurs ça me donne des idées pour accélérer certaines détections de collisions entre souris et certains éléments de décors fixes)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0]sf::Sprite getPixel
« Réponse #13 le: Avril 20, 2012, 05:06:45 pm »
Citer
L'une des "circonstances extrêmes" que j'ai trouvé, c'est une de mes "fenêtres" ( élément graphique spécifique dessiné sur la sf::RenderWindow ) qui serait défini comme l'ensemble de ses éléments (ie pas de "fond", on dessine sur un rectangle transparent et tout ce qui est transparent ne ferait alors pas partie de la fenêtre).
En général, les interfaces graphiques font des tests de collision récursifs pour la souris. Donc tu ne testes pas la fenêtre directement, mais tu cherches plutôt à savoir sur quel composant enfant de la fenêtre la souris se trouve, et par conséquent si c'est aucun c'est que la souris n'est pas sur la fenêtre.
Laurent Gomila - SFML developer

 

anything