1、在QOpenGLWidget 第五篇(相机空间)中我们实现了一个OpenGLMVP投影转换类以及OpenGLCamera相机类,在这里我们用另一个已有的QMatrix类来替代这两个投影变换以及相机空间类。
在QMatrix矩阵类中,已经存在接口perspective来设置透视投影和otho正射投影。而且还存在接口lookAt这个类来设置观察方向。
有了这三个接口,那我们就可以完全去掉投影转换以及相机空间。
改动地方:
1、在OpenGLWidget头文件中将 OpenGLCamera *m_pCamera; 替换为QMatrix4x4 m_mvpMatrix;
2、将OpenGLWidget源文件中第47行到第54行替换为 m_shaderProgram->setUniformValue("gWorld", m_mvpMatrix);
3、将OpenGLWidget类中的initOpenGLCamera方法删掉;
4、修改鼠标滚轮事件:
void OpenGLWidget::wheelEvent(QWheelEvent *ev)
{
double val = ev->delta() * 1.0 / 40;
m_mvpMatrix.translate(0, 0, val * 0.1);
repaint(); QOpenGLWidget::wheelEvent(ev);
}
5、修改鼠标平移事件:
void OpenGLWidget::mouseMoveEvent(QMouseEvent *ev)
{
if(m_mouseStatus &= kMouseMove)
{
QPoint pt = ev->pos();
double w = width(), h = height();
double x = (pt.x() - m_lastPt.x()) / w;
double y = (m_lastPt.y() - pt.y()) / h;
m_mvpMatrix.translate(x, y, 0);
m_lastPt = pt; repaint();
}
QOpenGLWidget::mouseMoveEvent(ev);
}
void OpenGLWidget::mousePressEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::MiddleButton)
{
m_mouseStatus |= kMouseMove;
m_lastPt = ev->pos();
}
QOpenGLWidget::mousePressEvent(ev);
}
void OpenGLWidget::mouseReleaseEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::MiddleButton)
m_mouseStatus ^= kMouseMove;
QOpenGLWidget::mouseReleaseEvent(ev);
}
6、修改键盘控制事件:
void OpenGLWidget::keyPressEvent(QKeyEvent *ev)
{
QVector3D trans;
switch(ev->key())
{
case Qt::Key_Up: trans = QVector3D(0, 1, 0); break;
case Qt::Key_Down: trans = QVector3D(0, -1, 0); break;
case Qt::Key_Left: trans = QVector3D(-1, 0, 0); break;
case Qt::Key_Right: trans = QVector3D(1, 0, 0); break;
}
repaint();
QOpenGLWidget::keyPressEvent(ev);
}
7、最后在头文件中添加鼠标状态枚举并且添加成员变量MouseStatus m_mouseStatus = kMouseNone;
鼠标状态枚举:
enum MouseStatusFlag
{
kMouseNone = 0,
kMouseMove = 1,
kMouseScale = 2
};
Q_DECLARE_FLAGS(MouseStatus, MouseStatusFlag)
成员变量:
QPoint m_lastPt;
QMatrix4x4 m_mvpMatrix;
QOpenGLBuffer m_vbo, m_ebo;
QOpenGLVertexArrayObject m_vao;
QOpenGLShaderProgram *m_shaderProgram;
MouseStatus m_mouseStatus = kMouseNone;
最终运行效果如下:
如果没有运行出来可以下载源码:源码下载地址