OpenGL教程翻译 第十四课 相机控制(一)

第十四课 相机控制(一)

原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载)

背景

在之前的教程中我们学习了如果当相机不位于初始位置时,如何使得得场景中的物体正确的投影到屏幕上面,那么我们下一步就应该学着去控制这个相机,使得相机可以在场景中自由移动。我们可以用鼠标和键盘控制相机——鼠标控制视口方向,键盘控制相机的位置。这些都和第一人称视角相似,这一节我们主要来学习鼠标和键盘对相机的控制。

我们仍然使用上下左右四个方向键。记住,我们的相机的变换取决于相机的位置、target 向量和 up 向量。当我们使用键盘移动相机时,我们只改变了我们的位置信息。上下左右的操作不会导致相机倾斜或旋转,所以 target 向量和 up 向量都不会受到影响。

由于要捕捉到键盘的按键信息,所以我们这里用到另一个 GLUT API:glutSpecialFunc()。当一个“特定”按键被按下时,并且我们之前为这个按键注册了一个回调函数,那么 glutSpecialFunc 就会去调用这个回调函数作为对这个按键按下的响应。这些特定的键包括:功能键、方向键和 PAGE-UP / PAGE-DOWN / HOME/END / INSERT 键。如果你想要捕获常规键(字符或者数字),那么请使用 glutKeyboardFunc()。

代码

相机的功能封装在相机类内。这个类存储相机的属性,并且可以通过接收到的移动事件改变这些属性。管线类获取这些属性并通过它们产生变换矩阵。

(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;
};

这里我们声明了一个相机类,它存储着创建视口变换矩阵所需要的三个属性——位置向量、target 向量 和 up 向量。有两个构造函数。默认构造函数简单地将相机摆放在从原点并且朝向 Z 轴负方向,up 向量指向 “天空”(0,1,0)。此外我们还可以使用其带有形参的构造函数来创建一个具有特定属性值的相机。OnKeyboard() 函数里面实现了相机对于键盘事件的处理,它返回一个布尔值用来显示该事件是否被相机响应。如果点击的按键与我们定义的响应事件相关,则返回 true,否则返回 false。

(Camera.cpp:42)
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;
}

这个函数根据键盘事件对相机进行移动。GLUT 定义了与方向键相应的宏命令,而上面的switch语句正是基于此。不幸的是,这些宏定义的类型都是只是“int”类型,而不是枚举类型。

向前向后的移动是最简单的,因为移动总是沿着 target 向量,我们就只需要让当前位置加上或者减去 target 向量就可以了,target 向量本身不改变。注意,在加上或者减去target 向量之前,我们用一个叫做 “StepSize” 的常数来缩放它。对所有的方向键,我们都做如此处理。StepSize 提供了一个改变相机移动速度的方法(在后面我们也许将会把这个值添加到类属性中)。为使步长一致,我们要确保我们总是乘上单位长度的向量(即我们必须确保 target 向量和 up 向量是单位长度的)。

向侧面移动则有些复杂,因为它是沿着垂直于 target 向量和 up 向量所确定的平面的矢量的移动。这个平面将三维空间分成了两个部分,并且有两个向量垂直于它,且方向相反。我们称其中的一个向量为 “left” ,另一个为 “right” 。这两个向量是由 target 向量和 up 向量的叉乘两种不同情况得到——target × up 和 up × target (叉积运算没有交换律——也就是说,在叉积运算中,改变参数的顺序会得到不同的结果)。得到left / right向量之后,我们先将其规范化,之后再用 StepSize 缩放,最后添加到 position变量里面(使相机向左右方向移动)。此外,target 向量和 up 向量不会受到影响。

注意,这个函数的内部操作里使用了一些新的运算符,比如 “+=” 和“-=”,这些都在 Vector3f 类中进行了重载。

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

这里,我们注册一个新的回调函数来处理键盘事件,在按键被触发的时候,回调函数接收按键按下的信息,并且把这个事件传递给成相机类的一个实例,这个实例早已在全局变量中进行了定义。

