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

Auteur Sujet: Besoin d'un p'tit coup de main sur un sf::Drawable  (Lu 2302 fois)

0 Membres et 1 Invité sur ce sujet

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Besoin d'un p'tit coup de main sur un sf::Drawable
« le: Janvier 04, 2015, 12:21:54 pm »
Bonjour.

J'ai besoin d'un p'tit coup de main sur l'élaboration de ma sf::Drawable. Je préfère être honnête, il y a certainement quelques notions de c++ qui devront intervenir pour pouvoir m'aider  :o .
a vo't bon coeur messieurs dames  :-\

voila: je stock des adresses d'EI (EntitesImages) dans un std::multiset, dans le but de les trier au fur et a mesure en fonction de leur "m_z", ou zOrder.

J'ai donc mon objet dérivé de sf::Drawable et un froncteur, mais qui ne marche pas. Il compare donc certainement des adresse, et non des m_z , pour zOrder, ou d'autres explication que je ne comprend pas.
Il me semble qu'il faille pour ce faire, appel a une template, (chose que, j’avoue, je ne maîtrise pas, et d'autant plus que je n'ai pas construit la class sf::Drawable ) .

Voici ma sf::Drawable:



class EI : public sf::Drawable
{
public:

    friend struct MonFoncteur;

    void recoitTexture(sf::Texture *texture)
    {
        m_texture = texture;
        m_actif = true;
    }
    void recoitVertex(sf::Vertex vertex[4])
    {
        m_tableauVertex[0] = vertex[0];
        m_tableauVertex[1] = vertex[1];
        m_tableauVertex[2] = vertex[2];
        m_tableauVertex[3] = vertex[3];

    }
    void active(bool actif)
    {
        m_actif = actif;
    }
    void recoitZ(int z)
    {
        m_z = z;
    }

private:

    virtual void draw(sf::RenderTarget& cible, sf::RenderStates states) const
    {
        if(m_actif)
        {
        cible.draw(m_tableauVertex,4, sf::Quads, m_texture);
        }
    }

    bool m_actif;
    float m_z;
    sf::Vertex m_tableauVertex[4];
    sf::Texture *m_texture;

};

struct MonFoncteur
{
   bool operator() (const EI* (*un), const EI* (*deux)) const
   {
       if( (*un)->m_z == (*deux)->m_z)
       {
        return (*un)->m_z;
       }
       else
      return (*un)->m_z < (*deux)->m_z;
   }
};


 


J'ai essayé pleins de possibilités différentes avec le foncteur, mais sans résultat (cette version est sans doute une des plus artistique  :'( ).

Merci beaucoup si vous pouvez m'aider voir , ca me rendrait grand service et me ferait gagner du temps, m'apporter une solution..

Merci  :D


Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Besoin d'un p'tit coup de main sur un sf::Drawable
« Réponse #1 le: Janvier 04, 2015, 01:52:41 pm »
Pour corriger ton foncteur il faut déjà voir la déclaration du multiset.
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : Besoin d'un p'tit coup de main sur un sf::Drawable
« Réponse #2 le: Janvier 04, 2015, 05:05:05 pm »
Merci pour votre réponse.

class Afficheur
{
public:

    Afficheur();
    ~Afficheur();

    void                               recoitFenetre(sf::RenderWindow *fenetre);
    void                               recoitEI(EI* entiteImage);
    void                               affiche();
    ...

private:


    sf::RenderWindow                *m_fenetre;
    multiset<EI*>                      m_EI;
   ...

};
 

...

void Afficheur::recoitEI(EI* entiteImage)
{
    multiset<EI*>::iterator it = m_EI.begin();
    m_EI.insert(it,entiteImage);
}

 



void Afficheur::affiche()
{
    m_vue.rafraichi(m_temps);
    m_temps = false;

    m_fenetre->setView(*m_vue.renvoiVue());


    for(multiset<EI*>::iterator it = m_EI.begin() ; it != m_EI.end() ; it ++)
    {
        m_fenetre->draw(**it);
    }

}

 

et l'Afficheur est déclaré, puis utilisé ainsi depuis le main: (tant qu'a faire je vous met tout le code. merci si vous y jetez un coup d'eil et commentez s'il y a des erreurs/mauvaises choses  :D )


