简介:这份PDF是GAMES101课程作业0的官方说明文档,面向正在学习计算机图形学、需要搭建统一开发环境的学生与自学者。内容围绕虚拟机使用展开,涵盖VirtualBox安装、虚拟硬盘配置、Guest Additions增强功能安装、作业框架传输与编辑,以及VSCode开发工具和C++语法注意事项,帮助读者免去手动配置环境的麻烦,快速进入作业编写与调试环节。资源包共1个PDF文件,大小约874KB,篇幅紧凑,适合作为环境搭建与作业入门的操作参考。目前已有433人学习下载。通过这份文档,读者可以掌握从零搭建Ubuntu虚拟机的完整流程,理解拖放传输、命令行编译运行等关键操作,并借助C++常见错误指南与Eigen库说明,为后续图形学作业打下扎实的环境与语言基础。
1. 从 Games101 作业 0 说起:为什么一个「配环境」的 PDF 值得单独写一篇
很多人第一次打开 Games101 作业 0 的 PDF,心里是有点不屑的:不就是装个虚拟机、配个 C++ 环境、跑个 Eigen 吗,能有多难。结果真上手,卡住的地方往往不是图形学,而是 CMake 报错、Eigen 找不到、VS Code 底部状态栏那个 Configure 按钮到底该不该点。作业 0 的 PDF 本质是一份环境搭建说明书,它要你在一台干净的机器上,把 C++ 工具链、CMake、Eigen 和编辑器串成一条能编译能运行的链路。这件事对新手是门槛,对熟手是肌肉记忆,但恰恰是这条链路决定了你后面十几个作业能不能顺利跑起来。这篇不聊光栅化也不聊光线追踪,只把作业 0 背后的环境工程拆开讲清楚:每一步在干什么、参数怎么设、报错怎么读、哪些坑我踩过。适合刚拿到 PDF 还没动手的人,也适合配到一半卡住想找后悔药的人。
2. 作业 0 到底要你搭什么:工具链拆解与选型理由
2.1 虚拟机、WSL 还是原生系统:三条路怎么选
作业 0 的 PDF 通常建议在 Linux 环境下做,原因很实际:后续作业会用到 OpenCV、Eigen 这些库,Linux 下的包管理和编译链路最顺,助教和网上的参考资料也大多基于 Ubuntu。于是问题变成:Linux 环境怎么来。常见做法有三种,我按自己的使用顺序说。
第一种是 VMware 或 VirtualBox 装 Ubuntu 虚拟机。优点是隔离干净,装崩了直接删掉重来,对新手最友好,也是热搜里「vmware 虚拟机安装教程」被反复搜的原因。缺点是吃内存,编译大项目时慢,图形界面偶尔黑屏进不去桌面。第二种是 Windows 自带的 WSL2,装 Ubuntu 子系统,性能接近原生,文件互通方便,缺点是图形界面和 OpenGL 相关的东西配置起来比虚拟机麻烦,后面做渲染作业可能遇到显示问题。第三种是直接装双系统或纯 Linux,性能最好,但装系统本身对新手就是一道坎,装坏了影响日常使用。
我的建议很直接:第一次做 Games101,用虚拟机装 Ubuntu,别折腾。等你把作业 0 到作业 2 跑通了,再考虑换 WSL 或原生。选型不是比谁高级,是比谁让你最快进入写代码的状态。
2.2 编译器、CMake、Eigen 各自负责什么
把工具链拆开看,每个角色都很清楚。编译器(g++ 或 clang++)负责把 C++ 源码翻译成可执行文件,这是最底层的一环。CMake 是构建系统生成器,它读 CMakeLists.txt,生成 Makefile 或 Ninja 文件,再由 make 去调用编译器。很多人分不清 makefile 和 cmake 的区别,一句话:makefile 是给 make 用的构建脚本,cmake 是生成这些脚本的工具,跨平台能力更强,作业 0 用的就是 CMake。
Eigen 是纯头文件的线性代数库,矩阵、向量、变换都靠它,图形学里到处是向量和矩阵运算,所以作业 0 让你先把它配好。注意 Eigen 不需要编译安装,它是一堆 .h 文件,只要让编译器能找到头文件路径就行,这也是后面 CMake 里 find_package 或 include_directories 要处理的事。
| 组件 | 作用 | 作业 0 里的角色 |
|---|---|---|
| g++ / clang++ | 编译 C++ 源码 | 最终把 .cpp 变成可执行文件 |
| CMake | 生成构建文件 | 读 CMakeLists.txt,产出 Makefile |
| make | 执行构建 | 按 Makefile 调用编译器 |
| Eigen | 线性代数库 | 提供 Matrix、Vector 等类型 |
| VS Code | 编辑器 | 写代码、点 Configure、看报错 |
2.3 为什么作业 0 要你先跑通一个最小程序
作业 0 的 PDF 一般会让你编译一个最简单的程序,可能只是打印一句话或者做个矩阵乘法。这不是走过场,是在验证整条链路:CMake 能不能找到编译器、能不能找到 Eigen、生成的 Makefile 能不能跑、可执行文件能不能运行。任何一环断了,你都会在后面的作业里以更隐蔽的方式再遇到。所以作业 0 的价值不在代码本身,在于它把环境问题提前暴露出来。跑通它,等于给自己买了一份后悔药。
3. 在 Ubuntu 虚拟机上把环境配到能编译:命令与参数
3.1 装完 Ubuntu 后先做这几件事
虚拟机装好 Ubuntu 之后,别急着开 VS Code。先打开终端,把系统更新和基础工具装上。这一步能避免后面一堆「找不到命令」的报错。
# 更新软件源索引,确保装到的是较新版本 sudo apt update # 升级已安装的包,第一次装完系统建议做一次 sudo apt upgrade -y # 安装编译工具链、CMake、Git 和 Eigen sudo apt install -y build-essential cmake git libeigen3-devbuild-essential 里包含了 g++、make 这些核心工具,cmake 是构建工具,libeigen3-dev 是 Ubuntu 仓库里的 Eigen 包。装完之后用下面几条命令验证,每条都要有输出,没输出就是没装好。
g++ --version # 看编译器版本 cmake --version # 看 CMake 版本 ls /usr/include/eigen3 # 看 Eigen 头文件在不在Eigen 装在 /usr/include/eigen3 这个路径下,记住它,后面 CMake 找不到 Eigen 时大概率是路径没配对。如果 ls 报「没有那个文件或目录」,说明 libeigen3-dev 没装上,回去看 apt 的报错信息。
3.2 用 CMake 跑通第一个最小工程
在 home 目录下建一个练习文件夹,写两个文件:CMakeLists.txt 和 main.cpp。这是作业 0 最核心的一步,也是后面所有作业的模板。
# CMakeLists.txt cmake_minimum_required(VERSION 3.10) # 最低版本要求,Ubuntu 自带的通常够 project(Games101_HW0) # 工程名,随便起 set(CMAKE_CXX_STANDARD 17) # 用 C++17,作业里常用 set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Eigen3 REQUIRED) # 找 Eigen,找不到会直接报错 include_directories(${EIGEN3_INCLUDE_DIR}) # 把头文件路径加进来 add_executable(main main.cpp) # 生成可执行文件 main// main.cpp #include <iostream> #include <Eigen/Dense> // Eigen 的核心头文件 int main() { Eigen::Matrix2f m; // 定义一个 2x2 的 float 矩阵 m << 1, 2, 3, 4; std::cout << "matrix:\n" << m << std::endl; std::cout << "determinant: " << m.determinant() << std::endl; return 0; }CMakeLists.txt 的逻辑是:声明版本、设 C++ 标准、找 Eigen、加头文件路径、生成可执行文件。find_package(Eigen3 REQUIRED) 里的 REQUIRED 表示找不到就报错停止,这是好事,能让你第一时间发现问题而不是编译到一半才炸。main.cpp 里用 Eigen::Matrix2f 定义矩阵,determinant() 算行列式,能打印出结果就说明 Eigen 真的被链接上了。
编译运行:
mkdir build && cd build # 建一个 build 目录,保持源码目录干净 cmake .. # 生成构建文件,.. 指向上一级的 CMakeLists.txt make # 执行编译 ./main # 运行mkdir build && cd build 这个习惯要养成,CMake 官方推荐 out-of-source 构建,所有中间文件都在 build 里,删掉 build 就等于清理干净,不会污染源码目录。cmake .. 里的两个点表示 CMakeLists.txt 在上一级目录。如果 cmake .. 报错,先看它说的找不到什么,再对症下药。
3.3 VS Code 里那个 Configure 按钮到底该不该点
热搜里有人问「vscode 安装 cmake tools 底部状态栏应该有 configure 按钮吗」,答案是:装了 CMake Tools 扩展并且打开了一个含 CMakeLists.txt 的文件夹,底部状态栏就会出现 Configure。点它等价于在终端敲 cmake,只是把命令图形化了。点之前要确保已经选好编译器套件(Kit),否则它会让你先选一个。
我一般的工作流是:终端里手动 cmake .. && make 跑通一次,确认环境没问题,再用 VS Code 的按钮。这样出问题时你能分清是环境问题还是编辑器配置问题。VS Code 的 CMake Tools 有时会缓存旧的配置,改了 CMakeLists.txt 后按钮行为不对,可以按 Ctrl+Shift+P 找「CMake: Delete Cache and Reconfigure」清掉重来。这个缓存问题坑过不少人,报错信息看着莫名其妙,其实清一下就好。
4. 编译报错怎么读:从 CMake 输出定位真实问题
4.1 报错信息的分层结构
CMake 的报错看着吓人,其实有结构。最上面通常是「CMake Error at ...」,告诉你哪个文件哪一行出错,接着是具体描述,最后是「Configuring incomplete, errors occurred」。读报错先读第一行的文件路径和行号,再看描述里的关键词,比如 Could NOT find Eigen3、No CMAKE_CXX_COMPILER could be found。关键词决定了你该去查什么。
编译阶段的报错来自 g++,格式是「文件:行:列: error: 描述」。这类报错通常是语法问题、头文件没包含、类型不匹配。Eigen 的报错尤其长,模板展开后能刷屏,这时候看最上面第一个 error 就行,后面的往往是连锁反应。
4.2 三类高频报错的处理路径
第一类,找不到 Eigen。现象是 CMake 报 Could NOT find Eigen3。原因通常是 libeigen3-dev 没装,或者装了但 CMake 的查找路径不对。解决:先确认 /usr/include/eigen3 存在,如果存在还报错,在 CMakeLists.txt 里手动指定 include_directories(/usr/include/eigen3)。
第二类,找不到编译器。现象是 No CMAKE_CXX_COMPILER could be found。原因多半是 build-essential 没装全,或者你在一个没装编译器的环境里跑。解决:sudo apt install build-essential,然后删掉 build 目录重新 cmake。
第三类,C++ 标准不匹配。现象是编译时报一堆 Eigen 内部的语法错误,或者提示需要 C++11 以上。原因是你没设 CMAKE_CXX_STANDARD,编译器默认用了老标准。解决:在 CMakeLists.txt 里加上 set(CMAKE_CXX_STANDARD 17)。
4.3 用最小复现缩小问题范围
环境问题最怕的是「不知道哪一环坏了」。我的做法是准备一个最小工程,就是 3.2 里那套 CMakeLists.txt 加 main.cpp,任何环境改动后先跑它。如果最小工程能过,说明工具链没问题,问题在你新加的代码或配置里;如果最小工程都过不了,说明是环境本身的问题,别在业务代码里找原因。这个习惯能省掉大量瞎猜的时间。
5. 避坑与排查:作业 0 里最容易翻车的五件事
5.1 虚拟机装完黑屏进不去桌面
现象:VMware 里 Ubuntu 装完重启,卡在黑屏或者只有光标。原因通常是显卡驱动或显示配置和虚拟机不兼容,也可能是安装时选了 3D 加速但宿主机不支持。解决:关机后在虚拟机设置里关掉「加速 3D 图形」,把显存调大一点,再启动。如果还不行,启动时进 GRUB 选 recovery 模式,用 nomodeset 参数进系统再装驱动。
5.2 外面的命令复制不进虚拟机终端
现象:在宿主机复制了一条命令,到虚拟机终端里 Ctrl+V 没反应。原因是虚拟机默认没装或没开剪贴板共享。解决:VMware 里装 open-vm-tools 和 open-vm-tools-desktop,然后重启。命令是 sudo apt install -y open-vm-tools open-vm-tools-desktop。装完宿主机和虚拟机之间就能复制粘贴了,这个对新手体验影响很大。
5.3 CMake 缓存导致的玄学报错
现象:改了 CMakeLists.txt,重新 cmake 还是报旧错误,或者行为跟改之前一样。原因是 build 目录里缓存了上次的配置。解决:删掉整个 build 目录重新来,rm -rf build && mkdir build && cd build && cmake ..。VS Code 里就用前面说的 Delete Cache and Reconfigure。这个坑的特点是报错信息和你改的东西对不上,遇到对不上的报错先怀疑缓存。
5.4 Eigen 头文件路径写错
现象:编译时报 fatal error: Eigen/Dense: No such file or directory。原因是 include 路径不对。Eigen 装在 /usr/include/eigen3,所以代码里写 #include <Eigen/Dense>,而 CMake 里要把 /usr/include/eigen3 加进 include 路径。如果你手动写 include_directories(/usr/include),那代码里就得写 #include <eigen3/Eigen/Dense>。两种写法对应两种路径,别混。用 find_package(Eigen3) 加 EIGEN3_INCLUDE_DIR 是最省事的。
5.5 内存不够导致编译被 kill
现象:编译到一半进程突然消失,终端只显示 Killed。原因是虚拟机内存给小了,编译大文件时内存不够被系统杀掉。解决:把虚拟机内存调到 4GB 以上,编译时关掉浏览器等吃内存的程序。如果还是不够,用 make -j2 限制并行编译数量,减少同时占用的内存。
6. 把作业 0 的环境变成可复用的模板
配好一次环境之后,别让它只服务作业 0。我的习惯是把 CMakeLists.txt 整理成一个模板,后面每个作业复制过去改工程名和源文件就行。模板里固定这几样:C++17 标准、find_package(Eigen3)、include_directories、add_executable。这样每次开新作业,环境部分零思考,直接写业务代码。
再进一步,可以写一个 build.sh 把编译命令固化下来:
#!/bin/bash # build.sh:一键清理并重新编译 set -e # 任何一步失败就停止,避免带着错误继续 rm -rf build # 清掉旧构建,避免缓存问题 mkdir build cd build cmake .. # 生成构建文件 make -j$(nproc) # 用所有核心并行编译,加快速度set -e 是关键,它让脚本在 cmake 失败时立刻停下,不会继续跑 make 然后给你一堆误导性的报错。make -j$(nproc) 用满 CPU 核心,编译快很多,但内存小的机器要慎用,可以改成 make -j2。
验证环境是否真的没问题,我一般跑三个检查:g++ --version 有输出、cmake --version 有输出、最小工程能编译并打印矩阵行列式。三个都过,这个环境就能支撑后面所有作业。如果哪天作业编译突然报奇怪的错,先回到这三个检查,大概率能定位到是环境被改动了还是代码本身的问题。
说个我自己的教训:第一次做 Games101 时,我在 Windows 上直接装了 VS 和 CMake,折腾了两天才发现 Eigen 的路径怎么都配不对,最后换成 Ubuntu 虚拟机,半小时就跑通了。环境这件事,选对路比努力重要。后来我养成了一个习惯,每换一台机器,先花二十分钟把最小工程跑通,再开始做正事。这个习惯帮我省下的时间,远比这二十分钟多。希望帮到你。
本文还有配套的精品资源,点击获取