zoukankan      html  css  js  c++  java
  • opengl 教程(14) 摄像机控制(1)

    原帖地址:http://ogldev.atspace.co.uk/www/tutorial14/tutorial14.html

          前面一篇教程中,我们把摄像机放在三维空间的固定位置,本章我们尝试控制摄像机,在三维空间任意方向移动它。我们用键盘来控制摄像机的位置,用鼠标来改变摄像机lookat的方向,这个有点类似第一人称射击游戏中的摄像机控制。本章先来学习一下用键盘控制摄像机位置,下章来学习鼠标改变摄像机方位。

          注意:我们用键盘移动的时候,仅仅是改变摄像机的位置,并没有改变lookat方向和up方向。glut中控制键盘的回调函数是 glutSpecialFunc(),当特殊的键被按下的时候,将会执行这个函数,比如方向键、翻页键等等。普通的按键,则需要回调函数 glutKeyboardFunc()。

    主要代码:

          新建一个camera类来封装摄像机的所有操作,该类保存摄像机的参数,基于接收的事件来改变这些参数,从而控制摄像机的运动。

    Camera.h

    class Camera
    {
    public:
    Camera();
    Camera(const Vector3f& Pos, const Vector3f& Target, const Vector3f& Up);
    bool OnKeyboard(int Key);
    const Vector3f& GetPos() const
    const Vector3f& GetTarget() const
    const Vector3f& GetUp() const
    private:
    Vector3f m_pos;
    Vector3f m_target;
    Vector3f m_up;
    };

          camera类中存储了三个属性:位置 position, lookat 向量(target vector) 以及up向量,函数OnKeyboard()用来处理键盘事件。如果是指定的键,则会控制摄像机移动。

    Camera.cpp

    bool Camera::OnKeyboard(int Key)
    {
    bool Ret = false;
    switch (Key) {
    case GLUT_KEY_UP:
    {
    m_pos += (m_target * StepSize);
    Ret = true;
    }
    break;
    case GLUT_KEY_DOWN:
    {
    m_pos -= (m_target * StepSize);
    Ret = true;
    }
    break;
    case GLUT_KEY_LEFT:
    {
    Vector3f Left = m_target.Cross(m_up);
    Left.Normalize();
    Left *= StepSize;
    m_pos += Left;
    Ret = true;
    }
    break;
    case GLUT_KEY_RIGHT:
    {
    Vector3f Right = m_up.Cross(m_target);
    Right.Normalize();
    Right *= StepSize;
    m_pos += Right;
    Ret = true;
    }
    break;
    }
    return Ret;
    }

    当按下上下方向键时候,摄像机会沿着lookat方向移动,而左右方向键则会使摄4像沿着一个righ向量移动

    tutorial14.cpp

    static void SpecialKeyboardCB(int Key, int x, int y)
    {
    GameCamera.OnKeyboard(Key);
    }
    static void InitializeGlutCallbacks()
    {
    glutDisplayFunc(RenderSceneCB);
    glutIdleFunc(RenderSceneCB);
    glutSpecialFunc(SpecialKeyboardCB);
    }

    我们会注册一个新的回调函数,来处理特殊按键。

    tutorial14.cpp

    p.SetCamera(GameCamera.GetPos(), GameCamera.GetTarget(), GameCamera.GetUp());

    该命令用来初始化摄像机位置。

    程序运行后界面如下:

    image

  • 相关阅读:
    BZOJ2705: [SDOI2012]Longge的问题 欧拉函数
    BZOJ3884: 上帝与集合的正确用法 拓展欧拉定理
    BZOJ1296: [SCOI2009]粉刷匠 DP
    BZOJ5293: [Bjoi2018]求和 树上差分
    BZOJ1398: Vijos1382寻找主人 Necklace 字符串最小表示法
    BZOJ5189: [Usaco2018 Jan]Cow at Large 贪心+LCA
    BZOJ2654: tree 二分答案+最小生成树
    BZOJ1304: [CQOI2009]叶子的染色 树形dp
    BZOJ1632: [Usaco2007 Feb]Lilypad Pond SPFA+最短路计数
    BZOJ1726: [Usaco2006 Nov]Roadblocks第二短路 K短路
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/2861821.html
Copyright © 2011-2022 走看看