|
Výpočet FPS a plynulé animace
|
|
|
Tutorial na výpočet fps a plynulé animace, podle aktuálního fps.
|
|
|
Vše počítá proceduraCalcFPS
|
|
unit KTime;
interface
var
step: single; //proměnná pomocí které plynule běhá animace
procedure CalcFps; //výpočet fps a plynulé animace
implementation
uses
Windows, Sysutils, KRenderForm, Dialogs;
var
time2fps: integer; //druhý čas fps
time2synchro: integer; //druhý čas synchronizace
frame: integer; //hodnota snímku fps
synchro_frame: integer=1; //hodnota snímku synchronizace
procedure CalcFps; //vypočítej fps a plynulou animaci
var
counter: TLargeInteger; //aktuální počítadlo
freq: TLargeInteger; //výpočetní výkon za jednu sekundu
time1fps: integer; //prvni čas fps
time1synchro: integer; //první čas synchronizace
begin
if QueryPerformanceCounter(counter) then begin //jestliže systém podporuje Performance tak načti aktuální počítadlo
QueryPerformanceFrequency(freq); //načti výpočetní výkon za jednu sekundu
time1fps := counter div freq; //převeď na sekundu
time1synchro := counter div (freq div 10); //převeď na desetiny sekundy
if time1fps > time2fps then begin //pokud je první čas pro výpočet FPS vyšší než druhý
Form1.Label1.Caption := ' fps: ' + IntToStr(frame); //do editu vypiš hodnotu frame (FPS)
frame := 0; //vynuluj frame
end;
if time1synchro > time2synchro then begin //pokud je první čas pro výpočet synchronizace vyšší než druhý
step := 8 / synchro_frame; //vypočítej last_frame, podle kterého běží animace
synchro_frame := 0; //vynuluj synchronizační snímky
end;
frame := frame + 1; //jinak přičti snímek
time2fps := time1fps; //hoď první čas fps do druhého
synchro_frame := synchro_frame + 1; //přičti synchonizační snímek
time2synchro := time1synchro; //hoď první čas synchronizace do druhého
end;
end;
|
Princip je jednoduchý.
QueryPerformanceCounter(counter) - nám vyhodí aktuální stav
počítadla v milisekundách.
QueryPerformanceFrequency(freq); - 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 div freq; dostaneme
hodnotu, která se bude každou sekundu zvyšovat o jedničku.
Pak budeme přičítat snímky
frame := frame + 1; , 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 div (freq div 10);
Opět přičítám snímky
synchro_frame := synchro_frame + 1;, dokud nedojde ke zvýšení hodnoty
if time1synchro > time2synchro. Pokud ke zvýšení hodnoty dojde, tak vypočítám
velikost kroku animace
step := 8 / synchro_frame; a snímky vynuluju.synchro_frame := 0;
Při výpočtu animace pak násobím hodnoty animace hodnotou step
|
|
procedure TranRotCube;
begin
//začátek výpočtu pohybu objektu
if (start) then //jestliže probíhá první otočka cyklu
begin
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
end;
if ((translate.x >= 3) or (translate.x <= -3)) then //jetliže X pozice objektu přesáhne hodnoty 3 nebo -3
begin
direction.x := -direction.x; //otoč směr pohybu X
end;
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) or (translate.y <= -2)) then //jetlize Y pozice objektu přesáhne hodnoty 2 nebo -2
begin
direction.y := -direction.y; //otoč směr pohybu Y
end;
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) or (translate.z <= -20)) then //jetliže Z pozice objektu přesáhne hodnoty -6 nebo -20
begin
direction.z := -direction.z; //otoč směr pohybu Z
end;
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) then //jestliže je úhel větší, než 360 stupňů
begin
angle.x := angle.x -360; //odečti 360 stupňů
end;
angle.y := angle.y + (1 * step); //přičti 1 úhlu Y rotace podle velikosti kroku
if (angle.y >= 360) then //jestliže je úhel větší, než 360 stupňů
begin
angle.y := angle.y -360; //odečti 360 stupňů
end;
angle.z := angle.z + (1.5 * step); //přičti 1.5 úhlu Z rotace podle velikosti kroku
if (angle.z >= 360) then //jestliže je úhel větší, než 360 stupňů
begin
angle.z := angle.z -360; //odečti 360 stupňů
end;
//konec výpočtu rotace objektu
end;
|
Proceduru CalcFPS() voláme v nekonečné smyčce
|
|
procedure TForm1.RenderGLScene;
begin
DrawCube; //vykresli krychli
CalcFPS; //vypočítej fps
end;
Home