Forum de la communauté SFML

Aide => Général => Discussion démarrée par: coco le Juin 28, 2012, 01:45:05 pm

Titre: Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juin 28, 2012, 01:45:05 pm
Bonjour à tous !

Je travaille actuellement sur un jeu ( Exodus (http://www.galhmac-game-studio.com/Exodus-Alpha) ) utilisant un moteur de jeu maison, lui-même basé sur SFML. Nous utilisons une version un peu modifiée de SFML ( je ne connais pas exactement les détails des modifications effectuées, mais je pourrais me renseigner ), et nous sommes basés sur une version de SFML pré-2.0 ( un peu avant les changements de noms, l'ajout de transformable... ). Je n'ai pas toutes les infos a ce sujet puisque ce n'est pas moi qui m'en suis occupé, mais je pourrais obtenir des compléments d'info si besoin.

Sur la version de SFML que nous utilisons, nous avons encore le bug connu sur les cartes ATI, ce qui doit être "normal". J'ai cherché un peu sur le forum les solutions possibles :

- Passer à la sfml 2.0 : Nous avons déjà essayé, mais nous avons eu plein de soucis ( probablement dus au modifications que nous avons faites sur SFML, entre autres ), et nous pensons que ça nous prendrait beaucoup de temps.

- Version Static : Ce que j'essaye depuis un petit moment. Effectivement, ca corrige le pb sur les ATI, cependant j'ai 2 soucis avec la static que je n'ai pas avec la dynamic : Il semble qu'avec du nvidia ( au moins sur 2 pc différents ), j'ai un problème sur les images chargées dans un thread : elle restent blanches jusqu'à ce que j'arrive dans leur map, puis elles s'affichent. Au bout d'un petit temps, le jeu ( framerate ), voir le pc, commencent a partir en vrille ( j'ai eu des freezes de l'OS sur mon pc perso ( Trust ) ). Sur ATI en static, ça semble fonctionner correctement, mais au bout d'un temps, le framerate tombe à 10 ou moins, et le rendu des sprites prend vraiment beaucoup plus de temps qu'avant ( plus de RAM graphique ? ).

A savoir que je considère que le tout fonctionne "parfaitement" avec notre version de sfml en dynamic, mis a part sur les ATI.

Du coup après avoir un peu tout testé ( je crois ), je tenterai bien de corriger le bug ATI sur la dynamic de notre version ( même si c'est la solution la moins simple en théorie, mais dans notre cas je ne sais plus trop quelle solution est la plus simple ). Pour cela, j'aurais apprécié d'avoir quelques infos sur les sections qui posaient problème sur une ATI en dynamic ( je suppose les modules window et/ou graphic, mais quoi exactement ? ).

Toute aide sera la bienvenue =)

Colin

ps: Je sais que le sujet a déjà été largement traité, j'ai cherché avant de poster, mais il est possible que j'ai manqué le bon thread...

ps2: Pour l'instant nous travaillons sur Windows.
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juin 28, 2012, 01:53:29 pm
Ces problèmes que tu as avec la version statique... c'est pas normal du tout.

Pour ce qui est de corriger le bug ATI, l'énoncé est simple : il faut éviter la construction/destruction de contexte OpenGL en dehors du main() (je ne sais plus exactement où cela arrive avec un vieux SFML, il faut fouiller le module Window).

Mais franchement bon courage, j'ai dû reprendre toute la gestion des contextes OpenGL pour corriger ce bug. Mais votre version pré-2.0 est si vieille que ça ?

Le mieux serait sans doute de vous mettre à jour sur la toute dernière version. Et de me parler des modifications que vous avez effectuées.
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juin 28, 2012, 02:16:13 pm
Je suis d'accord pour la static, étant donné que nous avons commencé a travailler avec la static, sans avoir de soucis, puis nous sommes passés sur la dynamic il y a un an environ ( sans avoir connaissance du bug ATI ). Je pense que ce problème de static vient de nous, j'ai essayé de chercher ( pb de compil et/ou de libs ? ), mais j'ai pas encore trouvé...

Je pense aussi que passer sur la 2.0 serait la meilleure solution ( je crois en plus que certaines optis ont été appliquées, ce qui pourrait nous être utile... ), mais mon collègue avait déjà essayé et rencontré plein de soucis ( je lui laisse la main pour expliquer ces problèmes et les modifs qu'il a fait sur la SFML, quand il aura le temps ).

Le développement de notre moteur maison a  débuté il y a 3 ans sur la 1.6, nous avons essayé de mettre a jour en même temps que tu mettais a jour SFML vers 2.0, mais il y'a eu un soucis lors de changements majeurs, et on a décider de rester sur la version qui fonctionnait. Et ça nous retombe dessus maintenant ^^

Donc oui, ça date un peu =)

Je vais essayer de tracer la dynamic sur un pc avec une ATI pour voir ce que ça donne. Merci pour les infos en tout cas ^^

Edit :

Yeah !!

J'ai réussi a contourner le problème ( la fenêtre qui ne s'ouvre pas sur ATI ) en changeant les ContextType "referenceContext" et "defaultContext" (GlContext.cpp) en pointeurs. J'ai fait une fonction pour les créer et une pour les détruire que j'appelle au tout début et en toute fin du main. Du coup, le programme se lance normalement. Cependant, j'ai toujours ce problème de framerate qui tombe au bout d'un temps, je vais faire des tests sur d'autres configs pour voir si ça semble venir d'ATI ou de notre version d'SFML et/ou moteur.

En tout cas, merci pour l'info, ça m'a beaucoup aidé !!

Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juin 29, 2012, 10:18:34 am
Comme par hasard, on trouve toujours ce qu'on cherche après avoir posté :

http://en.sfml-dev.org/forums/index.php?topic=3438.0

On a toujours des soucis de framerate/freeze nvidia. Je suppose que ca vient de nous (moteur ou version de sfml ). On va donc essayer de passer sur la dernière 2.0

D'ailleurs il s'avère que nous n'avions pas fait de modifs internes a sfml, juste quelques const_cast pour pouvoir accéder a certains éléments. Mon ignorance me fait dire des bêtises ^^

Sinon pour le bug ATI sur la dynamic de la 1.6, effectivement il suffit de faire une fonction init et deinit et de passer les contextes réference et default en pointeurs. Je pourrais modifier les 3-4 fichiers nécessaires sur la 1.6 et les partager s'il y a encore des personnes qui rencontrent ce problème.

To be continued... =)
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juin 29, 2012, 10:47:47 am
Citer
Comme par hasard, on trouve toujours ce qu'on cherche après avoir posté
Mince, je ne me souvenais plus du tout que j'avais déjà donné une solution détaillée, désolé ;D
En tout cas c'est bien, vous avez tout de suite réussi à trouver la bonne solution.

