Bonjour tout le monde.
Voila je présente mon code.
Je cherche a éffectuer une décharge processeur au sein d'une application windows pour afficher des graphismes openGL.
Il s'agit plus ou moins de limiter le nombre de rendus opengl pour avoir par exemple 60 images/secondes.
J'utilise donc une constante référence de temps
time_per_frame = 1/60 sec = environ 16 ms.
Elle correspond au temps idéal pour afficher une image, cela veut dire qu'on ne veut afficher qu'une seule image toute les 16 ms.
Pour mesurer ma boucle d'affichage, j'ai créer une fonction qui mesure à chaque passage le temps écoulé :
get_time();
(cela renvoi une mesure de quelques millisecondes)
Cette fonction ne pose pas de problème, je suis pret à vous la montrer si besoin est.
Ensuite, dans ma boucle d'affichage, aprés chaque rendu, je mesure le temps écoulé.
(il s'agit du temps écoulé à chaque passage renvoyé par get_time)
Ce temps est appelé running_time.(unsigned int)
Je test ce temps pour voir si j'ai effectué moins de temps
"running_time" qu'il ne faut pour une image
"time_per_frame".
Si cela est le cas alors je fait perdre un delay à ma boucle: la différence de temps qu'il me reste pour attenidre
"time_per_frame".
Bon ce n'est pas facile à éxpliquer, tout ceci est bien sur très inspiré du siteduzéro sur le tutorial opengl 3D partie2.
Voici a quoi ressemble ma boucle :
Code C/C++ :
void loop()
{
#define FPS 60
static unsigned int time_per_frame = (unsigned int)static_cast<int>( (1000/FPS) + 0.5);
static unsigned int running_time = 0;
static DWORD delay = 0;
static unsigned int refresh_times = 0;
static bool is_first_time = true;
// initialistion effectué qu'au premier passage
init_opengl();
// animations pour une rotation 3D d'un plan
angle += 0.2;
// rendu opengl
draw();
// lecture framerate
framerate(running_time+delay);
// mesure du temps écoulé a chaque passage, la première fois running_time = 0;
running_time = get_time();
// décharge CPU
if (running_time < time_per_frame)
{
delay = time_per_frame - running_time;
Sleep(delay);
}
else
{ delay = 0;}
// lecture des temps dans une statusbar windows
refresh_times += running_time;
if (refresh_times > 800 || is_first_time)
{
send_statusbar_var(statusbar->debug,"time_per_frame = ",time_per_frame," ms");
send_statusbar_var(statusbar->refresh,"cycle = ",running_time," ms");
send_statusbar_var(statusbar->delay,"delay = ",delay," ms");
send_statusbar_var(statusbar->time,"add = ",running_time+delay," ms");
refresh_times = 0;
is_first_time = false;
}
}
Voila, ce code à l'air de fonctionner, mais apparement j'ai le cas "aléatoire" ou (
running_time >
time_per_frame).
Cela veut dire que en une boucle j'ai mis plus de 16ms à afficher un rendu openGL.
Dans ce cas je ne perd pas de temps et je réaffiche tout de suite (delay = 0).
Seulement sur mon ordinateur, j'ai des périodes ou cela se produit assez longtemps (au démarrage de l'ordinateur j'ai l'impression).
j'ai envie de dire que mon ordinateur est plombé.
Mais ce qui est plus étonnant, c'est que au bout d'un certain temps cela disparait, puis réapparait, sans explications.
Je tient à préciser que ce phénomène ne se produit pas en SDL, et que mon code fonctionne parfaitement en SDL.
(comme sur le site du zéro en fait)
Cela fait 2 semaines que je remet en cause mon programme, et je me pose des questions.
J'ai conscience que la fonction sleep(millisecondes); n'est pas précise, mais il me semble que ceci est rattrapé par une nouvelle mesure du temps avec mon get_time ?
Auriez des suggestions à me faire ?
J'ai supposé aussi que les messages windows peuvent etre source des décalages dans le temps.
(si c'est le cas je remesure le temps écoulé à chaque fois)
Je vous montre des screens shoots.
Fonctionnement idéal:
Default constaté:
Merci de m'éclairer.
le raton laveur <+"=