Partage
  • Partager sur Facebook
  • Partager sur Twitter

[OpenGL] - Problème de rotation lente -

Sujet résolu
    19 juin 2007 à 19:27:16

    Salut à tous !
    Alors voila, je suis exposé à un problème assez spécial. Vous connaissez tous le cube animé de Kayl. J'ai fait l'animation différement, mais ça marche exactement pareil :


    while (again == true)
    {
        SDL_PollEvent(&action);

        switch(action.type)
        {
            case SDL_QUIT :
                    again = false;
                    break;
        }

        actualTime = SDL_GetTicks();

        if (actualTime - lastTime >= 20)
        {
            angleX += 0.05;

            lastTime = actualTime;
        }

        else
        {
            SDL_Delay(20);
        }

        Paint();
    }


    J'ai testé c'est okay. Seulement voila le problème, dès que j'utilise en plus un mappage de texture sur le cube, ça commence à saccader et à ralentir sévèrement !
    Est-ce que quelqu'un pourrait m'expliquer pourquoi ? Je ne comprends vraiment pas !
    • Partager sur Facebook
    • Partager sur Twitter
      19 juin 2007 à 19:40:29

      Oui et je fais quoi avec ça rien de tout ça ne réponds à ma question :o
      • Partager sur Facebook
      • Partager sur Twitter
        19 juin 2007 à 19:49:32

        on peut avoir ta fonction "Paint()" ?
        • Partager sur Facebook
        • Partager sur Twitter
          19 juin 2007 à 19:55:16

          Citation : -Skypers-

          Oui et je fais quoi avec ça rien de tout ça ne réponds à ma question :o


              SDL_PollEvent(&action);

              switch(action.type)
              {
                  case SDL_QUIT :
                          again = false;
                          break;
              }

          Ca fait que si tu affiches plus longtemps que la fréquence des évènements, la pile des évènements va gonfler et tu vas traiter ceux d'il y a 1,2,3 voire 4 secondes avant.
          Fais voir un code compilable.
          • Partager sur Facebook
          • Partager sur Twitter
            19 juin 2007 à 20:08:53

            Le voici (j'ai volontairement exclu loadtexture et flipSurface)


            #include <windows.h>
            #include <SDL/SDL.h>
            #include <SDL/SDL_image.h>
            #include <gl/gl.h>
            #include <gl/glu.h>

            void Paint();

            SDL_Surface * flipSurface(SDL_Surface * surface);

            GLuint loadTexture(const char * filename,bool useMipMap);

            GLuint texture;

            double angleX = 0;

            int main(int argc, char *argv[])
            {
                SDL_Surface *screen = NULL;
                SDL_Event action;
                bool again = true;
                Uint32 actualTime = 0;
                Uint32 lastTime = 0;

                SDL_Init(SDL_INIT_VIDEO);
                SDL_WM_SetCaption("SDL GL - Chargement d'une texture", NULL);
                screen = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL);

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(70, (double)800/600, 1, 1000);

                glEnable(GL_DEPTH_TEST);
                glEnable(GL_TEXTURE_2D);

                texture = loadTexture("01.jpg", true);


                while (again == true)
                {
                    SDL_PollEvent(&action);

                    switch(action.type)
                    {
                        case SDL_QUIT :
                            again = false;
                            break;
                    }

                    actualTime = SDL_GetTicks();

                    if (actualTime - lastTime >= 20)
                    {
                        angleX += 1;

                        lastTime = actualTime;
                        Paint();
                    }

                    else
                    {
                        SDL_Delay(20 - (actualTime - lastTime));
                    }

                    }

                SDL_Quit();
                return 0;
            }

            void Paint()
            {
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();

                gluLookAt(1, 2, 3, 0, 0, 0, 0, 1, 0);

                glRotated(angleX, 1, 0, 0);

                glDisable(GL_TEXTURE_2D);

                glBegin(GL_LINES);
                    glColor3ub(255, 0, 0);    glVertex3d(0, 0, 0);
                                              glVertex3d(5, 0, 0);
                    glColor3ub(0, 255, 0);    glVertex3d(0, 0, 0);
                                              glVertex3d(0, 5, 0);
                       glColor3ub(0, 0, 255);    glVertex3d(0, 0, 0);
                                                 glVertex3d(0, 0, -5);
                glEnd();
                   
                glEnable(GL_TEXTURE_2D);

                glBindTexture(GL_TEXTURE_2D, texture);
                glBegin(GL_QUADS);
                    glColor3ub(255, 0, 0);    glTexCoord2d(0, 0);    glVertex3d(-1, -1, 1);
                    glColor3ub(0, 255, 0);    glTexCoord2d(0, 1);    glVertex3d(-1, 1, 1);
                    glColor3ub(0, 0, 255);    glTexCoord2d(1, 1);    glVertex3d(1, 1, 1);
                    glColor3ub(255, 255, 255);    glTexCoord2d(1, 0);    glVertex3d(1, -1, 1);

                    glColor3ub(255, 0, 0);    glTexCoord2d(0, 0);    glVertex3d(1, -1, 1);
                    glColor3ub(0, 255, 0);    glTexCoord2d(0, 1);    glVertex3d(1, 1, 1);
                    glColor3ub(0, 0, 255);    glTexCoord2d(1, 1);    glVertex3d(1, 1, -1);
                    glColor3ub(255, 255, 255);    glTexCoord2d(1, 0);    glVertex3d(1, -1, -1);

                    glColor3ub(255, 0, 0);    glTexCoord2d(0, 0);    glVertex3d(1, -1, -1);
                    glColor3ub(0, 255, 0);    glTexCoord2d(0, 1);    glVertex3d(1, 1, -1);
                    glColor3ub(0, 0, 255);    glTexCoord2d(1, 1);    glVertex3d(-1, 1, -1);
                    glColor3ub(255, 255, 255);    glTexCoord2d(1, 0);    glVertex3d(-1, -1, -1);

                    glColor3ub(255, 0, 0);    glTexCoord2d(0, 0);    glVertex3d(-1, -1, -1);
                    glColor3ub(0, 255, 0);    glTexCoord2d(0, 1);    glVertex3d(-1, 1, -1);
                    glColor3ub(0, 0, 255);    glTexCoord2d(1, 1);    glVertex3d(-1, 1, 1);
                    glColor3ub(255, 255, 255);    glTexCoord2d(1, 0);    glVertex3d(-1, -1, 1);

                    glColor3ub(255, 0, 0);    glTexCoord2d(0, 0);    glVertex3d(-1, -1, 1);
                    glColor3ub(0, 255, 0);    glTexCoord2d(0, 1);    glVertex3d(-1, -1, -1);
                    glColor3ub(0, 0, 255);    glTexCoord2d(1, 1);    glVertex3d(1, -1, -1);
                    glColor3ub(255, 255, 255);    glTexCoord2d(1, 0);    glVertex3d(1, -1, 1);

                    glColor3ub(255, 0, 0);    glTexCoord2d(0, 0);    glVertex3d(-1, 1, 1);
                    glColor3ub(0, 255, 0);    glTexCoord2d(0, 1);    glVertex3d(-1, 1, -1);
                    glColor3ub(0, 0, 255);    glTexCoord2d(1, 1);    glVertex3d(1, 1, -1);
                    glColor3ub(255, 255, 255);    glTexCoord2d(1, 0);    glVertex3d(1, 1, 1);
                glEnd();

                glFlush();
                SDL_GL_SwapBuffers();
            }
            • Partager sur Facebook
            • Partager sur Twitter
              19 juin 2007 à 22:40:48

              déjà pourquoi des glDisable/enable à gogo sur GL_TEXTURE_2D ?
              un seul glEnable au debut suffit non ?
              • Partager sur Facebook
              • Partager sur Twitter
                20 juin 2007 à 0:00:35

                Citation : minirop

                déjà pourquoi des glDisable/enable à gogo sur GL_TEXTURE_2D ?
                un seul glEnable au debut suffit non ?


                Naaan c'est bieng ! :D :
                http://jeux.developpez.com/faq/opengl/?page=optimisations#OPTIMISATIONS_ameliorer_perfs

                Je cite :

                Citation : FAQ dvp.com

                La règle de base est de savoir qu'OpenGL est une machine à états, c'est-à-dire que tout état acitvé à un instant T restera actif durant tous les instants suivants, à moins de désactiver cet état. Ceci implique pour le programmeur de bien savoir quels états sont actif à quel moment, afin d'utiliser le moins possible de fonctionnalités inutiles.



                Enfin bon, je reconnais qu'il les dispose un peu n'importe comment...

                Citation : Skypers

                while (again == true)

                Redondance !
                while(again)


                Ensuite (on ne le dira jamais assez, je devrais rajouter une q/r à la faq), il faut utiliser cette forme pour récupérer les événements :

                while(SDL_PollEvent(&ev))
                {
                    switch(ev.type)
                    {
                        ...
                    }
                }

                ...


                Ta texture est-elle grosse ? A-t-elle des dimensions puissance de 2 ? As-tu une carte graphique pourrie ? :-°
                • Partager sur Facebook
                • Partager sur Twitter
                  20 juin 2007 à 0:26:57

                  Deja merci beaucoup pour toute ces réponses. Ma carte graphique n'est pas du haut de gamme en effet mais n'est pas nan plus pourris (Config : AMD Athlon 64 x2 Duo, nVidia 6100 256Mo (intégrée :(:( ), 1024 Mo de RAM).

                  Pour ce qui est des glDisable, en fait c'est pour que je puisse tracer les axes XYZ, sinon il ne fonctionne pas vu que le mapping est actif.

                  Ensuite non pas du tout la texture fait 44 Ko pour 256*256.

                  La boucle while oui c'est une question de commodité, tout comme ( while (!again) ). Mais merci de m'y avoir fait penser, je vais le modifier !

                  Pour finir, je comprend l'utilité du PollEvent ici, mais j'ai déja essayé, ça rame toujours autant :(
                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 juin 2007 à 8:57:24

                    Moi, je n'ai aucun problème.....
                    Calcule le nombre de FPS que tu as.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 juin 2007 à 9:12:35

                      Citation : Skypers

                      nVidia 6100 256Mo (intégrée :(:( )


                      Evidemment c'est pas la joie...

                      Fais ce que t'as dit Pole, mais en virant ton "bloqueur" de FPS. C-à-d commente tout ça :
                      actualTime = SDL_GetTicks();

                              if (actualTime - lastTime >= 20)
                              {
                                  angleX += 1;

                                  lastTime = actualTime;
                                  Paint();
                              }

                              else
                              {
                                  SDL_Delay(20 - (actualTime - lastTime));
                              }

                      et remplaces-le juste par ton Paint() (attention le proco va tourner à fond).
                      • Partager sur Facebook
                      • Partager sur Twitter
                        20 juin 2007 à 12:36:41

                        Okay je vais faire ça et je vous dis

                        EDIT : C'est bon, mais je ne comprends pas bien les résultats

                        Voici l'algo que j'ai utilisé pour calculer les FPS


                        while (again == true)
                        {
                            SDL_PollEvent(&action);

                            switch(action.type)
                            {
                                case SDL_QUIT :
                                    again = false;
                                    break;
                            }

                            actualTime = SDL_GetTicks(); // Récupère le temps à chaque tour de boucle

                            if (actualTime - fpsTime >= 1000) // Si une seconde s'est écoulée depuis
                            { // la dernière sauvegarde des FPS
                                FPS = fopen("out.txt", "a");

                                if (FPS)
                                {
                                    fprintf(FPS, "%d\n", compteurFPS);

                                    fclose(FPS);
                                }

                                else; // -0-

                                compteurFPS = 0; // Réinitialisation du compteur FPS
                                fpsTime = actualTime;
                            }

                            else if (actualTime - lastTime >= 20) // Si 20 millisecondes se sont écoulées
                            {
                                thetaX += 5; // La distance angulaire de l'axe X s'accroit de 5°

                                lastTime = actualTime;
                                compteurFPS += 1; // Le compteur prend 1 de plus
                            }

                            Paint(); // Dessin du vase

                        }


                        Et voici les résultats (théoriquement les FPS devraient être à 50 (1000/20):


                        11
                        13
                        19
                        17
                        16
                        12
                        18
                        17
                        19
                        13
                        13
                        20
                        18
                        15
                        12
                        18
                        17
                        19
                        12
                        14
                        20
                        18
                        14
                        11
                        18
                        17
                        20
                        12
                        13
                        20
                        19
                        15
                        12
                        19
                        17
                        19
                        12
                        15
                        19
                        20
                        13
                        12
                        19
                        17
                        18
                        12
                        16
                        18
                        20
                        13
                        13
                        20
                        18
                        17
                        12
                        18
                        17
                        19


                        Après c'est infini mais donc voila, je suis loins de mes 50 FPS !!!

                        REEDIT !

                        Je viens de comprendre un truc : si je réduis l'application, j'ai pile poil mes 50 PFS. Par contre, dès que je l'ouvre, je passe à du 29, 17, 15, 14 ... Pourquoi ce bug ?
                        • Partager sur Facebook
                        • Partager sur Twitter
                          20 juin 2007 à 14:24:29

                          C'est pas un bug, c'est juste que quand tu reduis l'application il ne calcul plus ce qui ce passe dans la fenetre.

                          Pour pas ne voir de ralentissement quelque soit ton FPS, il faut multiplier l'augmentation de ta vitesse de rotation par le temps d'execution de ton tour de boucle.

                          Un truc du genre : thetaX += 5*(actualTime - lastTime)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            20 juin 2007 à 14:33:05

                            Merci beaucoup ! C'est impec comme ça, mais comment vous avez trouvé ça ?
                            • Partager sur Facebook
                            • Partager sur Twitter
                              20 juin 2007 à 14:38:32

                              C'est simple,
                              moins tu a de FPS, plus le nombre de tour de boucle est petit,
                              donc il y a moins d'incrémentation de la variable de rotation.

                              Donc on multiplie la variable de rotation par le temps d'execution de la boucle.
                              Si le temps d'execution d'un tour de boucle est long alors on incrémente bien plus.
                              Si le temps d'execution d'un tour de boucle est court alors on incrémente moins.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                20 juin 2007 à 14:39:36

                                Citation : -Skypers-



                                while (again == true)
                                {
                                    // ...

                                    actualTime = SDL_GetTicks(); // Récupère le temps à chaque tour de boucle

                                    if (actualTime - fpsTime >= 1000) // Si une seconde s'est écoulée depuis
                                    { // la dernière sauvegarde des FPS
                                        FPS = fopen("out.txt", "a");



                                Mais quelle horreur ! Tu te rend compte que tu fais la même erreur qu'avec les textures ?? Ouvres ton fichier une bonne fois pour toutes bon sang. Pas étonnant que ton application soit lente, si tu programmes tout comme ça...

                                Contentes-toi d'afficher les FPS sur la sortie standard (ah nan elle est invisible la console sous Windows...) d'erreur standard, stderr.

                                Autre chose : tu incrémentes ton compteur de FPS n'importe où, c'est n'importe quoi, incrémentes-le à chaque fois que tu dessine. Colle ton incrémentation à ton appel à Paint().
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  20 juin 2007 à 17:44:32


                                      SDL_PollEvent(&action);

                                      switch(action.type)
                                      {
                                          case SDL_QUIT :
                                              again = false;
                                              break;
                                      }

                                  Si tu ne suis pas les conseils que l'on te donne, ça sert à quoi de demander de l'aide?
                                  Les FPS c'est le nombres de frames en une seconde.
                                  Donc ça donne 1000*compteurFPS/(float)fpsTime.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    20 juin 2007 à 18:10:19

                                    Okay merci beaucoup ! Pour cette histoire d'ouverture de fichier, je fais de temps en temps des erreurs sur les itérations. Je suis en train de programmer une scène 3D simpliste avec une cloture, un terrain herbeux, deux cylindre en métal et une boule lévitant tournoillant autour des cylindres. Je vous posterai la source et vous me direz ce que vous en pensez. Personellement, je suis plus à l'aise avec l'encapsulation que les variables globales ;)
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    [OpenGL] - Problème de rotation lente -

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown