Game Development Community

GUI FPS Counter

by Jan Van Sweevelt · in Torque Game Engine · 03/14/2002 (2:58 pm) · 12 replies

I have added a FPS counter in the GUI object tree.
Here you can find the code
Create a new CC file in the directory engine\game\fps called guiFPSCounterHud.cc and copy this code in it:

//-----------------------------------------------------------------------------
// 
//-----------------------------------------------------------------------------

#include "dgl/dgl.h"
#include "gui/guiControl.h"
#include "console/consoleTypes.h"
#include "game/gameConnection.h"
#include "game/shapeBase.h"

extern F32 fpsReal;

//-----------------------------------------------------------------------------
/**
   basic FPS Counter.
*/
class GuiFPSCounterHud : public GuiControl
{
   typedef GuiControl Parent;

   bool     mShowFrame;
   bool     mShowFill;

   ColorF   mFillColor;
   ColorF   mFrameColor;
   ColorF   mTextColor;

public:
   GuiFPSCounterHud();

   void onRender( Point2I, const RectI &);
   static void initPersistFields();
   DECLARE_CONOBJECT( GuiFPSCounterHud );
};


//-----------------------------------------------------------------------------

IMPLEMENT_CONOBJECT( GuiFPSCounterHud );

GuiFPSCounterHud::GuiFPSCounterHud()
{
   mShowFrame = mShowFill = true;
   mFillColor.set(0, 0, 0, 0.5);
   mFrameColor.set(0, 1, 0, 1);
   mTextColor.set( 0, 1, 0, 1 );
}

void GuiFPSCounterHud::initPersistFields()
{
   Parent::initPersistFields();

   addField( "showFill", TypeBool, Offset( mShowFill, GuiFPSCounterHud ) );
   addField( "showFrame", TypeBool, Offset( mShowFrame, GuiFPSCounterHud ) );
   addField( "fillColor", TypeColorF, Offset( mFillColor, GuiFPSCounterHud ) );
   addField( "frameColor", TypeColorF, Offset( mFrameColor, GuiFPSCounterHud ) );
   addField( "textColor", TypeColorF, Offset( mTextColor, GuiFPSCounterHud ) );
}


//-----------------------------------------------------------------------------

void GuiFPSCounterHud::onRender(Point2I offset, const RectI &updateRect)
{
   // Background first
   if (mShowFill)
      dglDrawRectFill(updateRect, mFillColor);
   
   char buf[256];
   dSprintf(buf,sizeof(buf), "FPS : %4.1f", 1.0f/fpsReal);

   // Center the text
   offset.x += (mBounds.extent.x - mProfile->mFont->getStrWidth(buf)) / 2;
   offset.y += (mBounds.extent.y - mProfile->mFont->getHeight()) / 2;
   dglSetBitmapModulation(mTextColor);
   dglDrawText(mProfile->mFont, offset, buf);
   dglClearBitmapModulation();

   // Border last
   if (mShowFrame)
      dglDrawRect(updateRect, mFrameColor);
}

Add this file to your project off course

and change in main.cc the line :
static F32 fpsReal;
to
F32 fpsReal;

you have now in the GUI editor a new object called :

GuiFPSCounterHud

this object can be placed in the playGUI with the GUI editor and you have a permanent framecounter visible.

Before the flames start, I'm aware that the value of the fpsReal variable can be given to the object by script code, by adding some code to this object and adding a script. I have choosen myself not to do this because I don't want to hit the scripting engine when updating the counter. I'll leave this as an exercise to someone else.
;-)


Jan

#1
03/14/2002 (3:15 pm)
Bah, it's better to avoid scripts so i like it this way :)
I havent read the code yet but doesnt changing that static var have any bad effect on something else?
#2
03/14/2002 (3:21 pm)
not really. the var as static can only be used in main.cc
but it is exposed as an scripting var
#3
03/14/2002 (11:39 pm)
Cool stuff, you should probably post it as a resource...
#4
01/27/2003 (7:34 pm)
I'm having a problem with this code.

I cut/pasted it into a new file called guiFPSCounterHud.cc and stored it in \engine\game\fps as shown here. I added that file to the project and compiled - no errors. However, I get the following linker error:

guiFPSCounterHud.obj : error LNK2001: unresolved external symbol "float fpsReal" (?fpsReal@@3MA)

It's like the extern statement isn't allowing it to find fpsReal in main.cc.

This is with VC6 - anyone else have that problem?
#5
01/28/2003 (1:18 am)
I guess you didnt follow this step:

and change in main.cc the line :

static F32 fpsReal;

to

F32 fpsReal;

?

Or, you can get the fps like this:
// *** Retrieve the FPS variable ***
	const char* buf = Con::getVariable("fps::real");
#6
01/28/2003 (2:15 am)
Well, this is strange. I had 2 copies of main.cc open in the IDE for some reason, so the change I made to remove the 'static' didn't get saved when I re-compiled. It's working now :)
#7
02/14/2006 (9:50 pm)
If you are using TGE 1.4 modify this line:

#include "gui/guiControl.h"

to this:
#include "gui/core/guiControl.h"
#8
09/20/2006 (7:55 pm)
I tried this by accessing the console data and the data appears and dissappears according to events being recieved to widgets that take mouse focus? Or some such strange behavior.

Never mind both versions do it. I will have to figure this out. It must have something to do with the fact that I am using the camera or something.
#9
09/20/2006 (8:30 pm)
Another option is to just create a regular text control (using the GUI editor for PlayGUI) and then add a schedule() that sets the text of this control to the FPS value, once a second. That's all like ten lines of script, and no C++...
#10
09/20/2006 (8:36 pm)
I found out my width was too low because the FPS kept jumping to 110+ which caused the text to dissapear. So this is not an issue with the widget.
#11
09/20/2006 (11:22 pm)
What's wrong with:

'

type:
metrics(fps);

press
#12
09/21/2006 (8:58 pm)
It dissapears when you press F11 or F10. I am testing out some physics code and I want to drop objects into the scene via F11 and see the FPS as more objects are added to the scene.