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

OpenGL Discussion :

separer l affichage et les calculs


Sujet :

OpenGL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 7
    Points : 2
    Points
    2
    Par défaut separer l affichage et les calculs
    Bonjour,
    désolé par avance si ma question est bète mais voici mon problème:

    je fais un long cacul pour déterminer la position d'un ensemble de point, puis pour vérifier le résultat j'utilise opengl pour l'afficher. Pour cela j'utilise glutDisplayFunc(affichage); Peut on transmettre des parametres a la fct affichage? Il me semble que non. Or j'aimerais bien que mes points soient calculés une fois pour toute et si possible en dehors de la fonction affichage plutôt que les recalculer à chaque rafraichissement de l'image quand j'effectue par exemple une rotation.

    Je me répète mais j'aimerais que ma fonction caculpoint ne soit pas dans la fonction affichage et j'aimerais aussi éviter les astuce du genre, une variable globale A que j initialise a 0 puis dans affichage:
    if(A==0){calculpoint();A=1;}

    Merci par avance ++

  2. #2
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Février 2004
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2004
    Messages : 125
    Points : 139
    Points
    139
    Par défaut
    Ben tu n'a qu'à faire une fonction de calcul en dehors de tra fonction d'affichage et que tu lances à l'initialisation par exemple...
    MacBook - MacOS X.5.4
    C, Objective-C
    OpenGL, GLUT, Cocoa

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Salut,

    le problème c que la fonction d'affichage en faisant ce que tu me dis, elle connait pas la liste des points, vu que je peux pas lui transmettre en argument.

    Et j'ai pas non plus envie de la mettre en variable globale....

  4. #4
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Février 2004
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2004
    Messages : 125
    Points : 139
    Points
    139
    Par défaut
    Salut.

    Les diplays lists vont surement pouvoir t'aider
    Jette un coup d'oeil la dessus sur les tutoriaux Nehe qui sont très bien faits... http://nehe.gamedev.net/[/url]
    MacBook - MacOS X.5.4
    C, Objective-C
    OpenGL, GLUT, Cocoa

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Salut,

    le problème des gllist est qu'il s'agit de variables globales. Ce que j'aimerais éviter. Supponsons que je veuille faire un jeu d'aventure. J'imagine qu'il n'est pas d'usage de stocker tous les ennemis du jeu dans des gllist. Comment fait on? De plus si vous arrivez toujours à me suivre, si l'affichage passe toujours par la fonction appelée par glutDisplayFunc() , soit par exemple affiche_image(), affiche_image est donc la fonction principale du jeu? la racine de tout? et dans ce cas, à chaque affichage, on passe donc intégralement toute cette fonction dans laquelle tout le jeu est défini? (avec bien sûr ttes les sous fonctions), comment fait on alors pour déterminer l'état ou le joueur se trouve dans le jeu. Utilises ton des variable globale? Par exemple:

    int A=0; //en globale

    void affiche_image()
    {
    if(A==0) fonction_niveau_0_du_jeu();
    if(A==1) fonction_niveau_1_du_jeu();
    ...
    }

    ??

    J'ai un peu étoffé ma première question de base, mais ça continue de tourner autour du même problème et l'histoire du jeu vidéo m'interesse. J'espère que certain pourront m'aider ou simplement me dire ce qu'il en pense histoire d'en discuter.
    Merci ++

  6. #6
    Membre habitué
    Profil pro
    Étudiant
    Inscrit en
    Février 2004
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2004
    Messages : 125
    Points : 139
    Points
    139
    Par défaut
    Bon, je sais pas si ce que je fais est bien, mais j'ai plutôt tendance à mettre les instructions de déroulement du programme dans la fonction Idle et c'est vrai que j'utilise des variables globales.

    Pour stocker la donnée, je vois pas comment faire autrement, faut bien qu'elle existe ?

    Mais pour en revenir au glList, il me semble qu'il suffit d'avoir la donnée lors de la construction de la liste après, pouf, c'est dans OpenGL...
    MacBook - MacOS X.5.4
    C, Objective-C
    OpenGL, GLUT, Cocoa

  7. #7
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par ggwal
    De plus si vous arrivez toujours à me suivre, si l'affichage passe toujours par la fonction appelée par glutDisplayFunc() , soit par exemple affiche_image(), affiche_image est donc la fonction principale du jeu? la racine de tout? et dans ce cas, à chaque affichage, on passe donc intégralement toute cette fonction dans laquelle tout le jeu est défini? (avec bien sûr ttes les sous fonctions), comment fait on alors pour déterminer l'état ou le joueur se trouve dans le jeu. Utilises ton des variable globale? Par exemple:

    int A=0; //en globale

    void affiche_image()
    {
    if(A==0) fonction_niveau_0_du_jeu();
    if(A==1) fonction_niveau_1_du_jeu();
    ...
    }
    L'utilisation de la variable globale est quasi-nécessaire dans l'utilisation de glutDisplayFunc, du moins je n'ai jamais cherché plus loin. Ce que je fais généralement est une seule classe/structure (dépendant si le programme est en C++ ou en C) qui contient toutes les autres informations. Cela permet de regrouper le tout et de faire un gestionnaire des éléments qui doivent plus ou moins être globaux...

    Pour ce qui est de l'affiche_image, je faisais au début comme tu proposais. Dans des petits projets, cela peut suffire mais très rapidement cette fonction devient compliquer. J'utilise maintenant des pointeurs de fonctions pour la gestion d'évenement que j'initialise vers les fonctions d'affichage/gestion clavier/souris du menu principale. Lorsqu'un choix est fait, je modifie ces pointeurs pour qu'ils pointent vers les fonctions gérant le jeu ou les fonctions gérant l'éditeur (par exemple)...

    Donc mes fonctions qui sont passées à GLUT ressemblent à ceux-ci:
    // une demande d'affichage vient d'être générée
    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
    void affichage()
    {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    	glLoadIdentity();
    	(*g_engine.aff_fct)();
     
    	glutSwapBuffers();			// ?change des buffers d'affichage
    }
     
    void clavier(unsigned char touche, int x, int y)
    {
    	(*g_engine.keyb_fct)(touche,x,y);
    	glutPostRedisplay();		// on réaffiche
    }
     
    void souris(int bouton, int etat, int x, int y)
    {
    	(*g_engine.mouse_fct)(bouton,etat,x,y);
    	glutPostRedisplay();		// on réaffiche
    }
    Je ne sais pas si beaucoup de gens font comme cela, mais cela fonctionne bien pour moi...

    Jc

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    fearyourself, tu pourrais être un peu plus clair sur ta méthode.

    perso, je suis sur un projet ou je doit executer telle ou telle animation en fonction de cartaines conditions. Dans ma display(), j'ai juste quelques boucle qui affiche les éléments. Dans ma idle(), j'ai tout les "animation" (ce sont des modification des coordonnées de mes objets). Mais je me rend compte que ma idle() va être extremement complexe et longue (avec bcp que booléen en global pour n'acceder qu'a certaines partie du idle() à certains moment). Je ne sais pas si je me fait bien comprendre, mais par exemple pour déplacer un objet horizontalement, dans la idle() je modifie sa coordonnée et dans la display je l'affiche. Mais je voudrais pouvoir dans ma idle() juste mettre une fonction deplaceHorizontalement(objet) et elle s'occuperais du déplacement entier. J'entend par la que lorsque je rentre dans deplaceHorizontalement(objet), l'animation commence, et que qd j'en sort, l'animation se finie. En bref, est-il possible d'encapsuler toute une animation dans une seule fonction, tel que si j'appel une fois cette fonction, tout l'animation est affichée à l'écran.

    EX:

    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
     
    void display()
    {
    ...
    }
     
    void idle()
    {
           if(condition1)
                 animation1();
           else if (condition2)
                 animation2();
           else 
                  animation3();
    }
    qd je rentre dans idle(), si condition1 est vérifiée, je rentre dans animation1 qui elle meme met à jour les coordonées des objects et demande l'affichage directement (on aurais alors une boucle de mise à jour des coordonnée + demande d'affichage juste après).

    Pour info j'utilise glut, et c'est une alternative à glutPostRedisplay que je cherche. En effet qd on fait un glutPostRedisplay, il n'est pris en compte qu'au prochain tour de glutMainLoop, mais moi je voudrais qu'il soit pris en compte directement !

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    fearyourself, je viens de lire des trucs sur les pointeurs de fonction.

    Si je comprend bien, il devient possible de modifier l'addresse d'une fonction callback qd on le veut ?

    je reprend mon exemple :

    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
     
    void display()
    {
    ...
    }
     
    void idle()
    {
           if(condition1)
                 animation1();
           else if (condition2)
                 animation2();
           else
                  animation3();
    }
    si je rentre dans if(condition1), je pourrais donc modifier le pointeur idle pour qu'il pointe vers animation1 --> animation1 deviendrait ma nouvelle idle ??

    Si c'est le cas, pourrais tu m'expliquer en détails comment cela s'applique dans glut s'il-e-plait ?

  10. #10
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par KeN1985
    Si c'est le cas, pourrais tu m'expliquer en détails comment cela s'applique dans glut s'il-e-plait ?
    Voilà comment je fais:

    Je donne à glut des fonctions pour gérer les événements, dans la suite de ce post, je ne vais que traiter le cas de l'affichage. Donc du point de vue glut, cela donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    glutDisplayFunc(affichage);
    Ensuite ma fonction d'affichage est faite de seulement 4 lignes. Les trucs de bases:
    - Remettre à zéro (effacer l'image, les buffers...)
    - Dessiner
    - Echanger les buffers si on est en double-buffering

    Finalement, on remarque que dans cette fonction, rien ne se dessine vraiment, j'appelle
    une fonction qui se trouve dans ma classe globale Engine (moteur 3D pour les intimes).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // A redisplay has been requested
    void affichage()
    {
    //Clear color/depth/stencil buffers
          glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
          glLoadIdentity();
          //Call draw function
          (*g_engine.aff_fct)();
     
          glutSwapBuffers();                  //Swap the drawing buffers
    }
    Cette classe est déclarée comme ceci:
    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
     
    class Engine
    {
    private:
        ...
     
    public:
          Engine();
          ~Engine();
     
        //Initialize window with a name
          void Init(int w,int h, char *name); 
     
          //Pointer functions to be able to show what we want ;-)
          void (*aff_fct)(void);
          void (*keyb_fct)(unsigned char touche, int x, int y);
          void (*keybSpecial_fct)(int touche, int x, int y); 
          void (*mouse_fct)(int bouton, int etat, int x, int y);
     
          void setGameFct(); //Set function to point to game functions
          void setMainMenuFct(); //Set MainMenu functions
    };
    On remarquera deux choses, la fonction qu'appelle affichage est un pointeur de fonction et en plus public! tssk tssk tssk. Ce n'est pas forcément une bonne idée lorsqu'on ne sait pas ce qu'on fait mais vu que je programme généralement seul, cela me va très bien. Une meilleure solution serait de mettre un appel normal public qui lui appel le pointeur de fonction. Avec un get/set on pourrait vérifier la validité des changement, mais on a déjà deux indirections dans les appels et je trouve que cela fait déjà beaucoup:

    Glut -> affichage -> aff_fct...
    Bref... Donc comment on s'en sert? Et bien, supposons qu'on veut une image de départ et après avoir le jeu de base.

    J'utilise mes fonctions
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
          void setGameFct(); //Set function to point to game  functions
          void setMainMenuFct(); //Set MainMenu functions
    Si on regarde ces fonctions, elle ne font que mettre à jour les pointeurs de fonctions, par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      aff_fct = &mainMenu_aff;
    Cette fonction sera la vraie fonction d'affichage qui fera tout ce qu'on veut dans le menu général.

    En généralisant un peu et sous glut, je fais la même chose pour toutes les fonctions claviers, souris, idle...

    En continuant dans l'idée du menu général, lorsqu'on appuie sur 'p', on rentre donc dans la fonction du menu général et on voit:
    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
     
    void mainMenu_keyb(unsigned char touche, int x, int y)
    {
          if(touche == 'q')
            exit(1);
        else if(touche=='p')
          {
          cout << "Set Main Game" << endl;
          //Initialize Main Program
          cout << "Init" << endl;
          promain.Init();
          cout << "Load" << endl;
          promain.load("savedmodule");
          cout << "Switch functions" << endl;
          g_engine.setProMainFct();
          }
    }
    Donc, j'initialise le moteur du jeu (à ne pas confondre avec le moteur 3D du jeu), je charge la sauvegarde et je mets les pointeurs de fonctions à jour...

    En espérant avoir été clair,
    Jc

Discussions similaires

  1. Problème d'affichage dans les textbox
    Par popinenhbourg dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 28/02/2006, 11h36
  2. [IE 6.0] Plus d'affichage entre les balises [code] [/code]
    Par Trap D dans le forum Autres Logiciels
    Réponses: 2
    Dernier message: 20/10/2005, 10h39
  3. [TP7] Question sur les calculs en tp7
    Par argon dans le forum Turbo Pascal
    Réponses: 3
    Dernier message: 07/10/2005, 05h42
  4. Réponses: 6
    Dernier message: 19/05/2005, 11h06
  5. Conserver l'affichage pendant les calculs ?
    Par ceugniet dans le forum C++Builder
    Réponses: 5
    Dernier message: 31/03/2004, 12h19

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