title: OpenGL3 SFML 2.0rc FPS-style camera - shaky mouse movement
body: <p>I'm trying to make a first person shooter style camera for my project. Everything looks smooth if I'm moving forward or back, strafing left or right, or going diagonal... The problem is when I look around with the mouse while moving, the movements get really jittery. It is most prominent when I am strafing and turning with the mouse at the same time.</p>
  
  <p>I'm convinced my problem is similar to this: <a href="http://en.sfml-dev.org/forums/index.php?topic=4833.msg31550#msg31550" rel="nofollow">http://en.sfml-dev.org/forums/index.php?topic=4833.msg31550#msg31550</a> , however I am using Gentoo Linux, not OSX.</p>
  
  <p>It's quite likely that it's not SFML's fault though, and that I did something wrong, so I would like to get some feedback on my event handling code to see if there's a better way to get smooth mouse movements.</p>
  
  <p>In case you don't want to read through the link I posted, the short of what I think is happening is the mouse movement velocity is being lost every frame when I set the mouse's position back to the center of the screen, which causes a quick visible jerk on screen. This is my going theory as I've tried changing other stuff around for 3 days now and nothing I do makes it less jerky. So I would like to know if anyone has a better way of handling the mouse movements, or whether you think the problem lies elsewhere.</p>
  
  <p>An important note is I have enabled vsync which made a lot of other jitteriness and tearing go away, and I tried using a hard framerate limit like sf::Window::setFramerateLimit(60), but that didn't help at all.</p>
  
  <p>Here is the event handler (which uses the SFML 2.0 realtime interfaces instead of an event loop), you can probably ignore the part related to jumping:</p>
  
  <pre><code>void Test_World::handle_events(float&amp; time)
  {
      // camera stuff
      _mouse_x_pos = sf::Mouse::getPosition(*_window).x;
      _mouse_y_pos = sf::Mouse::getPosition(*_window).y;
  
      std::cout &lt;&lt; "mouse x: " &lt;&lt; _mouse_x_pos &lt;&lt; std::endl;
      std::cout &lt;&lt; "mouse y: " &lt;&lt; _mouse_y_pos &lt;&lt; std::endl;
  
      _horizontal_angle += time * _mouse_speed * float(_resolution_width/2 - _mouse_x_pos);
      _vertical_angle += time * _mouse_speed * float(_resolution_height/2 - _mouse_y_pos);
  
      // clamp rotation angle between 0 - 2*PI
      if (_horizontal_angle &gt; 3.14f*2) _horizontal_angle = 0;
      if (_horizontal_angle &lt; 0) _horizontal_angle = 3.14f*2;
  
      // clamp camera up/down values so we can't go upside down
      if (_vertical_angle &gt;= 3.14f/2.0f) _vertical_angle = 3.14f/2.0f;
      if (_vertical_angle &lt;= -3.14f/2.0f) _vertical_angle = -3.14f/2.0f;
  
      std::cout &lt;&lt; "horiz angle: " &lt;&lt; _horizontal_angle &lt;&lt; std::endl;
      std::cout &lt;&lt; "vert angle: " &lt;&lt; _vertical_angle &lt;&lt; std::endl;
  
      _direction = glm::vec3( cos(_vertical_angle) * sin(_horizontal_angle),
                              sin(_vertical_angle),
                              cos(_vertical_angle) * cos(_horizontal_angle) );
  
      _right = glm::vec3( sin(_horizontal_angle - 3.14f/2.0f),
                          0,
                          cos(_horizontal_angle - 3.14f/2.0f) );
  
      _up = glm::cross( _right, _direction );
  
      // keyboard: left, right, up, down
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) || sf::Keyboard::isKeyPressed(sf::Keyboard::A))
      {
          if (_jumping)
          {
              _position -= _right * time * _speed * ((_jump_speed/2) + 0.1f);
          }
          else
          {
              _position -= _right * time * _speed;
          }
      }
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right) || sf::Keyboard::isKeyPressed(sf::Keyboard::D))
      {
          if (_jumping)
          {
              _position += _right * time * _speed * ((_jump_speed/2) + 0.1f);
          }
          else
          {
              _position += _right * time * _speed;
          }
      }
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) || sf::Keyboard::isKeyPressed(sf::Keyboard::W))
      {
          glm::vec3 old_direction(_direction);
          _direction.y = 0;
  
          if (_jumping)
          {
              _position += _direction * time * _speed * ((_jump_speed/2) + 0.1f);
          }
          else
          {
              _position += _direction * time * _speed;
          }
  
          _direction = old_direction;
      }
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) || sf::Keyboard::isKeyPressed(sf::Keyboard::S))
      {
          glm::vec3 old_direction(_direction);
          _direction.y = 0;
  
          if (_jumping)
              _position -= _direction * time * _speed * ((_jump_speed/2) + 0.1f);
          else
              _position -= _direction * time * _speed;
  
          _direction = old_direction;
      }
  
      // keyboard: jump
      if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl))
      {
          // check if standing on something
          if (_standing)
          {
              _standing = false;
              _jumping = true;
          }
      }
  
      // apply gravity if off the ground
      if (_position.y &gt; _main_character_height &amp;&amp; !_jumping)
          _position.y -= time * _speed * _global_gravity;
  
      // if started jumping
      else if (_position.y &lt; _main_character_height + _jump_height - 3.0f &amp;&amp; _jumping)
      {
          if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl))
          {
              _position.y += time * _speed * _jump_speed;
          }
          else    // if stopped jumping
          {
              _position += _direction * time * (_speed/(_jump_hang_time*2));
              _jumping = false;
          }
      }
  
      // if near the highest part of the jump
      else if (_position.y &lt;= _main_character_height + _jump_height &amp;&amp; _jumping)
      {
          if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl))
          {
              _position.y += time * _speed * (_jump_speed/_jump_hang_time);
          }
          else    // if stopped jumping
          {
              _position += _direction * time * (_speed/(_jump_hang_time*2));
              _jumping = false;
          }
      }
  
      // if reached the highest part of the jump
      else if (_position.y &gt;= _main_character_height + _jump_height)
      {
          _position += _direction * time * (_speed/_jump_hang_time);
          _jumping = false;
      }
      else if (_position.y &lt;= _main_character_height)
      {
          _standing = true;
      }
  
      sf::Mouse::setPosition(_middle_of_window, *_window);
  }
  </code></pre>
  
  <p>After the events, I am changing my _view_matrix like this:</p>
  
  <pre><code>_view_matrix = glm::lookAt( _position, _position+_direction, _up );
  </code></pre>
  
  <p>Then, I recalculate my _modelview_matrix and _modelviewprojection_matrix:</p>
  
  <pre><code>_modelview_matrix = _view_matrix * _model_matrix;
  _modelviewprojection_matrix = _projection_matrix * _modelview_matrix;
  </code></pre>
  
  <p>After that I finally send the matrices to my shaders and draw the scene.</p>
  
  <p>I am open to any sage wisdom/advice with regards to OpenGL3, SFML 2.0, and/or FPS-style camera handling, and please let me know if it would help to include more code (if you think the problem isn't in the event handling, for example). Thanks in advance for the help!</p>
  
  <p><strong>Edit:</strong> I still haven't solved this problem, and FYI it doesn't look like the framerate is dropping at all during the shaky movements...</p>