我試圖製作一個以恆定幀速率運行的SDL程序。但是我發現即使我的程序滯後很多,並且跳過了很多幀(儘管它運行在低幀並且沒有渲染太多)。在SDL中實現恆定幀速率
你們有什麼建議讓我的程序運行更流暢嗎?
#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;
}
我認爲睡覺以節省電池可能是個好主意。插值是好的,在某些遊戲中無論如何都是好的,但如果我的遊戲在使用時達到60FPS,比如20%的CPU,絕對不需要更快地運行,因爲顯示器最有可能運行在60Hz無論如何,所以我只是在筆記本電腦和設備上浪費電池壽命。 – 2011-09-09 11:54:57
@TomA SDL不會執行VSync來限制幀率嗎? – 2014-01-11 03:18:28
您可以在SDL 2.x中選擇3種類型的V-Sync。參見SDL_GL_SetSwapInterval() – Michaelangel007 2014-03-14 19:47:50