# DirectX sprite movement seems 'glitchy'

This topic is 2143 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I've got a sprite that moves across the screen, slowly. I've noticed as it moves, there appear to be 'imperfections', by that I mean it looks like it changes size by about single pixel in width as it moves along, then changing back, then doing it again, etc.

I can paste code if needed, but I'm wondering if there may simply be some 'fundamental' aspect of drawing sprites in DirectX that I may have missed. Edited by Interminable

##### Share on other sites
Nope, you haven't missed anything. Thankfully, sprites do move very smoothly

I am currently writing a game with sprites alone and initially had poor movement. It was jumpy and ugly, and not smooth. But, it turned out it was the way I was calculating movement speed against framerate and I was using INT for positioning (which sounds logical as I was working in screenspace).

How did I fix it?

• Multiply the sprites movement speed against the time since last frame
• Position the sprites using float instead of int

Not having seen any of your code I would check these two things. I would love to know how you go (and happy to help where I can)

##### Share on other sites

Nope, you haven't missed anything. Thankfully, sprites do move very smoothly

I am currently writing a game with sprites alone and initially had poor movement. It was jumpy and ugly, and not smooth. But, it turned out it was the way I was calculating movement speed against framerate and I was using INT for positioning (which sounds logical as I was working in screenspace).

How did I fix it?

• Multiply the sprites movement speed against the time since last frame
• Position the sprites using float instead of int

Not having seen any of your code I would check these two things. I would love to know how you go (and happy to help where I can)

Here's what I was using to test it:

 void Object::Update() { coordinates.x += (20 * frameRenderTime); } 

