SDL程式設計入門(25)限制幀率

血色v殘陽發表於2020-12-30

限制幀率

我們可以用SDL定時器做的另一件事是手動限制幀率。在這裡,我們將禁用vsync,並保持最高幀率。

//螢幕尺寸常量
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_FPS = 60;
const int SCREEN_TICKS_PER_FRAME = 1000 / SCREEN_FPS;

在這個演示中,我們將正常渲染我們的幀,但在幀的最後,我們將等待,直到幀時間完成。例如這裡,當你想以60幀的速度渲染時,你必須花費每幀16又2/3毫秒的時間(1000ms/60幀)。這就是為什麼我們在這裡計算每幀的刻度數(以毫秒為單位)。

//Create renderer for window
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );

正如你所看到的,我們在這個演示中禁用了VSync,因為我們將手動設定幀率上限。

//Main loop flag
bool quit = false;

//Event handler
SDL_Event e;

//Set text color as black
SDL_Color textColor = { 0, 0, 0, 255 };

//每秒鐘定時器的幀數
LTimer fpsTimer;

//每秒幀數上限定時器
LTimer capTimer;

//In memory text stream
std::stringstream timeText;

//開始計算每秒的幀數
int countedFrames = 0;
fpsTimer.start();

對於這個程式,我們不僅需要一個定時器來計算幀率,還需要定時器來限制每秒的幀數。這裡在進入主迴圈之前,我們先宣告一些變數,並啟動fps定時器。

//While application is running
while( !quit )
{
    //啟動上限定時器
    capTimer.start();

為了設定FPS的上限,我們需要知道幀的渲染時間,這就是為什麼我們在每一幀開始時啟動一個計時器。

//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
    //User requests quit
    if( e.type == SDL_QUIT )
    {
        quit = true;
    }
}

//計算和校正幀數
float avgFPS = countedFrames / ( fpsTimer.getTicks() / 1000.f );
if( avgFPS > 2000000 )
{
    avgFPS = 0;
}

//設定要渲染的文字
timeText.str( "" );
timeText << "Average Frames Per Second (With Cap) " << avgFPS; 

//渲染文字
if( !gFPSTextTexture.loadFromRenderedText( timeText.str().c_str(), textColor ) )
{
    printf( "Unable to render FPS texture!\n" );
}

//Clear screen
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );

//Render textures
gFPSTextTexture.render( ( SCREEN_WIDTH - gFPSTextTexture.getWidth() ) / 2, ( SCREEN_HEIGHT - gFPSTextTexture.getHeight() ) / 2 );

//Update screen
SDL_RenderPresent( gRenderer );
++countedFrames;

這裡我們有之前的幀渲染和fps計算程式碼。

    //如果幀提前完成
    int frameTicks = capTimer.getTicks();
    if( frameTicks < SCREEN_TICKS_PER_FRAME )
    {
        //等待剩餘時間
        SDL_Delay( SCREEN_TICKS_PER_FRAME - frameTicks );
    }
}

最後在這裡我們有限制幀速率的程式碼。首先我們得到該幀完成所需的ticks數。如果該幀執行所需的ticks數小於每幀所需的ticks數,那麼我們就會對剩餘的時間進行延遲,以防止應用程式執行過快。

我們會在這些教程中使用VSync,而不是手動設定幀率上限,這是有原因的。當執行這個應用程式時,你會發現它的執行速度略快。由於我們使用的是整數(因為浮點數字不精確),每幀的ticks將是16ms,而不是精確的16 2/3ms。這個解決方案更多的是在你不得不處理不支援VSync的硬體的情況下的一個過渡。

這裡下載本教程的媒體和原始碼。

原文連結

關注我的公眾號:程式設計之路從0到1
程式設計之路從0到1

相關文章