Gerer la vitesse avec SDL

Proposé par Jerry Kan

le 27 December 2006 à 12h 41mn 53s

12808 visualisations



Salut

on parlait il y a quelque temps de gerer la vitesse d'execution du programme, je suis tombé sur des fonctions SDL tres pratiques qui permettent de faire ca tres simplement,(sans pour autant utiliser de l'affichage sdl bien sur) tout en évitant les appels systemes pas portables

pour ceux que ca interresse j'ai trouvé mes infos ici :
http://fearyourself.developpez.com/tuto … ur/#L2.2.b

en résumé il suffit de faire :

Code c++ :

#include <SDL_framerate.h>
// (...)

// on cree un manager
FPSmanager manager;
SDL_initFramerate(&manager);

//on définit le nombre d'action par seconde
SDL_setFramerate(&manager,40);

// la main loop
while(1)
{
  ...
  //on dessine
  game.draw();

  // on appelle frame delay qui s'arrange pour attendre le temps qui va bien
  SDL_framerateDelay(&manager);

}


les méthodes de FPSmanager :

Code:

void SDL_initFramerate(FPSmanager * manager);
int SDL_setFramerate(FPSmanager * manager, int rate);
int SDL_getFramerate(FPSmanager * manager);
void SDL_framerateDelay(FPSmanager * manager);

a noter que si c'est utilisé pour gerer les FPS, ca marche aussi bien pour n'importe quoi d'autre, comme  des calculs physiques, ou ce qu'on veux,


#1 

27-12-2006 13:56:16

Aranoth
Abonné
Lieu: Toulouse
Date d'inscription: 25-09-2006
Messages: 242
Site web

Intéressant ! Je n'ai jamais utilisé SDL_gfx donc je suis passé à côté de cette library, ça à l'air de bien faciliter la chose tout ça.

Merci !

Hors ligne


#2 

27-12-2006 14:59:14

Copland
Modérateur
Lieu: ZarbiLand
Date d'inscription: 22-09-2006
Messages: 657
Site web

Bonjour,
Si je peux me permettre, je connais pas bien SDL mais je désaprouve cette technique.
Pourquoi je m'explique :
On creé un mouvement...par exemple on avance de 10 unités par boucle.
Le système que tu décris va se contenter de faire une courte pause sur le programme, se qui dans le cas ou un pc est relativement rapide va provoquer un mouvement saccadé.
La meilleurre technique reste celle du Time Elapsed.
On calcule le temps écoulé entre deux boucles et on se sert du résultat pour lisser son mouvement selon le résultat obtenu par le Time Elapsed.
Se qui donnera un calcul du style :
Déplace mon objet de 10*TimeElapsed.
Si ta machine est rapide à calculer la scene, tu aurras un résultat très petit du genre 0.02 millisecondes.
si je reprend mon calcul ça va donner 10*0.02 = 0.2 Donc nous nous déplacerons de 0.2 unités par boucle.
Si ta machine est lente, et que t'a admétons un TimeElapsed de 0.5, ça va te donner un résultat : 10*0.5 = 5 Donc nous nous déplacerons de 5 unités par boucle.
Se qui donne à l'échelle du temps un mouvement identique sur toute les machines quelqu'en soit la rapidité.
Voilou @+

Dernière modification par Copland (27-12-2006 22:46:17)


Config : I5 2400, ATI HD6870 1Go DDR5, 4Go DDR3.
Single Boot : Windows Seven.

Hors ligne


#3 

27-12-2006 16:03:37

Jerry Kan
Habitué
Date d'inscription: 21-11-2006
Messages: 265

ey c'est vachement interressant ca !

merci du tuyau, je connaissais pas cette méthode

Hors ligne


#4 

27-12-2006 16:53:50

Aranoth
Abonné
Lieu: Toulouse
Date d'inscription: 25-09-2006
Messages: 242
Site web

La méthode de Copland est la meilleure mais elle demande que le programme soit prévu pour dès le départ.

Alors que la méthode du delay, plus approximative, peut servir de rustine.

Dernière modification par Aranoth (28-12-2006 16:32:37)

Hors ligne