coordinates is an instance of D3DXVECTOR3. Update() is called from another Update() function in my main Engine class, whose Update() function is called from main, inside the message loop:

 try { GetSystemTime(&systemTime); milliseconds = systemTime.wMilliseconds; if(milliseconds != prevMilliseconds && milliseconds%10 == 0) { if(milliseconds<prevMilliseconds) { prevMilliseconds -= 1000; // This will update roughly once every second. } frameRenderTime = milliseconds - prevMilliseconds; frameRenderTime /= 1000; prevMilliseconds = milliseconds; mainWindow.enginePointer()->Update(); } mainWindow.enginePointer()->rendererPointer()->Render(); } catch(std::exception e) { e.what(); return 1; }  Edited by Interminable

##### Share on other sites

This might help the issue.

http://msdn.microsof...0(v=vs.85).aspx

What the article describes sounds like it could be related to the issue I'm having.

The problem is, I'm not drawing a 2D texture to a surface. It's a standalone sprite. I'm unsure how I can deal with this.

##### Share on other sites

[quote name='JWBaker' timestamp='1342195376' post='4958828']
This might help the issue.

http://msdn.microsof...0(v=vs.85).aspx

What the article describes sounds like it could be related to the issue I'm having.

The problem is, I'm not drawing a 2D texture to a surface. It's a standalone sprite. I'm unsure how I can deal with this.
[/quote]

Do you mean you are using the Sprite class?

What you need to do is shift your Projection Matrix to account for the issue. This is how i setup mine and it seems to work. I'm not a DX master by any means but give it a shot and see if it helps. My Coordinate system has 0,0 at the center of the screen and +Y is up.

Device.SetTransform(TransformState.Projection, Matrix.Translation(-0.5f, 0.5f, 0.0f) * Matrix.OrthoLH(_form.ClientSize.Width, _form.ClientSize.Height, 0, 1));

##### Share on other sites

[quote name='Interminable' timestamp='1342209934' post='4958898']
[quote name='JWBaker' timestamp='1342195376' post='4958828']
This might help the issue.

http://msdn.microsof...0(v=vs.85).aspx

What the article describes sounds like it could be related to the issue I'm having.

The problem is, I'm not drawing a 2D texture to a surface. It's a standalone sprite. I'm unsure how I can deal with this.
[/quote]

Do you mean you are using the Sprite class?

What you need to do is shift your Projection Matrix to account for the issue. This is how i setup mine and it seems to work. I'm not a DX master by any means but give it a shot and see if it helps. My Coordinate system has 0,0 at the center of the screen and +Y is up.

Device.SetTransform(TransformState.Projection, Matrix.Translation(-0.5f, 0.5f, 0.0f) * Matrix.OrthoLH(_form.ClientSize.Width, _form.ClientSize.Height, 0, 1));
[/quote]

I was just altering the coordinates I was drawing it at with Id3DDevice::Draw(). ><

But I recall some of this transformation stuff now, I have a feeling I made a thread on here a while back which involved those but was to do with rotations...

Anyway, in trying to look at how you're doing that particular line, I am unsure how you're doing 'TransformState.Projection'. It doesn't seem to be possible with D3DTRANSFORMSTATETYPE. And that's the required first argument for iD3DXDevice::SetTransform().

In addition I assume there's some specific function for filling the D3DTRANSFORMSTATETYPE struct, but I can't seem to find it. ><

I have altered my code to how I was using SetTransform() in the past. First I have a PrepareTransform() function:

 void Renderer::PrepareTransform(int input) { transformStateType->Projection; d3dXSprite->SetTransform( D3DXMatrixTransformation2D(&d3dMatrix, NULL, 0.0, &D3DXVECTOR2(1.0,1.0), &D3DXVECTOR2(texturesToRender[input].objectPointer->originPointer()->x,texturesToRender[input].objectPointer->originPointer()->y), 0.0f, &D3DXVECTOR2(texturesToRender[input].objectPointer->coordinatesPointer()->x,texturesToRender[input].objectPointer->coordinatesPointer()->y)); d3dXSprite->SetTransform(&d3dMatrix); } 

And I draw after that function is called:

 if(FAILED(hResult = d3dXSprite->Draw(*texturesToRender.objectPointer->texturePointer()->texturePointer(), NULL, NULL, NULL, 0xffffffff))) { 

Unfortunately the issue still exists, but I would assume this is because I'm not dealing with this projection matrix stuff you're mentioning. Edited by Interminable

##### Share on other sites
I still think it is to do with your timer. GetSystemTime() seems to be only accurate to the millisecond.

If you have a basic scene you might be rendering faster than 1000 fps, so your scene will be choppy as the timer wont be acurate enough.

On my 3 year old video card my application (that also uses sprites) is rendering at 8000 FPS. This is why I had the same problems that your are experiencing. I had to re-think my timer.

Give my timer a try

 #pragma once class Timer { public: Timer() { liCurrent.QuadPart=0; liPrevious.QuadPart=0; } ~Timer() { } long double TimeSinceLastFrame() { QueryPerformanceFrequency(&liPerfFreq); QueryPerformanceCounter(&liCurrent); ddFrameTime=(liCurrent.QuadPart-liPrevious.QuadPart)/long double(liPerfFreq.QuadPart)*1000; liPrevious.QuadPart=liCurrent.QuadPart; return ddFrameTime; } private: LARGE_INTEGER liCurrent; LARGE_INTEGER liPrevious; LARGE_INTEGER liPerfFreq; LARGE_INTEGER liStart; long double ddFrameTime; }; TimeSinceLastFrame() will return exactly that (but using the performance counters)

I would love to know how you go Edited by lonewolff

##### Share on other sites

I still think it is to do with your timer. GetSystemTime() seems to be only accurate to the millisecond.

If you have a basic scene you might be rendering faster than 1000 fps, so your scene will be choppy as the timer wont be acurate enough.

On my 3 year old video card my application (that also uses sprites) is rendering at 8000 FPS. This is why I had the same problems that your are experiencing. I had to re-think my timer.

Give my timer a try

 #pragma once class Timer { public: Timer() { liCurrent.QuadPart=0; liPrevious.QuadPart=0; } ~Timer() { } long double TimeSinceLastFrame() { QueryPerformanceFrequency(&liPerfFreq); QueryPerformanceCounter(&liCurrent); ddFrameTime=(liCurrent.QuadPart-liPrevious.QuadPart)/long double(liPerfFreq.QuadPart)*1000; liPrevious.QuadPart=liCurrent.QuadPart; return ddFrameTime; } private: LARGE_INTEGER liCurrent; LARGE_INTEGER liPrevious; LARGE_INTEGER liPerfFreq; LARGE_INTEGER liStart; long double ddFrameTime; }; TimeSinceLastFrame() will return exactly that (but using the performance counters)

I would love to know how you go

I'll give it a try...but I'm also updating how far they should move using the time it takes to render the last frame. They appear to move smoothly already, just with minute changes in size as they go. Anyway, I'll EDIT this post with how I get on (or reply in a new post if there have been further responses).

EDIT: TimeSinceLastFrame()'s first return value is insanely high (eg 9029811) and screws up anything that relies on it for moving etc at the very beginning of the program. It eventually settles down to values of hundreds.

EDIT2: It appears to do this regardless of when the first call to it was, so I call it a few times needlessly at the beginning of my program to make it settle down a little before I start actually needing to use it.

Unfortunately the issue I am experiencing with the minute changes in size remains. Edited by Interminable

##### Share on other sites
I'll give it a try...but I'm also updating how far they should move using the time it takes to render the last frame.

No probs, but all you need to do is multiply your movement speed against TimeSinceLastFrame() Edited by lonewolff

• 36
• 12
• 10
• 10
• 9
• ### Forum Statistics

• Total Topics
631360
• Total Posts
2999546
×