Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » HELP!! I hate vsync...

This thread is locked; no one can reply to it. rss feed Print
HELP!! I hate vsync...
albin ego
Member #8,045
November 2006

ok.. a few weeks has gone by since a started this whole c++ and allegro thing... and all this time i had page flipping and tripplebuffering in the back of my mind, when i made more simple applications without timers and stuff i could use page flipping without problems.. but when i decided to create some heavy stuff... i found myself with an unexpected "problem" or rather a stupid wall that i can't break down.. it seems like show_video_bitmap takes the same time to finish as vsync - -... i was going crazy over this as my applications was not designed for that kind of *()/! stuff, so after a while i gave up and used dubble buffering... but that's just not satisfying!, so i got back into the fight with my current arch enemy, after a while i found request_video_bitmap and by reading the instructions i thought it would be the same thing as show_video_bitmap but without the annoying delay.. but i must have missunderstod the whole thing.. becouse no matter how i use them they have the same effect - -... om so angry that i could chop my legg of right now.. so could anyone please tell me what to do!! cause i NEED pageflipping and stuff.

Kitty Cat
Member #2,815
October 2002
avatar

Triple buffering allows you to not have to wait for vsync, although the actual flip will wait for it, so you're still limited to your monitor's refresh rate. And there's no real point in exceeding your monitor's refresh because then you'll get tears and waste CPU time on frames that'll only ever be partially seen.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Richard Phipps
Member #1,632
November 2001
avatar

Triple buffering is probably going to give you the best results.

If you do a search on the forums for Page Flipping or Triple Buffering you will find many threads including source code. Chris Barry also did a full screen API to handle double buffering, page flipping & triple buffering automatically.

albin ego
Member #8,045
November 2006

ok, it's more like this: im well aware of drawing the screen and show it more times than the maximum fps on the screen is unnecessary, but that's not the issue... i can make a very simple modell of my structure..

timer on 75ticks per second.
{
cf++;
}

