Jerky movement in DDraw, smooth in D3D

Started by
11 comments, last by FieroAddict 20 years, 11 months ago
I''ve been doing some experimenting with the graphics for my Asteroid''s clone I''ve been working on (using .NET and DirectX9). Right now I have three different versions: Direct3D 3D, 2D using Direct3D Sprites, and DirectDraw 2D. My question is this: The source code for the animations and logic for both 2D versions is the same, aside from the D3D or DDraw specific code for displaying images. The problem is that in the DDraw version, when the asteroids are moving at certain angles, it looks like they aren''t moving at a smooth angle, instead you can tell that it''s moving jerkily up and over each frame. In the D3D version, they all look perfectly smooth. I have all animations and movements moving independant of the FPS, but I still wasn''t sure if the problem was that the D3D version can easily pull off over 300fps and the DirectDraw version is locked at 75 fps. I tried to change the flags for Flip() to NoVsync, but the program refuses to run with that setting. Or, could the problem be that in Direct3D, there is just better support for floating point positions than in DirectDraw (singles vs. integers)?
Advertisement
Make sure that YOU are storing the positions as floating points. 75fps is plenty fast enough for smooth motion. When you blit the image to a surface in DirectDraw, it WILL round off to integers, but as long as you maintain the position internally as a floating point, all will be fine.

This seems to be a very common issue with time scaling. [To everyone:] IF YOU USE TIME SCALAING, USE ONLY FLOATING POINT GENERALIZED CO-ORDINATES. That includes positions, angles, frames, the whole nine... anything time scalled. Roundoff will kill you otherwise.
Yes, everything is floating point numbers (except for the fact that DDraw only works with integer values in it Draw() functions). But all of my calculations are made with floating point numbers.

I know 75fps is plenty fast for good animation, but what I was wondering is, does DirectDraw actually pause the program while it waits to draw to the screen, or does your program continue to run and DirectDraw draws the screen in the background? This could explain the jerkiness... that it''s not being drawn in sync with the speed of my movement calculations?
In my experience, by having VSYNC turned on, your "Flip" call will return right away but the first time you try and blit to a surface, it will wait for the flip to complete (unless you say NOWAIT in which case it will throw an error).

WHERE the pause occurs should not affect the smoothness, as long as it occurs at the same place each time through, which it will. I''d seriously check over the rest of the code and run a pile of tests before thinking the VSYNC is to blame for this... I''m just skeptical, as I''ve had it work perfectly in a number of other circumstances.

      Private sprites As Surface    Private frame() As Rectangle    Private destRect As Rectangle    Structure Vector        Dim X As Double        Dim Y As Double    End Structure    Private position As Vector    Private velocity As Vector        Public Sub Draw(ByRef backbuffer As Microsoft.DirectX.DirectDraw.Surface)        destRect = New Rectangle(position.X, position.Y, frame(currentFrame).Width, frame(currentFrame).Height)        backbuffer.Draw(destRect, sprites, frame(currentFrame), DrawFlags.DoNotWait Or DrawFlags.KeySource)    End Sub    Public Sub Update(ByVal seconds As Double)        position.X += velocity.X * seconds        position.Y += velocity.Y * seconds        If velocity.X > 0.0 And position.X >= 800.0 Then            ''if moving right and moved beyond screen            position.X = -64.0        End If        If velocity.X < 0.0 And position.X <= -64.0 Then            ''if moving left and moved beyond screen            position.X = 800.0        End If        If velocity.Y > 0.0 And position.Y >= 600.0 Then            ''if moving down and moved beyond screen            position.Y = -64.0        End If        If velocity.Y < 0.0 And position.Y <= -64.0 Then            ''if moving up and moved beyond screen            position.Y = 600.0        End If    End Sub  


That''s the draw() and update() routines for my "asteroid". I have the exact same code in the Direct3D version using the Sprite class and textures instead of DirectDraw surfaces and the movement is always very smooth, just the DirectDraw version has a slighy noticable jerk to it''s movements at certain angles. I was attributing it to the Sprite''s draw function supporting Single variable types as opposed to DirectDraw''s integer format. I''m just going to go with D3D because that''s what''s working... but I''m curious as to how it could be done in DirectDraw.
I don''t know... that *should* work, but then again, I''m no VB expert...
If you have the time, you can download the file (it's like 300k) and checkout the problem I'm refering to. This is the DirectDraw version.

At the menu, the only keys that do anything are 'S' and 'Q'. In the "game" you can hit 'Esc' to return to the menu. (I was just testing out the game framework.) You can't actually do anything in this version. But you'll notice that when the asteroids are at certain angles, they appear jumpy. I don't think it has anything to do with VB.NET. I'd like to see it run faster than my monitor refresh to see if that's causing a problem, but I can't get it to ignore the V-Sync. Maybe I'll have to try rewriting it in windowed mode as a test.


Btw, the .exe would require the .NET framework and DirectX 9.

[edited by - FieroAddict on May 8, 2003 1:19:21 PM]
Looks like integer precision to me. At shallow angles you see the jump from one coordinate to the next.

Edit:
There's nothing you can do about this in DirectDraw. It doesn't matter if you maintain the coordinates in floating point or not. The precision is lost as soon as the coordinates hit the API.

[edited by - Donavon Keithley on May 8, 2003 2:03:56 PM]
Donavon KeithleyNo, Inky Death Vole!
I agree it''s the integer precision. But, even in D3D, technically aren''t all pixels integers? You can''t have a fraction of a pixel can you? Seems I''ve played plenty of smooth games that were done in DirectDraw.
But vertices are not integral. With non-point filtering, the appearance of a sprite-like object will look different at (0,0) versus (0.25, 0) versus (0.5, 0), etc.

Asteroids is really a worst case scenario in this respect, because you have slow moving, non-animating objects that might jump a pixel as infrequently as every second and they''re drawn against a black background which makes it even easier to see the effect. If you had rotating asteroids you probably wouldn''t notice this.
Donavon KeithleyNo, Inky Death Vole!

This topic is closed to new replies.

Advertisement