電腦遊戲製作開發設計論壇 首頁 電腦遊戲製作開發設計論壇
任何可以在PC上跑的遊戲都可以討論,主要以遊戲之製作開發為主軸,希望讓台灣的遊戲人有個討論、交流、教學、經驗傳承的園地
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入 

Google
[轉貼自程式設計俱樂部]glut 教學 - 計算 frame rate 的正確方法

 
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫
上一篇主題 :: 下一篇主題  
發表人 內容
satanupup
喜歡上這裡的冒險者


註冊時間: 2007-05-29
文章: 80

68.10 果凍幣

發表發表於: 2007-6-28, PM 2:15 星期四    文章主題: [轉貼自程式設計俱樂部]glut 教學 - 計算 frame rate 的正確方法 引言回覆

作者 : ma_hty(白老鼠(Gary))
當我們要比較 3D 程式的效率, frame rate 是一個很重要的資料.

但是, 算 frame rate 也算得正確才有意思呀. 這次, 我就介紹一下如何算 frame rate.

首先, 讀者們, 你要先了解一件事, 現代的顯示卡, 已經不再是純粹把 digital 資料 轉成 analog 資料的低檔硬體, 它, 已經變成了一個 精密 而 架構複雜的系統. 因此, 算 frame rate 時, 也得了解它多一些.

算 frame rate, 最直接的想法, 就是把 display() 重複呼叫器一定的次數, 把 次數 除以 所需時間 就是 frame rate. 但是, 這是不正確的, 因為 glutSwapBuffers() 會等待 顯示器 完成最近一次更新, 才會完結的. 結果, 如果你的程式比 顯示器更新率 跑得更快, 所算出來的 frame rate 再多也只可能是 顯示器更新率. 舉例說, 在顯示器的更新率, 一般是 75 fps, 如上述算 frame rate, 最快也只會是 75 fps.

又說, 如果我們把 glutSwapBuffers() 拿掉, 就不用等待 顯示器 完成更新呀. 但是, 這樣算 frame rate 也不正確. 因為, 顯示卡是有一個指令緩衝的機制, 就是說, 你給 顯示卡 下繪圖指令時, 指令並不會被立即執行, 指令會先儲存在 顯示卡的指令緩衝區, 直到 緩衝區爆滿 或是 被特別地指令 緩衝區內的指令才會被執行. 因此, 只把 glutSwapBuffers() 拿掉, 所算出來的 frame rate, 只反映指令由 主記憶體 傳到 顯示卡緩衝區 的速度而已.

說到這裡, 聰明的讀者們大概也估計到要甚麼做, 就是, 把 glutSwapBuffers() 換成為 強制顯示卡執行指令. 這個指令, 就是 glFinish(). 只要把 glutSwapBuffers() 換成為 glFinish(), 所有繪令指令就會被執行, 又不用被 顯示器更新率 限制. 這樣算出來的 frame rate, 才能有效的反映 3D 程式效能.

好, 我們去寫程式算 frame rate 吧...

------------------------------------------------------------------
/////////////////////////
// glutTest10.cpp
//
// Created by Gary Ho, ma_hty@hotmail.com, 2006
//


#include <stdio.h>
#include <time.h>

#include "glut.h"

void display();
void keyboard( unsigned char key, int x, int y );

float g_fps( void (*func)(void), int n_frame );

bool finish_without_update = false;

void main()
{
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB );
glutInitWindowSize( 640, 640 );
glutCreateWindow( "glutTest10" );

glutDisplayFunc(display);
glutKeyboardFunc(keyboard);

glutMainLoop();
}

void keyboard( unsigned char key, int x, int y )
{
switch( key )
{
case 'F':
case 'f':
finish_without_update = true;
printf( "%f fps\n", g_fps( display, 100 ) );
finish_without_update = false;
break;
}
}

void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 20, 1, 0.1, 10 );

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(
0,0,1,
0,0,0,
0,1,0 );

glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable( GL_DEPTH_TEST );
glutSolidTeapot( .1 );

if( finish_without_update )
glFinish();
else
glutSwapBuffers();
}

float g_fps( void (*func)(void), int n_frame )
{
clock_t start, finish;
int i;
float fps;

printf( "Performing benchmark, please wait" );
start = clock();
for( i=0; i<n_frame; i++ )
{
if( (i+1)%10==0 )
printf(".");
func();
}
printf( "done\n" );
finish = clock();

fps = float(n_frame)/(finish-start)*CLOCKS_PER_SEC;
return fps;
}

------------------------------------------
void display()
{
// ...
if( finish_without_update )
glFinish();
else
glutSwapBuffers();
}

display() function 最後的幾行, 就是用來選擇用 glFinish() 還是用 glutSwapBuffers(), 算 frame rate 時, 我們用 glFinish(), 其他時間我們用 glutSwapBuffers().
----------------------------------
按 F 鍵 就會開始算 frame rate, 計算完畢, 結果就會顯示在 console 上.
回頂端
檢視會員個人資料 發送私人訊息
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫 所有的時間均為 台灣時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
可以 在這個版面附加檔案
可以 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作