Citer
Sinon pour le bug ATI sur la dynamic de la 1.6, effectivement il suffit de faire une fonction init et deinit et de passer les contextes réference et default en pointeurs. Je pourrais modifier les 3-4 fichiers nécessaires sur la 1.6 et les partager s'il y a encore des personnes qui rencontrent ce problème.
SFML 1.6 est déjà plus ou moins obsolète, je ne sais pas si ça vaut le coup.
En plus la correction serait sans doute un peu différente, j'avais déjà fait des modifs sur les contextes dans la version que vous utilisez -- si je me souviens bien.
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juillet 03, 2012, 01:43:12 pm
Le portage est en cours ( argh tous les noms ont changé ! )...

J'ai cru comprendre que la fonction draw remplace la fonction Render, mais elle est passée de protected à private, du coup impossible de l’appeler dans une classe fille ( a moins que mes connaissances en C++ ne soient un peu limitées ou que j'ai omis un détail... ).

Pour prendre un exemple, on a surchargé le draw du Text pour ajouter des appels openGL ( clip plane ) avant et après le draw, ce qui n'est plus trop possible apparement. De plus, il me semble impossible de refaire le draw du text "simplement" puisque tout est en private...

Aurais-je loupé une info ?

ps : C'est bien la classe ConvexShape qui propose les même possibilités que l'ancienne classe Shape ?
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: kimci86 le Juillet 03, 2012, 07:33:57 pm
Bonjour,
La méthode draw remplace la méthode ... Draw.
Chez les Drawables, elle est protected.
Celle des RenderTarget est public.

Pour la classe personnalisée de texte, il faudrait:
void CustomText::draw(sf::RenderTarget& target, RenderStates states) const
{
    /*
    mettre en place le clipping
    */


    // on dessine l'objet en tant que sf::Text
    sf::Text::draw(target, states);

    /*
    mettre fin au clipping
    */

}

J'espère vous avoir aidé.
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juillet 03, 2012, 09:22:38 pm
C'est ce que j'ai essayé de faire en premier, mais mon compilo n'aime pas trop l'appel a une fonction privée de la classe mère dans une classe fille ( en héritage public )...

