control the FPS of our Animation

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

control the FPS of our Animation

Post by Emil_halim »

Hi All

i made a TTimer class ,that will allow you to control the FPS & Duration of your Animation.it makes Irrlicht to
not take all the time of CPU.

you have to put your animation loop in a void function,and later the TTimer class will call
that function internally.

the class offers 4 Functions

1- PlayAnim(MY_FUNC_TYPE func,DWORD duration,int fps)
2- PlayMaxSpeedAnim(MY_FUNC_TYPE func,DWORD duration)
3- PlayAnimForever(MY_FUNC_TYPE func,int fps)
4- PlayAnimUntil(MY_BOOLFUNC_TYPE func,int fps)

for example
===========

void Render(void)
{
irrVideo->beginScene(true, true, SColor(0,200,200,200));
irrSceneMgr->drawAll();
irrVideo->endScene();
}

and in the main program

TTimer* cnrtl;
cnrtl = new TTimer(irrDevice);

cnrtl->PlayAnim(Render,14000,100)

this will play 14 Seconds with 100 FPS.
the parameters

1- the name of our Loop Function
2- the duration of animation
3- the FPS of animation

so you can divide the application into parts,one for introduction, one for the game itself
, and one for ending. you can do it like the following

void intro()
{
introduction animation stuff
}

BOOL game()
{
game stuff


if gameover
return false;
else
return true;
}

void Ending()
{
ending animation stuff
}

and in the main function

//play introduction in 20 second & 200 FPS

cnrtl->PlayAnim(intro,20000,200)

// play the game while game return true

cnrtl->PlayAnimUntil(game,200)

// finally ending ,6 sec & 200 FPS

cnrtl->PlayAnim(Ending,6000,200)


here is the TTimer class

Code: Select all


typedef void (*MY_FUNC_TYPE) (void);
typedef BOOL (*MY_BOOLFUNC_TYPE) (void);

class TTimer
  {
      private:
               LONGLONG  ticks_per_second;
               IrrlichtDevice*    Irr_Device;
      public:            
               ~TTimer() {}
                              
               TTimer(IrrlichtDevice* Device)
                {
                   Irr_Device = Device;  
                   QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second);
                }
               
               virtual void PlayMaxSpeedAnim(MY_FUNC_TYPE func,DWORD duration)
                {
                   LONGLONG  Anim_ticks,tick;
                   QueryPerformanceCounter((LARGE_INTEGER*)&tick);
                   Anim_ticks=tick+(duration/1000)*ticks_per_second;
                   while((Anim_ticks>tick && Irr_Device->run()))
                    {
                       QueryPerformanceCounter((LARGE_INTEGER*)&tick);
                       func();
                    }
                }
                
               virtual void PlayAnim(MY_FUNC_TYPE func,DWORD duration,int fps)
                {
                    LONGLONG  Anim_ticks,tick;
                    LONGLONG  Anim_fps,ticks = 0;
                    Anim_fps=(ticks_per_second/fps);
                    QueryPerformanceCounter((LARGE_INTEGER*)&tick);
                    Anim_ticks=tick+(duration/1000)*ticks_per_second;
                    while((Anim_ticks>ticks))
                     {
                        QueryPerformanceCounter((LARGE_INTEGER*)&ticks);
                        if(Irr_Device->run()==FALSE)break;    
                        if(ticks-tick >= Anim_fps)
                         {
                            func();
                            tick=ticks;
                         }
                     }
                }
                
               virtual void PlayAnimForever(MY_FUNC_TYPE func,int fps)
                {
                    LONGLONG  Anim_ticks,tick;
                    LONGLONG  Anim_fps,ticks = 0;
                    Anim_fps=(ticks_per_second/fps);
                    QueryPerformanceCounter((LARGE_INTEGER*)&tick);
                    while((TRUE))
                     {
                        QueryPerformanceCounter((LARGE_INTEGER*)&ticks);
                        if(Irr_Device->run()==FALSE)break;
                        if(ticks-tick>Anim_fps)
                         {
                            func();
                            tick=ticks;
                         }
                     }
                }
                
              virtual void PlayAnimUntil(MY_BOOLFUNC_TYPE func,int fps)
                {
                    LONGLONG  tick ,ticks = 0;
                    LONGLONG  Anim_fps;
                    BOOL Flag = TRUE;
                    Anim_fps=(ticks_per_second/fps);
                    QueryPerformanceCounter((LARGE_INTEGER*)&tick);
                    while((Flag))
                     {
                         QueryPerformanceCounter((LARGE_INTEGER*)&ticks);
                         if(Irr_Device->run()==FALSE)break;
                         if(ticks-tick>Anim_fps)
                          {
                             Flag=func();
                             tick=ticks;
                          }
                     }
                }    
  };                   
                                
