Jason Hoffoss wrote:
flip-thread
I don’t see how you can ever get smooth animation without rendering
exactly one frame per refresh…
If you try to sync to the vertical sync rate you have to deal with all
possible rates. A quick look at a couple of monitor manuals on my shelf
shows that one supports vsync rates of 60, 70, 75, and 80 Hz. The other
one supports vsync rates of between 50 and 160 Hz. Look at screen
properties under windows I find I can set the vsync rate on my current
desktop to 60, 70, 72, 80 and 100 Hz. These are the rate available for
my video card with my monitor. The same monitor connected to a
different video card, and vice versa, will have different rates.
Fine with me - as long as I get to render one frame for every refresh, or
at least, have a chance of knowing which refreshes I’m supposed to
"produce" frames for.
This is the problem with trying to base you animation on the vsync
rate.
That’s a completely different thing, and I’d never dream of it. It’s just
not flexible enough - you can’t even change the scroll speed in the game
without breaking it!
BTW, does Kobo Deluxe look like it’s controlled by the refresh rate? (I
hope not!
What is it? What will it be on other computers? The PC is NOT
like programming for a C64 or an old amigq where you can assume the
vsync rate is always the same. A game that works great when synched to
the refresh rate on one machine is going to look terrible when synched
to the refresh rate on another computer.
Yeah - if you do it that way… (Haven’t done that since the original
Project Spitfire, which relied on a VGA compatible video card anyway.
Wasn’t a problem then, but eventually, VGA hardware scrolling started
breaking on many video cards, and I never bothered switching to software
scrolling as I considered DOS dead anyway.)
So why bother?
Because you’re missing the whole point.
Synchronizing the rendering with the retrace is completely different
from synchronizing the whole game with it. For example, the engine I’m
using in Kobo Deluxe lets you select any “logic” frame rate you like, and
then interopolates all coordinates up or down to the actual rendering
frame rate, as required.
Now, if the rendering is implemented as “native OpenGL”, utilizing the
fractional parts of the output coordinates (8 bits right now…) for
sub-pixel accurate rendering, you get incredibly smooth scrolling and
animation regardless of refresh rate, or “logic frame rate”/refresh rate
ratio.
This is a fact, and I’ve implemented it and seen the result. It’s very
real, and totally portable, if it wasn’t for ONE thing: Linux basically
doesn’t have OpenGL drivers that perform retrace sync’ed flips - so
you’re not seeing anything but the usual tearing and crap to be expected
with such drivers. Still works though, it just doesn’t look any better
than the drivers allow.
It looks to me like you are making a number of assumptions. If I am
wrong, please tell me.
(See above.
It looks like you are assuming that the vsync
rate is the same on all machines.
Nope.
You can count on it being different.
that means you don’t know how much time you actually have to render a
frame.
If I don’t have enough power for the actual refresh rate, I’ll just have
to accept it, and “switch down” to a lower frame rate. Things would be
easier and look better if there was a reliable way of finding out exactly
which frames are dropped, but things would “kind of” work even if that
isn’t solved properly.
You don’t even know the speed and model of the CPU the game will
run on. You might have a million instructions per vsync, and you might
have 100 million.
You get the frame rate your machine can handle, and if that’s less than
full frame rate, the smoothness suffers. No news there.
It also looks to me like you are assuming that you
will have exclusive use of the CPU. This is not true on any of the
widely used OSes. There are a number of tasks that will sneak in and
grab cycles.
Right, and that’s a problem. Nothing much to do about that. However, it
gets much worse if you just hog the CPU, without ever blocking on
anything. (Like the retrace, when you’re out of buffers…)
Anyway, this won’t be much of a problem with Linux in the future. In
fact, it isn’t much of a problem if you use a Linux/lowlatency kernel,
or even one of the current preemptive kernels. If you’re entitled to run,
your thread will wake up within a fem ms, at most, and if it was
properly blocking on the retrace (real IRQ or timer emulation), things
would be just great.
We’ve been doing audio processing like this for quite a while (<3 ms
latency) with no drop-outs ever, despite heavy system stress of all
kinds. I’d say that anyone that claims that a “destop system” could never
do that is plain wrong - I have seen it in action on various PCs.
The fact that Windows can’t do it reliably, even with a real time kernel,
does not prove anything other than that there is lots of misbehaving code
in it, and it’s drivers.
It seems like you are assuming that you know that each
frame can be rendered in roughly the same amount of time.
I am, in the case of 2D games. Indeed, you could max out a 3D card with
2D levels as well, but that would be a very crowded screen with any
reasonably modern card…
Level
designers can really mess that up. One long hall with too many polygons
and your frame rate can drop by 90%…
Yeah - but that sounds more like an example of poor level design to me.
(I did read up some on 3D level design.)
Either way, if the fram rate drops, so be it. The only to completely
avoid the risk of that is to very carefully tune the game for a specific
machine, and then never run it on anything that could possibly be
slower under any circumstances.
An arcade game would be an example of such a solution - but considering
that even my dog slow G400 seems to be fast enough for what I want to do,
I’d guess 90% of the users with OpenGL would get a constant full frame
rate with the kind of games I’m thinking about.
It looks like you are also
making assumptions about the quality of the video device driver. There
is a good chance (almost certain) that the driver will only do a swap
at vsync time. A lot of hardware won’t swap at any other time.
Well, the last machine I saw that was at all capable of anything but that
was the Amiga, which didn’t have buffered video DMA pointers. You had to
use the copper to change them when you desired. Usually, you’d just reset
them to the start of the screen some time during the retrace, but you
could change the pointers at any time, to implement independently h/w
scrolled splitscreens and the like.
PC video cards just latch the frame buffer offset/pointer into an
internal counter right when it’s about to start a refresh. You can’t
force them to latch during the refresh - and it would be usesless anyway,
as it would just result in the output restarting at the first pixel of
the buffer immediately when you write the register… heh
There is
also a good chance that the driver is implementing a triple buffer
scheme if it can.
In fact, that’s exactly what I would want, as that gives me a much
better chance of maintaining a steady full frame rate, even if the OS has
crappy timing and/or my rendering times are “jittering” near the frame
rate limit.
The driver writers are highly motivated to make
graphics run as fast as possible on the device. (That is how they sell
video cards after all.)
That’s also the way I like it. What’s the problem? (Of course, disabling
the retrace sync sucks, but then again, I don’t think I’ve seen a Windows
driver that does that by default… It’s only meant for benchmarks.)
And, it also looks like you are assuming that a
hardware buffer swap involves and actual buffer swap, this also may not
be true, especially when dealing with a windowing system of any kind.
It can be faster to use the hardware to render in an off screen buffer
and do the swap with a blit.
I’m perfectly aware of that - as a matter of fact, my first subpixel
accurate scroller prototype was implemented on a system with a driver
that did “blit flips” even in fullscreen mode. That wasn’t a serious
problem, and I even managed to get retrace sync to work with it, to some
extent. (I never bothered switching to “half buffering”, so there would
be some tearing occasionally.)
Even if the driver gives you a flag or a
call back on vsync there is a reasonable chance that the call back is
generated from a timer or some other way that has nothing to do with
the actual vsync.
Well, that’s a broken driver IMHO. Nothing much to do about that - unless
it’s Open Source, of course.
In general, you just can’t know enough to justify doing anything to try
to sync with vertical retrace.
There’s no way I can agree, considering what I’ve seen so far.
I’m planning to release some form of demo RSN. I’m quite sure it will
work just fine on any Windows machine with OpenGL, or any other system
with an OpenGL driver that does retrace sync’ed pageflipping.
I have found that the best thing to do is just draw the graphics based
on actual elapsed time and check to see that the frame rate is fast
enough to give good game play.
Have you considered sub-pixel accurate rendering, and/or higher
resolutions? (Of course, both more or less require OpenGL.)
Anyway, the basic version of my “magic scroller” is to do exactly what
you’re describing. Provided you’re using OpenGL and a sensible resolution
on a decent machine, the frame rate most likely will be sufficient -
and if you pass the fractional part of your coordinates on to OpenGL,
there you go: Perfectly smooth scrolling!
That’s pretty much all there is to it, for machines that are fast enough
to take advantage of it. For slower machines, it’ll work just like what
you’re suggesting - although it might be a good idea to disable the
sub-pixel accuracy, at it’ll probably generate some blurring, if
anything.
(Do the test up front!)
Indeed.
This approach
gives your game a smooth visual feel. The frame you are looking at
reflects what the player expects at this time no matter how long it
took to create the frame. The frame rate may be jerky, but you don’t
get sudden slow downs and speed ups in the action.
Feel to ignore me and to disagree with me.
Well, this is what I do in Kobo Deluxe, and it seems to work very well,
so I can hardly disagree with this part.
However, I’m still 100% sure that a driver with retrace sync’ed flips +
sub-sample accurate rendering results in smoother animation.
//David Olofson — Programmer, Reologica Instruments AB
.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |
-------------------------------------> http://olofson.net -'On Sunday 17 March 2002 23:43, Bob Pendleton wrote:
----- Original Message -----
From: “David Olofson” <david.olofson at reologica.se>
To:
Sent: Wednesday, March 13, 2002 5:18 PM
Subject: Re: [SDL] CSDL with quad-buffering and a seperate