|
Výpočet FPS a plynulé animace
|
|
|
Tutorial na výpočet fps a plynulé animace, podle aktuálního fps.
|
|
|
Vše se počítá ve funkci CalcFPS()
|
|
//definice proměnných
float step; //proměnná pomocí které plynule běhá animace
int time2fps; //druhý čas fps
int time2synchro; //druhý čas synchronizace
int frame; //hodnota snímku fps
int synchro_frame=1; //hodnota snímku synchronizace
//---------------------------------------------------------------------------
void CalcFPS()
{
//definice proměnných
__int64 counter; //aktuálni počítadlo
__int64 freq; //frekvence procesoru (kolik je výpočtů za vteřinu)
int time1fps; //první čas fps
int time1synchro; //první čas synchronizace
//kód
bool perf=QueryPerformanceCounter((LARGE_INTEGER *)&counter); //zkus načíst aktuální počítadlo
if (perf) //jestliže systém podporuje Performance tak
{
QueryPerformanceFrequency((LARGE_INTEGER *)&freq); //načti výpočetní výkon za jednu sekundu
time1fps = counter / freq; //převeď na sekundy
time1synchro = counter / (freq / 10); //převeď na desetiny sekundy
if (time1fps > time2fps) //pokud je první čas pro výpočet FPS vyšší než druhý
{
Form1->Label1->Caption = " fps: " + IntToStr(frame); //tak do editu vypiš hodnotu frame (FPS)
frame = 0; //vynuluj frame
}
if (time1synchro > time2synchro) //pokud je prvni čas pro výpočet synchronizace vyšší než druhý
{
step = (8.0 / synchro_frame); //vypočítej krok, podle kterého běží animace
synchro_frame = 0; //vynuluj synchronizační snímky
}
frame++; //přičti snímek
time2fps = time1fps; //hoď první čas fps do druhého
synchro_frame++; //přičti synchonizační snímek
time2synchro = time1synchro; //hod první čas synchronizace do druhého
} //konec if (perf)
} //konec void CalcFPS()
|
Princip je jednoduchý.
QueryPerformanceCounter((LARGE_INTEGER *)&counter); - nám vyhodí aktuální stav
počítadla v milisekundách.
QueryPerformanceCounter((LARGE_INTEGER *)&counter); - nám vyhodí výpočetní výkon za jednu sekundu
Když vydělíme stav počítadla výpočetním výkonem time1fps = counter / freq; dostaneme
hodnotu, která se bude každou sekundu zvyšovat o jedničku.
Pak budeme přičítat snímky
frame++; , dokud nedojde ke zvýšení hodnoty
if (time1fps > time2fps). Pokud ke zvýšení hodnoty dojde, tak vykreslíme
aktuální stav snímků na Label1
Form1->Label1->Caption = " fps: " + IntToStr(frame); a snímky
vynulujem
frame = 0;
Výpočet plynulosti animace funguje na stejném principu s tim rozdílem, že budu hodnotu pro
výpočet velikosti kroku animace počítat každou desetinu sekundy
time1synchro = counter / (freq / 10);
Opět přičítám snímky
synchro_frame++;, dokud nedojde ke zvýšení hodnoty
if (time1synchro > time2synchro). Pokud ke zvýšení hodnoty dojde, tak vypočítám
velikost kroku animace
step = (8.0 / synchro_frame); a snímky vynuluju synchro_frame = 0;
Při výpočtu animace pak násobím hodnoty animace hodnotou step
|
|
void TranRotCube() //vypočítej pohyb a rotaci
{
//začátek výpočtu pohybu objektu
if (start) //jestliže probíhá první otočka cyklu
{
direction.x = 1; //nastav směr pohybu objektu v X směru na 1
direction.y = 1; //nastav směr pohybu objektu v Y směru na 1
direction.z = 1; //nastav směr pohybu objektu v Z směru na 1
translate.z = -8; //nastav Z pozici objektu
start = false; //nastav start na false, aby při další otočce cyklu se základní hodnoty nenačítaly
}
if ((translate.x >= 3) || (translate.x <= -3)) //jetliže X pozice objektu přesáhne hodnoty 3 nebo -3
{
direction.x = -direction.x; //otoč směr pohybu X
}
translate.x = translate.x + (0.01 * direction.x * (step)); //přičti 0.01 pozici X, podle směru pohybu X a velikosti kroku
if ((translate.y >= 2) || (translate.y <= -2)) //jetliže Y pozice objektu přesáhne hodnoty 2 nebo -2
{
direction.y = -direction.y; //otoč směr pohybu Y
}
translate.y = translate.y + (0.01 * direction.y * (step)); //přičti 0.01 pozici Y, podle směru pohybu Y a velikosti kroku
if ((translate.z >= -6) || (translate.z <= -20)) //jetliže Z pozice objektu přesáhne hodnoty -6 nebo -20
{
direction.z = -direction.z; //otoč směr pohybu Z
}
translate.z = translate.z + (0.01 * direction.z * (step)); //přičti 0.01 pozici Z, podle směru pohybu Z a velikosti kroku
//konec výpočtu pohybu objektu
//začátek výpočtu rotace objektu
angle.x = angle.x + (0.5 * (step)); //přičti 0.5 úhlu X rotace podle velikosti kroku
if (angle.x >= 360) //jestliže je úhel větší, než 360 stupňů
{
angle.x = angle.x -360; //odečti 360 stupňů
}
angle.y = angle.y + (1 * (step)); //přičti 1 úhlu Y rotace podle velikosti kroku
if (angle.y >= 360) //jestliže je úhel větší, než 360 stupňů
{
angle.y = angle.y -360; //odečti 360 stupňů
}
angle.z = angle.z + (1.5 * (step)); //přičti 1.5 úhlu Z rotace podle velikosti kroku
if (angle.z >= 360) //jestliže je úhel větší, než 360 stupňů
{
angle.z = angle.z -360; //odečti 360 stupňů
}
//konec výpočtu rotace objektu
}
|
Funkci CalcFPS() voláme v nekonečné smyčce
|
|
void __fastcall TForm1::RenderGLScene()
{
DrawCube(); //vykresli krychli
CalcFPS(); //vypočítej fps
}
Home