Frame Rates

Member
Posts: 196
Joined: 2002.04
Post: #1
Hi,
I'd like to get some kind of fps counter on my game but I'm having trouble. Here's the code:
Code:
NSTimer *time;
- (void)draw;

- (void)awakeFromNib
{
        time = [[NSTimer scheduledTimerWithTimeInterval: DEFAULT_TIME_INTERVAL
                    target:self
                    selector:@selector(draw)
                    userInfo:nil
                    repeats:YES]
                    retain
                    ];

}

- (void)draw
{
     // frame counter here
     // All I want is to print out the frames per second to NSLog();
}

My question is how do I get the time and compare it with the frames. I know this sounds like a really stupid question, but my Cocoa skills are still quite lacking due to the Cocoa book "Learning Cocoa" (1st edition). Btw the timer code was taken from someone elses codeBlush.

Thanks,
Iceman
Quote this message in a reply
Member
Posts: 509
Joined: 2002.05
Post: #2
Im still learning cocoa too, so I can't tell you code, but I can tell you how to make a FPS counter


time1 = (get the current time or timer here)
MAIN LOOP HERE
{

time2 = time1
time1 = (get the current time or timer here)

FPS = 1/(time1-time2)

}




Did that help at all?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #3
Code:
// in the interface for the class
NSTimeInterval elapsed;
NSTimeInterval lastFrame;
unsigned int frameCount;

Code:
// in the timer callback
NSTimeInterval thisFrame = +[NSDate timeIntervalSinceReferenceDate];
elapsed += (thisFrame - lastFrame);
++frameCount;
lastFrame = thisFrame;

if (elapsed > 1.0)
{
    printf("%f FPS\n", frameCount / elapsed);
    frameCount = 0;
    elapsed = 0.0;
}
Quote this message in a reply
Member
Posts: 177
Joined: 2002.08
Post: #4
I much prefer "static" framerate counters that update less often than every frame (so you get a number you can actually read instead of madly vibrating text).

Code:
gettimeofday(&startTime);
    framesPerSecond = 0;
    
    [Per frame:]

    framesPerSecond++;
    gettimeofday(&currentTime,NULL);
    if(currentTime.tv_sec > startTime.tv_sec)
    {
        printf("%d renders per second.\n", framesPerSecond); //or whatever
        framesPerSecond = 0;
        startTime = currentTime;
    }
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #5
Looks like everyone replied at once Wink

My solution only updates every second or so, so you don't get wildly spammed with hugely varying FPS numbers. It's also more accurate than Mark's solution, though the extra accuracy is probably below the consistency of your frame rate...

I generally prefer +[NSDate timeIntervalSinceReferenceDate] in Cocoa (and GetCurrentEventTime() in Carbon), since they return doubles already, so no mucking around like with gettimeofday. gettimeofday is more portable, though, so it does have its place...
Quote this message in a reply
Zoldar256
Unregistered
 
Post: #6
I find I need a non-cocoa method with more accuracy than gettimeofday. So I use:

[SOURCECODE]AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());[/SOURCECODE]
From the CoreAudio framework.
Overkill, but hey, it's really accurate ;-)
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #7
Thanks everyone for your helpful posts. Since I have a 500mhz g3 and limited cocoa skills I used One Sad Cookie's idea. I topped out at 43 FPS. Yes, I know that is just sad but remember this on 8mb of vram in a 800x600 32bit resolution. For some reason one of my older more polished versions runs at 53 - 60 FPS...oops (my newest version has been totally rewritten). Well, at least the code looks 100 times nicer on the new oneGrin.

Iceman
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #8
Quote:Originally posted by Zoldar256
I find I need a non-cocoa method with more accuracy than gettimeofday

More precision or less latency? gettimeofday is precise to the microsecond, why would you need more than that? It's probably quite a slow call, though... UpTime probably has the least latency of all the calls you could make.
Quote this message in a reply
Zoldar256
Unregistered
 
Post: #9
Even tho it's accurate to the microseconds, I think there is less latency dealing with a 64bit nanosecond time than a time structure. Both in the applications code, and also for the system call. But... My biggest problem is that I don't know if gettimeofday is updated continuesly or in ticks. The man page says either...

It would be interesting to see which is faster, gettimeofday, or AudioGetCurrentHostTime. One you'd ahve to deal with tiem structures and no guaranteed accuracy. The other, 64bit int arithmetic emulation.

Of course, something like that should be *the last* thing I'd consider optimizing... ;-)
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #10
Ok, this code has really got me going on finally being able to understand fonts and strings. Thanks! I have one problem though, the string keeps flashing on and off the screen. Here's the code:
Code:
- (void)draw
{
[self frameCounter];
}

- (void)frameCounter
{
    char s[32];
    int len, i;

    thisFrame = +[NSDate timeIntervalSinceReferenceDate];
    elapsed += (thisFrame - lastFrame);
    ++frameCount;
    lastFrame = thisFrame;
    
// This is the problem I think, but if I remove the "if (elapsed > 1.0)" it becomes impossible to read the string
    if (elapsed > 1.0) {
        sprintf( s, "%3.4f FPS\n", frameCount / elapsed);
        frameCount = 0;
        elapsed = 0.0;
    }
        
    glPushMatrix();    
        glTranslatef( 0.0, 0.0, -1.0);  
        glColor3f( 1.0, 0.0, 0.0);
        glRasterPos2f(-0.55, 0.39);
        
        len = (int) strlen(s);
        for (i = 0; i < len; i++) {
            glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, s[i]);
        }
    glPopMatrix();
}

Thank you so much:),
Iceman
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #11
The problem is that the string is being set to random garbage each time you call the function, and you're only printing something to it every second. Probably the best thing to do is make it persistent across calls to the function:

Code:
static char s[32] = "";
Quote this message in a reply
Member
Posts: 196
Joined: 2002.04
Post: #12
Doh!! I accidently left out the "static" part of the code from the other project that I was copying it fromBlush. Well, now I know what the "static" does hehe. Also, I did notice I was getting major garbage from what printf() was telling me.

Thanks again,
Iceman
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Previous frame inner to this frame (corrupt stack?) wyrmmage 9 7,464 Nov 29, 2006 05:14 PM
Last Post: wyrmmage