Pour la fonction Render, c'est ce qu'on redéfinissait ( en tant que draw ) sur notre ancienne version de SFML. C’était peut être des modifs temporaires entre la 1.6 et la 2.0...
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juillet 03, 2012, 11:14:24 pm
La fonction draw est protégée, pas privée.

Render était en effet une modif intermédiaire.
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juillet 04, 2012, 09:31:18 am
Sur la version sfml que j'ai téléchargé ( 2.0 rc ), elle est effectivement protégée sur Drawable, mais privée sur sf::Text. Et ceci ne compile pas :

namespace cream
{
//...
void Text::draw(sf::RenderTarget& target, RenderStates states) const
{
    /*
    code
    */


    // on dessine l'objet en tant que sf::Text
    sf::Text::draw(target, states);

    /*
   code
    */

}
//...
}
 

( impossible d'accéder à private membre déclaré dans la classe 'sf::Text' )

Ce code est censé compiler ?

Par ailleurs, Je ne comprends pas bien pourquoi elle est protégée sur Drawable et privée sur Text, Shape, Sprite...

Du coup, dans les classes qui en héritent, on est censés mettre le draw en protected ou en private ?
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: kimci86 le Juillet 04, 2012, 09:41:44 am
Je pense que cette astuce peut fonctionner:

void cream::Text::draw(sf::RenderTarget& target, RenderStates states) const
{
    /* ... */
    target.draw(static_cast<const sf::Text&>(*this), states);
    /* ... */
}
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juillet 04, 2012, 12:13:58 pm
Citer
Ce code est censé compiler ?
Non :)

Citer
Par ailleurs, Je ne comprends pas bien pourquoi elle est protégée sur Drawable et privée sur Text, Shape, Sprite...
C'est un moyen un peu vicieux de décourager les gens à dériver de ces classes. Elles ne sont pas vraiment faites pour.

Citer
Du coup, dans les classes qui en héritent, on est censés mettre le draw en protected ou en private ?
Comme tu veux, c'est toi qui décide de la conception de ta classe en fonction de son utilisation prévue. Mais dans tous les cas tu ne pourras pas appeler celle de la classe mère.

Citer
Je pense que cette astuce peut fonctionner:
Non, ça va rappeler cream::Text::draw puisqu'elle est virtuelle.
Cette limitation étant conceptuelle (et donc voulue), pas besoin de chercher d'astuce pour contourner. Si je voulais que ce soit possible je changerai directement l'accès de privé à protégé dans les classes concernées :P
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: kimci86 le Juillet 04, 2012, 12:22:42 pm
Quelles sont donc les raisons de telles limitations ?
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juillet 04, 2012, 12:48:09 pm
Je ne veux pas que les gens dérivent de ces classes car dans 99% des cas leur solution est incorrecte (du point de vue du design). J'essaye de les orienter vers les bons choix, qui est de les utiliser par aggrégation.

Après, on peut bien sûr discuter de chaque cas, et je me ferai un plaisir de revenir sur mes choix si quelqu'un me donne un excellent contre-exemple.
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juillet 04, 2012, 02:14:29 pm
C'est donc bien intentionnel ^^. Du coup je vais essayer de récupérer les sources et faire cette modif' ( private => protected ), parce que j'en ai vraiment besoin ( impossible de revoir tout le design du moteur juste pour ça pour le moment ).

Je ne suis pas sur de pouvoir fournir un excellent contre exemple, ou encore d'affirmer que notre solution est valable du point de vue design. Nous héritions des classes sfml principalement pour les interfacer avec nos systèmes de load/save a partir de fichiers / flux, ainsi que pour la gestion du positionnement des objets une fois insérés dans nos "Maps" ( positionnement local par rapport a la map parente pour l'affichage, Global pour la physique et autres... ). Nous avions aussi besoin de redéfinir les draw pour appeler automatiquement une update dans ce dernier ( mise a jour des animations pour les sprites, lancement&mise a jour de scripts lua, etc...).

Par exemple, pour les Sprites, nous avons redéfini les draw pour qu'ils gèrent certains cas supplémentaires ( animations/spritesheets etc... ), mais comme on utilise directement openGL pour afficher ( ou le Renderer à l'époque ou il existait ), on n'a pas ce souci protected/private. Par contre pour les textes, ça nous arrange de ne pas refaire l'affichage, qui doit être un brin plus complexe que celui de Sprite =)

On pourrait aussi sortir l'activation / désactivation des clip planes du draw pour l’appeler avant/après chaque affichage de texte, mais c'est beaucoup plus pratique que ce soit directement intégré dans le draw ( surtout quand on a un moteur et 3 jeux qui tournent dessus à convertir )

