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

SDL Discussion :

De très légères saccades ?


Sujet :

SDL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Par défaut De très légères saccades ?
    J'ai commencé à me servir de SDL il y a quelques jours, et je remarque seulement maintenant lorsque je déplace une simple image à l'aide du clavier de très légères saccades ttes les 1/2-1 seconde environ, alors que sinon c'est parfaitement fluide.(le mot "saccade" est presque exagéré, c'est presque un petit "saut" comme si le deplacement (ou l'affichage de l'image) n'etait pas totalement constant). Je n'ai aucune idée d'où ça vient, j'ai consulté plusieurs tutos, j'ai pensé au framerate, mais je gère les fps correctement je crois (du type if (SDL_Getticks()-previous_time>DELAY) { boucle(); } else SDL_Delay(1);
    Je me suis dit que ça venait peut-être de SDL_Delay() qui n'est pas très précis alors j'ai essayé aussi en laissant SDL gérer le framerate avec SDL_framerate.h , c'est exactement pareil.

    Ca ne vient pas de la gestion des touches non plus (j'ai essayé en déplaçant simplement l'image de droite à gauche sans l'action des touches et c'est pareil).

    A part ça je suis sous Linux..

    Voilà c'est peu d'infos mais si vous avez une idée merci de m'en faire part. J'éditerai le post pour mettre un lien vers mes sources et le programme compilé pour voir.

    Voilà j'ai fait un nouveau projet histoire de garder le strict nécessaire (ça ressemble plus à un copier-coller de divers tutos qu'à autre chose).
    Sources
    Executable
    (se placer dans le répertoire de l'executable pour le lancer histoire qu'il trouve les images..)

    Dites-moi si vous voyez aussi ces petites saccades..

    Edit : pour ceux qui auraient la flemme de télécharger de le .zip, voici le "code" (mais seul le main.cpp est important) :
    main.cpp :
    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
    39
    40
    41
    42
    43
    44
    45
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
     
    #include <SDL/SDL_image.h>
    #include "main.h"
    #include "controls.cpp"
    #include "graphics.cpp"
     
    int main(int argc, char *argv[])
    {
        int x=0,y=0;
     
        SDL_Init(SDL_INIT_VIDEO); // Initialisation de la SDL
     
        screen=SDL_SetVideoMode(W_SCREEN, H_SCREEN, 32, (SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_ANYFORMAT)); // Ouverture de la fenêtre
     
        LoadImages();
     
        for(;;)
        {
            if (SDL_GetTicks()-ticks >= DELAY)
            {
                ticks=SDL_GetTicks();
     
                DrawImage(bg, 0, 0, screen, 0, 0, W_SCREEN, H_SCREEN,0xFF00FF);
                DrawImage(tux, 0, 0, screen, x, y, 32, 32,0xFF00FF);
     
                if (keyboard.continu_key&KEY_LEFT) x--;
                if (keyboard.continu_key&KEY_UP) y--;
                if (keyboard.continu_key&KEY_RIGHT) x++;
                if (keyboard.continu_key&KEY_DOWN) y++;
     
                process_events();
                SDL_Flip(screen);
     
                if (quit==1) break;
            }
            else SDL_Delay(1);
        }
     
        SDL_Quit(); // Arrêt de la SDL
     
        return EXIT_SUCCESS; // Fermeture du programme
    }
    main.h :
    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
    #define W_SCREEN 320
    #define H_SCREEN 240
    #define LEFTCLICK 1
    #define RIGHTCLICK 2
    #define KEY_UP 1
    #define KEY_RIGHT 2
    #define KEY_DOWN 4
    #define KEY_LEFT 8
    #define FPS 60
    #define DELAY (1000/FPS)
     
    struct sMouse
    {
        int button;
        int x, y;
    } mouse;
     
    struct sKeyboard
    {
        int continu_key;
        int pressed_key;
    } keyboard={0,0};
     
    int MouseButton=0;
    int ticks=0;
    int t_fps=0;
    int quit=0;
     
    SDL_Surface *bg,*tux,*screen;
    controls.cpp :
    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
    39
    40
    41
    42
    void process_events()
    {
        SDL_Event event;
     
        mouse.button=0;
        keyboard.pressed_key=0;
     
        if(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                case SDL_QUIT:
                    quit=1;
                case SDL_MOUSEBUTTONDOWN:
                    mouse.button=event.button.button;
                    mouse.x=event.button.x;
                    mouse.y=event.button.y;
                    break;
                case SDL_KEYUP:
                    switch (event.key.keysym.sym)
                    {
                        case SDLK_UP: keyboard.continu_key&=~KEY_UP; break;
                        case SDLK_RIGHT: keyboard.continu_key&=~KEY_RIGHT; break;
                        case SDLK_DOWN: keyboard.continu_key&=~KEY_DOWN; break;
                        case SDLK_LEFT: keyboard.continu_key&=~KEY_LEFT; break;
                        default: break;
                    }
                    break;
                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym)
                    {
                        case SDLK_UP: keyboard.pressed_key|=KEY_UP; keyboard.continu_key|=KEY_UP; break;
                        case SDLK_RIGHT: keyboard.pressed_key|=KEY_RIGHT; keyboard.continu_key|=KEY_RIGHT; break;
                        case SDLK_DOWN: keyboard.pressed_key|=KEY_DOWN; keyboard.continu_key|=KEY_DOWN; break;
                        case SDLK_LEFT: keyboard.pressed_key|=KEY_LEFT; keyboard.continu_key|=KEY_LEFT; break;
                        default: break;
                    }
                default:
                    break;
            }
        }
    }
    graphics.cpp :
    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
    void LoadImages()
    {
        bg=IMG_Load("bg.bmp");
        tux=IMG_Load("tux.png");
    }
     
    void DrawImage(SDL_Surface *src, int bmp_x, int bmp_y, SDL_Surface *dest, int screen_x, int screen_y, int size_x, int size_y,int transp)
    {
            SDL_Rect src_blitrect = {bmp_x,bmp_y,size_x,size_y}, dest_blitrect = {screen_x,screen_y,size_x,size_y};
     
            int r,v,b;
            r=transp>>16;
            v=(transp>>8)&0xFF;
            b=transp&0xFF;
     
            SDL_SetColorKey(src, SDL_SRCCOLORKEY, SDL_MapRGB(src->format, r, v, b));
            SDL_BlitSurface(src, &src_blitrect, dest, &dest_blitrect);
    }

  2. #2
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Salut,

    je pense que ça peut venir de différentes raison, et qu'avoir les sources ça serait l'idéal.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Par défaut Edit du premier post
    Voilà j'ai édité il y a les "sources" et l'exécutable.. C'est relativement peu visible mais quand même.. ça me gêne un peu..

  4. #4
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Salut,

    j'ai fait quelques modif, sur mon ordi ça améliore un peu les choses

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
     
    #include <SDL/SDL_image.h>
    #include "main.h"
    #include "controls.cpp"
    #include "graphics.cpp"
     
    int x=0,y=0;
     
    Uint32 display(Uint32 delay, void *param)
    {
        if (keyboard.continu_key&KEY_LEFT) x-=1;
        if (keyboard.continu_key&KEY_UP) y-=1;
        if (keyboard.continu_key&KEY_RIGHT) x+=1;
        if (keyboard.continu_key&KEY_DOWN) y+=1;
     
        DrawImage(bg, 0, 0, screen, 0, 0, W_SCREEN, H_SCREEN,0xFF00FF);
        DrawImage(tux, 0, 0, screen, x, y, 32, 32,0xFF00FF);
     
        SDL_Flip(screen);
     
        return 10;
    }
     
    int main(int argc, char *argv[])
    {
        SDL_Init(SDL_INIT_EVERYTHING); // Initialisation de la SDL
     
        screen=SDL_SetVideoMode(W_SCREEN, H_SCREEN, 32, (SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_ANYFORMAT)); // Ouverture de la fenêtre
     
        SDL_AddTimer(10, display, NULL);
     
        LoadImages();
     
        for(;;)
        {
            process_events();
            if (quit==1) break;
            SDL_Delay(1);
        }
     
        SDL_Quit(); // Arrêt de la SDL
     
        return EXIT_SUCCESS; // Fermeture du programme
    }
    J'ai utilisé un SDL_Timer: ça veut dire que toutes les 10 ms, la fonction dans le timer est appelée. Attention, pour pouvoir utiliser les timers, il faut ajouter le flag approprié dans SDL_Init.

    Voici le lien de la doc officielle: http://www.libsdl.org/cgi/docwiki.cgi/SDL_AddTimer

    Et comme il est expliqué, il y a une 'granularité' de 10 ms, ça veut dire qu'en gros il vaut mieux utiliser des valeurs comme 10/20/30/40... ms
    Donc avec 10ms ça rend bien, avec 16 ms moins bien (probablement du fait de cette granularité)

    Enfin c'est vraiment pas grand chose, mais je doute qu'il y ait un autre moyen.

    Sinon, fais attention dans ton main.h, à mettre des parenthèses pour delay:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define DELAY (1000/FPS)
    est plus prudent dans le cas où tu es amené à faire des divisions par DELAY.

    Peut être que d'autres membres ont des meilleures solutions/explications, moi je vois pas grand chose

    Coyotte507

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 11
    Par défaut Merci
    Effectivement on n'a plus ce problème de saccades... Mais je ne comprends pas trop d'où venait le problème.. ?
    Et puis ce code est bizarre, je n'ai jamais vu de fonctions de ce genre en C : quand la fonction display est-elle appelée ? On dirait du C++.. ? (je connais peu le C++)
    S'il n'y a pas d'autre solution je ferai comme ça, mais j'aimerais autant comprendre d'où venait le problème.
    Merci beaucoup en tout cas.

  6. #6
    Membre Expert
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Par défaut
    Salut,

    le problème venait surement de SDL_Delay(1) qui peut faire un délai plus important (genre 10 ms et quelquefois un peu plus).

    Ce code n'est pas du C++, loin de là.

    En fait (je ne sais pas si tu connais les threads), SDL va faire en sorte que la fonction soit appelée toutes les X ms (en utilisant le truc de l'OS je crois, ce qui est plus précis).

    On passe un pointeur de fonction à une fonction qui crée un thread pour exécuter la fonction dans le pointeur en parallèle du programme principal toutes les X ms

Discussions similaires

  1. Affichage très saccadé !
    Par jlb59 dans le forum Windows XP
    Réponses: 9
    Dernier message: 09/05/2011, 07h32
  2. déplacement d'un label très saccadé
    Par marco62118 dans le forum VB 6 et antérieur
    Réponses: 20
    Dernier message: 13/01/2008, 00h02
  3. glissement d'objet très saccadé même en mode création
    Par marco62118 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 10/01/2008, 11h23
  4. base de données très légère
    Par julio02200 dans le forum Excel
    Réponses: 4
    Dernier message: 28/10/2007, 00h39
  5. saccades très bizarres
    Par Myth_Titans dans le forum SDL
    Réponses: 3
    Dernier message: 26/08/2006, 17h19

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