zl程序教程

您现在的位置是:首页 >  后端

当前栏目

GAMES101作业3-遇到的各种问题及解决方法

方法 解决 遇到 各种 作业 问题
2023-09-11 14:22:30 时间

目录

程序运行报错

C2039 std缺少成员

 找不到文件

导出图片问题

导出图片是全黑的

导出图片前后颠倒


程序运行报错

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

修改后牛牛就正过来啦!