initstuff:
while(bla bla)
{
if(cf>mx)
draw();

therest();

i have two values which i display on my screen when i runt he program. fps and a home made def called: rlps.. as it should be the fps counter stays on 75 every second, but the rlps which increases by one every time therest(); depends on what buffering i use... becouse of the delay on the show/request_video_bitmap, so when using dubblebuffering fps on: 75, and rlps is about 80000000 every second. but when i use show/request_video_bitmap(for page flipping and triplebuffering) both counter satys on 75.. which is an obvious result... but that's what i dont want! becouse my code gets screwd - -..

this is ofcourse not how my program looks but it has the same effect.

Kitty Cat
Member #2,815
October 2002
avatar

I don't see anything wrong with that. therest() being called 80000000 times per second means the function is being called way more times than necesarry. Basically you just need to have a loop like this:

while(playing)
{
   while(cf == 0)
      rest(1);
   while(cf > 0)
   {
      --cf;
      logic();
   }
   draw();
}

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

albin ego
Member #8,045
November 2006

actually, i like it when therest() is being called 80000000, becouse then i can see how much the code is burdening my computer, and i can keep track of many timer functions, it's har to explain, but if my whole program ran 75 times per second...

this is nothing like my code/s, i just wrote it as a question.

struct player
{
int canmove;
int x;
int y;
int speed=1000;
}player;

timer tick 1000 times per second.
{
player.canmove++;
}

mainsapifnsf

while(whevr)
{
if(player.canmove>=playerspeed)
{
player.canmove=0;

if(key[KEY_UP])
player.y--;

}

}

ok, this psudo may be wierd and wrong but im to tired to write much.
i think(or it should) this kind of code would create a big(not really big) delay depending on the fps.
someone might say theres no need to write it this way, but im new to c++ and allegro so im learning.
but can you understand my problem even if its all wrong?.

Dustin Dettmer
Member #3,935
October 2003
avatar

I have a wrapper that'll handle triple buffer, page flipping, double buffer, raw and one other mode that i forgot (some other form of triple buffer). You specify which modes you want it to be able to try and it'll try the most efficent one, falling back on less efficent modes if needed.

If I get motivated enough and you're interested I'll post the code when i get home.

Answer to your question:

while(poll_scroll()); // Incase the last flip hasnt finished yet, we wait for it.
request_video_bitmap(the_video_page);

albin ego
Member #8,045
November 2006

huh, now im confused, would:

while(poll_scroll()); // Incase the last flip hasnt finished yet, we wait for it.
request_video_bitmap(the_video_page);

not create the very effect that im trying to avoid?

and:
what's a wrapper :P,

Kitty Cat
Member #2,815
October 2002
avatar

You don't want to avoid being stopped from displaying more frames than the monitor can display. If you want to see how your code performs (how much CPU time parts take up), profile it.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

albin ego
Member #8,045
November 2006

but noooo, thats why i have a timer for controling the fps, i don't want any vsync.
i want my code to uppdate very often, but 75 times per second is way to little.
i just don't want the stupid vsync to effect my code! i like dynamic programs with small factors, and thats how i want to keep it, i dont want to optimize my code for the vsync. i doesn't matter how fast my code is since a timer controls the fps, and jumps over that part, but i want the rest of the code to execute very often so the game will go smooth even if i use very small factors.

and what is profiling?.

Neil Walker
Member #210
April 2000
avatar

perhaps what you want is dirty rectangles for your drawing code and not use a fps based loop but a delta based loop.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Kitty Cat
Member #2,815
October 2002
avatar

Your timer controls your logic rate (which doubles as your maximum FPS). Vsync is used to stop tearing. 75 FPS is just fine (most people would have trouble discerning anything higher anyway), and if someone's monitor is at a 75hz refresh, doing more frames than that won't make it any smoother.

Profiling is a function of the compiler that puts in extra code to time how long functions take to run. So you can see how much time certain functions are taking.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

albin ego
Member #8,045
November 2006

dirty rectangles?
delta based loop?
sounds like something worth knowing more about, can you give me a short description of each subject?

and kitty cat:
are you saying that i should put the WHOLE logic part into a timer???..
and if your not: are you saying that as my timers controll the logic part
the whole routine would not need a higher rate than 75?
ive been thinking about that but i really dont want to compromize to that,
becouse as i said before i want my code to logic part to update VERY fast, besides, im want a code that can handle many many many many small changes,

:/, is there really no way to use triplebuffering without the rest of the program going at a rate of 75?. what if wanted to create a function that works just like draw() but with a higher frequency... nocando..
maaah!.

Dustin Dettmer
Member #3,935
October 2003
avatar

Quote:

but noooo, thats why i have a timer for controling the fps, i don't want any vsync.

You can't send two frame to the screen at once, that just wouldnt make any sense.

The codewhie(poll_scroll());waits for last frame's vsync to finish.

[edit]

Quote:

what's a wrapper :P,

A group of functions that handle some difficult task for you, making the task (theoretically) as easy as possible.

Basically I've written the hard to write code, and you can replace all of your triple buffer / page flipping code with function calls to my code.

albin ego
Member #8,045
November 2006

reply to Dustin Dettmer's post:

um, i must have said something strange.. couse i dont recall sayin anything about rendering two screens att once... i said that a timer should handle the fps,
like this:

timer(fps(controlled by a config file) ticks per second)
{
maxfps++;
}

timer2(one tick per second)
{
maxfps=0;
cframe=0;
}

...
while(1==1)
{
logic

if(cframe<maxfps)
{
draw();
}

in draw()
...
cframe++;
...

this would mean that if the fps's on 75 the maxfps can only be 75.
and that the draw() function only can be used 75 times per second with equal sized space between ticks, and if the logic is to hard for the computer the fps would compremize, and the logic part be updated as fast as possible, as i want my app to use the processor to the maximum.
why wait when we can work...

about the wrapper: thx alot man, but i prefer to do as much as i can with my own hands :P, there's no fun in using other peoples work :). but thx anyway.

Dustin Dettmer
Member #3,935
October 2003
avatar

Quote:

um, i must have said something strange.. couse i dont recall sayin anything about rendering two screens att once...

Carefully re-read my post. It wasn't a critique of anything you said, I was clarifying what the while(poll_scroll()); code does, as it doesn't wait for vsync as you appear to think it does.

albin ego
Member #8,045
November 2006

^^'

hmm, maybe i should run some more tests using that pool_scroll(), it would be nice if you would post a whole code as an example :), hmm, but still, even if it waits for the last frame vsync to finish, would it not still cause the whole routine to run 75 times per second? and by "last" do you mean the frame that were waiting for to be drawn? or something else? becouse i don't think i understand :P.

Dustin Dettmer
Member #3,935
October 2003
avatar

as long as you are not drawing faster then the monitor can handle, poll_scroll() will always return false. If you go too fast, poll_scroll() will slow you down to the fastest possible speed your monitor will let you. If you decide not to check poll_scroll request_video_bitmap will simply fail with untold nightmares awaiting you. Theres no point calling request_video_bitmap at all unless poll_scroll() returns false.

So, yes, poll_scroll will limit you to your monitor's hertz rating. But only for drawing, if you want to use the CPU for stuff, then you still can. Go right ahead. When you're done with the CPU and its time to render the frame, you have no choice but to wait for the projector head to finish its last job (drawing the last frame) before it'll accept a new one.

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

are you saying that as my timers controll the logic part
the whole routine would not need a higher rate than 75?
ive been thinking about that but i really dont want to compromize to that,
becouse as i said before i want my code to logic part to update VERY fast, besides, im want a code that can handle many many many many small changes,

Basically what I'm saying is:
fps = MIN(game logic rate, monitor refresh rate);
Your logic rate is how many times you do logic calculations per second. This is also the theoretical max for your fps. As well, there's no need to display more frames than your monitor can show. So if you have a 75hz refresh rate, and a logic rate of 100, you should have 75fps. If you tried to draw all 100 frames, you'd end up wasting CPU time on partial frames.

On the flip side, if you have a logic rate of 100, and a refresh rate of 120, you'd limit your fps to 100. Since there's no sense drawing a frame if your logic hasn't run (you'd just draw the same scene over again).

