therealkf therealkf - 2 months ago 17
C++ Question

Non instantaneous/jerky movement using SDL2 & OpenGL

I've been working on a little 3D engine trying to fix up the camera and make it less jerky. I've been using SDL for the input and while it works it's doing this thing where if I press and hold a button it will instantly move once then pause and then start moving properly making the movement feel unresponsive.

I recorded a GIF of it and while it may be slightly hard to see what's happening hopefully it'll give some idea:

gif



Moving forward and then right would be like:

w wwwwwwwwwwwwwwww a aaaaaaaaaaaaaaaaaaaaa

The important code is here but feel free to ask for more if necessary:

//Poll events
SDL_Event event;
while (m_EngineState != EngineState::EXIT)
{
m_last = m_current;
m_current = SDL_GetPerformanceCounter();
deltaTime = (double)((m_current - m_last) * 1000 / SDL_GetPerformanceFrequency());

while (SDL_PollEvent(&event))
{
switch (event.type) {
case SDL_QUIT:
m_EngineState = EngineState::EXIT;
break;

case SDL_MOUSEMOTION:
break;

case SDL_KEYDOWN:
m_Keys[event.key.keysym.sym] = true;
break;
case SDL_KEYUP:
m_Keys[event.key.keysym.sym] = false;
break;
}
ProcessEvents();
}

void Engine::ProcessEvents()
{
if (m_Keys[SDLK_w])
{
m_Camera->MoveForward(5.0f*(deltaTime*0.001));
}
if (m_Keys[SDLK_s])
{
m_Camera->MoveForward(-5.0f*(deltaTime*0.001));
}
if (m_Keys[SDLK_d])
{
m_Camera->MoveRight(5.0f*(deltaTime*0.001));
}
if (m_Keys[SDLK_a])
{
m_Camera->MoveRight(-5.0f*(deltaTime*0.001));
}
}

void Camera::MoveForward(float amount)
{
m_pos += m_forward * amount;
}

void Camera::MoveRight(float amount)
{
m_pos += glm::cross(m_forward, m_up) * amount;
}

Answer

Do not use SDL_PollEvent, it is subject to OS keyboard repeat rates. Which is great for typing, but not for camera/player controls. Use SDL_GetKeyState(NULL) in stead to query the current state of the key.

For example:

Uint8* keystate = SDL_GetKeyState(NULL);

if(keystate[SDLK_w])
{
  m_Camera->MoveForward(5.0f*(deltaTime*0.001));
}
if(keystate[SDLK_s])
{
  m_Camera->MoveForward(-5.0f*(deltaTime*0.001));
}
// etc
Comments