
简介Games101课程作业0的完整指南面向选课学生与自学计算机图形学的初学者旨在帮助大家通过虚拟机完成统一环境配置避免手动搭建依赖的麻烦。文档完整覆盖从VirtualBox安装、虚拟硬盘文件下载与挂载到Guest Additions增强功能安装再到作业框架导入与VSCode编辑的整个流程并附有C与Eigen库使用注意事项能有效降低首次接触课程作业的上手难度。资源为单份PDF文件压缩包仅874KB内容精炼但步骤详尽适合对照操作。已有433人学习使用无论是课程正式学员还是希望提前熟悉环境配置的图形学爱好者均可借此快速进入作业环节。1. 先搞懂一件事这门图形学入门课的“作业0”到底在练什么很多新手第一次下载这份《GAMES101-作业0pdf》时打开一看第一感觉是“这不是习题集而是一份虚拟机安装说明书”。其实这恰恰是这门零基础入门课刻意安排的第一步在开始写渲染代码之前先让你把环境彻底跑通。课程主讲老师不希望把时间浪费在每个同学“各自电脑上装不出依赖库”这种事情上所以设计了这份不用评分的作业让你通过“安装虚拟机—导入虚拟硬盘—写一个简单的C程序—用cmake编译运行”这一整条链路把后面所有作业都要用的工具链摸一遍。你可以把它理解成学做菜之前先学会开火菜谱再精彩灶台点不着什么都白搭。这道作业证明了你有能力在一台统一配置的环境里编译并运行图形学代码后面的路才走得下去。2. 为什么要用虚拟机一份“装好环境”的镜像替你免去配置地狱2.1 虚拟机是什么一台住在你电脑里的“临时电脑”如果把你的电脑比作一套房子那虚拟机就是在这套房子里再隔出一间“样板间”。这间样板间有自己独立的地板、水管和电闸里面的装修风格和外面的房间完全无关哪怕你在里面把墙砸了外面的房子也毫发无损。具体到这个场景里VirtualBox 就是帮你“隔房间”的工具而课程提供的那份虚拟硬盘文件后缀是 .vdi则是一张已经装修好的“样板间图纸”。你不需要自己买水泥沙子和瓷砖只需要把这份图纸加载进 VirtualBox一台完整的、装好各种开发工具的 Ubuntu 系统就凭空出现了。第一次学虚拟机的人容易把它想得很玄学其实关键动作只有两个装一个 VirtualBox再指定一个虚拟硬盘文件。之后你点击“启动”看到的是一个完整的 Linux 桌面和操作一台真实电脑没有区别。唯一的差别是这台电脑的“真实心脏”还是你笔记本的 CPU 和内存只是被 VirtualBox“切片”出了一部分供它使用。2.2 图形学作业为什么坚持让新手用虚拟机很多新手会不服气为什么不能直接在自己电脑上装环境这个问题的答案等你做第三、四次作业时会深有体会。图形学代码涉及矩阵运算、图像读写、OpenGL 接口依赖链很长。个人电脑的操作系统版本、编译器版本、第三方库安装路径任何一个不一致都会导致“在我电脑上明明能跑”的经典翻车现场。虚拟机的好处是“环境快照”。课程提供了一个已经配置好的 Ubuntu 系统镜像里面预装了编译器、cmake、Eigen 库甚至文本编辑器都已经装好。你把这份镜下载下来所有人的起点就完全一致了。老师讲解时是这套环境你运行代码也是这套环境所谓的“配置地狱”就整个被绕过了。此外图形学代码有时候会写出段错误甚至把系统搞崩在虚拟机里跑顶多重启虚拟机不会伤到你的宿主机。对于新手来说这层“隔离”本身就是一种保护让你敢大胆改代码、大胆试错。2.3 这份虚拟硬盘里已经预装了什么课程提供的虚拟硬盘文件是 Ubuntu 18.04 系统。登录进去之后你会发现桌面环境是完整的图形界面常用的软件已经帮你铺好了文本编辑器Visual Studio Code 和 Sublime 都已经装好课程推荐用 VS Code 编辑代码。编译工具链包括 g 编译器和 cmake。后面每次作业都会用到这两个东西。数学库Eigen 已经被放在系统目录里你在代码里直接 include 头文件就能用。有一点需要注意这个 Ubuntu 系统的登录密码按原文是 Ilovegraphics只是你虚拟机内部的登录口令不要用在其他地方也不要在真实服务器上设置类似弱密码。它的作用是让你能进入系统完成作业仅此而已。3. 迈出第一步把 VirtualBox 和虚拟硬盘接起来3.1 下载并安装 VirtualBox你要用的虚拟机软件叫 Oracle VM VirtualBox这是一款免费开源的虚拟机软件支持 Windows、macOS 和 Linux 三种宿主机系统。新手第一次下载软件最容易踩的坑是跑到第三方下载站下载到捆绑广告的安装包。正确做法是直接去官网的下载页面认准对应的操作系统那一栏。Windows下载 .exe 安装包双击运行全程按默认选项“下一步”即可。macOS下载 .dmg 磁盘映像双击挂载后把应用到应用程序文件夹里。Linux官网会列出各种发行版的安装方式按命令逐个执行即可。安装完成后打开 VirtualBox你会看到一个比较朴素的蓝色窗口左边是虚拟机列表右边是一些功能按钮。这个界面不用怕我们只用到其中一小部分。安装完之后要先确认 VirtualBox 能正常启动后面所有步骤都基于它进行。3.2 下载虚拟硬盘文件并解压下一步是下载课程提供的虚拟硬盘文件。文档里给的地址需要输入一个提取密码下载后你拿到的实际是一个压缩包文件名后面带着“(64bit).rar”解压之后才是真正的虚拟硬盘文件后缀是 .vdi。这里有两个新手常见的小问题。第一个是压缩包很大下载时间会比较长属正常现象耐心等就好。第二个是解压软件需要支持 rar 格式。Windows 上如果右键不能直接解压装一个支持 rar 的免费解压软件即可macOS 自带归档工具默认不支持 rar需要另外装解压工具。解压完成后请把 .vdi 文件放在一个比较好找的位置比如桌面或某个专门放课程的文件夹里。这个文件就是你的“整套系统”暂时不要移动它也不要在解压完之后把压缩包删掉万一后面需要重新解压还得重新下载一次。3.3 新建虚拟机类型、版本、内存、硬盘分别怎么填拿到 .vdi 文件后打开 VirtualBox点击窗口左上角的“新建”按钮会弹出创建向导。这里有几个关键参数新手容易迷茫我逐个解释。第一项是名称可以随便填比如“GAMES101”它只是显示名字。第二项是类型必须选择 Linux。第三项是版本必须选择 Ubuntu (64-bit)。这个版本选择很重要如果选成了 32 位或选错系统后面虚拟硬盘可能无法正确启动。接下来是内存大小。课程原文档建议设为 2GB也就是 2048 MB。如果你的宿主机内存比较充裕8GB 或更多设置成 2GB 没有问题如果你的宿主机内存比较紧张至少要保证 1.5GB否则虚拟机里系统会非常卡。继续往后走会看到一个“虚拟硬盘”选项默认是“创建新的虚拟硬盘”这里一定要手动改成“使用已有的虚拟硬盘文件”然后点击文件夹图标选择刚才解压出来的那个 .vdi 文件。最后点击“创建”虚拟机的配置就完成了。记住顺序是先选已有硬盘再点创建不要倒过来否则会白创建一个空盘。3.4 启动虚拟机并登录系统配置完成的虚拟机会出现在 VirtualBox 主界面的左侧列表中。选中它点击上方的“启动”按钮会弹出一个新窗口这就是你的虚拟机屏幕。启动过程其实就是一台 Linux 电脑的开机过程耐心等几十秒。等到界面出现登录框时在用户名对应的输入框里输入文档提供的默认用户名密码输入文档注明的那串字符串。这里有一个新手容易翻车的点密码输入时屏幕上不会显示任何字符不是键盘坏了是 Linux 的安全设计你正常输入后直接按回车即可。登录成功后就进入了 Ubuntu 桌面。你可以试着打开一下文件管理器、终端这些基本工具确认系统没有异常。到这里你的虚拟机就跑起来了后面所有代码都在这台“电脑”里完成。3.5 安装增强功能让虚拟机不再“难用”刚装好的虚拟机有一个很明显的短板屏幕分辨率固定、菜单栏和宿主机之间不能直接拖拽文件、共享剪贴板也没开。解决这些问题的办法是安装 Guest Additions虚拟机的增强功能。在虚拟机窗口顶部的菜单栏里找到“设备”下拉菜单里有一项“安装增强功能”直接点击系统会往虚拟光驱里挂载一个安装程序。进入系统后会弹出提示让你运行安装脚本。这个过程是全自动的等到终端里输出“Press Return to close this window…”之类的提示按回车关闭窗口重启虚拟机增强功能就生效了。如果图形界面方式安装失败别慌还有一条命令行路径。在虚拟机里按 CtrlAltT 调出终端执行以下命令手动完成安装sudo mkdir -p /media/cdrom sudo mount -t auto /dev/cdrom /media/cdrom/ cd /media/cdrom sudo sh VBoxLinuxAdditions.run逐行解释一下这几条命令的作用第一行创建一个目录作为光驱挂载点第二行把虚拟光驱挂载到这个目录第三行进入该目录第四行用超级管理员权限执行安装脚本。执行完毕之后重启虚拟机系统增强功能就装好了。安装完增强功能记得做一个小测试试试从宿主机拖一个文件进虚拟机窗口如果能拖进去说明双向拖放已经生效了。这个能力后面传输作业框架时会频繁用到。4. 在虚拟机里写出第一个程序从 C 语法到 Eigen 库到 cmake4.1 传输作业框架并认识文本编辑器作业框架的传输方式文档里推荐的是“拖拽”。但前提是刚才那一节的增强功能已经装好而且要在虚拟机窗口顶部的“设备”菜单里把“拖放”设置为“双向”。设置好之后从宿主机桌面拖一个文件夹进虚拟机窗口松手就能看到它出现在虚拟机的文件系统里。接下来用 VS Code 打开这个文件夹在虚拟机桌面上右键点击文件夹选择“使用其他应用打开”然后选 Visual Studio Code。第一次打开可能有点慢之后就会很流畅。VS Code 打开后左侧会显示文件夹内的文件单击 main.cpp 就能看到课程给出的样例代码了。建议新手中途不要纠结哪个编辑器更好课程推荐 VS Code 就用 VS Code等熟练之后再换不迟。4.2 看懂样例代码头文件、主函数、标准输出打开 main.cpp 后你先看到的是一段很短的 C 程序。它不复杂但包含了很多新手后面会反复接触的基础概念。先看头文件部分#include cmath #include iostream这两行的作用是引入现成的功能模块。cmath 提供了数学函数比如平方根、三角函数iostream 提供了输入输出能力比如在屏幕上打印文字。C 不像某些语言自带“全功能包”你用到什么功能就需要引入对应的头文件这是 C 的基本规则后面写任何程序都适用。再看主函数部分int main() { float a 1.0, b 2.0; std::cout a std::endl; std::cout a / b std::endl; std::cout std::sqrt(a) std::endl; std::cout std::acos(-1) std::endl; std::cout std::sin(30.0 / 180.0 * acos(-1)) std::endl; return 0; }这个程序做了五件事定义了两个浮点数 a 和 b然后依次打印 a 的值、a 除以 b 的值、a 的平方根、arccos(-1)、sin(30°)。最后 return 0 表示程序正常结束。注意最后一行算 sin(30) 时先把 30 度换算成了弧度因为 C 的三角函数使用弧度制而不是角度制这就是为什么 30.0 / 180.0 再乘以 π用 acos(-1) 表示 π 的近似值。4.3 Eigen 库向量和矩阵就是图形学的“基本粒子”图形学里最核心的数学工具是向量和矩阵。Eigen 是一个 C 的线性代数库课程里所有的向量变换都靠它。它的使用方法需要重点掌握因为后面几乎每次作业都要用到。向量部分先看定义和输出#include eigen3/Eigen/Core Eigen::Vector3f v(1.0f, 2.0f, 3.0f); Eigen::Vector3f w(1.0f, 0.0f, 0.0f); std::cout v std::endl; std::cout v w std::endl; std::cout v * 3.0f std::endl; std::cout 2.0f * v std::endl;这里定义了两个三维向量 v 和 w然后分别演示了三类基础运算加法v w、数乘向量乘一个标量。输出结果会是 v 的每个分量分别加上 w 的分量、以及每个分量乘以 3。看到输出后你可以试着把 * 改成 .dot() 调点积感受一下 Eigen 的语法风格。矩阵部分也类似Eigen::Matrix3f i, j; i 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0; j 2.0, 3.0, 1.0, 4.0, 6.0, 5.0, 9.0, 7.0, 8.0; std::cout i std::endl; std::cout i j std::endl;Matrix3f 是 3x3 浮点矩阵。定义方式比较特殊用 操作符按行填入 9 个数顺序是从左到右、从上到下。输出矩阵后你可以尝试着把 i * j 补上去那是矩阵乘法和刚才的加法有本质区别矩阵乘法要求左矩阵列数等于右矩阵行数而且运算规则是“行乘以列再求和”不是对应位置相乘。要特别提醒新手的是 Eigen 的头文件写法是 eigen3/Eigen/Core这种带路径的写法一开始会觉得奇怪但这是系统目录里 Eigen 库的安装位置决定的。只要按这个写法 include编译器就能找到它。4.4 本次作业真正要做的绕原点旋转加平移现在终于到了作业本体。描述很简单给定一个点 P (2, 1)先绕原点逆时针旋转 45°再平移 (1, 2)计算变换后点的坐标要求用齐次坐标。什么叫“用齐次坐标”简单说就是把二维平面上的点从 (x, y) 表示扩展成 (x, y, 1)。这个多出来的 1 分量使得“旋转”和“平移”可以统一写成 3x3 矩阵相乘的形式。如果不用齐次坐标平移必须写成加法无法和旋转合并成一次乘法这在后续复杂变换中会非常麻烦。旋转矩阵在齐次坐标下的形式是 3x3 矩阵前三行前三列填写二维旋转矩阵第三行第三列是 1。旋转 45° 时cos45° 和 sin45° 都是 √2/2 的近似值 0.7071。平移矩阵则是在旋转矩阵基础上把第一行第三列设为 1水平平移量、第二行第三列设为 2竖直平移量。最终结果是两个矩阵相乘再乘点向量。完整的代码可以写成#include cmath #include iostream #include eigen3/Eigen/Core int main() { float angle 45.0f / 180.0f * std::acos(-1.0f); Eigen::Vector3f P(2.0f, 1.0f, 1.0f); Eigen::Matrix3f R; R std::cos(angle), -std::sin(angle), 0.0f, std::sin(angle), std::cos(angle), 0.0f, 0.0f, 0.0f, 1.0f; Eigen::Matrix3f T; T 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 2.0f, 0.0f, 0.0f, 1.0f; Eigen::Vector3f result T * R * P; std::cout result.x() result.y() std::endl; return 0; }解释几个关键参数angle 把 45° 换算成弧度P 的第三个分量是 1这是齐次坐标的“开关”R 前三列是旋转部分T 的第三列分别是平移量 1 和 2。result T * R * P 这行代码体现了“先旋转再平移”的顺序P 先被 R 作用再被 T 作用。这一点初学者容易搞反记住矩阵乘法从右往左读。编译运行需要用到 cmake文档给了明确的五步命令mkdir build cd build cmake .. make ./Transformation逐条解释第一行创建 build 目录目的是把编译产物和源码分开第二行进入 build 目录第三行 cmake .. 让 cmake 读取上一级目录的 CMakeLists.txt 文件并生成 Makefile注意这里必须是两个点代表上一级目录第四行 make 根据 Makefile 执行真正的编译第五行 ./Transformation 运行编译出来的可执行文件。你需要在项目根目录写好 main.cpp 和 CMakeLists.txt 之后再依次执行这些命令。看到终端输出结果1.7071 4.12132就说明整个链路全通了。5. 新手最容易踩的五个坑现象、原因和解决方法5.1 从宿主机拖文件进虚拟机没有反应现象你试着把一个作业框架文件夹拖进虚拟机窗口松手后什么都没发生。原因虚拟机的“拖放”功能默认是关闭的只安装了增强功能还不够必须在虚拟机的菜单里手动设置。解决在虚拟机窗口顶部的菜单栏点击“设备”找到“拖放”切换为“双向”。如果这里选的是“仅主机到客户机”你从宿主机往虚拟机拖是可以的但反向可能不行。如果切换后仍然无效先重启一次虚拟机再试。这个坑非常常见几乎每位新手都会遇到一次。5.2 编译时报错 undefined reference to xxx现象make 执行时终端里出现一堆错误关键字是 undefined reference后面跟着某个函数名。原因这类错误一般不是你的代码语法写错了而是链接阶段缺少库。在 C 里声明函数和实际实现函数是两个阶段如果你的 CMakeLists.txt 里没有把相关的库或源文件加进去链接器就找不到函数的实现体。比如你用到了某个数学函数却没链接对应模块就会出现这种错误。解决回到项目根目录打开 CMakeLists.txt检查 target_link_libraries 或 add_executable 部分是否把需要的模块都写上了。你可以把报错信息完整复制到搜索引擎里搜Stack Overflow 上提到的问题基本都有对应解法。这里特别提醒修改完 CMakeLists.txt 后建议把 build 目录删掉重新走一遍 mkdir、cmake、make因为 cmake 有时会缓存旧的配置。5.3 虚拟机启动后卡顿、黑屏或内存不足现象启动虚拟机后系统要很久才进入桌面或者操作起来一卡一卡的甚至提示内存不足。原因虚拟机是 “吃” 宿主机内存的。如果你创建虚拟机时只分配了很低的数值比如 1GB而 Ubuntu 桌面系统本身就要占用不少内存再在虚拟机里打开浏览器加 VS Code内存马上就紧张了。解决关闭虚拟机后在 VirtualBox 主界面选中该虚拟机点击“设置”进入“系统”页面把内存调大。一般建议 2GB如果宿主机有 8GB 以上内存调到 3GB 内体验会更好。调完后重新启动虚拟机。另外尽量不要在虚拟机里同时开太多程序它毕竟只是课程作业用不是主力生产机器。5.4 登录虚拟机时密码一直不正确现象输入文档里给的密码屏幕提示认证失败反复尝试仍然进不去系统。原因最常见的原因是大小写没注意或者使用了全角字符。Linux 密码是区分大小写的而且默认输入时不回显任何字符容易让人误以为没输进去。解决先用鼠标点击一下密码输入框确认焦点在输入框里输入时注意第一字母是否大写确认没有启用全角输入法如果实在不行重启虚拟机在选择系统界面的引导菜单里进入恢复模式通过 root shell 重置密码。不过课程提供的虚拟机密码是明文写在文档里的最可能的坑还是大小写耐心一点再试一次基本就能解决。5.5 计算结果和参考答案对不上现象代码运行完输出的坐标不是预期值差了挺多。原因这个坑一般不是 cmake 的问题而是数学处理的问题。最常见的是角度没有转弧度把 sin(45) 当成了角度制或者齐次坐标的第三个分量忘了写 1导致平移量被当作缩放倍数作用再或者是“先旋转再平移”的矩阵乘法顺序写反了。解决回到代码逐行检查角度换算是否用了 45.0 / 180.0 * acos(-1)向量 P 的第三个分量是否为 1旋转矩阵的 sin 项符号是否正确T * R * P 是否写成了 R * T * P。这四个检查点都过了结果基本就是正确的。顺带一提计算类作业的调试思路也是以后做图形学作业的核心方法一步一步把中间结果打印出来看是在哪一个变换之后开始偏离预期。6. 完成作业之后下一步怎么走作业0跑通之后不要急着关掉虚拟机也别急着把文件删掉。它的真正价值是建立起一套“编写—编译—运行—调试”的完整循环。你接下来要做的是顺着这条已经打通的路继续往下走让这套技能长成肌肉记忆。建议的学习顺序是这样的。先花一点时间把 Eigen 的官方文档里“矩阵和向量运算”部分翻一遍不需要读通全部只看矩阵加减、矩阵乘法、向量点积叉积这几节。作业0里只用到了矩阵乘向量而作业1开始就会用到更复杂的角度计算比如绕任意轴旋转。其次把 C 的类与构造函数稍微补一下后面几次作业的框架代码用到了类封装你不需要自己能设计类但至少要看得懂成员函数是怎么被调用的。最后学习路径里很重要的一环是线性代数中“齐次坐标”的几何含义为什么三维坐标可以表示二维变换为什么平移能写进矩阵。你可以配合一些直观的图形化讲解比如数学可视化题材的视频来理解比干看书本舒服得多。从作业0到作业1的具体跨越其实就是“二维点”升级成“三维顶点”作业0你算子变换的是一个点 P作业1里你会一次性变换整个三角形的三个顶点而且矩阵从 3x3 变成 4x4。但核心思想完全一致都是构造变换矩阵然后矩阵乘向量。所以作业0的代码不要删保存好作业1写代码时直接复制框架逻辑只修改矩阵维度和数值即可。想起我第一次学这门课时因为嫌麻烦跳过了虚拟机直接在自己电脑上配环境结果花了整整两天处理各种编译依赖最后还因为库版本不一致花了一天时间排查一个根本不该出现的渲染黑屏问题。从那以后我每次拿到新的课程或项目都强制自己先花半天把环境彻底跑通再写业务代码再也不在这种事情上省时间。希望帮到你。本文还有配套的精品资源点击获取