I created a simple, frame-independent, variable time step, linear movement in Direct3D9 using ID3DXSprite . Most users cannot notice this, but on some (including my) computers this happens often, and sometimes it stutters a lot.
Attenuation occurs when VSync on and off.
I realized that this is happening in the OpenGL renderer.
Not a floating point problem.
It seems that the problem exists only in the AERO Transparent Glass window mode (excellent or at least much less noticeable in full-screen, borderless full screen or with the aeron off), which is even worse when the window has lost focus.
/ li>
EDIT:
The delta time of the frame leaves no boundaries of 16 .. 17 ms even when stuttering.
It looks like my delta time error log has been tapped. I fixed it now.
- Usually, with the VSync frame turned on, 17 ms is displayed, but sometimes (perhaps at startup) it jumps to 25-30 ms.
(I leave the log only once at application exit, and not at runtime, rendering, so it does not affect performance)
device->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 255, 255, 255), 0, 0); device->BeginScene(); sprite->Begin(D3DXSPRITE_ALPHABLEND); QueryPerformanceCounter(&counter); float time = counter.QuadPart / (float) frequency.QuadPart; float deltaTime = time - currentTime; currentTime = time; position.x += velocity * deltaTime; if (position.x > 640) velocity = -250; else if (position.x < 0) velocity = 250; position.x = (int) position.x; sprite->Draw(texture, 0, 0, &position, D3DCOLOR_ARGB(255, 255, 255, 255)); sprite->End(); device->EndScene(); device->Present(0, 0, 0, 0);
Timer fixed thanks to Eduard Wirch and Ben Voigt (although it does not fix the initial problem)
float time() { static LARGE_INTEGER start = {0}; static LARGE_INTEGER frequency; if (start.QuadPart == 0) { QueryPerformanceFrequency(&frequency); QueryPerformanceCounter(&start); } LARGE_INTEGER counter; QueryPerformanceCounter(&counter); return (float) ((counter.QuadPart - start.QuadPart) / (double) frequency.QuadPart); }
EDIT # 2:
So far I have tried three update methods:
1) Variable time step
x += velocity * deltaTime;
2) Fixed time step
x += 4;
3) Fixed time step + Interpolation
accumulator += deltaTime; float updateTime = 0.001f; while (accumulator > updateTime) { previousX = x; x += velocity * updateTime; accumulator -= updateTime; } float alpha = accumulator / updateTime; float interpolatedX = x * alpha + previousX * (1 - alpha);
All methods work almost the same way, a fixed time step looks better, but it does not completely depend on the frame rate and does not solve the problem completely (still rarely (stutters) rarely).
For now, disabling AERO Transparent Glass or switching to full-screen mode is only a significant positive change.
I use NVIDIA latest GeForce 332.21 Driver and Windows 7 x64 Ultimate drivers.