En tout cas, merci pour les infos =)
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juillet 04, 2012, 02:29:24 pm
Merci pour les détails :)

Citer
Nous héritions des classes sfml principalement pour les interfacer avec nos systèmes de load/save a partir de fichiers / flux
Ce genre de chose se fait très bien en dehors des classes, typiquement avec des fonctions surchargées. D'ailleurs il n'y a pas à aller bien loin pour le constater : pour rendre une classe X compatible avec std::ostream, tu n'as pas besoin de dériver de X, il faut uniquement fournir une surcharge de l'opérateur <<.

Citer
ainsi que pour la gestion du positionnement des objets une fois insérés dans nos "Maps" ( positionnement local par rapport a la map parente pour l'affichage, Global pour la physique et autres... )
Ca je ne commente pas car j'ai du mal à voir ce que ça implique au niveau du code.

Citer
Nous avions aussi besoin de redéfinir les draw pour appeler automatiquement une update dans ce dernier
Ouhlala que c'est moche ça :P
Ne jamais mettre dessin et mise à jour ensemble ! C'est la solution de facilité pour les fainéants dans les codes courts, mais dans un moteur complet, non. D'ailleurs pour éviter ça j'ai mis une autre barrière : la fonction draw est const ;)

Remarque globale : qu'est-ce qui vous empêche d'avoir des classes qui contiennent des sprites/textes/shapes, plutôt que des classes qui en dérivent ? Vous faites vos propres sf::Drawable, avec leur propre interface publique qui colle pile poil à votre moteur, et dedans vous utilisez un sf::Sprite, un sf::Text, etc. Et là vous restez maîtres à 100% de votre design, vous utilisez SFML uniquement comme outil d'implémentation. C'est ça que je défend comme conception avec le design que j'ai choisi pour les classes de SFML.
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juillet 09, 2012, 10:37:33 am
Salut !

J'ai bien avancé sur le portage, sans que ce soit pour autant fini. J'ai pas trouvé la 2.0rc en recompilable ( j'ai surement mal cherché ), donc j'ai récup un snapshot du dépot. Pour l'instant j'ai modifié la lib en attendant d'avoir le temps de me pencher sur les suggestions que tu nous as fait. Ca nous embêtait un peu de contenir les objets sfml dans nos sprites, car ça nous oblige a faire des accesseurs d'accesseurs pour les données de sfml. C'est tout aussi perturbant de faire un getSprite sur un Sprite...

On essaiera de revoir le design lorsqu'on aura du temps pour ça =)

Sinon j'ai rencontré un autre problème :

En dynamic, J'ai un crash lorsque je quitte le progamme en ayant instancié un objet audio, je pense plus ou moins lié à ce bug (sur Trust ~= XP )

https://github.com/SFML/SFML/issues/30

La static corrige effectivement le problème, mais bon c'est pas l'idéal pour la dynamic. Si j'ai bien compris, ce bug ne sera pas corrigé pour la 2.0 mais la suivante ? C'est pas un peu le même genre de problème que pour l'ATI sur la 1.6 ?

Merci =)

Colin

Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juillet 09, 2012, 10:40:20 am
En effet ce sera corrigé pour la 2.1, et en effet c'est le même genre de bug que 1.6/ATI :)
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juillet 09, 2012, 10:57:31 am
Il "suffirait" donc de faire une fonction init/deinit pour les contextes openAL ?

Sinon pour la 2.1, il y aura des modifs niveau utilisateur par rapport à la 2.0 ? Et tu as une estimation du délai avant qu'elle soit prête ?

Merci pour ces réponses =)
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juillet 09, 2012, 11:10:31 am
Aucune idée. Je fais les choses l'une après l'autre, et pour l'instant je suis encore dans 2.0 ;)
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juillet 20, 2012, 01:47:11 pm
Bonjour !

On a finalement réussi tant bien que mal a passer à la 2.0. Le moteur et les jeux tournent, j'ai du revoir certaines parties, mais ça c'est plutôt bien passé dans l'ensemble.

En revanche j'ai trouvé 2 problèmes ( je pense pouvoir fournir un code minimal si besoin )

- Spécifique ATI, apparement :
En parcourant le forum, j'ai cru comprendre qu'il n'y avait plus besoin de déclarer un sf::Context dans les threads pour charger les textures. Sur une nvidia ça fonctionne, par contre sur un pc avec une ATI, une texture chargée dans un thread, puis liée à un sprite lui même dessiné dans le main thread ne s'affiche pas. Déclarer un sf::Context dans le thread corrige le problème.

