games101 作业1

games101 作业1,第1张

依然是用windows+vs2019完成作业

新的安装与配置:

安装与配置openCV计算机视觉库:
https://blog.csdn.net/maizousidemao/article/details/81474834
挨着扔进去

遇到的问题:

1.error LNK1112: 模块计算机类型“X86”与目标计算机类型“x64”冲突
解决办法:解决方案使用debug x64,如果之前是x86,要全部重新配置一下

(以下错误建立在我把基础配置的库文件名给添加反了(错误添加为opencv_world455.lib而不是opencv_world455d.lib),遇到的一系列错误。

2.错误 LNK2019 无法解析的外部符号 “public: void __cdecl cv::Mat::copyTo(class cv::debug_build_guard::_OutputArray
解决办法:https://blog.csdn.net/goethe/article/details/111032728
3.Microsoft C++ 异常: std::bad_alloc。

大概就是空间溢出,报错的函数是:imshow(“image”, image);
解决办法:。



好吧最后都没解决。


最后意识到自己的错误了,把配置的最后一步写错了,忘了给库文件名加上d,除此之外还需要把上一步添加的宏定义:CV_IGNORE_DEBUG_BUILD_GUARD 给删除。

不删除这个的话,只改掉库文件名依然会报错。

作业分析


认真阅读了作业文档后,一直在纠结自己到底要写哪一个部分,看了很久不知道要rasterizer需要写什么,最后发现,是需要理解rasterizer.hpp和修改main.cpp。




更具体的话,是只需要自己写main函数当中的 Matrix4f get_model_matrix(float rotation_angle) 还有 Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,float zNear, float zFar) 。

如果什么都不写的话,直接运行出来会显示出一根直线:

代码部分

尽自己可能理解一下

#include "Triangle.hpp"
#include "rasterizer.hpp"
#include 
#include 
#include 

using namespace std;
using namespace Eigen;
using namespace cv;

constexpr double MY_PI = 3.1415926;
//矩阵平移,上一个作业内容
Matrix4f get_view_matrix(Vector3f eye_pos)
{
    Matrix4f view = Matrix4f::Identity();

    Matrix4f translate;
    translate << 1, 0, 0, -eye_pos[0], 0, 1, 0, -eye_pos[1], 0, 0, 1,
        -eye_pos[2], 0, 0, 0, 1;

    view = translate * view;

    return view;
}
//矩阵绕z轴旋转,传入参数是旋转角度
//本次需要填写的内容
Matrix4f get_model_matrix(float rotation_angle)
{
    Matrix4f model = Matrix4f::Identity();
	//视频里面的成品公式直接代入
	Matrix4f rotation;
    float rot = rotation_angle * MY_PI / 180.0;
    rotation << cos(rot), -sin(rot), 0, 0,
        sin(rot), cos(rot), 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1;
    model = rotation * model;
    return model;
}
//透视投影,根据名字判断,4个参数分别是:上下可视角度,长宽比width / height,z近距离,z远距离(分别为视频5,5,4,4提到的内容)
//本次需要填写的内容
Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                      float zNear, float zFar)
{
    Matrix4f projection = Matrix4f::Identity();
	//其实也是视频里面成品公式直接代入,只不过需要理解怎么把上面给的参数给转换成我们需要的数据
	Matrix4f persp;
    Matrix4f ortho1,ortho2;

    float r, l, t, b, n, f;//视频里面老师举例子一模一样的参数,可以根据视频挨个对应
    float angle = eye_fov * MY_PI / 180.0 / 2;//只看上半部分,已经除以2
    n = zNear;
    f = zFar;
    t = tan(angle) * n;
    b = -tan(angle) * n;
    r = t * aspect_ratio;
    l = -t * aspect_ratio;

    persp << n, 0, 0, 0,//视频4最后的那道题的结果
        0, n, 0, 0,
        0, 0, n+f, -n*f,
        0, 0, 1, 0;

    ortho1 << 2 / (r - l), 0, 0, 0,
        0, 2 / (t - b), 0, 0,
        0, 0, 2 / (n - f), 0,
        0, 0, 0, 1;

    ortho2 << 1, 0, 0, -(r + l) / 2,
        0, 1, 0, -(t + b) / 2,
        0, 0, 1, -(n + f) / 2,
        0, 0, 0, 1;
        
    projection = ortho1 * ortho2 * persp * projection;
    return projection;
}

int main(int argc, const char** argv)
{
    float angle = 0;
	//使用命令行的方法来控制,这时候会保存到指定位置,注销了来区分一下两种输入方法
//    bool command_line = false;
//    string filename = "output.png";
    
//    if (argc >= 3) {
//        command_line = true;
//        angle = stof(argv[2]); // -r by default
//        if (argc == 4) {
//            filename = string(argv[3]);
//        }
//    }

    rst::rasterizer r(700, 700);

    Vector3f eye_pos = {0, 0, 5};

    vector<Vector3f> pos{{2, 0, -2}, {0, 2, -2}, {-2, 0, -2}};

    vector<Vector3i> ind{{0, 1, 2}};

    auto pos_id = r.load_positions(pos);
    auto ind_id = r.load_indices(ind);

    int key = 0;//键盘输入
    int frame_count = 0;//循环次数统计

    //使用命令行的部分,通过注销来区分一下,可以直接不用
    //if (command_line) {
    //    r.clear(rst::Buffers::Color | rst::Buffers::Depth);

    //    r.set_model(get_model_matrix(angle));
    //    r.set_view(get_view_matrix(eye_pos));
    //    r.set_projection(get_projection_matrix(45, 1, 0.1, 50));

    //    r.draw(pos_id, ind_id, rst::Primitive::Triangle);
    //    Mat image(700,700, CV_32FC3, r.frame_buffer().data());
    //    image.convertTo(image, CV_8UC3, 1.0f);

    //    imwrite(filename, image);

    //    return 0;
    //}

    while (key != 27) {//运行后输入esc退出
        r.clear(rst::Buffers::Color | rst::Buffers::Depth);
		//图形建立
        r.set_model(get_model_matrix(angle));
        r.set_view(get_view_matrix(eye_pos));
        r.set_projection(get_projection_matrix(45, 1, 0.1, 50));

        r.draw(pos_id, ind_id, rst::Primitive::Triangle);

        Mat image(700, 700, CV_32FC3, r.frame_buffer().data());
        image.convertTo(image, CV_8UC3, 1.0f);//图像的各种参数
        imshow("image", image);//显示图像
        key = waitKey(10);//每次等待一小段时间再刷新图片

        cout << "frame count: " << frame_count++ << '\n';//while循环次数统计

        if (key == 'a') {//输入a,角度+10
            angle += 10;
        }
        else if (key == 'd') {//输入b,角度-10
            angle -= 10;
        }
    }

    return 0;
}


运行结果

初始,以及按了两次a后的结果
i

疑问:

做的时候有个问题就是,按照这个参数给的方法,其实已经限定了透视投影的那个图形是一个在z的负轴上,对于x轴上下对称,y轴左右对称的一个图形。

其实很不能理解为什么可以默认这样,为什么不能在其他位置呢。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/674707.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存