diff --git a/CMakeLists.txt b/CMakeLists.txt index 31556e8..0d7a959 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ # 设置最小 cmake 版本 cmake_minimum_required(VERSION 3.27 FATAL_ERROR) + # 设置项目名与版本 project(SimpleRenderer VERSION 0.0.1) diff --git a/CMakePresets.json b/CMakePresets.json index cdab07d..d01acbd 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -2,20 +2,10 @@ "version": 6, "cmakeMinimumRequired": { "major": 3, - "minor": 27, + "minor": 23, "patch": 0 }, "configurePresets": [ - { - "name": "host", - "description": "Linux Only", - "hidden": true, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Linux" - } - }, { "name": "std", "description": "This preset makes sure the project actually builds with at least the specified standard", @@ -30,13 +20,10 @@ } }, { - "name": "configurePresets_base", + "name": "config-base", "hidden": true, - "inherits": [ - "host", - "std" - ], - "displayName": "configurePresets_base", + "inherits": [ "std" ], + "displayName": "config-base", "description": "base configurePresets", "binaryDir": "${sourceDir}/build", "cacheVariables": { @@ -58,14 +45,40 @@ } } }, + { + "name": "config-macos", + "hidden": true, + "inherits": [ "config-base" ], + "displayName": "config-base", + "description": "macOS configurePresets", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Darwin" + }, + "cacheVariables": { + "CMAKE_MACOSX_RPATH": "1", + "CMAKE_INSTALL_RPATH": "/Library/Frameworks", + "CMAKE_BUILD_WITH_INSTALL_RPATH": "TRUE" + } + }, { "name": "build", "hidden": false, "inherits": [ - "configurePresets_base" + "config-base" + ], + "displayName": "build-base", + "description": "build base configurePresets" + }, + { + "name": "build-macos", + "hidden": false, + "inherits": [ + "config-macos" ], - "displayName": "build", - "description": "build" + "displayName": "build-macos", + "description": "macOS build configurePresets" } ] } \ No newline at end of file diff --git a/cmake/3rd.cmake b/cmake/3rd.cmake index 496cbb8..2cf4f9e 100644 --- a/cmake/3rd.cmake +++ b/cmake/3rd.cmake @@ -57,27 +57,29 @@ CPMAddPackage( "gtest_force_shared_crt ON" ) -# https://github.com/aminosbh/sdl2-cmake-modules.git +# https://github.com/libsdl-org/SDL CPMAddPackage( - NAME sdl2-cmake-modules - GIT_REPOSITORY https://github.com/aminosbh/sdl2-cmake-modules.git - GIT_TAG ad006a3daae65a612ed87415037e32188b81071e - DOWNLOAD_ONLY True + NAME SDL2 + GITHUB_REPOSITORY libsdl-org/SDL + GIT_TAG release-2.30.6 + OPTIONS + "SDL2_DISABLE_INSTALL ON" + "SDL_SHARED OFF" + "SDL_STATIC ON" + "SDL_STATIC_PIC ON" + "SDL_WERROR OFF" ) -if (sdl2-cmake-modules_ADDED) - list(APPEND CMAKE_MODULE_PATH ${sdl2-cmake-modules_SOURCE_DIR}) -endif () -## https://github.com/freetype/freetype -#CPMAddPackage( -# NAME freetype -# GIT_REPOSITORY https://github.com/freetype/freetype.git -# GIT_TAG VER-2-13-0 -# VERSION 2.13.0 -#) -#if (freetype_ADDED) -# add_library(Freetype::Freetype ALIAS freetype) -#endif () +# # https://github.com/aminosbh/sdl2-cmake-modules.git +# CPMAddPackage( +# NAME sdl2-cmake-modules +# GIT_REPOSITORY https://github.com/aminosbh/sdl2-cmake-modules.git +# GIT_TAG ad006a3daae65a612ed87415037e32188b81071e +# DOWNLOAD_ONLY True +# ) +# if (sdl2-cmake-modules_ADDED) +# list(APPEND CMAKE_MODULE_PATH ${sdl2-cmake-modules_SOURCE_DIR}) +# endif () # https://github.com/tinyobjloader/tinyobjloader.git CPMAddPackage( @@ -95,6 +97,13 @@ if (tinyobjloader_ADDED) ) endif () +# https://github.com/g-truc/glm +CPMAddPackage( + NAME glm + GITHUB_REPOSITORY g-truc/glm + GIT_TAG 1.0.1 +) + # https://github.com/nothings/stb.git CPMAddPackage( NAME stb @@ -111,19 +120,6 @@ if (stb_ADDED) ) endif () -# https://gitlab.com/libeigen/eigen.git -CPMAddPackage( - NAME Eigen - GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git - GIT_TAG 3.4.0 - VERSION 3.4.0 - DOWNLOAD_ONLY True -) -if (Eigen_ADDED) - add_library(Eigen INTERFACE IMPORTED) - target_include_directories(Eigen INTERFACE ${Eigen_SOURCE_DIR}) -endif () - # http://wenq.org/wqy2/index.cgi?ZenHei CPMAddPackage( NAME wqy_font @@ -235,12 +231,6 @@ if (NOT LCOV_EXE) "Following https://github.com/linux-test-project/lcov to install.") endif () -find_package(SDL2 REQUIRED) -if (NOT SDL2_FOUND) - message(FATAL_ERROR "sdl2 not found.\n" - "Following https://github.com/libsdl-org/SDL to install.") -endif () - find_package(OpenMP REQUIRED) if (NOT OpenMP_FOUND) message(FATAL_ERROR "OpenMP not found.\n" @@ -251,4 +241,4 @@ find_package(spdlog REQUIRED) if (NOT spdlog_FOUND) message(FATAL_ERROR "spdlog not found.\n" "Following https://github.com/gabime/spdlog to install.") -endif () +endif () \ No newline at end of file diff --git a/cmake/compile_config.cmake b/cmake/compile_config.cmake index 330a14a..b82917f 100644 --- a/cmake/compile_config.cmake +++ b/cmake/compile_config.cmake @@ -17,8 +17,8 @@ list(APPEND DEFAULT_LINK_LIB spdlog::spdlog stb tinyobjloader - Eigen + glm::glm ${glog_LIBRARIES} - SDL2::Main + SDL2::SDL2 OpenMP::OpenMP_CXX ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2fbf564..d037097 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,31 +5,21 @@ # CMakeLists.txt for Simple-XX/SimpleRenderer. # 生成静态库 -add_library(${PROJECT_NAME} STATIC - log_system.cpp - color.cpp - include/vector.hpp - include/matrix.hpp - include/model.hpp - include/shader_base.h - include/default_shader.h - include/light.h - model.cpp - light.cpp - shader_base.cpp - default_shader.cpp - simple_renderer.cpp +file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS + "*.cpp" + "*.c" ) +add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) target_include_directories(${PROJECT_NAME} PRIVATE - $ - $ + $ + $ ) target_compile_options(${PROJECT_NAME} PRIVATE - ${DEFAULT_COMPILE_OPTIONS} + ${DEFAULT_COMPILE_OPTIONS} ) target_link_libraries(${PROJECT_NAME} PRIVATE - ${DEFAULT_LINK_LIB} + ${DEFAULT_LINK_LIB} ) diff --git a/src/default_shader.cpp b/src/default_shader.cpp index 4a90f8a..91a8f3d 100644 --- a/src/default_shader.cpp +++ b/src/default_shader.cpp @@ -23,23 +23,23 @@ auto DefaultShader::InterpolateColor( const Vector3f &barycentric_coord) -> Color { return Color( static_cast(static_cast(color0[Color::kColorIndexRed]) * - barycentric_coord.x() + + barycentric_coord.x + static_cast(color1[Color::kColorIndexRed]) * - barycentric_coord.y() + + barycentric_coord.y + static_cast(color2[Color::kColorIndexRed]) * - barycentric_coord.z()), + barycentric_coord.z), static_cast(static_cast(color0[Color::kColorIndexGreen]) * - barycentric_coord.x() + + barycentric_coord.x + static_cast(color1[Color::kColorIndexGreen]) * - barycentric_coord.y() + + barycentric_coord.y + static_cast(color2[Color::kColorIndexGreen]) * - barycentric_coord.z()), + barycentric_coord.z), static_cast(static_cast(color0[Color::kColorIndexBlue]) * - barycentric_coord.x() + + barycentric_coord.x + static_cast(color1[Color::kColorIndexBlue]) * - barycentric_coord.y() + + barycentric_coord.y + static_cast(color2[Color::kColorIndexBlue]) * - barycentric_coord.z())); + barycentric_coord.z)); } /// @todo 巨大性能开销 @@ -56,7 +56,8 @@ auto DefaultShader::Vertex(const ShaderVertexIn &shader_vertex_in) const auto DefaultShader::Fragment(const ShaderFragmentIn &shader_fragment_in) const -> ShaderFragmentOut { - auto intensity = (shader_fragment_in.normal_.dot(shader_fragment_in.light_)); + auto intensity = + glm::dot(shader_fragment_in.normal_, shader_fragment_in.light_); auto is_need_draw = true; // 光照方向为正,不绘制背面 if (intensity <= 0) { diff --git a/src/include/matrix.hpp b/src/include/matrix.hpp index 30a1e1b..c9de6a1 100755 --- a/src/include/matrix.hpp +++ b/src/include/matrix.hpp @@ -17,14 +17,13 @@ #ifndef SIMPLERENDER_SRC_INCLUDE_MATRIX_HPP_ #define SIMPLERENDER_SRC_INCLUDE_MATRIX_HPP_ -#include +#define GLM_ENABLE_EXPERIMENTAL +#include #include "log_system.h" namespace simple_renderer { - -using Matrix4f = Eigen::Matrix4f; - +using Matrix4f = glm::mat4; } // namespace simple_renderer /** @@ -32,11 +31,15 @@ using Matrix4f = Eigen::Matrix4f; */ template <> struct fmt::formatter : fmt::formatter { - auto format(simple_renderer::Matrix4f matrix, format_context &format_context) - const -> decltype(format_context.out()) { - std::stringstream buf; - buf << matrix; - return fmt::format_to(format_context.out(), "\n{}", buf.str()); + auto format(const simple_renderer::Matrix4f &matrix, + fmt::format_context &ctx) const -> decltype(ctx.out()) { + // Convert the Matrix4f to a string using glm::to_string + // 转化矩阵为字符串 + std::string matrix_str = glm::to_string(matrix); + + // Format and output the string + // 输出格式化后的字符串 + return fmt::format_to(ctx.out(), "\n{}", matrix_str); } }; diff --git a/src/include/model.hpp b/src/include/model.hpp index 635436e..fd782cd 100755 --- a/src/include/model.hpp +++ b/src/include/model.hpp @@ -40,7 +40,7 @@ class Model { /// 法向量 using Normal = Vector3f; /// 贴图 - using TextureCoord = Vector2f; + using TextureCoord = glm::vec2; class Material { public: diff --git a/src/include/shader_base.h b/src/include/shader_base.h index aa04937..b846eef 100644 --- a/src/include/shader_base.h +++ b/src/include/shader_base.h @@ -160,11 +160,11 @@ class ShaderFragmentOut { class ShaderData { public: /// 模型变换矩阵 - Matrix4f model_matrix_ = Matrix4f().setIdentity(); + Matrix4f model_matrix_ = Matrix4f(1.0f); /// 视图变换矩阵 - Matrix4f view_matrix_ = Matrix4f().setIdentity(); + Matrix4f view_matrix_ = Matrix4f(1.0f); /// 正交变换矩阵 - Matrix4f project_matrix_ = Matrix4f().setIdentity(); + Matrix4f project_matrix_ = Matrix4f(1.0f); /** * 构造函数 diff --git a/src/include/vector.hpp b/src/include/vector.hpp index eab8995..b0045f2 100755 --- a/src/include/vector.hpp +++ b/src/include/vector.hpp @@ -17,16 +17,17 @@ #ifndef SIMPLERENDER_SRC_INCLUDE_VECTOR_HPP_ #define SIMPLERENDER_SRC_INCLUDE_VECTOR_HPP_ -#include +#include + +#define GLM_ENABLE_EXPERIMENTAL +#include #include "log_system.h" namespace simple_renderer { - -using Vector2f = Eigen::Vector2f; -using Vector3f = Eigen::Vector3f; -using Vector4f = Eigen::Vector4f; - +using Vector2f = glm::vec2; +using Vector3f = glm::vec3; +using Vector4f = glm::vec4; } // namespace simple_renderer /** @@ -34,11 +35,12 @@ using Vector4f = Eigen::Vector4f; */ template <> struct fmt::formatter : fmt::formatter { - auto format(simple_renderer::Vector3f vector, format_context &format_context) - const -> decltype(format_context.out()) { - std::stringstream buf; - buf << vector; - return fmt::format_to(format_context.out(), "\n{}", buf.str()); + auto format(const simple_renderer::Vector3f &vector, + fmt::format_context &ctx) const -> decltype(ctx.out()) { + std::string vector_string = glm::to_string(vector); + + // Format and output the string + return fmt::format_to(ctx.out(), "\n{}", vector_string); } }; @@ -47,11 +49,12 @@ struct fmt::formatter : fmt::formatter { */ template <> struct fmt::formatter : fmt::formatter { - auto format(simple_renderer::Vector4f vector, format_context &format_context) - const -> decltype(format_context.out()) { - std::stringstream buf; - buf << vector; - return fmt::format_to(format_context.out(), "\n{}", buf.str()); + auto format(const simple_renderer::Vector4f &vector, + fmt::format_context &ctx) const -> decltype(ctx.out()) { + std::string vector_string = glm::to_string(vector); + + // Format and output the string + return fmt::format_to(ctx.out(), "\n{}", vector_string); } }; diff --git a/src/log_system.cpp b/src/log_system.cpp index dc8cc66..e6e7218 100755 --- a/src/log_system.cpp +++ b/src/log_system.cpp @@ -22,15 +22,17 @@ #include #include +#include + namespace simple_renderer { LogSystem::LogSystem(const std::string &log_file_path, size_t lig_file_max_size, size_t log_file_max_count) { spdlog::init_thread_pool(65536, 1); + // std::string log_file_paths = "./logs/simple_renderer.log"; auto stdout_sink = std::make_shared(); auto rotating_sink = std::make_shared( log_file_path, lig_file_max_size, log_file_max_count); - std::vector sinks{stdout_sink, rotating_sink}; logger_ = std::make_shared( "multi_sink", sinks.begin(), sinks.end(), spdlog::thread_pool(), diff --git a/src/model.cpp b/src/model.cpp index 8ce949b..fd2c857 100755 --- a/src/model.cpp +++ b/src/model.cpp @@ -16,6 +16,7 @@ #include "model.hpp" +#include #include #define TINYOBJLOADER_IMPLEMENTATION @@ -33,14 +34,19 @@ Model::Vertex::Vertex(Coord coord, Normal normal, TextureCoord texture_coord, color_(color) {} auto Model::Vertex::operator*(const Matrix4f &tran) const -> Model::Vertex { - auto vertex(*this); + Vertex vertex(*this); - auto res4 = Vector4f(coord_.x(), coord_.y(), coord_.z(), 1); - auto ret4 = Vector4f(tran * res4); + // Convert the 3D coordinate to a 4D vector by adding a 1.0 w-component + // 将 3D 坐标转换为 4D 向量,通过添加 1.0 w-分量 + Vector4f res4(coord_, 1.0f); - vertex.coord_.x() = ret4.x(); - vertex.coord_.y() = ret4.y(); - vertex.coord_.z() = ret4.z(); + // Apply the transformation matrix + // 应用变换矩阵 + Vector4f ret4 = tran * res4; + + // Update the vertex coordinates with the transformed values + // 使用变换后的值更新顶点坐标 + vertex.coord_ = Vector3f(ret4); /// @todo 变换法线 @@ -52,16 +58,17 @@ Model::Face::Face(const Model::Vertex &v0, const Model::Vertex &v1, : v0_(v0), v1_(v1), v2_(v2), material_(std::move(material)) { // 计算法向量 // 如果 obj 内包含法向量,直接使用即可 - if (v0.normal_.norm() != 0 && v1.normal_.norm() != 0 && - v2.normal_.norm() != 0) { - normal_ = (v0.normal_ + v1.normal_ + v2.normal_).normalized(); + if (glm::normalize(v0.normal_) != Vector3f(0.0f) && + glm::normalize(v1.normal_) != Vector3f(0.0f) && + glm::normalize(v2.normal_) != Vector3f(0.0f)) { + normal_ = glm::normalize((v0.normal_ + v1.normal_ + v2.normal_)); } // 手动计算 else { // 两条相临边的叉积 auto v2v0 = v2.coord_ - v0.coord_; auto v1v0 = v1.coord_ - v0.coord_; - normal_ = (v2v0.cross(v1v0)).normalized(); + normal_ = glm::normalize(glm::cross(v2v0, v1v0)); } } @@ -71,10 +78,10 @@ auto Model::Face::operator*(const Matrix4f &tran) const -> Model::Face { face.v1_ = face.v1_ * tran; face.v2_ = face.v2_ * tran; - /// @todo 通过矩阵变换法线 - auto v2v0 = face.v2_.coord_ - face.v0_.coord_; - auto v1v0 = face.v1_.coord_ - face.v0_.coord_; - face.normal_ = (v2v0.cross(v1v0)).normalized(); + // Calculate the transformed normal + Vector3f v2v0 = face.v2_.coord_ - face.v0_.coord_; + Vector3f v1v0 = face.v1_.coord_ - face.v0_.coord_; + face.normal_ = glm::normalize(glm::cross(v2v0, v1v0)); return face; } @@ -143,7 +150,7 @@ Model::Model(const std::string &obj_path, const std::string &mtl_path) // 如果法线索引存在(即 idx.normal_index >= 0), // 则构造并保存,否则设置为 0 - Normal normal = Normal::Zero(); + Normal normal = Vector3f(0.0f); if (idx.normal_index >= 0) { normal = Normal(attrib.normals[3 * size_t(idx.normal_index) + 0], attrib.normals[3 * size_t(idx.normal_index) + 1], @@ -152,7 +159,7 @@ Model::Model(const std::string &obj_path, const std::string &mtl_path) // 如果贴图索引存在(即 idx.texcoord_index >= 0), // 则构造并保存,否则设置为 0 - TextureCoord texture_coord = TextureCoord::Zero(); + TextureCoord texture_coord = Vector3f(0.0f); if (idx.texcoord_index >= 0) { texture_coord = TextureCoord( attrib.texcoords[2 * size_t(idx.texcoord_index) + 0], @@ -213,27 +220,27 @@ std::pair Model::GetMaxMinXYX() { std::numeric_limits::max()); for (const auto &i : faces_) { - auto curr_max_x = std::max(i.v0_.coord_.x(), - std::max(i.v1_.coord_.x(), i.v2_.coord_.x())); - auto curr_max_y = std::max(i.v0_.coord_.y(), - std::max(i.v1_.coord_.y(), i.v2_.coord_.y())); - auto curr_max_z = std::max(i.v0_.coord_.z(), - std::max(i.v1_.coord_.z(), i.v2_.coord_.z())); - - max.x() = curr_max_x > max.x() ? curr_max_x : max.x(); - max.y() = curr_max_y > max.y() ? curr_max_y : max.y(); - max.z() = curr_max_z > max.z() ? curr_max_z : max.z(); - - auto curr_min_x = std::min(i.v0_.coord_.x(), - std::min(i.v1_.coord_.x(), i.v2_.coord_.x())); - auto curr_min_y = std::min(i.v0_.coord_.y(), - std::min(i.v1_.coord_.y(), i.v2_.coord_.y())); - auto curr_min_z = std::min(i.v0_.coord_.z(), - std::min(i.v1_.coord_.z(), i.v2_.coord_.z())); - - min.x() = curr_min_x < min.x() ? curr_min_x : min.x(); - min.y() = curr_min_y < min.y() ? curr_min_y : min.y(); - min.z() = curr_min_z < min.z() ? curr_min_z : min.z(); + auto curr_max_x = + std::max(i.v0_.coord_.x, std::max(i.v1_.coord_.x, i.v2_.coord_.x)); + auto curr_max_y = + std::max(i.v0_.coord_.y, std::max(i.v1_.coord_.y, i.v2_.coord_.y)); + auto curr_max_z = + std::max(i.v0_.coord_.z, std::max(i.v1_.coord_.z, i.v2_.coord_.z)); + + max.x = curr_max_x > max.x ? curr_max_x : max.x; + max.y = curr_max_y > max.y ? curr_max_y : max.y; + max.z = curr_max_z > max.z ? curr_max_z : max.z; + + auto curr_min_x = + std::min(i.v0_.coord_.x, std::min(i.v1_.coord_.x, i.v2_.coord_.x)); + auto curr_min_y = + std::min(i.v0_.coord_.y, std::min(i.v1_.coord_.y, i.v2_.coord_.y)); + auto curr_min_z = + std::min(i.v0_.coord_.z, std::min(i.v1_.coord_.z, i.v2_.coord_.z)); + + min.x = curr_min_x < min.x ? curr_min_x : min.x; + min.y = curr_min_y < min.y ? curr_min_y : min.y; + min.z = curr_min_z < min.z ? curr_min_z : min.z; } return {max, min}; } @@ -241,25 +248,34 @@ std::pair Model::GetMaxMinXYX() { void Model::Normalize() { auto [max, min] = GetMaxMinXYX(); - auto x = std::abs(max.x()) + std::abs(min.x()); - auto y = std::abs(max.y()) + std::abs(min.y()); - auto z = std::abs(max.z()) + std::abs(min.z()); + // Compute the dimensions of the bounding box + auto x = std::abs(max.x) + std::abs(min.x); + auto y = std::abs(max.y) + std::abs(min.y); + auto z = std::abs(max.z) + std::abs(min.z); + // Calculate the scaling factor auto scale = 1.0f / std::max(x, std::max(y, z)); - auto scale_matrix = Matrix4f(Matrix4f::Identity()); - scale_matrix.diagonal() << scale, scale, scale, 1; - auto center = Coord((max.x() + min.x()) / 2.f, (max.y() + min.y()) / 2.f, - (max.z() + min.z()) / 2.f); - auto translation_matrix = Matrix4f(Matrix4f::Identity()); - translation_matrix.col(translation_matrix.cols() - 1) << -center.x(), - -center.y(), -center.z(), 1; + // Create the scaling matrix + Matrix4f scale_matrix = + glm::scale(Matrix4f(1.0f), Vector3f(scale, scale, scale)); + + // Calculate the center of the bounding box + Vector3f center = Vector3f((max.x + min.x) / 2.0f, (max.y + min.y) / 2.0f, + (max.z + min.z) / 2.0f); + + // Create the translation matrix + Matrix4f translation_matrix = glm::translate(Matrix4f(1.0f), -center); - auto matrix = Matrix4f(scale_matrix * translation_matrix); + // Combine the scaling and translation matrices + Matrix4f normalization_matrix = scale_matrix * translation_matrix; - SPDLOG_DEBUG("matrix: {}", matrix); + // Debug output + SPDLOG_DEBUG("normalization_matrix: \n{}", + glm::to_string(normalization_matrix)); - *this = *this * matrix; + // Apply the normalization matrix to the model + *this = *this * normalization_matrix; } } // namespace simple_renderer diff --git a/src/scene.cpp b/src/scene.cpp deleted file mode 100644 index 49c48e9..0000000 --- a/src/scene.cpp +++ /dev/null @@ -1,43 +0,0 @@ - -/** - * @file scene.cpp - * @brief 场景抽象 - * @author Zone.N (Zone.Niuzh@hotmail.com) - * @version 1.0 - * @date 2022-12-15 - * @copyright MIT LICENSE - * https://github.com/Simple-XX/SimpleRenderer - * @par change log: - * - *
DateAuthorDescription - *
2022-12-15Zone.N创建文件 - *
- */ - -#include "scene.h" -#include "log_system.h" -#include "matrix.hpp" - -namespace simple_renderer { - -scene_t::scene_t(const std::string &_name, uint64_t _x, uint64_t _y, - uint64_t _z) - : name(_name), x(_x), y(_y), z(_z) {} - -void scene_t::add_model(const model_t &_model, const vector3f_t _pos) { - models.push_back(std::pair(_model, _pos)); - SPDLOG_LOGGER_INFO(SRLOG, "add_model: {} to: {}, total: {}", _model.obj_path, - name, models.size()); -} - -void scene_t::add_light(const light_t &_light) { - lights.push_back(_light); - SPDLOG_LOGGER_INFO(SRLOG, "add_light: {} to: {}", _light.name, name); -} - -void scene_t::add_camera(const SimpleRenderer::camera_t &_camera) { - camera = _camera; - SPDLOG_LOGGER_INFO(SRLOG, "add_camera: {} to: {}", _camera.name, name); -} - -} // namespace SimpleRenderer diff --git a/src/simple_renderer.cpp b/src/simple_renderer.cpp index c259899..cee8747 100755 --- a/src/simple_renderer.cpp +++ b/src/simple_renderer.cpp @@ -135,25 +135,25 @@ void SimpleRenderer::DrawTriangle(const ShaderBase &shader, const Light &light, // 获取三角形的最小 box auto min = v0.coord_; auto max = v1.coord_; - auto max_x = std::max(face.v0_.coord_.x(), - std::max(face.v1_.coord_.x(), face.v2_.coord_.x())); - auto max_y = std::max(face.v0_.coord_.y(), - std::max(face.v1_.coord_.y(), face.v2_.coord_.y())); - max.x() = max_x > max.x() ? max_x : max.x(); - max.y() = max_y > max.y() ? max_y : max.y(); - max.z() = 0; - auto min_x = std::min(face.v0_.coord_.x(), - std::min(face.v1_.coord_.x(), face.v2_.coord_.x())); - auto min_y = std::min(face.v0_.coord_.y(), - std::min(face.v1_.coord_.y(), face.v2_.coord_.y())); - min.x() = min_x < min.x() ? min_x : min.x(); - min.y() = min_y < min.y() ? min_y : min.y(); - min.z() = 0; + auto max_x = std::max(face.v0_.coord_.x, + std::max(face.v1_.coord_.x, face.v2_.coord_.x)); + auto max_y = std::max(face.v0_.coord_.y, + std::max(face.v1_.coord_.y, face.v2_.coord_.y)); + max.x = max_x > max.x ? max_x : max.x; + max.y = max_y > max.y ? max_y : max.y; + max.z = 0; + auto min_x = std::min(face.v0_.coord_.x, + std::min(face.v1_.coord_.x, face.v2_.coord_.x)); + auto min_y = std::min(face.v0_.coord_.y, + std::min(face.v1_.coord_.y, face.v2_.coord_.y)); + min.x = min_x < min.x ? min_x : min.x; + min.y = min_y < min.y ? min_y : min.y; + min.z = 0; #pragma omp parallel for num_threads(kNProc) collapse(2) default(none) \ shared(min, max, v0, v1, v2, shader) firstprivate(normal, light) - for (auto x = int32_t(min.x()); x <= int32_t(max.x()); x++) { - for (auto y = int32_t(min.y()); y <= int32_t(max.y()); y++) { + for (auto x = int32_t(min.x); x <= int32_t(max.x); x++) { + for (auto y = int32_t(min.y); y <= int32_t(max.y); y++) { /// @todo 这里要用裁剪替换掉 if ((unsigned)x >= width_ || (unsigned)y >= height_) { continue; @@ -166,7 +166,7 @@ void SimpleRenderer::DrawTriangle(const ShaderBase &shader, const Light &light, continue; } // 计算该点的深度,通过重心坐标插值计算 - auto z = InterpolateDepth(v0.coord_.z(), v1.coord_.z(), v2.coord_.z(), + auto z = InterpolateDepth(v0.coord_.z, v1.coord_.z, v2.coord_.z, barycentric_coord); // 深度在已有颜色之上 if (z < depth_buffer_[y * width_ + x]) { @@ -202,12 +202,12 @@ void SimpleRenderer::DrawModel(const ShaderBase &shader, const Light &light, for (const auto &f : model.GetFace()) { /// @todo 巨大性能开销 auto face = shader.Vertex(ShaderVertexIn(f)).face_; - DrawLine(face.v0_.coord_.x(), face.v0_.coord_.y(), face.v1_.coord_.x(), - face.v1_.coord_.y(), Color::kRed); - DrawLine(face.v1_.coord_.x(), face.v1_.coord_.y(), face.v2_.coord_.x(), - face.v2_.coord_.y(), Color::kGreen); - DrawLine(face.v2_.coord_.x(), face.v2_.coord_.y(), face.v0_.coord_.x(), - face.v0_.coord_.y(), Color::kBlue); + DrawLine(face.v0_.coord_.x, face.v0_.coord_.y, face.v1_.coord_.x, + face.v1_.coord_.y, Color::kRed); + DrawLine(face.v1_.coord_.x, face.v1_.coord_.y, face.v2_.coord_.x, + face.v2_.coord_.y, Color::kGreen); + DrawLine(face.v2_.coord_.x, face.v2_.coord_.y, face.v0_.coord_.x, + face.v0_.coord_.y, Color::kBlue); } } if (draw_triangle) { @@ -229,17 +229,17 @@ auto SimpleRenderer::GetBarycentricCoord(const Vector3f &p0, const Vector3f &p1, auto p2p0 = p2 - p0; auto pap0 = pa - p0; - auto deno = (p1p0.x() * p2p0.y() - p1p0.y() * p2p0.x()); + auto deno = (p1p0.x * p2p0.y - p1p0.y * p2p0.x); if (std::abs(deno) < std::numeric_limits::epsilon()) { return std::pair{false, Vector3f()}; } - auto s = (p2p0.y() * pap0.x() - p2p0.x() * pap0.y()) / deno; + auto s = (p2p0.y * pap0.x - p2p0.x * pap0.y) / deno; if ((s > 1) || (s < 0)) { return std::pair{false, Vector3f()}; } - auto t = (p1p0.x() * pap0.y() - p1p0.y() * pap0.x()) / deno; + auto t = (p1p0.x * pap0.y - p1p0.y * pap0.x) / deno; if ((t > 1) || (t < 0)) { return std::pair{false, Vector3f()}; } @@ -254,9 +254,9 @@ auto SimpleRenderer::GetBarycentricCoord(const Vector3f &p0, const Vector3f &p1, auto SimpleRenderer::InterpolateDepth(float depth0, float depth1, float depth2, const Vector3f &_barycentric_coord) -> float { - auto depth = depth0 * _barycentric_coord.x(); - depth += depth1 * _barycentric_coord.y(); - depth += depth2 * _barycentric_coord.z(); + auto depth = depth0 * _barycentric_coord.x; + depth += depth1 * _barycentric_coord.y; + depth += depth2 * _barycentric_coord.z; return depth; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a568aeb..8872e67 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,30 +14,31 @@ enable_testing() include(GoogleTest) include_directories( - ${SimpleRenderer_SOURCE_DIR}/src/include + ${SimpleRenderer_SOURCE_DIR}/src/include ) list(APPEND DEFAULT_TEST_COMPILE_OPTIONS - ${DEFAULT_COMPILE_OPTIONS} - --coverage + ${DEFAULT_COMPILE_OPTIONS} + --coverage ) list(APPEND DEFAULT_TEST_LINK_OPTIONS - --coverage - $<$: - # -fsanitize=leak - > - # -fsanitize=address - -fno-omit-frame-pointer + --coverage + $<$: + # -fsanitize=leak + > + # -fsanitize=address + -fno-omit-frame-pointer ) link_libraries( - ${DEFAULT_LINK_LIB} - gtest_main - ${glog_LIBRARIES} - SimpleRenderer + ${DEFAULT_LINK_LIB} + gtest_main + ${glog_LIBRARIES} + SimpleRenderer ) + add_subdirectory(unit_test) #add_subdirectory(integration_test) add_subdirectory(system_test) diff --git a/test/system_test/main.cpp b/test/system_test/main.cpp index 6000cd2..63cb649 100755 --- a/test/system_test/main.cpp +++ b/test/system_test/main.cpp @@ -59,11 +59,18 @@ int main(int argc, char **argv) { // objs.emplace_back(obj_path + "/african_head.obj"); objs.emplace_back(obj_path + "/utah-teapot/utah-teapot.obj"); - - auto matrix = - simple_renderer::Matrix4f(simple_renderer::Matrix4f::Identity()); - matrix.diagonal() << 500, 500, 500, 1; - matrix.col(matrix.cols() - 1) << kWidth / 2, kHeight / 2, 0, 1; + auto matrix = simple_renderer::Matrix4f(1.0f); + simple_renderer::Matrix4f scale_matrix = + glm::scale(simple_renderer::Matrix4f(1.0f), + simple_renderer::Vector3f(500.0f, 500.0f, 500.0f)); + + // Translation matrix + simple_renderer::Matrix4f translation_matrix = glm::translate( + simple_renderer::Matrix4f(1.0f), + simple_renderer::Vector3f(kWidth / 2.0f, kHeight / 2.0f, 0.0f)); + + // Combined transformation matrix + matrix = translation_matrix * scale_matrix; // 矩阵运算的顺序 // 归一化