[ kish @ 02.08.2007. 13:05 ] @
Pokusao sam da napravim proceduru za izracunavanje FPS-a na sledeci nacin:
Code:

#include <time.h>

int fps_tprev=0;
float fps_FPS=0;

int TimeForFrame() {
    int res,clck;
    
    clck=clock();
    res=clck-fps_tprev;
    fps_tprev=clck;

    return res;
}

float CalcFPS() {
    fps_FPS=1000.0f/(float)TimeForFrame();
    return fps_FPS;
}

Funkcija TimeForFrame() bi trebalo da izracunava vreme potrebno za iscrtavanje jednog frame-a, dok CalcFPS() na osnovu toga racuna FPS. Koliko sam ja razumeo clock() bi trebalo da vrati broj milisekundi koji je prosao od pokretanja programa (Calculates the processor time used by the calling process). Problem je u tome sto kad ovo stavim u vremensku petlju (prazan OpenGL screen sa nekim textom - FPS-om), TimeForFrame vraca ili 10 ili 20.. retko kad nesto drugo (11,21). To kad se primeni na CalcFPS, logicno da se dobija FPS od 50 ili FPS od 100, sto je, medjutim, jako neprecizno. Pitanje je da li sam ja uopste pravilno koristio ovu funkciju i, ako ne, da li postoji neki precizniji nacin da se ovo izvede?
[ tosa @ 02.08.2007. 16:31 ] @
TimeGetTime je neprecizna funkcija, pogledaj QueryPerformanceCounter i QueryPerformanceFrequency.
Ukoliko je na kompu uključen power saving, QueryPerformanceFrequency moraš zvati više puta zato
što je moguće da se promeni takt procesora.
Takođe, bilo bi bolje da pratiš istoriju u poslednjih 15-20 frejmova i da korišćenjem srednje
vrednosti računaš FPS, pošto razlike iz frejma u frejm mogu biti primetne.
[ kish @ 04.08.2007. 13:44 ] @
Hmmm... MSDN ne govori bas mnogo o ovim funkcijama.... Moze malo vise detalja o njihovoj primeni? Inace problem sam donekle resio tako sto sam posmatrao poslednjih 30 frejmova pa se stvar donekle stabilizovala... dovoljno da program radi kako treba. E sad, kako ce raditi ako program postane slozeniji, videcemo...
[ dragansm @ 04.08.2007. 20:48 ] @
Koriscenje performance countera je sasvim precizno objasnjeno u MSDN-u.
Klasa koja koristi PC-ter (izbaci namespace GraphicsLib)

h fajl

Code:

#pragma once

namespace GraphicsLib
{
    class Timer
    {
    public:
        Timer();
        GLvoid Reset();
        GLfloat GetLapTime();
        GLfloat GetElapsedTime();
        __int64 GetLapTickCount();
        __int64 GetElapsedTickCount();
    private:
        LARGE_INTEGER m_nLastTime;
        static float s_fInvFrequency;
    };
}


cpp fajl

Code:

#include "stdafx.h"

static GLfloat GetFrequency()
{
    LARGE_INTEGER nFrequency;
    QueryPerformanceFrequency( &nFrequency );
    return (GLfloat)nFrequency.QuadPart;
}

float GraphicsLib::Timer::s_fInvFrequency = 1.0f/GetFrequency();

GraphicsLib::Timer::Timer()
{
    QueryPerformanceCounter( &m_nLastTime );
}

GLvoid GraphicsLib::Timer::Reset()
{
    QueryPerformanceCounter( &m_nLastTime );
}

GLfloat GraphicsLib::Timer::GetLapTime()
{
    LARGE_INTEGER nCurrentTime;
    QueryPerformanceCounter( &nCurrentTime );
    GLfloat fResult = ( nCurrentTime.QuadPart - m_nLastTime.QuadPart )*s_fInvFrequency;
    m_nLastTime = nCurrentTime;
    return fResult;
}

GLfloat GraphicsLib::Timer::GetElapsedTime()
{
    LARGE_INTEGER nCurrentTime;
    QueryPerformanceCounter( &nCurrentTime );
    GLfloat fResult = ( nCurrentTime.QuadPart - m_nLastTime.QuadPart )*s_fInvFrequency;
    return fResult;
}

__int64 GraphicsLib::Timer::GetLapTickCount()
{
    LARGE_INTEGER nCurrentTime;
    LARGE_INTEGER nResult;
    QueryPerformanceCounter( &nCurrentTime );
    nResult.QuadPart = nCurrentTime.QuadPart - m_nLastTime.QuadPart;
    m_nLastTime = nCurrentTime;
    return nResult.QuadPart;
}

__int64 GraphicsLib::Timer::GetElapsedTickCount()
{
    LARGE_INTEGER nCurrentTime;
    LARGE_INTEGER nResult;
    QueryPerformanceCounter( &nCurrentTime );
    nResult.QuadPart = nCurrentTime.QuadPart - m_nLastTime.QuadPart;
    return nResult.QuadPart;
}