SDL程式設計入門(25)限制幀率
限制幀率
我們可以用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
相關文章
- SDL程式設計入門(26)運動程式設計
- SDL程式設計入門(29)圓形碰撞檢測程式設計
- SDL程式設計入門(23)高階定時器程式設計定時器
- SDL程式設計入門(28)每畫素碰撞檢測程式設計
- 入門程式碼程式設計程式設計
- Python程式設計入門Python程式設計
- Shell 程式設計入門程式設計
- 程式設計和網路程式設計入門程式設計
- 併發程式設計 棧幀程式設計
- Number 1 — 程式設計入門程式設計
- Flink DataStream 程式設計入門AST程式設計
- java Swing程式設計入門Java程式設計
- SDL3 入門(5):紋理渲染
- JAVA NIO程式設計入門(二)Java程式設計
- JAVA NIO 程式設計入門(三)Java程式設計
- JAVA NIO程式設計入門(一)Java程式設計
- 遊戲程式設計入門指南遊戲程式設計
- Python 非同步程式設計入門Python非同步程式設計
- Linux入門---(三)Shell程式設計Linux程式設計
- JavaScript 非同步程式設計入門JavaScript非同步程式設計
- 程式設計入門學什麼?程式設計
- Linux系統程式設計入門Linux程式設計
- SAP PM 入門系列25 - 計量點
- Flutter幀率監控 | 由淺入深,詳解獲取幀率的那些事Flutter
- 程式設計正規化 —— 函數語言程式設計入門程式設計函數
- 【Linux】Linux系統程式設計入門Linux程式設計
- 響應式程式設計入門(RxJava)程式設計RxJava
- 14.1 Socket 套接字程式設計入門程式設計
- Go語言程式設計快速入門Go程式設計
- Java入門之基礎程式設計Java程式設計
- 程式設計入門先學什麼?程式設計
- iOS 逆向程式設計(入門條件)iOS程式設計
- 幀數,從入門到入土
- SDL3 入門(2):第一個視窗
- SDL3 入門(4):選擇圖形引擎
- 程式設計師程式設計入門一定知道!程式設計師需要學什麼?程式設計師
- 程式設計入門,這763位老程式設計師有話講!程式設計師
- 物件導向程式設計入門 - Janos Pasztor物件程式設計