IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Operateur de cast


Sujet :

C++

  1. #1
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut Operateur de cast
    Bonjour,

    Contexte :
    Je suis actuellement entrain de travailler sur un programme utilisant OpenGL. Avec les nouvelles spécificités OpenGL beaucoup de fonctions sont devenues dépréciées notamment toutes les fonctions concernant la manipulation des matrices Modelview et Projection.

    Pour me faciliter la gestion mathématique de mon programme et notamment tout ce qui touche aux matrices j'utilise la bibliothèque mathématique : OpenGL Mathematics (ou GLM, site : http://glm.g-truc.net/). Néanmoins cette bibliothèque ne propose pas la gestion des piles de matrices à la similitude des fonctions OpenGL glPushMatrix et glPopMatrix, fonctions dépréciées. J'ai donc par conséquent voulu reproduire ce type de fonction pour cela j'ai utilisé une classe du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
     
    class pile_matrix
    {
    public:
        //constructeur/destructeur
        pile_matrix(const glm::mat4& m);
        pile_matrix();
        ~pile_matrix();
     
        /*
        ....
          méthodes sur ma pile
        ....
        */
     
     
         operator glm::mat4&()  //cast qui ne va pas ou fait pas ce que je voudrai
        {
              return pile.back();
        }
    private:
    std::vector<mat4> pile;
     
    }
    Mon problème est que je voudrais utiliser de façon transparente un objet de ma classe pile_matrix comme étant un objet mat4. En gros avoir un cast automatique de ma classe pile_matrix en mat4 mais ce que je n'arrive pas à obtenir. Par exemple le code suivant ne fonctionne pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pile_matrix modelview, projection;
    glm::mat4 matriceA, matriceB;
    buffer = matriceA + modelview * projection * matriceB; //erreur lors de la compilation sur les operateurs
    Est-il nécessaire que je redéfinisse la globalité des opérateurs entre mat4 et pile_matrix ? ou une autre solution existe notamment au niveau du cast ? je fais une erreur quelque part ?


    (Je me suis permis de poster sur le forum c++ et non OpenGL étant donné que c'est plus un problème de langage que OpenGL, néanmoins si je me trompe de forum je déplacerai mon post)
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  2. #2
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    bonjour,

    tu as un message d'erreur à montrer ?


    bon je sais c'est toi qui demande de l'aide et c'est moi qui pose des questions,
    mais "l'opérateur de cast" il n'a pas de type de retour (d'accord pas de paramètre car il l'effectue sur this, mais pas de type retour non plus ça marche comment ? ) ?

    Edit : je n'ai rien dit

    sinon pourquoi dans ton attribut tu n'as pas besoin de spécifier le scope de tes mat4 alors que tu le fait partout ailleurs ?

    pour le cast, tu essaie de caster un élement en référence sur cet élément ?
    Nullius in verba

  3. #3
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Si bien sur.

    L'erreur donné par VS c++ express :

    1>main.cpp(95): error C2679: '*' binaire*: aucun opérateur trouvé qui accepte un opérande de partie droite de type 'pile_mat4' (ou il n'existe pas de conversion acceptable)
    1> c:\documents and settings\fresnel\bureau\opengl labo\rxenginegl3+\rxengine\ressources\glm-0.9.2.7\glm\core\type_mat4x4.inl(637): peut être 'glm::detail::tmat4x4<T> glm::detail::operator *<glm::core::type::precision::lowp_float>(const glm::detail::tmat4x4<T> &,const float &)' [trouvé à l'aide d'une recherche dépendante d'un argument]
    1> with
    1> [
    1> T=glm::core::type::precision::lowp_float
    1> ]
    1> c:\documents and settings\fresnel\bureau\opengl labo\rxenginegl3+\rxengine\ressources\glm-0.9.2.7\glm\core\type_mat4x4.inl(665): ou 'glm::detail::tvec4<T> glm::detail::operator *<glm::core::type::precision::lowp_float>(const glm::detail::tmat4x4<T> &,const glm::detail::tvec4<T> &)' [trouvé à l'aide d'une recherche dépendante d'un argument]
    1> with
    1> [
    1> T=glm::core::type::precision::mediump_float
    1> ]
    1> c:\documents and settings\fresnel\bureau\opengl labo\rxenginegl3+\rxengine\ressources\glm-0.9.2.7\glm\core\type_half.hpp(62): ou 'glm::detail::thalf glm::detail::operator *(const glm::detail::thalf &,const glm::detail::thalf &)' [trouvé à l'aide d'une recherche dépendante d'un argument]
    1> lors de la tentative de mise en correspondance de la liste des arguments '(glm::core::type::mat4, pile_mat4)'

    Dans mon programme la classe s'appelle pile_mat4 au lieu de pile_matrix et le log ici concerne que l'opérateur * mais cela le fait bien évidemment avec l'emploie d'un autre opérateur de la classe glm::mat4.

    Dans le log ce qui me chagrine c'est la remarque : "(ou il n'existe pas de conversion acceptable)".
    Ma méthode operator mat4&() n'est pas acceptable ? et pourquoi ?

    Edit :
    Pour info la class mat4 est un typedef float de la meta classe tmat4x4<T> :
    mat4 <=> tmat4x4<float>

    J'ai le morceau de code suivant qui marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pile_mat4 pile;
    mat4 m = pile;
    mais toujours pas un truc du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    mat4 m,n;
    pile_mat4 pile;
    m = n*pile;
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  4. #4
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par Robxley Voir le message
    Bonjour,

    Contexte :
    Je suis actuellement entrain de travailler sur un programme utilisant Opengl. Avec les nouvelles spécificités Opengl beaucoup de fonctions sont devenues dépréciées notamment toutes les fonctions concernant la manipulation des matrices Modelview et Projection.

    Pour me faciliter la gestion mathématique de mon programme et notamment tout ce qui touche aux matrices j'utilise la librairie mathématique : OpenGL Mathematics (ou GLM, site : http://glm.g-truc.net/). Néanmoins cette librairie ne propose pas la gestion des piles de matrices à la similitude des fonctions OpenGL glPushMatrix et glPopMatrix, fonctions dépréciées. J'ai donc par conséquent voulu reproduire ce type de fonction pour cela j'ai utilisé une classe du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
     
    class pile_matrix
    {
    public:
        //constructeur/destructeur
        pile_matrix(const glm::mat4& m);
        pile_matrix();
        ~pile_matrix();
     
        /*
        ....
          méthodes sur ma pile
        ....
        */
     
     
         operator glm::mat4&()  //cast qui ne va pas ou fait pas ce que je voudrai
        {
              return pile.back();
        }
    private:
    std::vector<mat4> pile;
     
    }
    Mon problème est que je voudrais utiliser de façon transparente un objet de ma class pile_matrix comme étant un objet mat4. En gros avoir un cast automatique de ma classe pile_matrix en mat4 mais ce que je n'arrive pas à obtenir. Par exemple le code suivant ne fonctionne pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    pile_matrix modelview, projection;
    glm::mat4 matriceA, matriceB;
    buffer = matriceA + modelview * projection * matriceB; //erreur lors de la compilation sur les operateurs
    Est-il nécessaire que je redéfinisse la globalité des opérateurs entre mat4 et pile_matrix ? ou une autre solution existe notamment au niveau du cast ? je fais une erreur quelque part ?


    (Je me suis permis de poster sur le forum c++ et non opengl étant donné que c'est plus un problème de langage que Opengl, néanmoins si je me trompe de forum je déplacerai mon post)
    Non, pas de cast implicite. Il est beaucoup plus sage de redéfinir les opérateurs de manière à accepter des objets pile_matrice et des objets mat4 (ça ne fait pas beaucoup de travail, quand même).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    pile_matrice operator*(const pile_matrice& pm, const mat4& m);
    pile_matrice operator*(const mat4& m, const pile_matrice& pm);
    pile_matrice operator+(const pile_matrice& pm, const mat4& m);
    pile_matrice operator+(const mat4& m, const pile_matrice& pm);
    pile_matrice operator-(const pile_matrice& pm, const mat4& m);
    pile_matrice operator-(const mat4& m, const pile_matrice& pm);
    // vs. scalaires
    pile_matrice operator*(const pile_matrice& pm, float f);
    pile_matrice operator*(float f, const pile_matrice& pm);
    pile_matrice operator/(const pile_matrice& pm, float f);
    Ne pas oublier +=, -=, *= et /* (avec un float).

    Il va rester un problème léger : toutes les fonctions qui prennent en paramètre un mat4 pour le modifier ou créer un nouvel objet mat4 devront peut-être êtres surchargées pour travailler sur des pile_matrice.

    Au delà de ça, je me demande quand même si c'est une idée judicieuse au niveau du design. Une pile_matrice n'est pas une matrice, et son but n'est pas le même.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour

    Hum... problème de NIH ?
    Il existe déjà une classe stack qui fait ce que tu souhaites : std::stack.
    Ensuite, d'un point de vue sémantique, une pile n'est pas une matrice et ne devrait pas pourvoir être convertir implicitement en matrice.

  6. #6
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    je ne pensais pas que l'on puisse convertir un élément en référence sur cet élément directement.

    Je ne sais pas si c'est lié à ton problème, mais dans le code que tu montre, ton attribut de type std::vector<T> contient mat4, et pas glm::mat4. A part le fait que je ne comprend pas comment il peut compiler (à part si tu es sous le 2003), tu ne lui dis pas le scope dans lequel se trouvent tes mat4 (apparemment dans le namespace glm).

    Ensuite,
    buffer = matriceA + modelview * projection * matriceB
    tu l'utilises quand ton opérateur de cast ? parce que le compilo te précise qu'il ne peut pas faire ce genre de truc avec une opérande à droite de type "pile_mat4" mais il ne parle pas de "pile_mat4&" c'est donc que la conversion implicite n'est pas passée.

    Edit : Du coup, rien ne dit que ton cast soit le problème. Mais bon moi je dis plus rien les pros sont arrivés...
    Nullius in verba

  7. #7
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Au pire, tu utilises un fonction libre, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef std::stack<glm::mat4> mat4stack;
    glm::mat4& top(mat4stack& s) { return s.top(); }
    glm::mat4 const& top(mat4stack const& s) { return s.top(); }
     
    buffer = matriceA + top(modelview) * top(projection) * matriceB;

  8. #8
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Merci pour vos réponses :

    @Kaamui :
    c'est bien un vector<glm::mat4> et non un vector<mat4>, un simple oublie durant l'écriture du post (y a pas de debugger sur le post ).
    tu l'utilises quand ton opérateur de cast ? parce que le compilo te précise qu'il ne peut pas faire ce genre de truc avec une opérande à droite de type "pile_mat4" mais il ne parle pas de "pile_mat4&" c'est donc que la conversion implicite n'est pas passée.
    C'était plus ou moins ma question, si mon cast était correct pour ce que je souhaite faire ^^

    @gbdivers
    Ensuite, d'un point de vue sémantique, une pile n'est pas une matrice et ne devrait pas pourvoir être convertir implicitement en matrice.
    Je comprends bien et c'est pour cela qu'au départ j'avais une méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    glm::mat4& pile_mat4::getActive()
    {
        return pile.back();
    }
    Et alors je faisais mes opérations de la façon suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    pile_mat4 modelView, projection;
    glm::mat4 m, rotation;
    m =projection.getActive()*modelView.getActive()*rotation
    mais c'est relativement long comme écriture et beaucoup moins lisible que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m =projection*modelView*rotation
    Et je préfère utiliser une structure vector que stack car avec vector via la méthode reserve tu peux allouer une partie de la mémoire avant même l'utilisation de l'objet vector, ce qui évite lors de multi push_back, pop_back de allouer/libérer indéfiniment de l'espace mémoire. Mais possible que je me trompe sur le réel intérêt.

    @Emmanuel Deloget
    Au delà de ça, je me demande quand même si c'est une idée judicieuse au niveau du design. Une pile_matrice n'est pas une matrice, et son but n'est pas le même.
    Même réponse qu'a gbdivers, c'est plus pour une question de visibilité de lecture mathématique que de niveau du design.


    Je ne suis toujours pas décidé vers quoi je vais me tourner si je garde la syntaxe lourde avec la méthode getActive...ou la surcharge d'opérateur mentionné par Emmanuel Deloget.

    Edit (post entre mon post) :
    @Emmanuel Deloget
    Effectivement c'est ce que je faisais auparavant avec mon getActive, je vais peut etre le raccourcir le nom pour une meilleur lisibilité. Un truc du genre pile_mat4::top
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  9. #9
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    si c'est juste que tu trouves ça trop long alors encapsule tes opérations comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //m =projection*modelView*rotation à remplacer par...
     
    m = x(&projetction,&modelView,&rotation); //là tu garde une taille raisonnable
     
    //...avec : 
     
    glm::mat4 x(const pile_mat4& p, const pile_mat4& m, const glm::mat4& r) const
    {
        return (p.GetActive() * m.GetActive() * r);
    }
    mais c'est sur que c'est moins joli que ton instruction de départ
    Nullius in verba

  10. #10
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    La méthode que tu proposes Kaamui est très peu flexible.

    Ca va dans le cas des exemples exposées pour mes questions, cependant les opérations matricielles de mon programme ne se limitent pas forcement à l'utilisation des matrices projection, modelview et une matrice de transformation mais plusieurs autres matrices, ainsi que l’utilisation de vecteurs. En effet avec la surcharge d'opérateur de glm tu peux effectuer des opérations du type :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    vec4 v,w,r;
    mat4 T1,T2; //matrices de transformation;
    r = projection.top()* modelview.top*T1*v - projection.top()* modelview.top*T2*w;


    Non mais, si non c'est pas très grave je vais m'en tenir à l'utilisation d'une méthode interne qui renvoie l'éléments du dessus de ma pile et puis c'est tout. Ma question était plus par curiosité pour voir s'il n'existait pas un opérateur de cast ou autre pour simplifier l'écriture. Ca aurait été idiot de pas en profiter par peur de poser la question.
    Je vais laisser comme c'est et utiliser une fonction top()
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  11. #11
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    En effet cela ne s'applique que dans ce cas précis.

    Dans cas la meilleure solution reste alors la proposition de Emmanuel Deloget.

    Nullius in verba

  12. #12
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Mais mais quand est-ce qu'il est pertinent de redéfinir des opérateurs de type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    operator mat4&();
    operator const mat4&();
    operator mat4();
    si cela ne sert à rien dans ce cas ci. C'est que je n'ai pas très bien compris leurs utilisations. Et la faq ne donne aucune précision sur ces opérateurs un peu particulier.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  13. #13
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour Robxley

    C'est pertinent que dans les très rares cas où le même concept est représenté par plusieurs types différents. Par exemple, une chaîne de caractères qui pourrait être représentée par std::string et const char* (dans une lib C). Mais ces opérateurs sont la plus part du temps à éviter (conversion implicite = on ne sait pas forcement quand elle a lieu, ce qui peut être une source de bug).

    Dans ton cas, très clairement, c'est une mauvaise idée : tu as bien 2 concepts différents (une matrice et une pile de matrice) et avoir une conversion implicite peut te faire gagner quelques caractères à taper (c'est si grave ?) mais cela peut être source de confusion.


    Petite réflexion du matin. Pourquoi redéfinir une telle pile ?
    Les anciennes version d'OpenGL utilisait cette approche pour des raisons de simplification de l'interface et pour limiter les copies inutiles entre le client OpenGL et les utilisateurs du client. Cette approche a justement était supprimé parce qu'elle n'était pas très performante. Il fallait mettre en pile pour chaque objet d'une scène. Il est bien plus performant de manipuler plusieurs matrice (1 par objet par exemple) que d'utiliser une pile. Par exemple, quand on a les objets d'une scène qui sont hiérarchisés dans un tree, il est beaucoup plus efficace et pratique d'associer une matrice à chaque noeud (ce que ne permet pas la pile).
    Bref, je me demande si tu n'essaies pas de faire "comme avant" alors qu'on n'a plus cette contrainte et qu'il y a plus efficace.

  14. #14
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    @gbdivers

    J'ai abandonné l'utilisation de operator var() et garder comme initialement l'utilisation de méthode type top() que je maîtrise et dont je suis sur du fonctionnement.

    Comme vous le faite remarquer dans votre post les fonctions glPopMatrix, et glPushMatrix sont devenues dépréciées car elles faisait faire beaucoup d'aller retour entre le GPU-CPU.
    Mais votre remarque est juste. Les piles ne sont pas ce qu'il y a de plus optimisées pour une utilisation définitive, mais ce type de fonctionnement est très utile pour un débugage rapide (au niveau 3D je parle). Mon programme est un long et semé de plein de pièges (la plupart posés par moi-même ). Quelques outils peuvent s'avérer très efficaces pour évaluer rapidement une fonction 3D que l'on vient de programmer, ou un shader, etc. Cela me permet de placer rapidement quelques objets tests de façon opportun dans ma scène pour évaluer une routine toute fraîchement codée. Si non effectivement j'utilise un arbre (un pseudo arbre pour être honnête, un arbre de Pise ) d'autant plus que la majorité de mes objets sont statiques donc les calculs matriciels peuvent se faire en among du programme et non dans la boucle principale comme c'est le cas avec des pushmatrix et popmatrix.

    En tous cas merci à tous pour vos réponses. Je mets cette discussion sur résolu.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  15. #15
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    En effet, c'est toujours intéressant de pouvoir suivre ce qui se passe dans les calculs. Par contre, plutôt que d'utiliser une pile de matrices dans le code (ce qui oblige finalement à écrire 2 codes, un pour les tests et un pour la version finale), je serais plutôt parti sur un observer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    // pour pouvoir observer autre chose que mat4
    template<typename T>
    struct Printer {
       static void print(T*) const {}
    };
     
    template<>
    struct Printer<glm::mat4> {
       static void print(glm::mat4* m) const { /* on affiche m */ }
    };
     
    struct Printable {
       virtual void print() const = 0;
    };
     
    template<typename T, template<typename T> class Printer)
    struct Watcher : public Printable {
       std::string name;
       T* matrix;
     
       MatrixWatcher(std::string const& n, T* m)
          name(n), matrix(m) {}
     
       void print const { Printer::print(matrix); }
    };
     
    struct WatcherStack {
       std::list<Printable*> watched;
     
       void append(Printable* p) { watcher.push_back(p); }
       void print() const { for f(Printable* p : watched) { p->print(); } }
    };
     
    glm::mat4 m;
    WatcherStack s;
    s.append(&m);
    ... // opérations sur m
    s.print();
    Cela permet de séparer dans le code le stockage des matrices à afficher (pour le déboguage) et leurs utilisations (et donc sans avoir besoin d'un code spécifique pour les matrices). Tu ajoutes un ou deux petits #define pour utiliser ou non ce code en debug et release et tu as un code plus stable

  16. #16
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Merci pour cette info, je ne connaissais pas le concept d'observateur.

    Mais à première vue ça serait pour afficher le contenu de mes matrices/(ou données numériques) si j'ai bien tout compris, or en faite le contenu de mes matrices entre guillemets je m'en moque un peu. J'ai du me faire mal comprendre, mon utilisation de pile de matrices est juste faite pour afficher à chaud très rapidement du contenu 3D (objet 3D à l'écran) afin de tester les routines que je viens de coder. La pile de matrice est juste la pour placer rapidement ces objets dans le champs de la caméra. Ce n'est donc pas le contenu des matrices en elles mêmes qui m’intéresse.
    Pour donner un exemple, supposons que j'ai fais une routine qui charge un fichier 3D (.obj, pour l'exemple). Pour vérifier la validité de ma routine, j'affiche rapidement un objet quelconque .obj chargé avec ma routine devant la caméra avec ma pile de matrices. L'information utile ici ce n'est pas en soit ma pile de matrice mais la validité de la routine. Et comme l'information utile à une représentation dans l'espace le moyen le plus simple pour vérifier la validité de la routine c'est d'afficher cette objet. Supposons bêtement que j'ai inversé les x avec les z, je le verrai tout de suite avec un affichage 3D (objet difforme, renversé ...), ce que je ne verrai que difficilement avec l'affichage de données numériques que ce soit de mes matrices ou autres données numériques grâce au concepts d'observateur. Des nombres restent des nombres, les afficher ne me permettra pas de savoir que j'ai inversé x et z.
    Je sais pas si j'ai été claire

    Mais bon c'est tout neuf le concept d'observateur je n'ai peut être pas bien compris son emploie je vais aller faire quelques recherches sur le net et trouver quelques exemples. Il est fort probable que ça me servent pour évaluer cette fois certaines données/variables de mon programme.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  17. #17
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    J'utilise le terme observateur mais c'est un abus de langage... ce n'est pas réellement un design pattern observateur
    L'idée principale est surtout de séparer la partie test de tes routines de leurs définition et utilisation.
    Et tu peux tout à fait changer la classe Printer en Drawer pour afficher un objet. Le principale est surtout d'être le moins intrusif dans le code que tu écris

  18. #18
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Oui je viens de comprendre en commencant à lire : http://come-david.developpez.com/tut...ge=Observateur

    Qui effectivement n'a pas grand chose à voir .

    Si non, je ne mélange pas mon code définitif et le code de test.
    J'ai une fonction void bac_a_sable() ou tous mes tests sont faits à l’intérieur de cette fonction et cette fonction n'est appelé qu'en mode debug avec l'utilisation de #if DEBUG #endif.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. operateur de cast et tableau
    Par Awakening dans le forum Langage
    Réponses: 12
    Dernier message: 27/02/2014, 17h31
  2. Réponses: 2
    Dernier message: 16/07/2007, 16h34
  3. CAST DATETIME ----> SMALLDATETIME
    Par Guizz dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 26/06/2003, 13h07
  4. [langage] l'operateur tr///
    Par March' dans le forum Langage
    Réponses: 4
    Dernier message: 03/03/2003, 22h57
  5. traduction en delphi "reinterpreted cast"
    Par Chupakabra dans le forum Langage
    Réponses: 3
    Dernier message: 13/02/2003, 16h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo