I'm in the process of learning how to use the DirectX 11 API and came upon the following problem:
Although my rendering function executes quite fast at around 150 fps (as one expects considering how little geometry is rendered), the mouse and keyboard input is massivly delayed. Sometimes the "game" reacts several seconds too late or doesn't react at all; looking around is a pain.
When I increase the framerate even further to, let's say, 400 (by reducing the rendering resolution/rendering less objects), the effect vanishes and the every keystroke is detected precisely.
My update() function (see code below) is called by the StepTimer class of the DirectX Tool Kit from the main message handling loop. I tried both fixed and variable timestep mode.
Main loop calling update() and render()
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
static DX::StepTimer stepTimer;
stepTimer.Tick([&]() { update(stepTimer); });
render();
}
The update() function:
void update(DX::StepTimer const &timer)
{
static Keyboard::KeyboardStateTracker keyboardTracker;
static Mouse::ButtonStateTracker mouseTracker;
Keyboard::State keyboardState = keyboard->GetState();
Mouse::State mouseState = mouse->GetState();
keyboardTracker.Update(keyboardState);
mouseTracker.Update(mouseState);
fps = timer.GetFramesPerSecond();
if (keyboardState.Escape) PostQuitMessage(0);
static float pitch = 0.0f;
static float yaw = 0.0f;
if (mouseState.positionMode == Mouse::MODE_RELATIVE)
{
pitch = std::max(std::min(pitch - float(mouseState.y) * 0.001f, XM_PI / 2.0f - 0.01f), -XM_PI / 2.0f + 0.01f);
yaw -= float(mouseState.x) * 0.001f;
if (yaw < -XM_PI) yaw += XM_PI * 2.0f;
if (yaw > XM_PI) yaw -= XM_PI * 2.0f;
}
if(mouseTracker.leftButton == Mouse::ButtonStateTracker::RELEASED) mouse->SetMode(mouseState.positionMode == Mouse::MODE_ABSOLUTE ? Mouse::MODE_RELATIVE : Mouse::MODE_ABSOLUTE);
Vector3 cameraDir(-sin(yaw) * cos(pitch), sin(pitch), cos(yaw) * cos(pitch));
Vector3 motionVec = { 0.0f, 0.0f, 0.0f };
float speed = 4.2f;
if (keyboardState.W || keyboardState.Up)
{
motionVec.x += cameraDir.x;
motionVec.z += cameraDir.z;
}
if (keyboardState.S || keyboardState.Down)
{
motionVec.x -= cameraDir.x;
motionVec.z -= cameraDir.z;
}
if (keyboardState.A || keyboardState.Left)
{
motionVec.x -= cameraDir.z;
motionVec.z += cameraDir.x;
}
if (keyboardState.D || keyboardState.Right)
{
motionVec.x += cameraDir.z;
motionVec.z -= cameraDir.x;
}
if (keyboardState.Space || keyboardState.PageUp)
{
motionVec.y += 1.0f;
}
if (keyboardState.LeftShift || keyboardState.PageDown)
{
motionVec.y -= 1.0f;
}
motionVec *= speed;
static Vector3 cameraPos = { 0.0f, 2.0f, 0.0f };
if (keyboardState.R)
{
cameraPos = { 0.0f, 2.0f, 0.0f };
pitch = 0.0f;
yaw = 0.0f;
}
cameraPos += motionVec * float(timer.GetElapsedSeconds());
matrixCamera = XMMatrixLookToLH(cameraPos.XMVECTOR(), cameraDir.XMVECTOR(), { 0.0f, 1.0f, 0.0f });
}
Is there any hint you can give me? Or might this even by a bug in the StepTimer class?
StepTimer
as a global or as a member of a global singleton class, not as a local static variable. See this blog post and the wiki for additional documentation forStepTimer
. BTW, you should do the same with your mouse & keyboard button tracker objects. \$\endgroup\$