replace the orbital cam by a free flying cam

This commit is contained in:
ccolin 2021-01-04 17:37:49 +01:00
parent 81108c1b0f
commit 03da9c5cf9
2 changed files with 78 additions and 18 deletions

View File

@ -24,13 +24,21 @@ OpenGLWidget *OpenGLWidget::instance = nullptr;
OpenGLWidget::OpenGLWidget(QWidget *parent) OpenGLWidget::OpenGLWidget(QWidget *parent)
:QOpenGLWidget(parent) { :QOpenGLWidget(parent),
move_timer(this) {
OpenGLWidget::instance = this; OpenGLWidget::instance = this;
QSurfaceFormat format; QSurfaceFormat format;
format.setProfile(QSurfaceFormat::CoreProfile); format.setProfile(QSurfaceFormat::CoreProfile);
format.setDepthBufferSize(24); format.setDepthBufferSize(24);
format.setSamples(4); format.setSamples(4);
setFormat(format); setFormat(format);
setFocusPolicy(Qt::StrongFocus);
trans.translate(0, -10, -10);
rot.rotate(30, QVector3D(1, 0, 0));
rot_start = rot;
move_timer.setTimerType(Qt::PreciseTimer);
connect(&move_timer, &QTimer::timeout, this, &OpenGLWidget::move);
move_timer.start(16);
} }
@ -179,9 +187,7 @@ void OpenGLWidget::paintGL() {
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 trans; QMatrix4x4 view = rot * trans;
trans.translate(0, 0, -cam_dist);
QMatrix4x4 view = trans * rot;
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
@ -230,18 +236,62 @@ void OpenGLWidget::mouseReleaseEvent(QMouseEvent *e) {
void OpenGLWidget::mouseMoveEvent(QMouseEvent *e) { void OpenGLWidget::mouseMoveEvent(QMouseEvent *e) {
if (e->buttons() & Qt::LeftButton) { if (!(e->buttons() & Qt::LeftButton)) return;
QPoint delta = e->pos() - mouse_pos; QPoint delta = e->pos() - mouse_pos;
rot = rot_start; rot = rot_start;
rot.rotate(delta.x() / 5., 0, 1, 0); rot.rotate(delta.x() / 5., 0, 1, 0);
rot.rotate(delta.y() / 5., QVector3D(1, 0, 0) * rot); rot.rotate(delta.y() / 5., QVector3D(1, 0, 0) * rot);
update(); update();
} }
bool OpenGLWidget::keyEvent(QKeyEvent *e, bool press) {
if (e->isAutoRepeat()) return false;
/* would do wasd if qt had proper support for layout-independent
input, but it doesnt :< */
switch (e->key()) {
case Qt::Key_Up:
move_forward = press;
break;
case Qt::Key_Down:
move_back = press;
break;
case Qt::Key_Left:
move_left = press;
break;
case Qt::Key_Right:
move_right = press;
break;
default:
return false;
}
update();
return true;
} }
void OpenGLWidget::wheelEvent(QWheelEvent *e) { void OpenGLWidget::keyPressEvent(QKeyEvent *e) {
cam_dist -= e->angleDelta().y() / 1000. * cam_dist; if (!keyEvent(e, true)) QOpenGLWidget::keyPressEvent(e);
}
void OpenGLWidget::keyReleaseEvent(QKeyEvent *e) {
if (!keyEvent(e, false)) QOpenGLWidget::keyReleaseEvent(e);
}
void OpenGLWidget::focusOutEvent(QFocusEvent *e) {
Q_UNUSED(e);
move_forward = move_back = move_left = move_right = false;
}
void OpenGLWidget::move() {
QMatrix4x4 rotation = rot.inverted();
if (move_forward) trans.translate(-(rotation * QVector3D(0, 0, -1)));
if (move_back) trans.translate(-(rotation * QVector3D(0, 0, 1)));
if (move_left) trans.translate(-(rotation * QVector3D(-1, 0, 0)));
if (move_right) trans.translate(-(rotation * QVector3D(1, 0, 0)));
update(); update();
} }
@ -261,9 +311,7 @@ QOpenGLShaderProgram *OpenGLWidget::getLineProgram() {
bool OpenGLWidget::project(const QVector3D &p, QPoint &point) const { bool OpenGLWidget::project(const QVector3D &p, QPoint &point) const {
QMatrix4x4 trans; QMatrix4x4 view = rot * trans;
trans.translate(0, 0, -cam_dist);
QMatrix4x4 view = trans * rot;
QVector3D projected = proj * view * p; QVector3D projected = proj * view * p;
if (projected.x() < -1 || projected.x() > 1 if (projected.x() < -1 || projected.x() > 1
|| projected.y() < -1 || projected.y() > 1 || projected.y() < -1 || projected.y() > 1

View File

@ -9,6 +9,7 @@
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject> #include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QTimer>
#define FOV 70 #define FOV 70
@ -26,8 +27,13 @@ class OpenGLWidget : public QOpenGLWidget, public QOpenGLExtraFunctions {
Q_OBJECT Q_OBJECT
QMatrix4x4 rot, rot_start, proj; QMatrix4x4 rot, rot_start, proj;
GLfloat cam_dist = 1; QMatrix4x4 trans;
QPoint mouse_pos; QPoint mouse_pos;
QTimer move_timer;
bool move_forward = false;
bool move_back = false;
bool move_left = false;
bool move_right = false;
QOpenGLShaderProgram main_program; QOpenGLShaderProgram main_program;
QOpenGLShaderProgram skybox_program; QOpenGLShaderProgram skybox_program;
@ -39,14 +45,20 @@ class OpenGLWidget : public QOpenGLWidget, public QOpenGLExtraFunctions {
void loadSkybox(); void loadSkybox();
void loadGround(); void loadGround();
bool keyEvent(QKeyEvent *e, bool press);
const Painter *painter = nullptr; const Painter *painter = nullptr;
private slots:
void move();
protected: protected:
virtual void mousePressEvent(QMouseEvent *e); virtual void mousePressEvent(QMouseEvent *e);
virtual void mouseReleaseEvent(QMouseEvent *e); virtual void mouseReleaseEvent(QMouseEvent *e);
virtual void mouseMoveEvent(QMouseEvent *e); virtual void mouseMoveEvent(QMouseEvent *e);
virtual void wheelEvent(QWheelEvent *e); virtual void keyPressEvent(QKeyEvent *e);
virtual void keyReleaseEvent(QKeyEvent *e);
virtual void focusOutEvent(QFocusEvent *e);
public: public:
static OpenGLWidget *instance; static OpenGLWidget *instance;