(tutorial14.cpp:55)
p.SetCamera(GameCamera.GetPos(), GameCamera.GetTarget(), GameCamera.GetUp());

以前,我们在管线类中用硬编码的方式来初始化相机参数。现在,我们不再使用这些向量,而是从Camera类直接获取相机属性。

操作结果

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
总目录   第一章 OpenGL与三维图形世界     1.1 OpenGL使人们进入三维图形世界     1.2 OpenGL提供直观的三维图形开发环境     1.3 OpenGL称为目前三维图形开发标准   第二章 OpenGL概念建立     2.1 OpenGL基本理解     2.2 OpenGL工作流程     2.3 OpenGL图形操作步骤   第三章 Windows NT环境下的OpenGL     3.1 Windows NT下的OpenGL函数     3.2 OpenGL基本功能     3.3 Windows NT下OpenGL结构   第四章 OpenGL基本程序结构   第五章 OpenGL数据类型和函数名   第六章 OpenGL辅助库的基本使用     6.1 辅助库函数分类     6.2 辅助库应用示例   第七章 OpenGL建模     7.1 描述图元      7.1.1 齐次坐标      7.1.2 点      7.1.3 线      7.1.4 多边形     7.2 绘制图元      7.2.1 定义顶点      7.2.2 构造几何图元   第八章 OpenGL变换     8.1 从三维空间到二维平面      8.1.1 相机模拟      8.1.2 三维图形显示流程      8.1.3 基本变换简单分析     8.2 几何变换      8.2.1 两个矩阵函数解释      8.2.2 平移      8.2.3 旋转      8.2.4 缩放和反射      8.2.5 几何变换举例     8.3 投影变换      8.3.1 正射投影      8.3.2 透视投影     8.4 裁剪变换     8.5 视口变换     8.6 堆栈操作   第九章 OpenGL颜色     9.1 计算机颜色      9.1.1 颜色生成原理      9.1.2 RGB色立体     9.2 颜色模式      9.2.1 RGBA模式      9.2.2 颜色表模式      9.2.3 两种模式应用场合     9.3 颜色应用举例   第十章 OpenGL光照     10.1 真实感图形基本概念     10.2 光照模型      10.2.1 简单光照模型      10.2.2 OpenGL光组成      10.2.3 创建光源      10.2.4 启动光照     10.3 明暗处理     10.4 材质      10.4.1 材质颜色      10.4.2 材质定义      10.4.3 材质RGB值和光源RGB值的关系      10.4.4 材质改变   第十一章 OpenGL位图和图像     11.1 位图      11.1.1 位图和字符      11.1.2 当前光栅位置      11.1.3 位图显示     11.2 图像      11.2.1 象素读写      11.2.2 象素拷贝      11.2.3 图像缩放      11.2.4 图像例程   第十二章 OpenGL纹理     12.1 基本步骤     12.2 纹理定义     12.3 纹理控制      12.3.1 滤波      12.3.2 重复与约简     12.4 映射方式     12.5 纹理坐标       12.5.1 坐标定义       12.5.2 坐标自动产生   第十三章 OpenGL复杂物体建模     13.1 图元扩展      13.1.1 点和线      13.1.2 多边形     13.2 法向计算      13.2.1 法向基本计算方法      13.2.2 法向定义     13.3 曲线生成      13.3.1 曲线绘制举例      13.3.2 曲线定义和启动      13.3.3 曲线坐标计算      13.3.4 定义均匀间隔曲线坐标值     13.4 曲面构造      13.4.1 曲面定义和坐标计算      13.4.2 定义均匀间隔的曲面坐标值      13.4.3 纹理曲面      13.4.4 NURBS曲面   第十四章 OpenGL特殊光处理     14.1 光照模型      14.1.1 全局环境光      14.1.2 近视点与无穷远视点      14.1.3 双面光照     14.2 光源位置与衰减     14.3 聚光与多光源      14.3.1 聚光      14.3.2 多光源与例程     14.4 光源位置与方向的控制     14.5 辐射光   第十五章 OpenGL效果处理     15.1 融合      15.1.1 Alpha值与融合      15.1.2 融合因子      15.1.3 融合实例     15.2 反走样      15.2.1 行为控制函数      15.2.2 点和线的反走样      15.2.3 多边形的反走样     15.3 雾      15.3.1 雾的概论和例程      15.3.2 雾化步骤   第十六章 OpenGL显示列表     16.1 显示列表概论      16.1.1 显示列表的优势      16.1.2 显示列表的适用场合     16.2 创建和执行显示列表      16.2.1 创建显示列表      16.2.2 执行显示列表     16.3 管理显示列表      16.4 多级显示列表   第十七章 OpenGL帧缓存和动画     17.1 帧缓存      17.1.1 帧缓存组成      17.1.2 缓存清除     17.2 动画
前言 第1章OpenGL简介 1.1什么是OpenGL? 1.2一段简单的OpenGL代码 1.3OpenGL函数的语法 1.4OpenGL是个状态机 1.5OpenGL渲染管线 1.5.1显示列表 1.5.2求值器 1.5.3基于顶点的操作 1.5.4图元装配 1.5.5像素操作 1.5.6纹理装配 1.5.7光栅化 1.5.8片断操作 1.6与OpenGL相关的函数库 1.6.1包含文件 1.6.2GLUT,OpenGL实用工具包 1.7动画 1.7.1暂停刷新 1.7.2动画=重绘+交换 第2章状态管理和绘制几何物体 2.1绘图工具箱 2.1.1清除窗口 2.1.2指定颜色 2.1.3强制完成绘图操作 2.1.4坐标系统工具箱 2.2描述点、直线和多边形 2.2.1什么是点、直线和多边形? 2.2.2指定顶点 2.2.3OpenGL几何图元 2.3基本状态管理 2.4显示点、直线和多边形 2.4.1点的细节 2.4.2直线的细节 2.4.3多边形的细节 2.5法线向量 2.6顶点数组 2.6.1步骤1:启用数组 2.6.2步骤2:指定数组的数据 2.6.3步骤3:解引用和渲染 2.7缓冲区对象 2.7.1创建缓冲区对象 2.7.2激活缓冲区对象 2.7.3用数据分配和初始化缓冲区对象 2.7.4更新缓冲区对象的数据值 2.7.5清除缓冲区对象 2.7.6使用缓冲区对象存储顶点数据数据 2.8属性组 2.9关于创建多边形表面模型的一些提示 2.9.1例子:创建一个二十面体 第3章视图 3.1简介:照相机比喻 3.2.1一个简单的例子:绘制立方体 3.1.2通用的变换函数 3.2视图和模型变换 3.2.1对变换进行思考 3.2.2模型变换 3.2.3视图变换 3.3投影变换 3.3.1透视投影 …… 第4章颜色 第5章光照 第6章混合、抗锯齿、雾和多边形偏移 第7章显示列表 第8章绘制像素、位图、字体和图像 第9章纹理贴图 第10章帧缓冲区 第11章分格化和二次方程表面 第12章求值器和NURBS 第13章选择和反馈 第14章OpenGL高级技巧 第15章OpenGL着色语言 附录A操作顺序 附录B状态变量 附录COpenGL和窗口系统 附录DGLUT(OpenGL实用工具库)基础知识 附录E计算法线向量 附录F齐次坐标和变换矩阵 附录G编程提示 附录HOpenGL的不变性规则 附录IOpenGL着色语言内置的变量和函数 术语表
  总目录   第一章 OpenGL与三维图形世界     1.1 OpenGL使人们进入三维图形世界     1.2 OpenGL提供直观的三维图形开发环境     1.3 OpenGL称为目前三维图形开发标准   第二章 OpenGL概念建立     2.1 OpenGL基本理解     2.2 OpenGL工作流程     2.3 OpenGL图形操作步骤   第三章 Windows NT环境下的OpenGL     3.1 Windows NT下的OpenGL函数     3.2 OpenGL基本功能     3.3 Windows NT下OpenGL结构   第四章 OpenGL基本程序结构   第五章 OpenGL数据类型和函数名   第六章 OpenGL辅助库的基本使用     6.1 辅助库函数分类     6.2 辅助库应用示例   第七章 OpenGL建模     7.1 描述图元      7.1.1 齐次坐标      7.1.2 点      7.1.3 线      7.1.4 多边形     7.2 绘制图元      7.2.1 定义顶点      7.2.2 构造几何图元   第八章 OpenGL变换     8.1 从三维空间到二维平面      8.1.1 相机模拟      8.1.2 三维图形显示流程      8.1.3 基本变换简单分析     8.2 几何变换      8.2.1 两个矩阵函数解释      8.2.2 平移      8.2.3 旋转      8.2.4 缩放和反射      8.2.5 几何变换举例     8.3 投影变换      8.3.1 正射投影      8.3.2 透视投影     8.4 裁剪变换     8.5 视口变换     8.6 堆栈操作   第九章 OpenGL颜色     9.1 计算机颜色      9.1.1 颜色生成原理      9.1.2 RGB色立体     9.2 颜色模式      9.2.1 RGBA模式      9.2.2 颜色表模式      9.2.3 两种模式应用场合     9.3 颜色应用举例   第十章 OpenGL光照     10.1 真实感图形基本概念     10.2 光照模型      10.2.1 简单光照模型      10.2.2 OpenGL光组成      10.2.3 创建光源      10.2.4 启动光照     10.3 明暗处理     10.4 材质      10.4.1 材质颜色      10.4.2 材质定义      10.4.3 材质RGB值和光源RGB值的关系      10.4.4 材质改变   第十一章 OpenGL位图和图像     11.1 位图      11.1.1 位图和字符      11.1.2 当前光栅位置      11.1.3 位图显示     11.2 图像      11.2.1 象素读写      11.2.2 象素拷贝      11.2.3 图像缩放      11.2.4 图像例程   第十二章 OpenGL纹理     12.1 基本步骤     12.2 纹理定义     12.3 纹理控制      12.3.1 滤波      12.3.2 重复与约简     12.4 映射方式     12.5 纹理坐标       12.5.1 坐标定义       12.5.2 坐标自动产生   第十三章 OpenGL复杂物体建模     13.1 图元扩展      13.1.1 点和线      13.1.2 多边形     13.2 法向计算      13.2.1 法向基本计算方法      13.2.2 法向定义     13.3 曲线生成      13.3.1 曲线绘制举例      13.3.2 曲线定义和启动      13.3.3 曲线坐标计算      13.3.4 定义均匀间隔曲线坐标值     13.4 曲面构造      13.4.1 曲面定义和坐标计算      13.4.2 定义均匀间隔的曲面坐标值      13.4.3 纹理曲面      13.4.4 NURBS曲面   第十四章 OpenGL特殊光处理     14.1 光照模型      14.1.1 全局环境光      14.1.2 近视点与无穷远视点      14.1.3 双面光照     14.2 光源位置与衰减     14.3 聚光与多光源      14.3.1 聚光      14.3.2 多光源与例程     14.4 光源位置与方向的控制     14.5 辐射光   第十五章 OpenGL效果处理     15.1 融合      15.1.1 Alpha值与融合      15.1.2 融合因子      15.1.3 融合实例     15.2 反走样      15.2.1 行为控制函数      15.2.2 点和线的反走样      15.2.3 多边形的反走样     15.3 雾      15.3.1 雾的概论和例程      15.3.2 雾化步骤   第十六章 OpenGL显示列表     16.1 显示列表概论      16.1.1 显示列表的优势      16.1.2 显示列表的适用场合     16.2 创建和执行显示列表      16.2.1 创建显示列表      16.2.2 执行显示列表     16.3 管理显示列表      16.4 多级显示列表   第十七章 OpenGL帧缓存和动画     17.1 帧缓存      17.1.1 帧缓存组成      17.1.2 缓存清除     17.2 动画
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值