【OpenGL学习笔记十】摄像机

目录

摄像机盯着原点看

摄像机始终向前看,并通过键盘实现相机的前后左右的移动

通过鼠标实现视角移动的效果

实现缩放的效果


根据之前的学习已经学习到,如果需要从不同的角度去观察空间中的物体,其实就是构造LookAt矩阵即观察矩阵。构造lookAt矩阵,给出几个坐标即可

void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up);

观察矩阵把所有世界坐标变换为相对于摄像机位置与方向的观察坐标。

定义一个摄像机需要四个向量

1.摄像机位置,世界空间中一个指向摄像机位置的向量

2.摄像机方向,摄像机位置减去目标位置得到的向量

3.右轴,摄像机空间x轴的正方向,根据向上量和摄像机方向向量算出的和这两个向量垂直的向量

4.上轴,根据x轴和z轴算出和这两个向量垂直的向量

其中右轴和上轴只要给出一个就能计算出另外一个

摄像机盯着原点看

cameraFront_ = QVector3D(0.0f, 0.0f, 0.0f);//center坐标设为原点

cameraPos_ = QVector3D(0.0f, 0.0f, 3.0f);
cameraFront_ = QVector3D(0.0f, 0.0f, 0.0f);//center坐标设为原点
cameraUp_ = QVector3D(0.0f, 1.0f, 0.0f);

/****************************************************************************/
QMatrix4x4 view;
view.lookAt(cameraPos_, cameraPos_ + cameraFront_ ,cameraUp_);

摄像机始终向前看,并通过键盘实现相机的前后左右的移动

cameraFront_ = QVector3D(0.0f, 0.0f, -1.0f);

cameraPos_ = QVector3D(0.0f, 0.0f, 3.0f);
cameraFront_ = QVector3D(0.0f, 0.0f, -1.0f);
cameraUp_ = QVector3D(0.0f, 1.0f, 0.0f);

/****************************************************************************/
QMatrix4x4 view;
view.lookAt(cameraPos_, cameraPos_ + cameraFront_ ,cameraUp_);


/****************************************************************************/
void glWidget::keyPressEvent(QKeyEvent * event)
{
    switch (event->key())
    {
        case Qt::Key_W:
        {
            cameraPos_ += 0.05 * cameraFront_;
            update();
        }
        break;

        case Qt::Key_S:
        {
            cameraPos_ -= 0.05 * cameraFront_;
            update();
        }
        break;

        case Qt::Key_A:
        {
            QVector3D cameraRight = QVector3D::crossProduct(cameraUp_, cameraFront_);
            cameraRight.normalize();
            cameraPos_ -= 0.05 * cameraRight;
            update();
        }
        break;

        case Qt::Key_D:
        {
            QVector3D cameraRight = QVector3D::crossProduct(cameraUp_, cameraFront_);
            cameraRight.normalize();
            cameraPos_ += 0.05 * cameraRight;
            update();
        }
        break;
        default:break;
    }
}

通过鼠标实现视角移动的效果

上面的代码实现的效果始终是往前看的,实际中摄像机还需要能够向上看,向下看,向左看,向右看,为了实现这个效果,改变cameraFront即可

旋转的角度如何定义?通过欧拉角

俯仰角是描述我们如何往上或往下看的角,可以在第一张图中看到。第二张图展示了偏航角,偏航角表示我们往左和往右看的程度。滚转角代表我们如何翻滚摄像机,通常在太空飞船的摄像机中使用。每个欧拉角都有一个值来表示,把三个角结合起来我们就能够计算3D空间中任何的旋转向量了。

对于我们的摄像机系统来说,我们只关心俯仰角和偏航角,所以我们不会讨论滚转角。给定一个俯仰角和偏航角,我们可以把它们转换为一个代表新的方向向量的3D向量。

也就是只要有pitch和yaw的角度即可算出方向的向量,根据下图可以很方便的理解计算过程

在这里插入图片描述

glm::vec3 front;
front.x = cos(glm::radians(pitch)) * cos(glm::radians(yaw));
front.y = sin(glm::radians(pitch));
front.z = cos(glm::radians(pitch)) * sin(glm::radians(yaw));
cameraFront = glm::normalize(front);

 基于QT的代码实现

void glWidget::mouseMoveEvent(QMouseEvent *event)
{
    static float yaw = -90;
    static float pitch = 0;
    static QPoint lastPos(width()/2, height()/2);

    QPoint curpos = event->pos();
    QPoint deltapos = curpos - lastPos;
    lastPos = curpos;

    if(event->buttons() & Qt::LeftButton)
    {
        deltapos *= 0.1f;
        yaw -= deltapos.x();
        pitch += deltapos.y();

        if(pitch > 89.0)pitch = 89.0;
        if(pitch < -89.0)pitch = -89.0;
        cameraFront_.setX(cos(yaw*3.14/180)*cos(pitch*3.14/180));
        cameraFront_.setY(sin(pitch*3.14/180));
        cameraFront_.setZ(sin(yaw*3.14/180)*cos(pitch*3.14/180));
        cameraFront_.normalize();
        update();
    }

}

实现缩放的效果

缩放效果只需改变fov即可

void glWidget::wheelEvent(QWheelEvent *event)
{
    if(fov_ >= 1.0f && fov_ <= 45.0f)
        fov_ -= event->angleDelta().y()/120;
      if(fov_ <= 1.0f)
        fov_ = 1.0f;
      if(fov_ >= 45.0f)
        fov_ = 45.0f;
    update();
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值