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

Langage C++ Discussion :

[Operateurs ## et #] Boucle d'appel de fonction paramétrée


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 34
    Par défaut [Operateurs ## et #] Boucle d'appel de fonction paramétrée
    Bonjour,

    Comme d'habitude, je viens ici pour poser une question un peu tordue.
    En gros, en OpenGL, on définit un certain nombre de lumières activables en passant l'appel
    X est le numéro de la lumière. De base, il y en a jusqu'à 8, mais ça peut aller au-delà. Cette limitation est fixée par la constante GL_MAX_LIGHTS en fonction du système sur lequel OpenGL tourne (software & hardware je suppose).
    Maintenant, ce que je voudrais faire, c'est quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #define ENABLE_LIGHT(i) glEnable(i);
    #define ENABLE_LIGHTS   for(int i = 0; i < GL_MAX_LIGHTS; ++i) \
        ENABLE_LIGHT(GL_LIGHT ## #i);
    Ce qui dans ma tête aurait pour sortie si on a GL_MAX_LIGHTS = 8 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHT1);
    ...
    glEnable(GL_LIGHT7);
    Seulement, j'ai une sortie d'erreur du compilateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    error: pasting "GL_LIGHT" and "#" does not give a valid preprocessing token
    error: stray '#' in program
    J'ai essayé de multiples combinaisons, mais pour le coup, ça fonctionne vraiment pas, et ça m'embête bien.
    Je me doutais que sous cette forme c'était pas possible, mais je suis certain (pour avoir vu un code dans le thème) que dans l'esprit c'est faisable.

    J'ai cherché en vain sur le net, je ne tombe que sur des trucs bien moches avec des appels hideux du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LOOP8(x) glxps(8); LOOP7(x)
    Bon, après, ce que je me dis, c'est que vu que GL_MAX_LIGHTS sera déterminé par la machine où je compilerai le programme, ça signifie qu'il faudra que je compile obligatoirement ces macros à chaque fois que je veux installer mon application quelque part. Mais c'est pas trop grave ça.

    Bref, est-ce que l'un de vous aurait une idée derrière la tête pour faire ce genre de cochonceté ?

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    #i ne sera pas bon, ça transforme i en chaîne de caractère => "i"
    ## sert à concaténer, et ne marchera pas non plus : GL_LIGHT ## i => GL_LIGHTi

    Il faudrait que la boucle for soit déroulée à la compilation, un moyen en métaprogrammation existe peut-être, mais m'est inconnu.

    Sinon, puisque les GL_LIGHTx sont des define qui se suivent, tu peux essayer ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define ENABLE_LIGHTS   for(int i = 0; i < GL_MAX_LIGHTS; ++i) \
        ENABLE_LIGHT(GL_LIGHT0 + i);
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Inactif  


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

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Si ce n'est pas une erreur et que c'est bien du C++ et non du C...
    Ce que tu fais est une horreur et il n'y a pas de raison de faire ça. Faire une macro avec 1 paramètre pour appeler une fonction à 1 paramètre, ça n'a pas de sens. Tu peux bannir (ou presque) les #define en C++.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const GLenum LIGHT_VALUES[8] = { GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7 };
    inline void enableLight(glInt i) { glEnable(LIGHT_VALUES[i]); }
    inline void enableLights() { for(int i = 0; i < GL_MAX_LIGHTS; ++i) enableLight(i); }
    Et je conseillerais de passer à de l'OpenGL moderne (> 3.x ou ES 2.0 dans lequel GL_LIGHT est déprécié)

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Même si je pense que gbdivers a raison, je donne juste un indice pour réaliser ce que tu demandes initialement :
    Il existe une biblitohèque boost pour réaliser de la meta-programmation à l'aide du préprocesseur. Par exemple :
    http://www.boost.org/doc/libs/1_48_0...doc/index.html
    Et en particulier :
    http://www.boost.org/doc/libs/1_48_0...um_params.html
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre averti
    Inscrit en
    Janvier 2010
    Messages
    34
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 34
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Bonsoir,
    Sinon, puisque les GL_LIGHTx sont des define qui se suivent, tu peux essayer ceci
    Oui, j'y avais pensé. Mais je n'aime pas cette solution dans le sens où elle n'utilise plus les constantes prévues à cet effet, et que je désolidarise le paramétrage de mon contexte OpenGL des conventions. Si jamais les valeurs des lumières changent, je me retrouverai avec un bug.

    Citation Envoyé par gbdivers Voir le message
    Et je conseillerais de passer à de l'OpenGL moderne (> 3.x ou ES 2.0 dans lequel GL_LIGHT est déprécié)
    Malheureusement, l'OpenGL moderne n'est pas, selon certains, ou peu supporté. Et même si ma machine personnelle est compatible à 100% jusqu'à l'OpenGL 3.3, moi je dois me contenter des versions 1.2 et moins.
    Pour ce que tu m'as dit, je comprends, mais l'idée qui me dérange dans le code que tu m'as montré, c'est qu'il prend un nombre de lumières fixes. Alors que selon le système, cela peut varier, il peut y en avoir bien plus que 8.
    Je préférerai une solution plus souple, d'où le fait que je regardais du côté des macros pour avoir des GL_LIGHTXX avec un nombre potentiellement grand.
    Accessoirement, pourquoi faudrait-il bannir les macros ? Surtout dans ce genre de cas ? La méta-programmation n'est-elle pas une bonne chose, quelle que soit le paradigme de programmation utilisé ?

    Citation Envoyé par JolyLoic Voir le message
    Même si je pense que gbdivers a raison, je donne juste un indice pour réaliser ce que tu demandes initialement :
    Il existe une biblitohèque boost pour réaliser de la meta-programmation à l'aide du préprocesseur. Par exemple :
    http://www.boost.org/doc/libs/1_48_0...doc/index.html
    Et en particulier :
    http://www.boost.org/doc/libs/1_48_0...um_params.html
    Merci beaucoup. C'est exactement ça. Par contre, j'aimerai bien savoir comment ça marche à l'intérieur. Je suppose que je peux regarder le code source de boost, j'ai juste peur qu'il soit illisible comme la plupart du temps.
    En tout cas, si ils ont réussi à faire cette fonctionnalité, je suppose que ça veut dire que je pourrai la reproduire sans boost, non ?

  6. #6
    Inactif  


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

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Citation Envoyé par Ylvin Voir le message
    Malheureusement, l'OpenGL moderne n'est pas, selon certains, ou peu supporté. Et même si ma machine personnelle est compatible à 100% jusqu'à l'OpenGL 3.3, moi je dois me contenter des versions 1.2 et moins.
    Pour ce que tu m'as dit, je comprends, mais l'idée qui me dérange dans le code que tu m'as montré, c'est qu'il prend un nombre de lumières fixes. Alors que selon le système, cela peut varier, il peut y en avoir bien plus que 8.
    Je préférerai une solution plus souple, d'où le fait que je regardais du côté des macros pour avoir des GL_LIGHTXX avec un nombre potentiellement grand.
    Le pipeline programmable date quand même de OpenGL 2, c'est à dire 2004. Tu peux au moins utiliser cette version. Le pipeline programmable est très bien supporté.
    Pour les lumières, les spécifications limitent bien le nombre de lumière à 8 maximum. Peut être que certaine implémentation en propose plus, mais c'est pas portable d'en utiliser plus.
    Et il suffit de modifier le code avec un petit hack suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    inline void enableLight(glInt i) { glEnable(GL_LIGHT0 + i); }
    inline void enableLights() { for(int i = 0; i < GL_MAX_LIGHTS; ++i) enableLight(i); }
    Citation Envoyé par Ylvin Voir le message
    Accessoirement, pourquoi faudrait-il bannir les macros ? Surtout dans ce genre de cas ? La méta-programmation n'est-elle pas une bonne chose, quelle que soit le paradigme de programmation utilisé ?
    Parce que les macros permettent de faire des choses très moches, donc peu maintenables, difficilement évolutives et pas type safe. De plus, je suis pas sur qu'on puisse parler de méta programmation avec les macros. Et les macro ne sont pas un paradigme.

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Ylvin Voir le message
    Je suppose que je peux regarder le code source de boost, j'ai juste peur qu'il soit illisible comme la plupart du temps.
    Je ne pense pas. Je pense qu'il est en fait bien plus illisible que la plupart du temps... :S
    Citation Envoyé par Ylvin Voir le message
    En tout cas, si ils ont réussi à faire cette fonctionnalité, je suppose que ça veut dire que je pourrai la reproduire sans boost, non ?
    Oui, assurément. Mais à quel coût ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. des appel de fonction(paramétre, référence )
    Par aefmaaradji dans le forum C++
    Réponses: 2
    Dernier message: 12/04/2009, 13h32
  2. Réponses: 1
    Dernier message: 25/07/2007, 10h03
  3. appel procédure avec paramètres ds fonction
    Par cpattin dans le forum VB.NET
    Réponses: 7
    Dernier message: 14/06/2007, 22h11
  4. [Function]Appel de fonction avec paramètre
    Par julienOriano dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 02/06/2006, 07h48
  5. [Système] Operateur @ devant un appel de fonction
    Par Tarul dans le forum Langage
    Réponses: 2
    Dernier message: 08/03/2006, 11h29

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