From 94759bb51fb56be877ff4520fd4b91d890a344b4 Mon Sep 17 00:00:00 2001 From: "tianlei.richard" Date: Fri, 1 Mar 2024 21:31:47 +0800 Subject: [PATCH] Implement some common class. --- .gitignore | 4 +++- src/CMakeLists.txt | 9 +++------ src/minus_renderer.cc | 23 +++++++++++++++-------- src/rasterizer.cc | 24 ++++++++++++++++++++++++ src/rasterizer.h | 24 ++++++++++++++++++++++++ src/triangle.cc | 40 ++++++++++++++++++++++++++++++++++++++++ src/triangle.h | 40 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 149 insertions(+), 15 deletions(-) create mode 100644 src/rasterizer.cc create mode 100644 src/rasterizer.h create mode 100644 src/triangle.cc create mode 100644 src/triangle.h diff --git a/.gitignore b/.gitignore index 7b53a75..bbe7deb 100644 --- a/.gitignore +++ b/.gitignore @@ -205,5 +205,7 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +.idea/ +# Visual Studio Code +.vscode diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c98216..63759f0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,10 +1,7 @@ cmake_minimum_required(VERSION 3.9) PROJECT(renderer) - aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} CPP_FILES) -foreach(FILE_PATH ${CPP_FILES}) - get_filename_component(FILE_NAME ${FILE_PATH} NAME_WLE) - add_executable(${FILE_NAME} ${FILE_PATH}) - target_link_libraries(${FILE_NAME} LINK_PUBLIC spdlog eigen ${OpenCV_LIBS}) -endforeach() + +add_executable(${CMAKE_PROJECT_NAME} ${CPP_FILES}) +target_link_libraries(${CMAKE_PROJECT_NAME} LINK_PUBLIC spdlog eigen ${OpenCV_LIBS}) diff --git a/src/minus_renderer.cc b/src/minus_renderer.cc index e3511aa..5a0124b 100644 --- a/src/minus_renderer.cc +++ b/src/minus_renderer.cc @@ -1,3 +1,6 @@ +// Copyright 2024 Bytedance Inc. All Rights Reserved. +// Author: tianlei.richard@qq.com (tianlei.richard) + #include #include @@ -6,18 +9,22 @@ #include "spdlog/spdlog.h" #include "spdlog/fmt/ostr.h" // github.com/gabime/spdlog/issues/1638 +#include "rasterizer.h" +#include "triangle.h" + using namespace Eigen; using namespace cv; -int main(int argc, char* argv[]) { - spdlog::info("Hello, world."); +int main(int argc, char *argv[]) { - MatrixXd m(2,2); - m(0,0) = 3; - m(1,0) = 2.5; - m(0,1) = -1; - m(1,1) = m(1,0) + m(0,1); - spdlog::info("\n{}", m); + const int width = 1280; + const int height = 720; + + Triangle t{Triangle::PointType{1, 1, 0}, Triangle::PointType{3, 1, 0}, + Triangle::PointType{2, 4, 0}}; + + Rasterizer rasterizer{width, height}; + rasterizer.rasterize(t); return 0; } diff --git a/src/rasterizer.cc b/src/rasterizer.cc new file mode 100644 index 0000000..bdbaff1 --- /dev/null +++ b/src/rasterizer.cc @@ -0,0 +1,24 @@ +// Copyright 2024 Bytedance Inc. All Rights Reserved. +// Author: tianlei.richard@qq.com (tianlei.richard) + +#include "rasterizer.h" +#include + +Rasterizer::Rasterizer(const int width, const int height) + : width_(width), height_(height), + pixels_(std::vector>( + height, + std::vector(width, std::numeric_limits::infinity()))) {} + +void Rasterizer::rasterize(const Triangle &t) { + const auto &aabb = t.axis_align_bbox(); + const int x_min = aabb.x; + const int x_max = aabb.x + aabb.width; + const int y_min = aabb.y; + const int y_max = aabb.y + aabb.height; + + for (int i = x_min; i < x_max; ++i) { + for (int j = y_min; j < y_max; ++j) { + } + } +} diff --git a/src/rasterizer.h b/src/rasterizer.h new file mode 100644 index 0000000..36d3748 --- /dev/null +++ b/src/rasterizer.h @@ -0,0 +1,24 @@ +// Copyright 2024 Bytedance Inc. All Rights Reserved. +// Author: tianlei.richard@qq.com (tianlei.richard) + +#pragma once + +#include "triangle.h" +#include +#include + +class Rasterizer { +public: + using RasterizeRange = cv::Rect2i; + +public: + Rasterizer(const int width, const int height); + +public: + void rasterize(const Triangle &t); + +private: + int width_; + int height_; + std::vector> pixels_; +}; diff --git a/src/triangle.cc b/src/triangle.cc new file mode 100644 index 0000000..1a4a34e --- /dev/null +++ b/src/triangle.cc @@ -0,0 +1,40 @@ +// Copyright 2024 Bytedance Inc. All Rights Reserved. +// Author: tianlei.richard@qq.com (tianlei.richard) + +#include "triangle.h" +#include + +Triangle::Triangle(const PointType &a, const PointType &b, const PointType &c) + : points_({HomoPointType{a[0], a[1], a[2], 1}, + HomoPointType{b[0], b[1], b[2], 1}, + HomoPointType{c[0], c[1], c[2], 1}}), + aabb_(calculate_aabb(points_[0], points_[1], points_[2])) {} + +Triangle::Triangle(const HomoPointType &a, const HomoPointType &b, + const HomoPointType &c) + : points_({a, b, c}), + aabb_(calculate_aabb(points_[0], points_[1], points_[2])) {} + +Triangle::BBoxType Triangle::calculate_aabb(const HomoPointType &a, + const HomoPointType &b, + const HomoPointType &c) { + const int x_min = std::min({a.x(), b.x(), c.x()}); + const int y_min = std::min({a.y(), b.y(), c.y()}); + const int x_max = std::max({a.x(), b.x(), c.x()}); + const int y_max = std::max({a.y(), b.y(), c.y()}); + return BBoxType{x_min, y_min, (x_max - x_min), (y_max - y_min)}; +} + +Triangle::BBoxType Triangle::axis_align_bbox() const { return aabb_; } + +void Triangle::affine_transform(const AffineTransformType &m) { + for (auto &p : points_) { + p = m * p; + } +} + +void Triangle::projective_transform(const ProjectiveTransformType &m) { + for (auto &p : points_) { + p = m * p; + } +} diff --git a/src/triangle.h b/src/triangle.h new file mode 100644 index 0000000..4979790 --- /dev/null +++ b/src/triangle.h @@ -0,0 +1,40 @@ +// Copyright 2024 Bytedance Inc. All Rights Reserved. +// Author: tianlei.richard@qq.com (tianlei.richard) + +#pragma once + +#include +#include +#include +#include + +class Triangle { +public: + using AffineTransformType = Eigen::Transform; + using ProjectiveTransformType = + Eigen::Transform; + using PointType = Eigen::Vector3d; + using BBoxType = cv::Rect2i; + +private: + using HomoPointType = Eigen::Vector4d; + +public: + Triangle(const PointType &a, const PointType &b, const PointType &c); + Triangle(const HomoPointType &a, const HomoPointType &b, + const HomoPointType &c); + +public: + BBoxType axis_align_bbox() const; + + void affine_transform(const AffineTransformType &m); + void projective_transform(const ProjectiveTransformType &m); + +private: + static BBoxType calculate_aabb(const HomoPointType &a, const HomoPointType &b, + const HomoPointType &c); + +private: + std::array points_; + BBoxType aabb_; +};