int main()
{

    std::vector<sf::VideoMode> resolutionDisponibles;
    resolutionDisponibles = sf::VideoMode::getFullscreenModes();
    std::vector<sf::VideoMode>::iterator itVideo = resolutionDisponibles.begin();
    int resolutionX = itVideo->width;
    int resolutionY = itVideo->height;

    sf::RenderWindow fenetre(sf::VideoMode(resolutionX, resolutionY), "Element", sf::Style::Fullscreen);




    boost::shared_ptr<Afficheur>  ptr_Afficheur(new Afficheur);
    boost::shared_ptr<sf::Event>  ptr_event(new sf::Event);

    ptr_Afficheur->recoitFenetre(&fenetre);
    ptr_Afficheur->recoitPtrEvent(ptr_event);

    Jeu jeu;
    jeu.recoitPtrAfficheur(ptr_Afficheur);

    sf::Clock clock;
    sf::Time ecoule;
    while (fenetre.isOpen())
    {

        while (fenetre.pollEvent(*ptr_event))
        {
            if (ptr_event->type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
            {
                fenetre.close();
            }
        }

    ecoule = clock.getElapsedTime();
    if(ecoule.asMicroseconds() >= 31250)
    {
        clock.restart();
        ptr_Afficheur->recoitTemps();
    }

    jeu.jouer();


    fenetre.clear();
    ptr_Afficheur->affiche();
    fenetre.display();

    }

    return 0;
}

 


« Modifié: Janvier 04, 2015, 05:10:05 pm par mazertys17 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Besoin d'un p'tit coup de main sur un sf::Drawable
« Réponse #3 le: Janvier 04, 2015, 05:37:45 pm »
struct MonFoncteur
{
   bool operator() (const EI* un, const EI* deux) const
   {
        return un->m_z < deux->m_z;
   }
};

std::multiset<EI*, MonFoncteur> m_EI;
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : Besoin d'un p'tit coup de main sur un sf::Drawable
« Réponse #4 le: Janvier 04, 2015, 05:40:20 pm »
Merci !!!

ca marche  :D :D
« Modifié: Janvier 04, 2015, 06:02:54 pm par mazertys17 »

Cpl.Bator

  • Hero Member
  • *****
  • Messages: 540
    • Voir le profil
Re : Besoin d'un p'tit coup de main sur un sf::Drawable
« Réponse #5 le: Janvier 04, 2015, 07:56:53 pm »
Citer
voila: je stock des adresses d'EI (EntitesImages) dans un std::multiset, dans le but de les trier au fur et a mesure en fonction de leur "m_z", ou zOrder.

Si tu est amener à faire des erase() sur ton multiset , tu risques d'avoir des problèmes de plantage.
un std::shared_ptr<EI> serais plus approprié

De même pour ta classe "Afficheur" , cela ne sert à rien de stocker le pointeur de la fenêtre.
sf::RenderWindow hérite de sf::RenderTarget , il faut en profité et tu gagneras une méthode en moins :

void Afficheur::Affiche ( sf::RenderTarget & target )
{
    target.draw( [Ce que tu veut] );
}

  Tu pourras même utilisé ta classe pour faire du rendu sur texture , car sf::RenderTexture hérite de la même classe : sf::RenderTarget.

un autre conseil , vire les pointeurs brut , c'est source de problème insoluble , surtout si tu débutes. prend le temps de comprendre.

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : Besoin d'un p'tit coup de main sur un sf::Drawable
« Réponse #6 le: Janvier 04, 2015, 10:01:06 pm »
Merci, Cpl.Bator.

Je vais prendre note de toutes ces indications, surtout à propos des pointeurs.
 
Citer
De même pour ta classe "Afficheur" , cela ne sert à rien de stocker le pointeur de la fenêtre.

En effet, dans cette exemple d'affichage, ce n'est pas nécessaire, cependant il y a d'autres moments ou ca peut m'être utile (sauf erreur), par ex dans une class qui récupère les coordonnées de la souris pour les mettre a l'échelle du niveau :


void Objet::rafraichi()
{

    sf::Vector2i pixelPos = sf::Mouse::getPosition(*m_ptr_afficheur->renvoiFenetre());
    sf::Vector2f worldPos = m_ptr_afficheur->renvoiFenetre()->mapPixelToCoords(pixelPos);
    ...
}
 


Citer
  Tu pourras même utilisé ta classe pour faire du rendu sur texture , car sf::RenderTexture hérite de la même classe : sf::RenderTarget.

Alors, là, j'avoue que c'est un chapitre que je n'ai pas vraiment potassé, bien que ca a l'air bien pratique.
Plusieurs questions a ce propos:

un sf::RenderTexture, c'est bien pour "fusionner" plusieurs images en une seul, au fond?

question surement bête : quand on utiliser sf::RenderTexture, crée-t-on une nouvelle texture pixels par pixels, comme si on la chargeait ? (ce qui le rendrait impraticable a utiliser en "temps réel", ou pour des sprites animés, il me semble).

Si ce n'est pas la cas, est-il plus intéressant/moins lourd, d'utiliser, par exemple, un sf::RenderTexture qui rassemble plusieurs images, ou d'utiliser plusieurs "draw" de chacunes des images ?
« Modifié: Janvier 04, 2015, 10:03:00 pm par mazertys17 »

Cpl.Bator

  • Hero Member
  • *****
  • Messages: 540
    • Voir le profil
Re : Besoin d'un p'tit coup de main sur un sf::Drawable
« Réponse #7 le: Janvier 04, 2015, 10:11:33 pm »
Considère le sf::RenderTexture comme un ecran "virtuel" que tu ne vois pas, cela sert à plein chose, comme séparé différent rendu , à la manière de calques sous photoshop , tu pourras appliqué des shaders ou autre effet sur tes texture.
Pour modifié les pixel d'une texture , c'est sf::Image.

void Objet::rafraichi()
{

    sf::Vector2i pixelPos = sf::Mouse::getPosition(*m_ptr_afficheur->renvoiFenetre());
    sf::Vector2f worldPos = m_ptr_afficheur->renvoiFenetre()->mapPixelToCoords(pixelPos);
    ...
}

Ok, si demain tu décides de rajouté la possibilité par exemple de switché en plein écran ou en mode fenetre , et que tu détruit ta fenetre originel avant de la réouvrir , il va se passer quoi ? plantage.
Il y a un bouquin qui traite des jeu & de la SFML , tu devrais y jeter un oeil et l'acheter , tu y verrais plus clair.

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : Besoin d'un p'tit coup de main sur un sf::Drawable
« Réponse #8 le: Janvier 05, 2015, 08:31:33 am »
Citer
Ok, si demain tu décides de rajouté la possibilité par exemple de switché en plein écran ou en mode fenetre , et que tu détruit ta fenetre originel avant de la réouvrir , il va se passer quoi ? plantage.

En effet. Après, je ne connais pas un jeu pc se jouant en plein écran qui puisse se jouer d'un coup en mode fenetre...Mais, bien sur, dans l'idée, il vaut mieux anticiper malgré tout ce genre de possibilités, pour avoir un programme fiable.
Si, dans un exemple semblable, je remplace "fenetre" par un pointeur intelligent "boost::shared_ptr<Fenetre> fenetre(new sf::RenderWindow;", cela empêcherait-il le plantage?

Citer
Il y a un bouquin qui traite des jeu & de la SFML , tu devrais y jeter un oeil et l'acheter , tu y verrais plus clair.

Pour être honnête, je ne suis pas très bouquin, pour ce qui est de l'apprentissage sur l'informatique. Il y a en général tout sur internet, j'ai essayé avec un livre sur le c++...et j'ai été déçu, ça ne m'a rien apporté. Je vais tout de même y réfléchir. Existe-t-il un bouquin en Francais ?

Cpl.Bator

  • Hero Member
  • *****
  • Messages: 540
    • Voir le profil
Re : Besoin d'un p'tit coup de main sur un sf::Drawable
« Réponse #9 le: Janvier 05, 2015, 03:16:06 pm »
Citer
cela empêcherait-il le plantage?

En fait , c'est le std::shared_ptr<> qui détruit la ressource , dès lors qu'elle n'est plus référencé nulle part , d'ou le nom de pointeur intelligent. insrit toi ici si ce n'est pas déjà fait : www.developpez.net

Citer
Pour être honnête, je ne suis pas très bouquin, pour ce qui est de l'apprentissage sur l'informatique. Il y a en général tout sur internet, j'ai essayé avec un livre sur le c++...et j'ai été déçu, ça ne m'a rien apporté. Je vais tout de même y réfléchir. Existe-t-il un bouquin en Francais ?

Ce bouquin traite de A à Z la création d'un jeu , apporte des concepts pour les débutants ou moins débutant , il est en anglais , mais c'est accessible.