- Général
C'est peut-être "normal", mais si on associe une texture à un sprite de la façon suivante :
sf::Sprite sprite;
sprite.setTexture(sf::Texture());
 
Ensuite si on le dessine ( avec cette texture "vide" ), puis on change de texture pour une texture "valide", le sprite avec la nouvelle texture ne s'affiche pas a l'écran.

A part cela, j'aurais une petite question sur les sf::Texture. Si j'ai bien compris, elle sont chargées sur la RAM graphique. Que se passe t'il si on essaie de charger une image alors qu'il n'y a plus de RAM graphique ( a moins que ça ne puisse pas arriver ) ?

Merci,
Colin
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juillet 20, 2012, 04:29:37 pm
Citer
- Spécifique ATI, apparement :
En parcourant le forum, j'ai cru comprendre qu'il n'y avait plus besoin de déclarer un sf::Context dans les threads pour charger les textures. Sur une nvidia ça fonctionne, par contre sur un pc avec une ATI, une texture chargée dans un thread, puis liée à un sprite lui même dessiné dans le main thread ne s'affiche pas. Déclarer un sf::Context dans le thread corrige le problème.
Je veux bien un code complet minimal, et un peu plus d'infos (OS, ...).

Citer
Ensuite si on le dessine ( avec cette texture "vide" ), puis on change de texture pour une texture "valide", le sprite avec la nouvelle texture ne s'affiche pas a l'écran.
Il faut utiliser le second paramètre de setTexture.

Citer
A part cela, j'aurais une petite question sur les sf::Texture. Si j'ai bien compris, elle sont chargées sur la RAM graphique. Que se passe t'il si on essaie de charger une image alors qu'il n'y a plus de RAM graphique ( a moins que ça ne puisse pas arriver ) ?
Une erreur, j'imagine. Mais mieux vaut ne pas en arriver là, si tu veux mon avis ;)
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Juillet 20, 2012, 05:10:29 pm
1 - J'ai oublié de préciser un peu, désolé ^^
Là, J'ai fait des tests sur Windows 7, avec une ATI et avec une Nvidia. Ca fonctionne bien sur le pc Nvidia et pas sur l'ATI. Je pense que les drivers de l'ATI sont a jour ( de fin juin ).

nb : Je te laisse remplacer l'image chargée par celle de ton choix...

sf::Texture* texture = NULL;

void createTexture()
{
   //sf::Context glContext; //Fonctionne correctement sur ATI si cette ligne est décommentée
   
   texture = new sf::Texture();
   texture->loadFromFile("image.png");//Changer pour une image accessible
}

int _tmain(int argc, _TCHAR* argv[])
{
   sf::RenderWindow window;

   window.create(sf::VideoMode(500,500,32), "test app");

   sf::Thread createThread(createTexture);

   createThread.launch();
   createThread.wait();

        sf::Sprite sprite;
   sprite.setTexture(*texture);

   bool loop = true;
   while ( loop )
   {
      sf::Event sfEvent;
      while (window.pollEvent(sfEvent))
      {
         if (sfEvent.type == sf::Event::Closed )
            loop = false;
      }

      window.clear(sf::Color::Black);
      window.draw(sprite);
      window.display();
   }

   delete texture;
   texture = NULL;

   window.close();
   return 0;
}
 

Si tu as besoin de plus d'informations...

2 - J'avais pas vu ce paramètre... ça peut aider ^^

3 - Je pense aussi que ça va poser problème, d'où ma question. Ce que je voulais dire, c'est est-ce qu'il les chargera en RAM normale si la RAM graphique est pleine ? Parce que sinon selon la capacité de la carte graphique de l'utilisateur, ça risque de poser plein de problèmes... du coup, ça limite beaucoup la quantité d'image utilisables en même temps ( par rapport a la 1.6 ), non ? Parce que là j'ai pas les chiffres exacts, mais sur Exodus on arrivait bien a 900 MO de ram ( dont surement au moins les 2/3 d'images, estimation rapide ). Si on peux compter sur n'importe quel pc un minimum récent pour avoir au moins 2GO de ram software, c'est pas la même pour celle des cartes graphiques...

Je suis loin d'être expert, c'est pour cela que je me renseigne...


Merci =)
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Juillet 20, 2012, 07:38:34 pm
1- Merci, je regarde ça dès que possible.

