PDA

View Full Version : DirectX MaxFPS?



lordzero
21-09-2007, 07:47 PM
Hello

to get the frame rate is very very easy.. i need only inc a integer value, and after one second for example i need get the FPS and reset the counter...

but.... how to setup the max FPS? if a set a value for example..

if FPS >= MaxFPS then
begin
//dont render
end;

i need ideas..........

Greets

arthurprs
21-09-2007, 07:56 PM
const
MAXFPS = 1000 div 101 // 101 is the max fps, replace with what you want

if gettickcount >= nextrender then
begin
Inc(nextrender, MAXFPS);
//render//
end;

I think there are better ways to do that with not having to call a tickcount function everytime :?

arthurprs
21-09-2007, 09:58 PM
{pt-br} e ai deu certo ? te add no msn xD

{eng} it works ? i have add you in msnmessenger

lordzero
22-09-2007, 12:17 AM
{pt-br} e ai deu certo ? te add no msn xD

{eng} it works ? i have add you in msnmessenger

hello

what you mean with next render?

eu n?Ło entendi direito a sua id?©ia, vou por um exemplo de c??digo aqui ok?
se tu puder por a solu?ß?Ło dentro do c??digo fica mais f?°cil de aprender...




var
LastCheckTime, NewCheckTime: Integer;
FPSCount: Integer;
FPS: Integer;

procedure CalculateFPS;
begin

//Pega o tempo atual
NewCheckTime := GetTickCount;

//Incrementa o contador de frames
Inc(FPSCount);

//Checa se o tempo atual menos o ultimo tempo ?© maior ou igual a um segundo
if NewCheckTime - LastCheckTime >= 1000 then
begin

//se for maior ou igual pega o valor total de quadros
FPS := FPSCount;
//zera o valor do contador
FPSCount := 0;
//o ultimo tempo se torna o tempo atual para o pr??ximo c?°lculo
LastCheckTime := NewCheckTime;
end;

end;


if (DXBase.Direct3DDevice = nil) then Exit;

DXBase.Direct3DDevice.Clear(0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, BgColor, 1.0, 0);

if (SUCCEEDED(DXBase.Direct3DDevice.BeginScene)) then
begin
//
end;

CalculateFPS;

DXBase.Direct3DDevice.EndScene;

DXBase.Direct3DDevice.Present(nil, nil, 0, nil);


greetings

arthurprs
22-09-2007, 01:27 AM
const
MAXFPS = 1000 div 101 // substitui o 101 pelo valor m?°ximo de fps desejado

var
LastCheckTime, NewCheckTime: Cardinal;
FPSCount: Integer;
FPS: Integer;
NextFrame : Cardinal;

/////////////////////////////////////

if (DXBase.Direct3DDevice = nil) then Exit;

if gettickcount >= NextFrame then
begin // MAX FPS IF BEGIN

// add the minimal interval for the next reder to NextFrame var
inc(NextFrame, MAXFPS);

DXBase.Direct3DDevice.Clear(0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, BgColor, 1.0, 0);

if (SUCCEEDED(DXBase.Direct3DDevice.BeginScene)) then
begin
// RENDER CODE HERE
end;

DXBase.Direct3DDevice.EndScene;

DXBase.Direct3DDevice.Present(nil, nil, 0, nil);
end; // MAX FPS IF END

CalculateFPS; // The same you are using


Post if you have any trouble

lordzero
22-09-2007, 03:55 AM
const
MAXFPS = 1000 div 101 // substitui o 101 pelo valor m?°ximo de fps desejado

var
LastCheckTime, NewCheckTime: Cardinal;
FPSCount: Integer;
FPS: Integer;
NextFrame : Cardinal;

/////////////////////////////////////

if (DXBase.Direct3DDevice = nil) then Exit;

if gettickcount >= NextFrame then
begin // MAX FPS IF BEGIN

// add the minimal interval for the next reder to NextFrame var
inc(NextFrame, MAXFPS);

DXBase.Direct3DDevice.Clear(0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, BgColor, 1.0, 0);

if (SUCCEEDED(DXBase.Direct3DDevice.BeginScene)) then
begin
// RENDER CODE HERE
end;

DXBase.Direct3DDevice.EndScene;

DXBase.Direct3DDevice.Present(nil, nil, 0, nil);
end; // MAX FPS IF END

CalculateFPS; // The same you are using


Post if you have any trouble

yeah i have trouble...

i have used your code... but dont are working......

can u see it?

http://www.lordzero.co.nr/tmp/MaxFPS.zip

arthurprs
22-09-2007, 04:51 AM
2 mistakes/erros

1¬? -> add a NextFrame:= GetTickCount; at FormCreate or D3DINIT

2¬? -> move Inc(FPSCount); to inside the render code =)

see the working code here http://pastebin.com/m789fe2eb

chronozphere
22-09-2007, 09:20 AM
A very easy way to do this is using a Timer component. :) Just drop it on your form and put the render-code in the OnTimer event. Set interval to 20 or 30 or something similar and your done!

I also advice you to use QueryPerformanceCounter and QueryPerformanceFrequncy instead of GetTickcount. These functions allow for more accurate timing.

QueryPerformanceCounter returns the ammount of clock cycles so far (not sure though :?)
QueryPerformanceCounter returns the ammount of clock cycles done in one second. This is a constant.


var MyTime1, MyTime2,Freq : Int64;
begin

QueryPerformanceCounter( MyTime1 );

//Do a lot of stuff

QueryPerformanceCounter( MyTime2 );
QueryPerformanceFrequncy( Freq );

Showmessage('Time elapsed while doing stuff: '+ FloatToStr( (MyTime2 - MyTime1)/Freq ) );
end;



You only need to call QueryPerformanceFrequency once @ program startup, because it remains constant.

Hope this helps. :)

arthurprs
22-09-2007, 12:41 PM
timers are completly unaccurate at small intervals, so if you really want big accuracy you can use

var
PerfFrequency: Int64;
InvPerfFrequency: Single;

// put this at formcreate or similar
QueryPerformanceFrequency(PerfFrequency);
InvPerfFrequency := 1.0 / PerfFrequency;


function GetTimeMicroseconds: Int64; //
var
Time: Int64;
begin
QueryPerformanceCounter(Time);
Result := Round(1000000 * InvPerfFrequency * Time);
end;

//Taken from imagingutils unit

it returns "us" instead of "ms"

but i have sure that is not necessary because we are cheking a 1000ms interval...

lordzero
23-09-2007, 03:25 AM
Hello

Thanks for th attention Arthur and Nathan, the code are working here... :)

when i have time... i will try check the other way with "accuracy".

Greets LZ