Atteindre un taux de trame constant dans SDL
Je suis en train de faire une SDL programme qui s'exécute avec une constante de fréquence d'image. Cependant je trouve que même si mon programme est à la traîne beaucoup et le fait de sauter un grand nombre d'images (même si il tourne à une cadence faible et n'est pas rendu beaucoup).
Avez-vous des suggestions pour faire mon programme tourne bien?
#include "SDL.h"
#include "SDL/SDL_ttf.h"
//in milliseconds
const int FPS = 24;
const int SCREENW = 400;
const int SCREENH = 300;
const int BPP = 32;
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination) {
SDL_Rect offset;
offset.x = x;
offset.y = y;
if(SDL_BlitSurface(source, NULL, destination, &offset) < 0) {
printf("%s\n", SDL_GetError());
}
}
int main(int argc, char* argv[]) {
//calculate the period
double period = 1.0 /(double)FPS;
period = period * 1000;
int milliPeriod = (int)period;
int sleep;
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
TTF_Font* font = TTF_OpenFont("/usr/share/fonts/truetype/freefont/FreeMono.ttf", 24);
SDL_Color textColor = { 0x00, 0x00, 0x00 };
SDL_Surface* screen = SDL_SetVideoMode(SCREENW, SCREENH, BPP, SDL_SWSURFACE);
SDL_Surface* message = NULL;
Uint32 white = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF);
SDL_Event event;
char str[15];
Uint32 lastTick;
Uint32 currentTick;
while(1) {
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
return 0;
}
else {
lastTick = SDL_GetTicks();
sprintf(str, "%d", lastTick);
message = TTF_RenderText_Solid(font, str, textColor);
if(message == NULL) { printf("%s\n", SDL_GetError()); return 1; }
//the actual blitting
SDL_FillRect(screen, &screen->clip_rect, white);
apply_surface(SCREENW /2, SCREENH /2, message, screen);
currentTick = SDL_GetTicks();
//wait the appropriate amount of time
sleep = milliPeriod - (currentTick - lastTick);
if(sleep < 0) { sleep = 0; }
SDL_Delay(sleep);
SDL_Flip(screen);
}
}
}
TTF_CloseFont(font);
TTF_Quit();
SDL_Quit();
return 0;
}
source d'informationauteur SDLFunTimes
Vous devez vous connecter pour publier un commentaire.
Ne pas dormir.
Au lieu de cela, utiliser une interpolation linéaire de la fonction pour calculer votre position, compte tenu de l'heure actuelle chaque fois que la boucle principale. Cela permettra de garantir que, peu importe le matériel, l'espace, les navires arrivent à destination en même temps (bien que sur une machine rapide, vous verrez plusieurs des étapes intermédiaires).
Il existe également d'autres interpolation/mélange de fonctions (comme linéaire facilité, facilité, quadratique atténuation en entrée/sortie, cubes, etc.) pour d'autres effets sympas.
Vérifier ce lien:
Fréquence D'Images Indépendantes, L'Interpolation Linéaire
Il y a un petit exemple de la façon de le faire à http://www.libsdl.org/release/SDL-1.2.15/docs/html/guidetimeexamples.html:
Comme dicroce lui a dit de ne pas dormir. Pourquoi? Parce que la plupart des systèmes d'exploitation de bureau ne sont pas difficiles en temps réel des systèmes, et donc
sleep(10)
ne signifie pas "wake me up dans exactement 10 millisecondes"cela signifie "s'assurer que je suis endormi pendant au moins 10 millisecondes". Cela signifie que, parfois, vous passez beaucoup plus de sommeil que vous avez voulu. C'est rarement ce que vous voulez. Si le gameplay lisse est important, c'est généralement vous voulez juste rendre aussi souvent que vous le pouvez - SDL_Flip poignées pour vous, grâce à votre vidéo, les pilotes n'ont pas de VSync désactivé.Au lieu de dormir, dicroce suggéré une interpolation linéaire de l'algorithme pour calculer la position correcte pour votre entités à un moment donné. Alors que c'est une stratégie raisonnable pour beaucoup de jeux, et j'ai l'habitude d'utiliser moi-même, il peut causer des problèmes dans certains cas, si ce n'est pas manipulé avec soin: le "Principes Fondamentaux De L'Intégration" l'article explique en partie cela. L'alternative proposée dans le même auteur de l'article suivant, appelé "Fixer Votre Timestep".