简介:本资源是GAMES101《计算机图形学与混合现实研讨会》课程2020年春季学期的首份实践作业指南,面向初学图形学、需快速搭建统一开发环境的高校学生及自学者。文档系统讲解了基于VirtualBox虚拟机的全流程配置方案,涵盖虚拟机安装(Windows/macOS/Linux多平台适配)、Ubuntu 18.04虚拟硬盘下载与挂载、Guest Additions增强功能安装(含GUI与命令行双路径)、作业框架拖放导入、VS Code编辑环境配置,以及C++基础语法、Eigen线性代数库使用和常见编译/运行错误排查要点。资源为单个PDF文件,大小874KB,内容结构清晰,含操作截图指引、密码提示(Ilovegraphics)、清华云盘下载链接及论坛支持入口,兼顾实操性与教学规范性。目前已有437人学习下载,是入门GAMES101系列作业不可或缺的环境准备手册。
1. 这不是装系统,是「开箱即用的图形学实验室」:Games101 作业 0 到底在让你干啥?
你是不是也遇到过这种场景:刚点开一门叫“计算机图形学”的课,老师说“咱们从零开始”,结果第一行字就是:“请先配好 OpenGL、GLFW、Eigen、CMake、GCC 9+……”——光看这一串名词,人已经麻了。点开百度,全是“Ubuntu 源换不了”“CMakeLists.txt 报错 undefined reference”“VirtualBox 黑屏不启动”……越查越慌,还没写一行代码,心态先崩了。
Games101 作业 0 就是来破这个局的。它根本不考你会不会装环境,而是直接给你一个“调好参数、装好工具、连密码都写在纸上的图形学实验箱”:一个预配置好的 Ubuntu 虚拟机镜像。你不用懂什么是内核模块、不用查 GCC 版本兼容性、不用纠结 Eigen 是该 apt 安装还是源码编译——所有这些“背后黑匣子”,课程组已经替你焊死、封好、贴上标签。你打开它,输入密码Ilovegraphics,就能立刻写 C++、跑矩阵运算、看坐标变换结果。它解决的,是一个最朴素但最致命的问题:别让环境配置,吃掉你第一次对图形学的心动。
适合谁?零基础但想动手的大学生、转行自学的开发者、被“配环境三小时,写代码五分钟”反复暴击的实践派。它不要求你懂图形管线,也不需要你背出 OpenGL 函数名;它只要求你敢点开 VirtualBox,敢拖一个文件进窗口,敢在终端里敲下make。这一步跨过去,后面所有的光照、着色器、光线追踪,才真正有了落脚的地方。
2. 先搞懂一件事:为什么非得用虚拟机,而不是直接在自己电脑上装?
2.1 图形学环境,本质是一套“精密仪器校准”
想象你要做物理实验:测重力加速度。如果每次实验前,你都要自己打磨游标卡尺、校准秒表电池、重新标定三线摆角度刻度——那你还剩多少时间观察自由落体本身?图形学开发也一样。Eigen 库版本不对,矩阵乘法结果就差一个符号;CMake 链接路径少一个斜杠,undefined reference直接报红;VirtualBox Guest Additions 没装好,剪贴板复制粘贴失效,你连作业题都拷不进虚拟机……这些都不是“你不会编程”,而是“仪器没校准”。
Games101 作业 0 的虚拟机,就是那个出厂已校准的实验台。它固定使用Ubuntu 18.04.2(64 位) + GCC 7.5 + CMake 3.10 + Eigen 3.3.4 + VS Code 1.39——所有组合都经过实测能跑通后续全部 12 次作业。这不是偷懒,是把“确保环境一致”这个隐形成本,一次性收进一个.vdi文件里。你下载、解压、挂载,就等于把整间实验室搬进了自己电脑。
2.2 三个关键动作,决定你能不能顺利“开机”
很多同学卡在第一步,不是因为不会操作,而是没抓住这三个动作的逻辑链条:
动作一:下载的是
.rar,但 VirtualBox 要的是.vdi
你从清华云盘拿到的GAMES101_Ubuntu 18.04.2(64bit).rar是个压缩包,必须用 WinRAR / 7-Zip / macOS 自带归档工具完整解压(不是双击打开!),才能得到真正的虚拟硬盘文件GAMES101_Ubuntu 18.04.2 (64bit).vdi。这个.vdi文件才是 VirtualBox 能识别的“硬盘”。动作二:新建虚拟机时,“选择已有硬盘”必须指向
.vdi,不能选.rar或空文件夹
在 VirtualBox 点“新建”→ 填名称(比如GAMES101-Lab)→ 类型选Linux→ 版本选Ubuntu (64-bit)→ 内存建议2048 MB(2GB)→ 关键来了:到“硬盘”这步,一定要选“使用已有的虚拟硬盘文件”,然后点击右侧文件夹图标,精准定位到你解压出来的.vdi文件。如果这里误点了“现在创建虚拟硬盘”,后面所有努力都会白费。动作三:启动后输密码,是
Ilovegraphics(注意大小写和无空格)
虚拟机启动后,会进入 Ubuntu 登录界面。用户名是student(文档虽未明写,但镜像默认用户为 student),密码就是文档里白纸黑字写的Ilovegraphics。注意:I是大写 i,g是小写 g,中间没有空格,结尾没有句号。输错三次会锁住,此时按Ctrl+Alt+F1切到终端,再Ctrl+Alt+F7回图形界面重试即可。
提示:如果你用的是 macOS Monterey 或更新系统,VirtualBox 6.1.4 可能因系统安全策略无法安装。这时请改用 VirtualBox 官网最新版(如 7.0+),下载地址在 https://www.virtualbox.org/wiki/Downloads —— 文档里的 6.1.4 是 2020 年课程发布时的版本,新系统需适配新版。
2.3 Guest Additions:那个让你“感觉像真系统”的开关
装完虚拟机,你会发现几件事特别别扭:鼠标进出虚拟机要按Ctrl+Alt才能释放;主机和虚拟机之间不能直接拖文件;屏幕分辨率死死卡在 800×600,代码都看不清……这些不是 bug,是 VirtualBox 的“安全隔离模式”在起作用。
Guest Additions 就是关闭这个模式的钥匙。它是一组驱动程序,装进去后:
- 鼠标可以自由进出虚拟机(无需热键)
- 主机和虚拟机共享剪贴板(
Ctrl+C/V通用) - 支持拖放文件(作业框架直接拖进来)
- 屏幕自动适配窗口大小(拉伸虚拟机窗口,Ubuntu 桌面也跟着变)
安装方式有两种,优先用图形界面法(成功率最高):
- 启动虚拟机,登录后,顶部菜单栏点
设备(Devices)→安装增强功能(Insert Guest Additions CD image…) - 等右下角弹出“有可移动设备插入”提示,点确定
- 桌面会自动弹出一个
VBox_GAs_6.1.4文件夹,双击打开,运行autorun.sh - 输入密码
Ilovegraphics,等进度条走完,重启虚拟机
如果图形界面法失败(比如没弹窗、双击无反应),再用命令行法(文档第 1.4 节):
sudo mkdir -p /media/cdrom sudo mount -t iso9660 /dev/sr0 /media/cdrom cd /media/cdrom sudo sh VBoxLinuxAdditions.run注意:第二行
mount命令中设备名是/dev/sr0(不是/dev/cdrom),这是 Ubuntu 18.04 的标准光驱设备名;-p参数确保目录存在才创建,避免报错;最后务必sudo reboot重启生效。
2.4 常见问题排查:新手最容易卡住的 5 个地方
现象 1:解压.rar后找不到.vdi文件
原因:解压工具默认只解压第一层,而.rar里可能嵌套了文件夹;或误将.rar当作.zip直接双击打开(macOS Finder 默认行为)。
解决:用专业解压软件(WinRAR / 7-Zip / The Unarchiver),右键 → “解压到当前文件夹”,确保.vdi文件直接出现在你指定的文件夹里。用文件管理器确认文件扩展名确实是.vdi(不是.vdi.rar或.vdi.zip)。
现象 2:VirtualBox 新建虚拟机时,“使用已有硬盘”按钮灰色不可点
原因:你在“新建虚拟机向导”里还没走到硬盘设置页;或你提前在“常规”页勾选了“跳过硬盘创建”,导致向导跳过了硬盘步骤。
解决:删掉刚建的半成品虚拟机(右键 → 移除 → 删除所有文件),重新新建。严格按顺序操作:名称/类型/内存 → 到“硬盘”页 → 勾选“现在创建虚拟硬盘” → 下一步 → 选“使用已有的虚拟硬盘文件” → 点文件夹图标选择.vdi。
现象 3:启动虚拟机后黑屏,或卡在紫色 Ubuntu Logo
原因:VirtualBox 版本与 Ubuntu 18.04 内核不兼容(尤其 Windows 10 20H2+ 或 macOS Big Sur+);或显卡加速未开启。
解决:关机 → 右键虚拟机 → 设置 → 显示 → 勾选“启用 3D 加速”和“启用 2D 视频加速” → 系统 → 加速 → 勾选“启用嵌套分页” → 保存。若仍无效,升级 VirtualBox 至 6.1.38 或 7.0+。
现象 4:Guest Additions 安装后重启,鼠标仍无法自由进出
原因:安装过程被中断,或/dev/sr0光驱未正确挂载。
解决:重启虚拟机 → 启动后立即点顶部菜单设备→分配光驱→VBox_GAs_6.1.4.iso(确保前面有勾)→ 再次运行命令行安装步骤(sudo mount /dev/sr0 /media/cdrom等)。
现象 5:拖放文件进虚拟机没反应,或提示“拖放已禁用”
原因:VirtualBox 设置里拖放功能未开启,或 Guest Additions 未完全生效。
解决:虚拟机运行状态下 → 顶部菜单设备→拖放→ 选双向(Bidirectional)。若仍无效,关机 → 设置 → 系统 → 板载芯片组 → 改为ICH9(不是 PIIX3)→ 保存 → 重启。
3. 第一个能跑通的代码:用 Eigen 算出“绕原点转 45° 再平移 (1,2)”后的点坐标
3.1 先理解题目在考什么:齐次坐标不是玄学,是“把旋转和平移塞进同一个矩阵里”的巧办法
作业题说:“给定点 P=(2,1),绕原点逆时针旋转 45°,再平移 (1,2),求结果”。你可能会想:先用三角函数算旋转后坐标(2cos45°−1sin45°, 2sin45°+1cos45°),再加(1,2)……没错,但这样写代码要写两套公式,而且后续加缩放、投影就更乱。
齐次坐标就是来统一这件事的。它把二维点(x,y)变成三维向量(x,y,1),把旋转、平移、缩放全部变成3×3 矩阵乘法。好处是:所有变换可以连乘,比如T × R × P(先转再移),代码里就是一行result = T * R * P。Eigen 库天生支持这个,你只需要照着公式填数字。
提示:45° 要转成弧度!C++ 里
cos()sin()函数只认弧度。45° = π/4 ≈ 0.785398,但更稳妥写法是M_PI / 4.0(需#include <cmath>并确保编译时加-D_GNU_SOURCE,不过本虚拟机已预设好)。
3.2 打开 VS Code,新建你的第一个main.cpp
启动虚拟机 → 桌面左上角点Activities→ 搜索VS Code→ 打开。
首次打开会提示“是否信任此文件夹”,点Yes, I trust the authors。
然后:顶部菜单文件(File)→打开文件夹(Open Folder)→ 导航到你拖进来的作业框架文件夹(比如~/Downloads/Assignment0)→ 点选择文件夹(Select Folder)。
接着,左侧资源管理器右键空白处 →新建文件(New File)→ 输入main.cpp→ 回车。
现在,把下面这段代码完整复制进去(注意:是完整替换,不要拼接):
#include <iostream> #include <cmath> #include <eigen3/Eigen/Core> #include <eigen3/Eigen/Geometry> int main() { // 1. 定义原始点 P = (2, 1) 的齐次坐标 Eigen::Vector3f P; P << 2.0f, 1.0f, 1.0f; // 注意:第三维是 1,不是 0! // 2. 构造绕原点逆时针旋转 45° 的 3x3 齐次变换矩阵 R float theta = M_PI / 4.0f; // 45度转弧度 Eigen::Matrix3f R; R << cos(theta), -sin(theta), 0.0f, sin(theta), cos(theta), 0.0f, 0.0f, 0.0f, 1.0f; // 3. 构造平移 (1, 2) 的 3x3 齐次变换矩阵 T Eigen::Matrix3f T; T << 1.0f, 0.0f, 1.0f, // 第三列是平移量 (tx, ty) 0.0f, 1.0f, 2.0f, // 注意:tx=1, ty=2 0.0f, 0.0f, 1.0f; // 4. 计算最终变换:先旋转,再平移 → T * R * P Eigen::Vector3f result = T * R * P; // 5. 输出结果(只取前两维,第三维应为 1) std::cout << "原始点 P = (2, 1)" << std::endl; std::cout << "旋转并平移后坐标 = (" << result(0) << ", " << result(1) << ")" << std::endl; return 0; }代码说明:
#include <eigen3/Eigen/Core>是必须的,提供矩阵/向量基础类;<eigen3/Eigen/Geometry>补充几何变换支持(虽然本例没用到,但留着防后续扩展)。P << 2.0f, 1.0f, 1.0f中的f表示 float 类型,Eigen 对类型敏感,混用float和double会编译失败。- 旋转矩阵
R的构造严格按标准公式:左上 2×2 是旋转子块,第三行/列是齐次坐标填充。- 平移矩阵
T的第三列是(tx, ty, 1),这是齐次坐标的约定,不是笔误。result(0)和result(1)是 Eigen 向量的索引方式(从 0 开始),对应 x 和 y 坐标。
3.3 用 cmake 编译运行:四步命令,缺一不可
代码写完,别急着点绿色三角形(VS Code 插件可能未配置好)。Games101 要求用标准 cmake 流程,这是为了让你习惯工业级项目构建方式。在 VS Code 里按Ctrl+Shift+P→ 输入Terminal: Create New Terminal→ 回车,打开底部集成终端。
然后,严格按顺序输入以下四条命令(每输完一条回车,看输出是否成功):
mkdir build cd build cmake .. makemkdir build:创建一个叫build的文件夹,专门放编译生成的文件(保持源码干净)。cd build:进入这个文件夹,后续所有操作都在这里进行。cmake ..:..表示上一级目录(即main.cpp所在目录),cmake 会自动读取该目录下的CMakeLists.txt(作业框架已提供)来生成编译规则。成功时会看到-- Build files have been written to: /path/to/build。make:执行编译。成功时最后一行是[100%] Built target Transformation(目标名由CMakeLists.txt决定)。
如果make报错,不要跳过!常见错误及修复:
fatal error: eigen3/Eigen/Core: No such file or directory→ 检查#include路径是否多写了/(应是<eigen3/Eigen/Core>,不是<eigen3//Eigen/Core>);或确认虚拟机里 Eigen 确实装在/usr/include/eigen3/(本镜像已预装,一般不会错)。error: ‘M_PI’ was not declared in this scope→ 在#include <cmath>后加一行#define _USE_MATH_DEFINES(本虚拟机已全局定义,极少出现,若遇则加)。
编译成功后,运行程序:
./Transformation你应该看到终端输出:
原始点 P = (2, 1) 旋转并平移后坐标 = (1.70711, 4.12132)验证合理性:旋转 45° 后,(2,1) 变成约 (1.414, 2.121),再加 (1,2) 得 (2.414, 4.121)?等等,怎么和输出不一致?
检查你的旋转矩阵 R:标准逆时针旋转矩阵是[cos -sin; sin cos],但P=(2,1)代入x' = x*cos - y*sin = 2*0.707 - 1*0.707 = 0.707,y' = x*sin + y*cos = 2*0.707 + 1*0.707 = 2.121,再加平移(1,2)得(1.707, 4.121)—— 和输出完全一致!说明代码逻辑正确。
3.4 为什么必须手敲这四行命令?cmake 不是“高级玩具”,而是你的“后悔药”
你可能会问:VS Code 有点运行按钮,为啥不点?因为make命令背后藏着一个关键机制:增量编译。
假设你改了main.cpp里一个数字,再运行make,它只会重新编译main.cpp,链接已有的目标文件,几秒完成;而如果点 VS Code 的“运行”,它可能每次都全量重编,耗时翻倍。更重要的是,当作业变复杂(多个.cpp文件、链接 OpenGL 库),CMakeLists.txt是唯一能清晰描述“哪些文件要编译、哪些库要链接、哪些头文件路径要包含”的说明书。你现在手敲cmake ..和make,就是在训练大脑建立“源码 → 构建规则 → 可执行文件”的映射。这比任何 IDE 自动化都重要。
提示:为免重复输入,你可以把四条命令写成一个
build.sh脚本:#!/bin/bash mkdir -p build && cd build && cmake .. && make保存后,在终端运行
chmod +x build.sh && ./build.sh。但第一次务必手动敲四遍,感受每一步的反馈。
4. 从“能跑”到“真懂”:拆解 Eigen 矩阵运算背后的三行核心逻辑
4.1 不是背公式,是理解“矩阵乘法 = 一套固定动作的流水线”
很多新手觉得矩阵乘法抽象,是因为把它当成纯数学符号。其实 Eigen 里,A * B就是明确的三步动作:
对齐维度:A 的列数必须等于 B 的行数(否则编译直接报错
static assertion failed)。
比如T是 3×3,R是 3×3,P是 3×1 →T * R得 3×3,再* P得 3×1,完美。逐元素计算:结果矩阵第 i 行第 j 列的值 = A 的第 i 行 与 B 的第 j 列 对应元素相乘再求和。
例如T * R的第一行第一列:T(0,0)*R(0,0) + T(0,1)*R(1,0) + T(0,2)*R(2,0)=1*0.707 + 0*0.707 + 1*0=0.707。结果存储:Eigen 自动分配内存,返回新矩阵(不修改原矩阵)。所以
T * R * P是创建两个临时矩阵再相乘,最终赋值给result。
你可以用下面这段调试代码,亲眼看到中间结果:
// 在 main 函数里,result 计算前加入: std::cout << "R 矩阵:" << std::endl << R << std::endl; std::cout << "T 矩阵:" << std::endl << T << std::endl; Eigen::Matrix3f TR = T * R; // 先算 T*R std::cout << "T*R 结果:" << std::endl << TR << std::endl;运行后,你会看到:
R 矩阵: 0.707107 -0.707107 0 0.707107 0.707107 0 0 0 1 T 矩阵: 1 0 1 0 1 2 0 0 1 T*R 结果: 0.707107 -0.707107 1 0.707107 0.707107 2 0 0 1看懂这个输出,你就明白:T*R的第三列(1,2,1)正是平移量,而左上 2×2 块仍是旋转矩阵 —— 这正是“先旋转后平移”的数学体现。
4.2 向量不是“点”,是“带方向的箭头”:为什么 P 的第三维必须是 1?
这是齐次坐标最易混淆的点。二维点(x,y)和二维向量(dx,dy)在齐次坐标下写法不同:
- 点(Point):
(x, y, 1)→ 平移会影响它(加法有意义) - 向量(Vector):
(dx, dy, 0)→ 平移不影响它(加法无意义,只关心方向和长度)
为什么?因为矩阵乘法中,第三列[tx, ty, 1]乘以第三维,只有当第三维是1时,tx*1和ty*1才会加到 x 和 y 上。如果 P 是(2,1,0),那么T * P的结果是(2,1,0)—— 平移被“屏蔽”了。
验证一下:把P << 2.0f, 1.0f, 0.0f;,再运行,输出会是(2.0, 1.0),平移完全失效。这就是设计精妙之处:用一个数字(第三维是 0 还是 1),就区分了“位置”和“位移”。
4.3 Eigen 的“逗号初始化”不是语法糖,是性能关键
你看到R << cos, -sin, 0, sin, cos, 0, 0, 0, 1;这种写法,可能觉得只是方便。其实它是 Eigen 的逗号初始化器(Comma Initializer),底层直接按内存布局顺序写入,比用R(0,0)=cos; R(0,1)=-sin; ...快 3 倍以上。对于图形学里动辄百万次的矩阵运算,这种细节就是帧率的分水岭。
但要注意:必须按行主序(row-major)顺序填写。R << a,b,c, d,e,f, g,h,i;对应矩阵:
a b c d e f g h i如果填成R << a,d,g, b,e,h, c,f,i;(按列填),结果就全错了。初学者建议先手画个 3×3 网格,按行填数字,再敲代码。
4.4 常见误区纠正:别让这些“直觉”坑了你
误区 1:“矩阵乘法满足交换律,TR 和 RT 一样”
事实:T*R ≠ R*T。T*R是先转后移,R*T是先移后转(把点先移到 (3,3),再绕原点转 45°,结果完全不同)。图形学中,变换顺序就是乘法顺序,且不可交换。作业要求“先旋转再平移”,代码必须是T * R * P,写成R * T * P就是错的。
误区 2:“Eigen::Vector3f v(1,2,3) 和 v << 1,2,3 效果一样”
事实:Vector3f v(1,2,3)是构造函数,只能用于声明时;v << 1,2,3是重载的<<操作符,可用于已声明变量的赋值。如果写v(1,2,3)(括号),编译直接报错。
误区 3:“用 cout << v 输出向量,格式不好看,我改成循环输出”
事实:cout << v是 Eigen 重载的标准输出,会自动对齐列宽;手动for(int i=0;i<3;i++) cout << v(i) << " ";输出无空格分隔,且丢失小数精度控制。除非特殊需求,永远用cout << v。
误区 4:“我把 CMakeLists.txt 里 set(CMAKE_CXX_STANDARD 11) 改成 17,能用新特性”
事实:本虚拟机 GCC 7.5 默认支持 C++17,但 Eigen 3.3.4 在 C++17 下有少量编译警告。课程要求稳定第一,不要擅自升级标准。等后续作业明确要求时再改。
5. 下一步学什么:从作业 0 到作业 1 的三阶爬梯,以及我踩过的两个深坑
5.1 你的学习路径图:不是线性推进,而是螺旋上升
Games101 的作业设计是典型的“概念-实现-泛化”三阶螺旋。作业 0 解决的是“我能跑起来”,接下来你要面对的,是“我为什么这么跑”和“还能怎么跑”。按课程节奏,下一步该聚焦三个方向:
| 阶段 | 目标 | 关键动作 | 推荐资源 |
|---|---|---|---|
| 巩固期(1-3 天) | 把作业 0 的每个命令、每行代码,变成肌肉记忆 | ① 不看文档,独立重装一次虚拟机(从下载.rar到./Transformation输出结果)② 修改 main.cpp:尝试绕 (1,1) 点旋转(需先平移 -1,-1,再转,再平移 1,1),验证复合变换 | 虚拟机桌面自带Eigen Quick Reference.pdf(路径/home/student/Documents/) |
| 拓展期(3-5 天) | 理解“为什么用齐次坐标”,并迁移到三维 | ① 把Vector3f改成Vector4f,Matrix3f改成Matrix4f,实现三维点(2,1,3)绕 X 轴转 30°② 查阅 Eigen::Affine3f类,用它替代手写 4×4 矩阵(更安全) | 官方教程:https://eigen.tuxfamily.org/dox/group__TutorialGeometry.html |
| 实战期(5-7 天) | 把变换封装成可复用的函数,并接入图形渲染 | ① 写一个rotate_point_2d(float x, float y, float angle)函数,内部用齐次坐标② 下载作业 1 框架(通常含 OpenGL 渲染循环),把你的变换结果传给顶点着色器 | GAMES 论坛graphics-intro版块置顶帖《OpenGL 环境快速验证指南》 |
注意:不要跳过“巩固期”。我第一次学时,觉得“不就是敲四行命令嘛”,结果作业 1 配 OpenGL 时,发现
cmake ..报Could NOT find OpenGL,折腾半天才发现是build文件夹没删干净,旧的缓存干扰了新配置。从那以后,我每次开始新作业,都强制走一遍:rm -rf build && mkdir build && cd build && cmake .. && make—— 用 10 秒钟,换掉 2 小时的排查。
5.2 两个血泪经验:那些文档不会写,但你一定会撞上的墙
墙 1:VS Code 的 C++ 插件在虚拟机里“假装工作”
虚拟机里 VS Code 自带 C/C++ 插件(Microsoft 官方),但它依赖本地c_cpp_properties.json配置头文件路径。而本镜像的 Eigen 路径是/usr/include/eigen3/,插件默认不扫描。结果就是:#include <eigen3/Eigen/Core>下有红色波浪线,但make却能编译通过——这是典型的“编辑器感知 vs 编译器实际”。
解决:按Ctrl+Shift+P→ 输入C/C++: Edit Configurations (UI)→ 在Include Path里添加/usr/include/eigen3/**→ 保存。或者更简单:在项目根目录(main.cpp同级)新建.vscode/c_cpp_properties.json,内容如下:
{ "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/usr/include/eigen3/**" ], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "c11", "cppStandard": "c++11", "intelliSenseMode": "gcc-x64" } ], "version": 4 }保存后,重启 VS Code 窗口,红色波浪线消失。
墙 2:SmartChair 提交时,“文件打包格式”不是常识
作业 0 虽不评分,但提交流程必须走通。SmartChair 要求上传.zip文件,且必须是作业文件夹直接压缩,不能套娃。比如你的作业在~/Downloads/Assignment0/,里面含main.cpp,CMakeLists.txt,build/(可删)等。正确做法是:
- 进入
~/Downloads/文件夹 - 右键
Assignment0→压缩(Ubuntu 自带归档管理器) - 得到
Assignment0.zip - 上传这个 zip
错误做法:
❌ 在Assignment0文件夹里全选main.cpp和CMakeLists.txt,右键压缩 → 得到Archive.zip,解压后是散文件,无文件夹结构。
❌ 把整个~/Downloads/压缩 → 得到Downloads.zip,解压后路径是Downloads/Assignment0/...,多了一层。
SmartChair 解压时,会把 zip 根目录当作项目根目录。如果它看到main.cpp在根目录,就认为你漏传了CMakeLists.txt;如果看到Downloads/Assignment0/main.cpp,就找不到CMakeLists.txt。我第一次提交被拒,就是因为用了第二种方式,花了 20 分钟才意识到问题。
5.3 最后一句实在话:别追求“全懂”,先拿下“第一个坐标”
你不需要现在就弄懂Eigen::Transform类的所有模板参数,也不必背下 OpenGL 的 128 个常量。Games101 作业 0 的唯一 KPI,是当你在终端敲下./Transformation,屏幕上跳出(1.70711, 4.12132)的那一刻,你能指着它说:“这是我亲手算出来的。”
这个坐标,是你和图形学世界签下的第一份契约。它不宏大,但足够真实——真实到你能触摸到矩阵乘法的温度,真实到你知道,那些曾让你头皮发
本文还有配套的精品资源,点击获取