FPS counter problem

Started by
14 comments, last by Aram 21 years, 8 months ago
Hi!! I have made an fps counter that doesn''t seem to work right. If the fps is between 33 and 50 the counter shows correctly but when it goes below or above it just show 33 or 50. I dont undertand why because as I see it this is just some simple math.
  
			if(CURRENTTIME - FRAMESTART >= FRAMETIME)
			{
				FRAMES = 1000/(CURRENTTIME - FRAMESTART);
				FRAMESTART = timeGetTime();
					DrawScene();
						
			}
			CURRENTTIME = timeGetTime();
  

  
void ShowFrames(UINT frames)
{
	UCHAR THOUSANDS,HUNDREDS,TENS,NUMBERS;
	THOUSANDS = frames/1000;
	HUNDREDS = (frames/100)%10;
	TENS = (frames/10)%10;
	NUMBERS = frames%10; 
switch(THOUSANDS)
	{
		case 0:
			D3dDevice->SetTexture(0, t_FrameNumber[0]);
			break;
		case 1:
			D3dDevice->SetTexture(0, t_FrameNumber[1]);
			break;
		case 2:
			D3dDevice->SetTexture(0, t_FrameNumber[2]);
			break;
		case 3:
			D3dDevice->SetTexture(0, t_FrameNumber[3]);
			break;
		case 4:
			D3dDevice->SetTexture(0, t_FrameNumber[4]);
			break;
		case 5:
			D3dDevice->SetTexture(0, t_FrameNumber[5]);
			break;
		case 6:
			D3dDevice->SetTexture(0, t_FrameNumber[6]);
			break;
		case 7:
			D3dDevice->SetTexture(0, t_FrameNumber[7]);
			break;
		case 8:
			D3dDevice->SetTexture(0, t_FrameNumber[8]);
			break;
		case 9:
			D3dDevice->SetTexture(0, t_FrameNumber[9]);
			break;
	}

	D3dDevice->SetStreamSource(0, vb_FrameCounter[3], sizeof(PANELVERTEX));
	D3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

	switch(HUNDREDS)
	{
		case 0:
			D3dDevice->SetTexture(0, t_FrameNumber[0]);
			break;
		case 1:
			D3dDevice->SetTexture(0, t_FrameNumber[1]);
			break;
		case 2:
			D3dDevice->SetTexture(0, t_FrameNumber[2]);
			break;
		case 3:
			D3dDevice->SetTexture(0, t_FrameNumber[3]);
			break;
		case 4:
			D3dDevice->SetTexture(0, t_FrameNumber[4]);
			break;
		case 5:
			D3dDevice->SetTexture(0, t_FrameNumber[5]);
			break;
		case 6:
			D3dDevice->SetTexture(0, t_FrameNumber[6]);
			break;
		case 7:
			D3dDevice->SetTexture(0, t_FrameNumber[7]);
			break;
		case 8:
			D3dDevice->SetTexture(0, t_FrameNumber[8]);
			break;
		case 9:
			D3dDevice->SetTexture(0, t_FrameNumber[9]);
			break;
	}

	D3dDevice->SetStreamSource(0, vb_FrameCounter[2], sizeof(PANELVERTEX));
	D3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

	switch(TENS)
	{
		case 0:
			D3dDevice->SetTexture(0, t_FrameNumber[0]);
			break;
		case 1:
			D3dDevice->SetTexture(0, t_FrameNumber[1]);
			break;
		case 2:
			D3dDevice->SetTexture(0, t_FrameNumber[2]);
			break;
		case 3:
			D3dDevice->SetTexture(0, t_FrameNumber[3]);
			break;
		case 4:
			D3dDevice->SetTexture(0, t_FrameNumber[4]);
			break;
		case 5:
			D3dDevice->SetTexture(0, t_FrameNumber[5]);
			break;
		case 6:
			D3dDevice->SetTexture(0, t_FrameNumber[6]);
			break;
		case 7:
			D3dDevice->SetTexture(0, t_FrameNumber[7]);
			break;
		case 8:
			D3dDevice->SetTexture(0, t_FrameNumber[8]);
			break;
		case 9:
			D3dDevice->SetTexture(0, t_FrameNumber[9]);
			break;
	}

	D3dDevice->SetStreamSource(0, vb_FrameCounter[1], sizeof(PANELVERTEX));
	D3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

	switch(NUMBERS)
	{
		case 0:
			D3dDevice->SetTexture(0, t_FrameNumber[0]);
			break;
		case 1:
			D3dDevice->SetTexture(0, t_FrameNumber[1]);
			break;
		case 2:
			D3dDevice->SetTexture(0, t_FrameNumber[2]);
			break;
		case 3:
			D3dDevice->SetTexture(0, t_FrameNumber[3]);
			break;
		case 4:
			D3dDevice->SetTexture(0, t_FrameNumber[4]);
			break;
		case 5:
			D3dDevice->SetTexture(0, t_FrameNumber[5]);
			break;
		case 6:
			D3dDevice->SetTexture(0, t_FrameNumber[6]);
			break;
		case 7:
			D3dDevice->SetTexture(0, t_FrameNumber[7]);
			break;
		case 8:
			D3dDevice->SetTexture(0, t_FrameNumber[8]);
			break;
		case 9:
			D3dDevice->SetTexture(0, t_FrameNumber[9]);
			break;
	}

	D3dDevice->SetStreamSource(0, vb_FrameCounter[0], sizeof(PANELVERTEX));
	D3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
}
  
