Fast Frame Rates but Still Ugly

Sage
Posts: 1,066
Joined: 2004.07
Post: #1
I am working through the tutorials at GameTutorials.com and I have reached the Time Based Motion tutorial. I noticed that while running this I am getting over 400 frames per second but I'm still getting choppy, disconnected geometry when I move the camera. Is this just something I have to deal with because I have to wait for the computer to process and draw all of the pyramids or is there some other problem?
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #2
turn on vsync? does that fix your problem?
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #3
I feel like a newb asking (well I guess to OpenGL I am a newb) but how do I turn on vsync?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #4
To expand on skyhawk's post, your display is physically incapable of displaying 400 fps. If it is an LCD it can only display 60 fps. A CRT, 75 or 90 or whatever refresh rate you've got it set at.

What happens when you try to display 400 fps on a 60 fps device? Well, as the device pixels are refreshed from top to bottom, they show whatever is in VRAM at the moment. So you end up with horizontal stretches of multiple frames on screen simultaneously, which is typically described as "tearing" or as you put it, "choppy, disconnected geometry".

Solution is to sync the refresh to VBL (vertical blanking interval), this is off by default on OS X but requires an entire two lines of code on your part. See this technote, though the API to use depends how you're using GL (AGL/NSGL/CGL...)

Note: enabling vsync will, by definition, frame limit you to the refresh rate of the display. Which has interesting side effects for your time-based motion tutorial. If you were running at 400 fps, it will jump down to 60 (or whatever) and should now be perfectly smooth. This is fine but to see the proper effects of the tutorial code, you'll either need a different monitor display Hz (change display mode on a CRT if you have one) or a much slower computer that can only run the example at < 60 fps, or a much more complex example.

There's also this sample code.
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #5
Thanks a lot. I wondered about how I was getting 400 frames per second on a screen that only refreshes 60 times per second.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #6
A followup (because this is a FAQ), if your code is using GLUT for GL, then there is a checkbox in GLUT's global preferences called "Default Synchronization to Vertical Blank" which will take effect the next time you launch your app.

Or, you can force the GLUT app to always sync regardless of that checkbox setting with two CGL lines placed in your init somewhere after your window and GL context have been created:
Code:
#ifdef __APPLE__
long VBL = 1;
CGLSetParameter(CGLGetCurrentContext(),  kCGLCPSwapInterval, &VBL);
#endif

This works for SDL based GL apps, too.
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #7
That didn't work with my code which is all SDL/OpenGL written in C++. Is there more too it? Or is it that I placed it in the incorrect location in my code?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #8
Well, where did you put it?
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #9
right near the end of my Init code. After the OpenGL had been set up.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #10
Are you sure you've requested a double-buffered GL context? There's no other trick to VBL.
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #11
When I put that code in I got a lot of unknown Function and Variable errors.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #12
You need to include the definitions for CGL:
Code:
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#endif
Quote this message in a reply
Member
Posts: 100
Joined: 2006.05
Post: #13
While we're on the subject, I just enabled vsync. However, my program now 'jerks'. All the movement and animation is time based so there's not problem there. There's not jerks if it's off but no matter what I do it's there when I turn it on.

What I mean by 'jerks' is that every second or so it will slow down or pause for a millisecond or so. Not very long but it's annoying as hell. And it won't stop for anything. Also it jerks like crazy the first second or so. It will continue to jerk literally about every second.

Anyway, this doesn't happen if I don't enable it, so what's going on here?
Quote this message in a reply
Sage
Posts: 1,066
Joined: 2004.07
Post: #14
Thanks for that. I was using "SDL_opengl.h" for my OpenGL header. Now I have both and that code works great. Locked at 60 frames per second. Nice.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #15
Nevada:
1) windowed or fullscreen?
2) ati or nvidia?
3) what display?
4) how does your timing work?

For example, if you say "windowed", "ATI 9600", "15" Studio display", "NSTimer @ 60 Hz" then there are several potential reasons why you're dropping a frame every second:

1) windowed contexts have to compete with the window manager, i.e. every other app running. that includes things like the airport and clock widgets in the menu bar, which update every second or so. fullscreen contexts don't have to compete.
2) the ATI drivers in 10.3 are really bad at competing. if you have two separate VBL synced regions updating, it's very easy for the window manager to end up syncing twice per refresh, dropping both apps to 30 fps. ATI under 10.2 had different problems but was better in this regard. nvidia is better at this under 10.2 or 10.3.
3) you may think your display refreshes at 60.000000 Hz, but it probably doesn't. A lot of LCD panels refresh at 60.01 or 59.94 Hz. If you're using a fixed rate timer, this small difference is enough make you drop frames once in a while. Find the real rate of an LCD panel with this.
4) timers like NSTimer are not particularly accurate. They don't guarantee firing within a given threshhold, only after it. One option is to just draw as fast as possible, with no timer, and let the VBL sync frame limit you.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Slowing Frame Rates and Display Lists Nick 4 3,052 Mar 27, 2005 06:08 AM
Last Post: wadesworld
  fast billboards reubert 2 2,801 Oct 7, 2004 04:41 AM
Last Post: OneSadCookie
  GL_LINE_SMOOTH looks ugly Vertizor 9 5,781 Sep 21, 2004 11:30 PM
Last Post: arekkusu
  Too fast! Silden 7 3,998 Apr 16, 2003 02:40 PM
Last Post: Mars_999
  how fast should this be? <seb> 3 3,836 Feb 25, 2003 12:51 PM
Last Post: <seb>