FPS摄像机自行旋转.QT 4.8 OpenGL C
FPS camera rotating by itself. QT 4.8 + OpenGL + C++
我正在尝试移植从sfml到qt上编写的高度图可视化程序,因此可以在窗口上显示并由GUI元素控制。
问题是,当我启动应用程序时,相机开始非常快地在其中心周围滚动(实际上,它看起来像是地形网绕着相机飞行,就像太阳周围的地球一样,没有任何动作我的身边(例如移动鼠标,按按钮)。
当我按下W,A,S,D时,相机应向前移动,向后,向左,右,并在移动鼠标时环顾四周(只是典型的FPS摄像机行为)。
我认为这个问题在程序的主要循环中,因为它不是QT中的标准while(true){ //do something// }
方法,而且有点令人困惑。
这是我的代码:
oglwidget class (在这里我在绘画。 我绝对确定地形和相机课程正确,因为自SFML项目以来我没有更改代码(除了使用Qimage而不是SF :: Image,但它也可以正确使用) *相机主算法: * 帮助我解决此问题。class OGLWidget :
public QGLWidget
{
Q_OBJECT
public:
OGLWidget(QWidget *parent = 0);
~OGLWidget(void);
public:
void paintGL();
void initializeGL();
void resizeGL();
public:
void updateCamera();
public slots:
void mainLoop();
protected:
void keyPressEvent(QKeyEvent *e);
void keyReleaseEvent(QKeyEvent *e);
private:
Terrain _terrain;
Camera _camera;
private:
int _keyPressed;
QTimer _timer;
QElapsedTimer _elapsedTimer;
float _simulationTime;
float _fps;
};
OGLWidget::OGLWidget(QWidget *parent) : QGLWidget(parent)
{
_terrain.loadHeightMap("normalHeightMap256_2.png");
_camera.setScreenDimension(this->width(), this->height());
//setting vertical sync
QGLFormat frmt;
frmt.setSwapInterval(1);
setFormat(frmt);
setMouseTracking(true);
setFocus();
_simulationTime = 0;
_fps = 1.f / 60.f;
connect(&_timer, SIGNAL(timeout()), this, SLOT(mainLoop()));
_timer.start();
_elapsedTimer.start();
}
OGLWidget::~OGLWidget(void)
{
}
void OGLWidget::mainLoop()
{
_simulationTime += _elapsedTimer.elapsed();
_elapsedTimer.restart();
while(_simulationTime > _fps)
{
_simulationTime -= _fps;
updateCamera();
}
updateGL();
}
void OGLWidget::updateCamera()
{
QPoint p = mapFromGlobal(QCursor::pos());
_camera.computeMatrices(p.x(), p.y(), _fps, _keyPressed);
glm::mat4 ViewMatrix = _camera.getViewMatrix();
glm::mat4 ProjectionMatrix = _camera.getProjectionMatrix();
glm::mat4 ModelMatrix = glm::mat4(1.0);
_terrain.setMvp(ProjectionMatrix * ViewMatrix * ModelMatrix);
QPoint center = mapToGlobal(QPoint(this->width() / 2, this->height() / 2));
QCursor::setPos(center);
}
void OGLWidget::initializeGL()
{
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
return;
}
glViewport(0, 0, this->width(), this->height());
_terrain.init();
}
void OGLWidget::paintGL()
{
_terrain.draw();
}
void OGLWidget::resizeGL()
{
glViewport(0, 0, this->width(), this->height());
}
void OGLWidget::keyPressEvent(QKeyEvent *e)
{
switch(e->key())
{
case Qt::Key::Key_Escape:
exit(0);
break;
case Qt::Key::Key_W:
_keyPressed = Key::KEY_PRESSED_UP;
break;
case Qt::Key::Key_S:
_keyPressed = Key::KEY_PRESSED_DOWN;
break;
case Qt::Key::Key_A:
_keyPressed = Key::KEY_PRESSED_LEFT;
break;
case Qt::Key::Key_D:
_keyPressed = Key::KEY_PRESSED_RIGHT;
break;
}
}
void OGLWidget::keyReleaseEvent(QKeyEvent *e)
{
if(e->key() == Qt::Key::Key_W ||
e->key() == Qt::Key::Key_S ||
e->key() == Qt::Key::Key_A ||
e->key() == Qt::Key::Key_D)
_keyPressed = KEY_RELEASED;
}
void Camera::computeMatrices(int mouseXpos, int mouseYpos, float deltaTime, int keyPressed)
{
_horizontalAngle += _mouseSpeed * deltaTime * float(_screenWidth / 2 - mouseXpos);
_verticalAngle += _mouseSpeed * deltaTime * float(_screenHeight / 2 - mouseYpos);
_direction = glm::vec3
(
cos(_verticalAngle) * sin(_horizontalAngle),
sin(_verticalAngle),
cos(_verticalAngle) * cos(_horizontalAngle)
);
glm::vec3 right = glm::vec3
(
sin(_horizontalAngle - 3.14f/2.0f),
0,
cos(_horizontalAngle - 3.14f/2.0f)
);
glm::vec3 up = glm::cross( right, _direction );
switch(keyPressed)
{
case Key::KEY_PRESSED_UP:
_position += _direction * deltaTime * _speed;
break;
case Key::KEY_PRESSED_DOWN:
_position -= _direction * deltaTime * _speed;
break;
case Key::KEY_PRESSED_LEFT:
_position -= right * deltaTime * _speed;
break;
case Key::KEY_PRESSED_RIGHT:
_position += right * deltaTime * _speed;
break;
case Key::KEY_RELEASED:
break;
}
_projectionMatrix = glm::perspective(_initialFoV, 4.0f / 3.0f, 0.1f, 1000.0f);
_viewMatrix = glm::lookAt
(
_position, // Camera is here
_position+_direction, // and looks here : at the same position, plus "direction"
up // Head is up (set to 0,-1,0 to look upside-down)
);
}
好吧,我想出了旋转相机的问题。原因是我在Camera::computeMatrices
中硬编码了纵横比,并使用了与它不匹配的小部件的分辨率:
_projectionMatrix = glm::perspective
(
_initialFoV,
4.0f / 3.0f, //here it is
0.1f,
1000.0f
);
我更改了(float)_screenWidth / (float)_screenHeight
上的4.0f / 3.0f
,但也没有帮助。
因此,我只是将小部件的分辨率更改为800 x 600
,它有所帮助。
新问题是它仅在4/3尺寸上工作(例如800x600
,1024x768
)。
纠正
的最佳方法_direction = glm::vec3
(
cos(_verticalAngle) * sin(_horizontalAngle),
sin(_verticalAngle),
cos(_verticalAngle) * cos(_horizontalAngle)
);
_direction.normalize();
...
- Qt OpenGL 渲染到纹理性能问题
- 透视视图的任何解决方案 openGL qt.
- QT Opengl 总是给黑屏
- 不再使用 QT OpenGL?
- Qt,openGL,小部件和屏幕外渲染
- 如何使用Qt多媒体和C++将.mp4视频从OpenGL纹理中保存出来
- 在Emscripten和Qt之间共享OpenGL代码
- QT在CentOS 7的openGL不起作用
- 我可以使用QT的OpenGL功能而没有任何小部件
- OpenGL QT 4.8渲染到纹理浮点
- QT 找不到要使用的 OpenGL API
- 异步渲染到 Qt OpenGL 窗口
- 如何使用Qt的原生OpenGL获得总GPU内存?
- OpenGL代码在GLFW上工作,但在QT OpenGL上不起作用
- 当QT与无角和-NO-OPENGL编译时会发生什么
- QT QML 中的 OpenGL,无法更新屏幕上的图像
- 使用 qt 和 opengl、定时精度和垂直同步问题、c++ 显示图像
- Qt OpenGL帧缓冲在一台PC上创建,但在另一台PC上失败
- 在Linux Mint上编译Qt-OpenGL功能测试失败
- 为 C++ + OpenGL + QT 分配阵列