Any comments on how to optimize is also welcom.... Thanks!!!
True words are not always beautiful, beautiful words are not always truthful.
Advertisement
i dont bother with miliseconds, integer arithmatic is no way to go for these things.

i use inline assembly with the RDTSC instructiona and a delay to get the actual number of cycles done in a certain abount of time. each frame, i use 64-bit math to find the number of ticks since the last frame and divide.

voila! a floating point time accurate to several decimal places calculated in only a few cycles. it is a lot easier to work with in animation and physics etc (Pos+Vel*t) and if you invert it you have the FPS.
spraff.net: don't laugh, I'm still just starting...
What on earth are those switch statements for? Surely all this:

  switch(THOUSANDS){case 0:D3dDevice->SetTexture(0, t_FrameNumber[0]);break;case 1:D3dDevice->SetTexture(0, t_FrameNumber[1]);break;case 2:D3dDevice->SetTexture(0, t_FrameNumber[2]);break;case 3:D3dDevice->SetTexture(0, t_FrameNumber[3]);break;case 4:D3dDevice->SetTexture(0, t_FrameNumber[4]);break;case 5:D3dDevice->SetTexture(0, t_FrameNumber[5]);break;case 6:D3dDevice->SetTexture(0, t_FrameNumber[6]);break;case 7:D3dDevice->SetTexture(0, t_FrameNumber[7]);break;case 8:D3dDevice->SetTexture(0, t_FrameNumber[8]);break;case 9:D3dDevice->SetTexture(0, t_FrameNumber[9]);break;}  

...could be done like this:

  D3dDevice->SetTexture(0, t_FrameNumber[THOUSANDS]);  

There''s an optimisation for you right there. As for your frame counter, you''re probably better off taking a windowed average, by timing how long it has taken to draw the last 10 frames and dividing that by 10. I also don''t know what kind of precision timeGetTime has, so it might not be too accurate when called too often.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files ]
The precision of timeGetTime() is 5 milliseconds, methinks.
timeBeginPeriod(2);
timeEndPeriod(2);

sets it to two milliseconds exactly, i think.. not sure, but i use this..

"take a look around" - limp bizkit
www.google.com
If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

Thanks a lot guys for your replys. When I''ll come back from work I''m going to try to optimize my counter as much as I can.

//Aram
True words are not always beautiful, beautiful words are not always truthful.
By the way...I''ve heard of something called QueryPerformanceFrequency and QueryPerformanceCounter. Are these more accurate and should I use these instead?

//Aram
True words are not always beautiful, beautiful words are not always truthful.
They are much more accurate because the so called Performance Counter can count in micro seconds because it is a kind of microprocessor running on 3.16 Mhz (I believe) and it is independent from the main CPU.
But it is not installed on every system so you will have to query for it first (QueryPerformanceFrequency will return 0 in the parameter if no Performance Counter is installed).

Im Anfang war die Tat...
Faust
Im Anfang war die Tat...Faust
Okay. But how do I use QueryPerformanceFrequency and QueryPerformanceCounter? What value does QueryPerformanceFrequency and QueryPerformanceCounter return?

Is it that QueryPerformanceFrequency returns a some number that is equal one microsecond and if so should I use it like this?

MICROSECS = QueryPerformanceCounter/QueryPerformanceFrequency

//Aram
True words are not always beautiful, beautiful words are not always truthful.
I don''t know, but I don''t use the performance counter because of this article in MSDN. It also uses 64 bit vars, which are slower than 32bits!!



Those who do not love don''t live.



[MSDN|Google|Bloodshed|My lousy page|email.me]
[My Lousy Page | Kings Of Chaos | Vampires | [email=lordlethis@hotmail.com]email.me[/email]]

This topic is closed to new replies.

Advertisement