#5 

27-12-2006 18:40:18

kedu
Modérateur
Date d'inscription: 23-09-2006
Messages: 155

Oui pour un jeu qui ne manipule pas ou très très peu de 3d ça peut être certainement suffisant.

Dans le cas contraire j'ai pu me rendre compte du carnage que cela pouvait faire lorsque cela tournait sur des configurations différentes de celle utilisée pour le développement/test du jeu.

Hors ligne


#6 

28-12-2006 12:10:50

White Threat
Petit nouveau
Date d'inscription: 18-12-2006
Messages: 7

Surtout si la methode fait simplement un sleep, alors tu perds completement le temps de calcul avant et apres l'image.

La seule facon de faire cela proprement serait de dire:
j'affiche une image par seconde (ce qui est totalement arbitraire) donc:

Code:

0) Je mets a zero mon timer.
1) Je fais mon precalcul.
2) j'attends pour l'affichage (temps attendu = 1000 milliseconde - timer en millisecondes)
3) je remets a zero mon timer
4) j'affiche
5) je fais mon post calcul
6) je boucle sur 1)

Vous avourez que la solution de Copland est de loin la plus efficace et la plus elegante.

Hors ligne


#7 

19-01-2007 13:02:18

Copland
Modérateur
Lieu: ZarbiLand
Date d'inscription: 22-09-2006
Messages: 657
Site web

Juste au cas ou, si ça peut servir ... J'utilise se genre de méthode :

Code:

f32 IrrTimeElapsed(IrrlichtDevice* device)
{
    static u32 LastCycle,LoopTime;
    f32 Result=0;
    LastCycle = device->getTimer()->getRealTime() - LoopTime;
    LoopTime = device->getTimer()->getRealTime();
    Result = 27/(1000.0f/LastCycle);
    if (Result > 5.0f){Result=5.0f;}
    if (Result < 0.0001f){Result = 0.0001f;}
    return Result;
}

Dernière modification par Copland (19-01-2007 13:02:47)


Config : I5 2400, ATI HD6870 1Go DDR5, 4Go DDR3.
Single Boot : Windows Seven.

Hors ligne


#8 

27-07-2007 19:15:45

alikettab
Petit nouveau
Date d'inscription: 28-02-2007
Messages: 3

C'est du bricolage, mais la méthode en elle meme est interressante....!  marci.

Dernière modification par alikettab (27-07-2007 19:17:29)

Hors ligne


#9 

27-12-2008 01:44:36

Metallizer
Abonné
Lieu: Région Parisienne
Date d'inscription: 07-01-2007
Messages: 100
Site web

Copland :

Bonjour,
Si je peux me permettre, je connais pas bien SDL mais je désaprouve cette technique.
Pourquoi je m'explique :
On creé un mouvement...par exemple on avance de 10 unités par boucle.
Le système que tu décris va se contenter de faire une courte pause sur le programme, se qui dans le cas ou un pc est relativement rapide va provoquer un mouvement saccadé.
La meilleurre technique reste celle du Time Elapsed.
On calcule le temps écoulé entre deux boucles et on se sert du résultat pour lisser son mouvement selon le résultat obtenu par le Time Elapsed.
Se qui donnera un calcul du style :
Déplace mon objet de 10*TimeElapsed.
Si ta machine est rapide à calculer la scene, tu aurras un résultat très petit du genre 0.02 millisecondes.
si je reprend mon calcul ça va donner 10*0.02 = 0.2 Donc nous nous déplacerons de 0.2 unités par boucle.
Si ta machine est lente, et que t'a admétons un TimeElapsed de 0.5, ça va te donner un résultat : 10*0.5 = 5 Donc nous nous déplacerons de 5 unités par boucle.
Se qui donne à l'échelle du temps un mouvement identique sur toute les machines quelqu'en soit la rapidité.
Voilou @+


Si j'ai bien compris, on aura un framerate variable avec cette méthode... Y'aurait moyen de lui fixer un framerate maxi ?

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
881 membres
1426 sujets
11116 messages
Dernier membre inscrit: Bidule
19 invités en ligne
Aucun membre connecté
RSS Feed