OpenGL3 SFML 2.0rc FPS
我试图为我的项目制作第一人称射击风格的相机。 如果我向前或向后移动,向左或向右扫动,或向对角线移动,一切看起来都很顺利......问题是,当我在移动时用鼠标环顾四周,动作变得非常紧张。 当我在同一时间用鼠标扫射和转动时,这是最突出的。
我确信我的问题与此类似:http://en.sfml-dev.org/forums/index.php?topic=4833.msg31550#msg31550,但是我使用的是Gentoo Linux,而不是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);
}
事件发生后,我正在改变我的_view_matrix像这样:
_view_matrix = glm::lookAt( _position, _position+_direction, _up );
然后,我重新计算我的_modelview_matrix和_modelviewprojection_matrix:
_modelview_matrix = _view_matrix * _model_matrix;
_modelviewprojection_matrix = _projection_matrix * _modelview_matrix;
之后,我最终将矩阵发送给我的着色器并绘制场景。
对于任何关于OpenGL3,SFML 2.0和/或FPS风格的相机处理的任何智慧/建议,我都乐于接受,请让我知道它是否有助于包含更多代码(如果您认为问题不在事件处理,例如)。 先谢谢您的帮助!
编辑:我仍然没有解决这个问题,仅供参考它看起来不像摇摆运动期间的帧率下降......
如果我是你,我会隐藏鼠标使用这个教程,然后只有当它移动到屏幕边缘移动鼠标移动到相反的一面,所以它可以继续在那个方向不受阻碍。 可能不是最好的解决方案,但我很确定它会解决您的问题。
......另一个想法是做一些记忆和估算他们在做什么,而不是使用位置数据本身,而只是使用位置数据来指导计算(即用物理来控制它而不是原始数据)。
只是我的想法,希望他们帮助^^
链接地址: http://www.djcxy.com/p/38487.html