3- Le mieux est de tester directement, je ne peux pas te donner une réponse sûre à 100%.
Titre: Re : Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Haze le Juillet 24, 2012, 12:22:04 pm
Je ne veux pas que les gens dérivent de ces classes car dans 99% des cas leur solution est incorrecte (du point de vue du design). J'essaye de les orienter vers les bons choix, qui est de les utiliser par aggrégation.

Après, on peut bien sûr discuter de chaque cas, et je me ferai un plaisir de revenir sur mes choix si quelqu'un me donne un excellent contre-exemple.
J'ai toujours eu pour habitude de faire hériter mes entitiés graphiques de sf::Sprite dans mes jeux. Je peux ainsi les dessiner directement — target.draw(entity) — et réutiliser les méthodes de sf::Sprite.

Si j'utilise l'aggrégation, je dois :
- soit mettre un getter non constant sur le sprite (crade...)
- soit recoder les méthodes nécessaires et les rediriger vers l'attribut sprite (redondance de code)

Quel intérêt aurais-je à utiliser l'aggrégation plutôt que l'héritage ?
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Hiura le Juillet 24, 2012, 01:47:31 pm
Citer
soit recoder les méthodes nécessaires et les rediriger vers l'attribut sprite (redondance de code)
Si tu veux faire ça, il y a un petit truc qui est plus court mais qui revient au même (avec la restriction que ça ne marche uniquement si tu as un seul attribut de type T) :

struct T { void foo(); };

class U1 {
    T myT;
public:
    void foo() { myT.foo(); }
};

class U2 : private T {
public:
    using T::foo;
};

U1 et U2 sont strictement équivalent pour l'utilisateur.

(Je n'ai pas lu toute la discussion, cette technique générale ne s'applique donc pas forcement à ton cas!)
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: mccusti le Juillet 24, 2012, 01:59:39 pm
Avec SFML 2 tu peux hériter de sf::Drawable pour pouvoir écrire target.draw(entity). Tu peux aussi hériter de sf::Transformable pour manipuler ton sprite à ta guise, sf::Sprite héritant lui-même de sf::Transformable. Enfin il reste les méthodes propres au sprite, du type setTexture. Ca fait peu de méthodes, surtout que toutes ne seront pas forcément utiles à la classe que tu écris. Donc ça permet, comme le disait Laurent, de supprimer des méthodes auxquelles l'utilisateur ne doit pas avoir accès. Tu as un très bon exemple ici http://fr.sfml-dev.org/forums/index.php?topic=8148.msg54382#msg54382 (http://fr.sfml-dev.org/forums/index.php?topic=8148.msg54382#msg54382) où Laurent explique bien mieux les choses que moi.
Titre: Re : Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Haze le Juillet 24, 2012, 02:27:02 pm
struct T { void foo(); };
class U1 {
    T myT;
public:
    void foo() { myT.foo(); }
};

class U2 : private T {
public:
    using T::foo;
};

U1 et U2 sont strictement équivalent pour l'utilisateur.
Merci ! Je ne connaissais pas cet usage de using. Très pratique pour exposer uniquement certaines méthodes de sf::Sprite, et ainsi ne pas surcharger l'interface publique des mes classes d'entité.
Mais on parle toujours d'héritage, et non de composition  ;)


Tu peux aussi hériter de sf::Transformable pour manipuler ton sprite à ta guise, sf::Sprite héritant lui-même de sf::Transformable.
Justement, puisque sf::Sprite hérite de sf::Transformable, je ne vois pas l'intérêt d'hériter de sf::Transformable si j'ai déjà un attribut sprite, ce serait redondant d'avoir 2 fois la matrice de transformation, et d'appliquer 2 fois les transformations (il faut bien transmettre l'info dans les sf::RenderStates au moment de dessiner le sprite).

Citation de: mccusti
Donc ça permet, comme le disait Laurent, de supprimer des méthodes auxquelles l'utilisateur ne doit pas avoir accès.
L'héritage privé m'a l'air la solution la plus adéquate pour ça (+ l'astuce de Hiura pour autoriser certaines méthodes uniquement), et celle qui requiert le moins de code également.

(Je n'ai pas lu toute la discussion, cette technique générale ne s'applique donc pas forcement à ton cas!)
Rien à voir avec le problème de l'OP, j'ai juste rebondi sur une citation de Laurent
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Hiura le Juillet 24, 2012, 02:48:32 pm
Citer
Mais on parle toujours d'héritage, et non de composition
Pas tout à fait, la nuance est subtile : on parle d'héritage privé et de composition. Ces deux choses sont pratiquement (dans les deux sens du terme, i.e., «pratique» et «approximatif») la même chose. Cline le décrit comme une variante syntaxique. (http://www.parashift.com/c%2B%2B-faq/priv-inherit-like-compos.html)
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Haze le Juillet 24, 2012, 03:07:04 pm
Ok. Si on a les avantages de la composition tout en conservant l'aisance syntaxique offert par l'héritage, c'est tout bon je trouve.
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Août 20, 2012, 02:30:51 pm
Bonjour !

