C++ OpenGL3 SFML 2.0rc FPS风格照相机-鼠标移动不稳

C++ OpenGL3 SFML 2.0rc FPS风格照相机-鼠标移动不稳,c++,sfml,opengl-3,C++,Sfml,Opengl 3,我正试图为我的项目制作一个第一人称射击风格的相机。如果我向前或向后移动,向左或向右扫射,或朝对角线方向移动,一切看起来都很顺利。。。问题是,当我在移动时用鼠标环顾四周时,动作会变得非常紧张。当我同时扫射和转动鼠标时,它最为突出 我确信我的问题与此类似:,但我使用的是GentooLinux,而不是OSX 很可能这不是SFML的错,而且我做错了什么,所以我想获得一些关于我的事件处理代码的反馈,看看是否有更好的方法来平滑鼠标移动 如果你不想阅读我发布的链接,我想出现的问题是,当我将鼠标位置设置回屏幕中

我正试图为我的项目制作一个第一人称射击风格的相机。如果我向前或向后移动,向左或向右扫射,或朝对角线方向移动,一切看起来都很顺利。。。问题是,当我在移动时用鼠标环顾四周时,动作会变得非常紧张。当我同时扫射和转动鼠标时,它最为突出

我确信我的问题与此类似:,但我使用的是GentooLinux,而不是OSX

很可能这不是SFML的错,而且我做错了什么,所以我想获得一些关于我的事件处理代码的反馈,看看是否有更好的方法来平滑鼠标移动

如果你不想阅读我发布的链接,我想出现的问题是,当我将鼠标位置设置回屏幕中心时,鼠标移动速度每一帧都会丢失,这会导致屏幕上快速可见的抖动。这是我的理论,因为我已经试着改变其他东西三天了,但我做什么都不能让它不那么急躁。所以我想知道是否有人有更好的方法来处理鼠标移动,或者你是否认为问题出在别处

一个重要的注意事项是,我启用了vsync,这消除了很多其他的抖动和撕裂,我尝试使用硬帧速率限制,如sf::Window::setFramerateLimit(60),但这一点都没有帮助

下面是事件处理程序(它使用SFML 2.0实时接口而不是事件循环),您可能可以忽略与跳转相关的部分:

void Test_World::handle_events(float& time)
{
    // camera stuff
    _mouse_x_pos = sf::Mouse::getPosition(*_window).x;
    _mouse_y_pos = sf::Mouse::getPosition(*_window).y;

    std::cout << "mouse x: " << _mouse_x_pos << std::endl;
    std::cout << "mouse y: " << _mouse_y_pos << 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 > 3.14f*2) _horizontal_angle = 0;
    if (_horizontal_angle < 0) _horizontal_angle = 3.14f*2;

    // clamp camera up/down values so we can't go upside down
    if (_vertical_angle >= 3.14f/2.0f) _vertical_angle = 3.14f/2.0f;
    if (_vertical_angle <= -3.14f/2.0f) _vertical_angle = -3.14f/2.0f;

    std::cout << "horiz angle: " << _horizontal_angle << std::endl;
    std::cout << "vert angle: " << _vertical_angle << 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 > _main_character_height && !_jumping)
        _position.y -= time * _speed * _global_gravity;

    // if started jumping
    else if (_position.y < _main_character_height + _jump_height - 3.0f && _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 <= _main_character_height + _jump_height && _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 >= _main_character_height + _jump_height)
    {
        _position += _direction * time * (_speed/_jump_hang_time);
        _jumping = false;
    }
    else if (_position.y <= _main_character_height)
    {
        _standing = true;
    }

    sf::Mouse::setPosition(_middle_of_window, *_window);
}
然后,我重新计算我的_modelview_矩阵和_modelviewprojection_矩阵:

_modelview_matrix = _view_matrix * _model_matrix;
_modelviewprojection_matrix = _projection_matrix * _modelview_matrix;
之后,我最终将矩阵发送到着色器并绘制场景

关于OpenGL3、SFML2.0和/或FPS风格的相机处理,我愿意听取任何睿智的意见/建议,请让我知道包含更多代码是否有帮助(例如,如果您认为问题不在事件处理中)。提前感谢您的帮助


编辑:我还没有解决这个问题,仅供参考,在不稳定的移动过程中,帧速率看起来一点也没有下降…

如果我是你,我会使用隐藏鼠标,然后仅在鼠标到达屏幕边缘时移动鼠标位置,将其移动到另一侧,以便它可以在该方向上不受阻碍地继续移动。也许不是最好的解决方案,但我很肯定它会解决你的问题

。。。另一个想法是对他们正在做的事情进行一些记忆和计算,而不是使用位置数据本身,而是简单地使用位置数据来指导计算(即使用物理来控制它而不是原始数据)


只是我的想法,希望能有所帮助^ ^

嘿,马修,谢谢你的指导。我已经改变了我的程序来隐藏鼠标,并且只在鼠标到达屏幕边缘时重置其位置。这确实使运动不那么摇晃,但当扫射和旋转同时进行时,仍然会发生摇晃。我真的很想用正确的方法(用正确的物理公式)来做这件事,但我不知道有什么好地方可以开始学习。有人能推荐一个好的网站或教科书来解释我需要为初学者学习的物理类型吗?我会在谷歌上查资料,直到我得到推荐。我会得到“3D游戏编程和计算机图形学数学,第三版”,除非有人对我有更好的想法。。。
_modelview_matrix = _view_matrix * _model_matrix;
_modelviewprojection_matrix = _projection_matrix * _modelview_matrix;