Your logic part will update very fast. Unless you're using hardware acceleration, your drawing will tend to be the slowest part of the code. Whether your logic runs 800000 times or 75 times a second doesn't matter, because each time will basically take the same amount of time.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

albin ego
Member #8,045
November 2006

i kinda understand what youre all sayin, but i still feel like i need different speeds. vsync isnt always the same so i can't rely on it, i think i have fount a way around my little vsync problem, but i still need to test it and it's not as good as it would be without the vsync stuff. the main reason why i dont want the vsync is becouse the timers would still go, and while the timers go and the variables reaches their destinations, the variabels will still be different and becouse of the little pause caused by the vsync, the variables would cause the things to execute at the same time... so then i dont really have any use for timers..i need the logic part to execute atleast 1000 times per second for the program to run as it was meant to run "perfectly", while i can still use dubblebuffering it is not as good looking and i hate it. i don't know if anyone will understand my problem but iv'e still got a lot of information i may be able to get some use of, if someone knows a way to use triplebuffering without waiting for vsync than please tell me, and if it's not possible, tell me anyway becouse it's good too know.

Kris Asick
Member #1,424
July 2001

If you check out my claim to fame, PixelShips, you'll notice that there's a "Please Wait" when it starts up. The reason it's doing this is that it's making a quick check to see if the desired framerate is the same one the monitor is doing, not by using get_refresh_rate(), because that doesn't always work, but by timing 1 second worth of frames with vsync(), running a timer at the desired sync rate, and then comparing the two. If the two are within 2 frames of each other, the game uses vsync() and double buffering, and if not, it does just double buffering and uses the timer instead.

Since switching to real-time semantics though, I've lost any will to care which is used, so I just add a vsyncing option to my games now. ;)

Real-Time + Vsynced Double Buffering = Almost as good as page flipping 8-)

I don't use page-flipping or triple-buffering in my games though because they can screw up the I/O interface for the keyboard, mouse and joystick in Windows 98 in the more recent 4.1.x and 4.2.x Allegro builds and trying to figure out why it happens never got anywhere. (Even after figuring out what version the problems began in.)

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

vsync isnt always the same so i can't rely on it

You don't rely on it. That's what your logic rate timer is for. vsync is just for smoothing out the video and preventing you from trying to display more frames than can be shown. Your logic rate timer is for keeping your game running the same speed regardless of the refresh rate. your actual FPS should be at your logic rate or refresh rate.. whichever's lower.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Andrei Ellman
Member #3,434
April 2003

show_video_bitmap() by default waits for a vertical retrace to occur. You can disable this behaviour by changing the value of the 'disable_vsync' key in the Allegro configuration file. It is possible for an app to have it's own configuration file (in the form onf an .INI file). See http://allegro.cc/manual/api/configuration-routines/ for details.

AE.

--
Don't let the illegitimates turn you into carbon.

albin ego
Member #8,045
November 2006

Thanks! ^^' used alot of other strange tactics to go around this, put show_video_bitmap into a timer is an example of that ^^, it worked, but sometimes the screen would look ok and other times not - -, and it took a lot of cpu power. I will look that disable_vsync up ^^, thank's goes too everyone else too!.. now i'm going back to "work".

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

I will look that disable_vsync up

Note that this is a user option (as is everything in the configuration file). Your program shouldn't attempt to override it. There should be no reason your game can't work with vsync on or off.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Go to: