目录
- VSCode
- Clion
- CMakeList.txt
VSCode
-
brew install cmake
-
更换下载源为阿里云下载 opencv,不然会很慢
cd "$(brew --repo)" git remote -v cd "$(brew --repo)" git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core" git remote set-url origin https://mirrors.aliyun.com/homebrew/homebrew-core.git echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.bash_profile source ~/.bash_profile
其中,
git remote -v
表示查看当前下载源 -
brew install opencv
-
用 VSCode 打开作业一文件夹,新建终端
cd ~/GitProjects/GAMES101/Assignment2 mkdir build cd build cmake ../ make
编译成功
现在是这个样子
-
之后不要去管那个 opencv 头文件引用失败,也不要去直接点右上角那个运行的按钮
头文件引用失败是因为 intellisence 工具(用来代码自动填充,文件自动索引)的问题,只要是 CMake 运行成功,那就说明项目配置是正确的,如果要修改,那么需要修改文件 c_cpp_properties.json,具体情况我就不知道了(我没成功)
.
右上角运行按钮需要自己再配置调试运行文件,一般是 C++(GDB/LLDB) ,有个 launch.json 文件,如果使用这种方法,里面的参数需要修改 -
仍然在终端,输入
./Rasterizer
即可运行代码,会有一个弹窗,里面是一条白线,因为你还没与实现投影矩阵函数。 -
你可以先把整个文件的代码替换为下方代码,再执行一遍流程
#include "Triangle.hpp"
#include "rasterizer.hpp"
#include <eigen3/Eigen/Eigen>
#include <iostream>
#include <opencv2/opencv.hpp>constexpr double MY_PI = 3.1415926;Eigen::Matrix4f get_view_matrix(Eigen::Vector3f eye_pos)
{Eigen::Matrix4f view = Eigen::Matrix4f::Identity();Eigen::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;
}Eigen::Matrix4f get_model_matrix(float rotation_angle)
{Eigen::Matrix4f model = Eigen::Matrix4f::Identity();// TODO: Implement this function// Create the model matrix for rotating the triangle around the Z axis.// Then return it.float a = rotation_angle / 180.0 * MY_PI;;model << cos(a), -sin(a), 0, 0,sin(a), cos(a), 0, 0,0, 0, 1, 0,0, 0, 0, 1;return model;
}Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,float zNear, float zFar)
{// Students will implement this functionEigen::Matrix4f projection = Eigen::Matrix4f::Identity();// TODO: Implement this function// Create the projection matrix for the given parameters.// Then return it.// 1. 透视投影转为正交投影矩阵float n = zNear;float f = zFar;Eigen::Matrix4f M_persp2Ortho;M_persp2Ortho << n, 0, 0, 0,0, n, 0, 0,0, 0, n + f, -n * f,0, 0, 1, 0;// 2. 正交投影转换到正则立方体float fov = eye_fov * MY_PI / 180.0;float t = -n * tan(fov / 2.);float b = -t;float r = aspect_ratio * t;float l = -r;Eigen::Matrix4f M_ortho, trans, scale;trans << 1, 0, 0, -(r+l)/2,0, 1, 0, -(t+b)/2,0, 0, 1, -(n+f)/2,0, 0, 0, 1;scale << 2/(r-l), 0, 0, 0,0, 2/(t-b), 0, 0,0, 0, 2/(n-f), 0,0, 0, 0, 1;M_ortho = scale * trans;projection = M_ortho * M_persp2Ortho ;return projection;
}int main(int argc, const char** argv)
{float angle = 0;bool command_line = false;std::string filename = "output.png";if (argc >= 3) {command_line = true;angle = std::stof(argv[2]); // -r by defaultif (argc == 4) {filename = std::string(argv[3]);}}rst::rasterizer r(700, 700);Eigen::Vector3f eye_pos = {0, 0, 5};std::vector<Eigen::Vector3f> pos{{2, 0, -2}, {0, 2, -2}, {-2, 0, -2}};std::vector<Eigen::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);cv::Mat image(700, 700, CV_32FC3, r.frame_buffer().data());image.convertTo(image, CV_8UC3, 1.0f);cv::imwrite(filename, image);return 0;}while (key != 27) {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);cv::Mat image(700, 700, CV_32FC3, r.frame_buffer().data());image.convertTo(image, CV_8UC3, 1.0f);cv::imshow("image", image);key = cv::waitKey(10);std::cout << "frame count: " << frame_count++ << '\n';if (key == 'a') {angle += 10;}else if (key == 'd') {angle -= 10;}}return 0;
}
看看结果是不是
会发现这个窗口的关闭按钮无法点击,回到 VSCode 的终端,command + c 可以停止(terminate)运行程序,如果是 command + z,挂起(suspend)程序
Clion
直接打开文件夹,之后会提示你选择哪个 CMakeListi.txt 文件,选择项目中的即可,点击运行,出现窗口,点击关闭,结束运行。
CMakeList.txt
cmake_minimum_required(VERSION 3.10)
project(Rasterizer)find_package(OpenCV REQUIRED)set(CMAKE_CXX_STANDARD 17)include_directories(/usr/local/include)add_executable(Rasterizer main.cpp rasterizer.hpp rasterizer.cpp Triangle.hpp Triangle.cpp)
target_link_libraries(Rasterizer ${OpenCV_LIBRARIES})
这个文件能很好适配 mac,看第5行的附加包含目录 /usr/local/include
即可看出
-
project() 表示此项目名
-
include_directories(/usr/local/include)
相当于附加包含目录,能够直接引用该目录下的头文件,即引用该文件夹下的头文件不会标红线 -
add_executable(Rasterizer main.cpp rasterizer.hpp rasterizer.cpp Triangle.hpp Triangle.cpp)
根据传入的四个参数文件,生成项目的可执行文件 Rasterizer这个指令非常好用,可以让你在一个 project 中运行多个拥有各自 main() 的 .cpp 文件,适合写 io 题
-
两行代码主要是让CMake可以使用 opencv2,因为 opencv2 文件被包含在了 opencv4 文件中,如果不添加这两段代码,直接使用 opencv2,编译器无法找到。
find_package(OpenCV REQUIRED) target_link_libraries(Rasterizer ${OpenCV_LIBRARIES})
(除了这种方法,可以自己手动添加一个 opencv2 的软链接,但没有必要。因为正常安装下,cmake文件中会自动包含有 opencv4 的软链接,如下图。这个里面包含了很多 .cmake 文件,像 OpenCV_DIR, OpenCV_INCLUDE_DIRS, OpenCV_LIBS 这些变量 cmake 都能自动获取到,只要在 CMakeLists.txt 里加上面两行就能正常使用,此信息来自于文章
https://blog.csdn.net/a13602955218/article/details/101625857
的评论区)