Skip to main content
GameDev.net gamedev.net
🔒 Locked

[java] Calculating And Displaying Fps Accurately And Efficiently

Started by CoryG89 Jan 10, 2011 at 8:27 AM 2 replies 3.2k views
Original Post
CoryG89
CoryG89
I was wondering if anyone could show me any code where they have used a JPanel
with double buffering and active rendering using a thread and was able to accurately and effectively calculate and display their FPS.

Here is my code:

/**
* Implements the Runnable interface. Responsible
* for updates, rendering, and sleeping the thread.
*/
@Override
public void run()
{
bRunning = true; // Keep flag set
long beforeTime, deltaTime, sleepTime;

beforeTime = System.currentTimeMillis();

initRender();

// Repeat update/animation loop, sleeping a bit
while (bRunning)
{

try
{
updateBoard();
} catch (IOException e)
{ System.err.println("Error: IO Failure"); }

renderBoard();
paintBoard();

deltaTime = System.currentTimeMillis() - beforeTime;
sleepTime = PERIOD - deltaTime;

if (sleepTime < 0)
{
timeOver = (-1) * (int) sleepTime;
sleepTime = 0;

}

try
{
Thread.sleep(sleepTime);
}
catch(InterruptedException ie)
{
System.err.println("Error: Thread exception!");
}
beforeTime = System.currentTimeMillis();
}

System.exit(0); // end of run
}



/**
* Renders the resulting output frame to
* an Image buffer. Off-screen rendering.
*/
private void renderBoard()
{

// Draw background, using correct coordinates
gDevice.drawImage(background, bX[0], 0, null);
gDevice.drawImage(background, bX[1], 0, null);
gDevice.drawImage(background, bX[2], 0, null);
gDevice.drawImage(background, bX[3], 0, null);

// Draw characters and all sprites
gChar.draw(gDevice);

// Test debug flags and take explicit action here
if (bFPSDebug)
calcAndDisplayFPS();
}


/**
* Used to calculate and paint the FPS on the GameBoard.
*/
private void calcAndDisplayFPS()
{
FPS = 1000 / ((Double) PERIOD + timeOver);
gDevice.drawString("FPS: " + String.valueOf(FPS), 20, 20);
}



This doesn't seem to work as my output is constantly either 62.0 or 66.0. This is with a const PERIOD of 10 milliseconds. This means as long as my computer can handle it I should be sleeping for 10 milliseconds which should give me 1000/10 = 100 FPS cap. Apparently I am not achieving this.

Does anyone know if what I am doing is sufficient to get an accurate FPS count. And also is calculating and drawing to the screen every loop like this going to be a performance hit in itself?
That which doesn't kill you makes you stronger.
Jason Petrasko
Jason Petrasko
I don't think any modern OS actually works with time slices as small as you may need here, and I bet if you changed the sleep() call to a wait loop it will work. It'll eat CPU, but it will work. I'd test that first, and post a reply if that doesn't work.
Danny02
Danny02
do I smell vsnyc here?
Red27
Red27
Two things:

1) If you're using a later version of Java, use System.nanoTime() - it has a much, much more accurate timer resolution than System.currentTimeMillis(), especially on Windows where the accuracy is only around 8 to 10ms (yes, that awful!). As an aside, to convert the nano seconds to milliseconds, you simply divide by 1,000,000 (one million).

2) Your issue is linked to the timeOver variable; if the resolution timer is inaccurate, because you are using the field as the extra time the render cycle took above the 10ms PERIOD (which from those figures seems like each render cycle timeOver is 5 or 6ms), plugging those figures into the FPS calculation:

FPS = 1000 / ((Double) PERIOD + timeOver);

gives you the FPS of 66 or 62 you're witnessing.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.