here is the demo

Code: Select all

#include "irrlicht.h" 
// Irrlicht Namespaces 
using namespace irr; 
using namespace core; 
using namespace scene; 
using namespace video; 
using namespace io; 
using namespace gui; 

#include "CTime.cpp"

static IrrlichtDevice* irrDevice;
static IVideoDriver*   irrVideo;
static ISceneManager*  irrSceneMgr;

void Render(void)
 {
    irrVideo->beginScene(true, true, SColor(0,200,200,200));  
    irrSceneMgr->drawAll(); 
    irrVideo->endScene();   
 } 

void main() 
  { 
      irrDevice = createDevice(EDT_DIRECTX9,dimension2d<s32>(640,480),32,false,false,false,0); 
      irrVideo  = irrDevice->getVideoDriver(); 
      irrSceneMgr = irrDevice->getSceneManager(); 
      
      IAnimatedMesh* mesh = irrSceneMgr->getMesh("media/sydney.md2");                         
      IAnimatedMeshSceneNode* node = irrSceneMgr->addAnimatedMeshSceneNode( mesh );
      node->setMaterialFlag(EMF_LIGHTING, false);
      node->setFrameLoop(0, 310);
      node->setMaterialTexture( 0, irrVideo->getTexture("media/sydney.bmp"));

      irrSceneMgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

      //here is our control class
      
      TTimer* cnrtl = new TTimer(irrDevice);
      
      cnrtl->PlayAnim(Render,14000,100);  
       
      irrDevice->drop(); 
      
      return 0; 
  }              
hope that is useful to any one here
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Re: control the FPS of our Animation

Post by Emil_halim »

Emil_halim wrote:Hi All

i made a TTimer class ,that will allow you to control the FPS & Duration of your Animation.it makes Irrlicht to
not take all the time of CPU.
sorry , i have discovered a bug,it does not work as expected.

if we put 100 FPS the playAnim function must call the render function 100 times per a second
and must not take the entire CPU usage time, but it takes the entire CPU usage time.

it is very strang,so i need help please.
jox
Bug Slayer
Posts: 726
Joined: Thu Apr 22, 2004 6:55 pm
Location: Germany

Post by jox »

It's probably because your while loops take the CPU time. The run at 100% even though the func() doesn't get called at each iteration. You could try to work with with the Sleep method or SetTimer. But this is limited to milliseconds and might not be as accurate.
It is like it is. And because it is like it is, things are like they are.
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

Firstly, your code here basically takes the main loop and puts it inside of your TTimer class. It doesnt change 'animation speed' so much as allow you to define MAX fps, while wrapping it up with a function pointer for switching different rendering game logic functions. In my own opinion, this class does too many things of different values-- I much rather keep switching of game logic in its own state-machine type structure ( thus, the code in ICE is what I use). But again, thats just my opinion. To answer your question of why its taking up 100% CPU-- you're not releasing the CPU anywhere, you're just only calling render the given ammount of times.

This is a tight loop:

Code: Select all

                        QueryPerformanceCounter((LARGE_INTEGER*)&ticks); 
                        if(Irr_Device->run()==FALSE)break;    
                        if(ticks-tick >= Anim_fps) 
                         { 
                            func(); 
                            tick=ticks; 
                         } 
instead you should add a sleep() function kind of like this (this code is just off the top of my head, so it probably doesnt work straight like this):

Code: Select all

if(ticks-tick >= Anim_fps) 
{ 
                            func(); 
                            tick=ticks; 
  } else {
     sleep(  you can probably calculate how much time to release basedon FPS );
}
a screen cap is worth 0x100000 DWORDS
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

jox:
keless:

thanks to both of you, it is now work as expected.

here is the fixing

Code: Select all

virtual void PlayAnim(MY_FUNC_TYPE func,DWORD duration,int fps)
                {
                    LONGLONG  Anim_ticks,tick;
                    LONGLONG  Anim_fps,ticks = 0;
                    Anim_fps=(ticks_per_second/fps);
                    QueryPerformanceCounter((LARGE_INTEGER*)&tick);
                    Anim_ticks=tick+(duration/1000)*ticks_per_second;
                    while((Anim_ticks>ticks))
                     {
                        QueryPerformanceCounter((LARGE_INTEGER*)&ticks);
                        if(Irr_Device->run()==FALSE)break;    
                        if(ticks-tick >= Anim_fps)
                         {
                            func();
                            tick=ticks;
                         }
                        else
                         {
                            Sleep(1);   
                         } 
                     }
                }

Keless:

what is the ICE that you point me to ?
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

"what is the ICE that you point me to ? "

You can take a look at it from here:
http://technomagicum.net/projects/IrrLicht/
a screen cap is worth 0x100000 DWORDS
Post Reply