目录
程序运行报错
C2039 std缺少成员
应该是VS的标准没有修改成c++17,还是默认的c++14
修改路径为:项目->属性->配置属性->常规->C++语言标准->选择 IOS C++17标准
找不到文件
出现以下错误:
[ WARN:0@0.158] global C:\build\master_winpack-build-win64-vc14\opencv\modules\imgcodecs\src\loadsave.cpp (239) cv::findDecoder imread_('../models/spot/hmap.jpg'): can't open/read file: check file path/integrity
OpenCV(4.5.5) Error: Assertion failed (!_src.empty()) in cv::cvtColor, file C:\build\master_winpack-build-win64-vc14\opencv\modules\imgproc\src\color.cpp, line 182
是main.cpp文件的模型路径的问题,以防万一可以改为绝对路径:
老师给的代码框架里的:
...
std::string filename = "output.png";
objl::Loader Loader;
std::string obj_path = "../models/spot/";
// Load .obj File
bool loadout = Loader.LoadFile("../models/spot/spot_triangulated_good.obj");
...
根据自己存的model路径修改就行:
...
std::string filename = "output.png";
objl::Loader Loader;
std::string obj_path = "D:/games101/Assignment3/Code/models/spot/";
// Load .obj File
bool loadout = Loader.LoadFile("D:/games101/Assignment3/Code/models/spot/spot_triangulated_good.obj");
...
注意:直接复制文件夹路径会是 D:\games101\Assignment3\Code\models\spot
要把 “\” 改成 "/"
导出图片问题
导出图片是全黑的
问题大部分出在上面提到的文件路径问题,看看是不是文件路径有误,或者没有把\改成/
导出图片前后颠倒
如图:
问题出在main.cpp的变换矩阵:
先展示一下我在作业1和作业2中用到的同一个透视矩阵:
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
float zNear, float zFar)
{
Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
//完全按照课程里的参数取值,这道题的相机就在(0,0,0),因此远近平面都是在z的负半轴,所以n和f的值应该为负
float f, n, l, r, b, t, fov;
fov = eye_fov / 180 * MY_PI;
n = -zNear; //znear是正值
f = zFar;
t = tan(fov/2) * zNear;
b = -t;
r = t * aspect_ratio;
l = -r;
//透视->正交 perspective->orthographic
Eigen::Matrix4f pertoorth;
pertoorth << n, 0, 0, 0,
0, n, 0, 0,
0, 0, n + f, -n*f,
0, 0, 1, 0;
//正交——移动
Eigen::Matrix4f orth1;
orth1 << 1, 0, 0, -(r + l) / 2,
0, 1, 0, -(t + b) / 2,
0, 0, 1, -(n + f) / 2,
0, 0, 0, 1;
//正交——缩放
Eigen::Matrix4f orth2;
orth2 << 2 / (r - l), 0, 0, 0,
0, 2 / (t - b), 0, 0,
0, 0, 2 / (n - f), 0,
0, 0, 0, 1;
projection = orth2*orth1 * pertoorth;//注意矩阵顺序,变换从右往左依次进行
return projection;
}
这里认为zNear和zFar都是正值,而作业输入的也确实如此,是正值。为了符合课上老师讲的n和f是负值所以最开始令n=-zNear,f=-zFar,但得到的牛牛前后颠倒了。
阅读了这一篇文章后:《GAMES101》作业框架问题详解 - 知乎 (zhihu.com)
终于明白为什么会前后颠倒!!问题出在z-buffer上面: “在讨论z-buffer时,要将z值换一个概念:z值越小离摄像机越近,z值越大离摄像机越远”。我在之前的写的GAMES101作业1-VS2019中也有提到,zNear和zFar这个概念是在OpenGL中找到的有具体的定义(具体是不是我也不确定)。因此推测作业3代码框架应该是参考OpenGL的。
既然z-buffer的z轴变成了z正方向,在之前的基础上加上一个将z轴旋转180°的矩阵就好!完整代码如下:
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
{
// TODO: Copy-paste your implementation from the previous assignment.
Eigen::Matrix4f projection;
float f, n, l, r, b, t, fov;
fov = eye_fov / 180 * MY_PI;
n = -zNear; //znear是正值
f = -zFar;
t = tan(fov / 2) * zNear;
b = -t;
r = t * aspect_ratio;
l = -r;
//透视->正交 perspective->orthographic
Eigen::Matrix4f pertoorth;
pertoorth <<
n, 0, 0, 0,
0, n, 0, 0,
0, 0, n + f, -n * f,
0, 0, 1, 0;
//正交——移动
Eigen::Matrix4f orth1;
orth1 <<
1, 0, 0, -(r + l) / 2,
0, 1, 0, -(t + b) / 2,
0, 0, 1, -(n + f) / 2,
0, 0, 0, 1;
//正交——缩放
Eigen::Matrix4f orth2;
orth2 <<
2 / (r - l), 0, 0, 0,
0, 2 / (t - b), 0, 0,
0, 0, 2 / (n - f), 0,
0, 0, 0, 1;
//确保图象是正的,要对z轴进行反转
Eigen::Matrix4f mirror;
mirror <<
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, -1, 0,
0, 0, 0, 1;
projection = mirror*orth2 * orth1 * pertoorth;//注意矩阵顺序,变换从右往左依次进行
return projection;
}
修改后牛牛就正过来啦!