Je reviens sur ce thread car j'ai toujours des soucis de compatibilité ATI et/ou 2.0 que j'ai absolument besoin de corriger.

J'ai testé un peu cette histoire de RAM graphique et normale. Il semble que le programme charge les nouvelles images en RAM normale lorsque la RAM graphique est pleine.

J'avais parlé plus tôt dans ce thread d'un bug sur les Threads avec les cartes ATI ( nécessité de déclarer un contexte explicitement, contrairement à Nvidia, sinon les images ne s'affichent pas ). J'ai l'impression que les images ne sont pas correctement déchargées au bout d'un moment. Sur un PC ATI ( Windows 7-64 ), la ram graphique augmente jusqu'a un point proche du max ( ~960/1024 ). Pendant un petit moment à charger/décharger des images, la RAM graphique oscille et la normale ne bouge pas. Au bout d'un moment, c'est la ram normale qui augmente, mais ne diminue plus lorsque les images sont détruites. lorsque la ram normale atteint un chiffre élevé ( ~1go ), le programme bloque dans la dll openGL d'ati ( pendant le rendu ou pendant un bind texture ).

Je n'ai pas réussi à reproduire ce comportement sur un pc Nvidia ( Windows 7 64 ).

Pour le moment je n'ai pas trouvé la source du problème ( et je galère un peu ). J'ai essayé de déclarer un contexte au moment de la destruction des textures ( et non plus uniquement à la création ), mais j'avais d'autres problèmes...

Petites questions au passage :
- Est-ce qu'une image chargée dans un thread doit être détruire dans le même thread ( même contexte )  ?
- J'ai vu dans les sources SFML qu'il y a une liste de internalContexts qui s'empilent pour chaque nouveau thread, et qui sont détruites uniquement dans la fonction de cleanUp global. C'est probablement de la que vient une partie de la fuite décrite dans ce bug : https://github.com/SFML/SFML/issues/120, et je me demandais si ça pouvait avoir un rapport avec mon problème.

je vais essayer de résumer le fonctionnement, au cas ou quelqu'un détecterait un problème potentiel :

on a un main thread qui fait quasiment tout ( affichage, physique... ). Lorsque le joueur change de map, on a un premier thread qui effectue l'initialisation des nouvelles maps, et qui envoie des requêtes de chargement de textures, effectuées par un troisième thread ( tout ça pendant que le jeu tourne dans le main ). Lorsqu'on s'éloigne d'une map, le premier thread désinitialise les maps et il détruit les textures.

Depuis le passage à la 2.0, on a aussi des chutes de framerate brutales ( localisées principalement dans l'affichage ), que nous n'avions pas sur la 1.6.

Je vais poursuivre mes investigations, et je mettrai a jour si je trouve quelque chose.

Je prends toute info ou suggestion pour essayer de localiser/corriger ce bug ( dans SFML si nécessaire ).

Merci de votre aide.

ps : Lorsque j'ai créé ce thread, j'ai pris le snapshot 2.0-rc-42-[...].
Actuellement c'est le 74 je crois. Serais-ce une bonne idée de mettre a jour au passage ?

ps2 : question "hors sujet" : Est ce qu'il y a déjà eu des jeux commerciaux sortis utilisant SFML ?

edit rapide : J'ai repris et modifié légèrement le code proposé par Ceylo ( https://github.com/SFML/SFML/issues/120 ) de la façon suivante :

#define TEX_SIZE 2048
sf::Image sharedImage;

void thread_func(void *data)
{
   // Reuse the same texture object
   sf::Texture** tex = ((sf::Texture **)data);
   (*tex) = new sf::Texture();

   //sf::Context ctx;

   // Should just erase the previous data
   (*tex)->loadFromImage(sharedImage);
}

int main()
{
   sf::Texture* tex = NULL;
   sharedImage.create(TEX_SIZE, TEX_SIZE, sf::Color::Red);
   sf::Thread th(thread_func, (void *)(&tex));

   sf::RenderWindow window;
   window.create(sf::VideoMode(256,256,32), "test");

   // Create one thread/sec
   while (true)
   {
          th.launch();
          th.wait();

          window.clear();
          sf::Sprite sprite;
          sprite.setTexture(*tex,true);

          window.draw(sprite);
          window.display();
          sprite.setTexture(sf::Texture(), true);
          delete tex;
   }

   return 0;
}
 

Résultat ( toujours sur mon pc win7 64 ATI ) : si je commente la déclaration du contexte dans le thread, j'ai une leak beaucoup plus importante ( ~16 Mo par itération ) contre beaucoup moins si je déclare le contexte dans le thread... C'est probablement lié a la nécessite de déclarer un contexte pour charger les images sur ATI. Si ça peut aider...
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: coco le Août 21, 2012, 04:42:37 pm
MAJ

J'ai fait quelques tests supplémentaires au niveau de l'utilisation de la mémoire graphique. J'ai utilisé le programme GPU-Z de TechPowerUp pour tracer la quantité de mémoire graphique utilisée par notre jeu.

J'ai remarqué que la mémoire graphique ne descendait presque jamais après la destruction d'une texture ( glDeleteTextures() dans le destructeur de Texture ). Après quelques recherches, je suis tombé sur un thread où ils conseillaient d'appeller glFlush() pour s'assurer que la mémoire opengl était correctement désallouée. J'ai donc rajouté des glFlush() juste après la destructions d'images, et, ô miracle, la mémoire graphique semble correcte ( augmente et diminue au fil des chargements/dechargements d'images ). En revanche, j'ai été obligé de placer le glFlush dans le même thread que le déchargement des images, sinon la mémoire n'était pas libérée ( problème de contexte openGL ? ).

Pour obtenir ces résultats, j'ai testé sur les deux pc ( Win 7 64, un avec une Nvidia, un avec une ATI ). J'ai le même comportement avec les deux configs au niveau de la mémoire graphique avec et sans glFlush(), même si le pc Nvidia semble "moins" affecté lorsque sa RAM graphique est blindée que l'ATI.

Est-ce correct d'appeller glFlush() manuellement ? Si quelqu'un a des infos...
Titre: Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: Laurent le Août 21, 2012, 09:00:44 pm
Il est correct d'appeler glFlush manuellement, tout ce que ça fait c'est exécuter les instructions en attente maintenant au lieu de plus tard.

Le seul inconvénient, c'est que ça force une resynchronisation entre le CPU et le GPU, et ça casse tout le parallèlisme entre les deux au moment où tu l'appelles. C'est donc sans danger dans un code final où les appels sont maîtrisés, mais c'est moins évident à placer dans SFML sans savoir de quelles manières seront appelées les fonctions.

Ceci-dit ça m'aide à avancer, merci. Je pense que comme les contextes "éphémères" créés par SFML en interne ne sont détruits qu'à la fin du programme, sans glFlush il se peut que certaines commandes OpenGL n'aient jamais l'occasion d'être exécutées. Du coup ça produit exactement ce que tu as constaté -- et peut-être même plus.
Titre: Re : Re : Demande d'infos : sfml 1.6-2.0, ATI et solutions
Posté par: christophedlr le Septembre 07, 2012, 11:37:08 am
Citer
- Spécifique ATI, apparement :
En parcourant le forum, j'ai cru comprendre qu'il n'y avait plus besoin de déclarer un sf::Context dans les threads pour charger les textures. Sur une nvidia ça fonctionne, par contre sur un pc avec une ATI, une texture chargée dans un thread, puis liée à un sprite lui même dessiné dans le main thread ne s'affiche pas. Déclarer un sf::Context dans le thread corrige le problème.
Je veux bien un code complet minimal, et un peu plus d'infos (OS, ...).

Citer
Ensuite si on le dessine ( avec cette texture "vide" ), puis on change de texture pour une texture "valide", le sprite avec la nouvelle texture ne s'affiche pas a l'écran.
Il faut utiliser le second paramètre de setTexture.

Citer
A part cela, j'aurais une petite question sur les sf::Texture. Si j'ai bien compris, elle sont chargées sur la RAM graphique. Que se passe t'il si on essaie de charger une image alors qu'il n'y a plus de RAM graphique ( a moins que ça ne puisse pas arriver ) ?
Une erreur, j'imagine. Mais mieux vaut ne pas en arriver là, si tu veux mon avis ;)

Non pas d'erreur. si c'est une carte graphique standard, le traitement ne sera pas fait tan que la carte n'aura pas de nouveau de la mémoire disponible. Si maintenant c'est une carte graphique dédiée, elle est extensible, elle prend donc sur la RAM de l'ordinateur.