web-dev-qa-db-ja.com

基本的なFPSカウンターの作り方は?

キューブレンダリングプログラムで1秒あたりのフレーム数を表示しようとしています。その性能を見たいです。だから、どうすればそれを行うことができますか?私はすでにこれについて調査しましたが、私が見た例では、複数のクラスを使用していてまだ機能しないか、私が持っていないライブラリを使用しています。 ctimeのようなプリインストールされたライブラリを使用してFPSを取得する方法はありますか?私はC++でOpenGLを使用しています。

これが私の(空の)関数です:

void GetFPS()
{

}

次に、レンダリング関数でFPSを次のように表示します。

std::cout << xRot << " " << yRot << " " << zRot << " " << FPS << "\n"; //xRot, yRot, and zRot are my cube's rotation.

私のプログラムは60FPSに設定されていますが、実際のFPSを確認したいのですが、設定されているものではありません。

7
Xenonic

clock()を使用して2つの異なる時間間隔をサンプリングする必要がありますが、いくつかの問題があることに注意してください。

  • クロックの解像度は数ミリ秒です(std :: chronoなどを使用して回避策を講じることができますが、実装によってはクロノでもそれほど高解像度ではない場合があります。GCC4.9.1を搭載したPCでは、std: :クロノ。
  • 通常、clock()を使用すると、0が何度も取得され、いつかリアルタイムで測定されます(私の場合、15/16ミリ秒のジャンプが発生します)。
  • 垂直同期(vsync)を使用していない限り、実際のフレームタイムは測定せず、レンダリングループで費やされたCPU時間のみを測定します(vsyncをアクティブにするには、OS関数でSetSwapInterval(1)を実行するか、たとえばSDLなどのライブラリを使用する必要があります。ポータブルクロスプラットフォームの実装を提供します)
  • 実際のレンダリング時間を測定するには、GLの時間クエリを使用できます(常に1つのタイマーしかバインドされていない可能性があるため、フレームレートを測定している場合、特定のレンダリングにかかる​​時間を測定することはできません)。
  • FPSを測定しないでください(ユーザーに表示したい場合を除いて)。代わりに、フレーム時間をミリ秒単位で測定してください。これにより、パフォーマンスをより直感的に概算できます。 (100から80 FPSへの移行は2.5ミリ秒の違いであり、40から20FPSへの移行は25ミリ秒の違いです!)

それを行う:

double clockToMilliseconds(clock_t ticks){
    // units/(units/time) => time (seconds) * 1000 = milliseconds
    return (ticks/(double)CLOCKS_PER_SEC)*1000.0;
}
//...

clock_t deltaTime = 0;
unsigned int frames = 0;
double  frameRate = 30;
double  averageFrameTimeMilliseconds = 33.333;

while(rendering){

    clock_t beginFrame = clock();
    render();
    clock_t endFrame = clock();

    deltaTime += endFrame - beginFrame;
    frames ++;

    //if you really want FPS
    if( clockToMilliseconds(deltaTime)>1000.0){ //every second
        frameRate = (double)frames*0.5 +  frameRate*0.5; //more stable
        frames = 0;
        deltaTime -= CLOCKS_PER_SEC;
        averageFrameTimeMilliseconds  = 1000.0/(frameRate==0?0.001:frameRate);

        if(vsync)
            std::cout<<"FrameTime was:"<<averageFrameTimeMilliseconds<<std::endl;
        else
           std::cout<<"CPU time was:"<<averageFrameTimeMilliseconds<<std::endl;
    }
}

上記のコードは、数秒かかることをした場合にも機能します。私は毎秒更新される計算を行います。もっと頻繁に更新することもできます。 (FPSを必要とするほとんどのプロジェクトでまさにそのコードを使用していることに注意してください)

13
CoffeDeveloper

シーンをレンダリングする前後の「ティック」の時間を節約し、簡単な計算を行うだけです。

_<ctime>_のclock()関数を使用する例を次に示します。 (clock()はプラットフォームによって動作が異なることに注意してください)

_clock_t current_ticks, delta_ticks;
clock_t fps = 0;
while(true)// your main loop. could also be the idle() function in glut or whatever
{
    current_ticks = clock();

    render();

    delta_ticks = clock() - current_ticks; //the time, in ms, that took to render the scene
    if(delta_ticks > 0)
        fps = CLOCKS_PER_SEC / delta_ticks;
    cout << fps << endl;
}
_
7
Pilpel