MinusculeRender/src/minus_renderer.cc

107 lines
3.5 KiB
C++
Raw Normal View History

2024-03-01 21:31:47 +08:00
// Copyright 2024 Bytedance Inc. All Rights Reserved.
// Author: tianlei.richard@qq.com (tianlei.richard)
2024-03-06 22:23:48 +08:00
#include <cmath>
#include <iostream>
#include "minus_renderer.h"
2024-03-01 21:31:47 +08:00
#include "rasterizer.h"
2024-03-06 22:23:48 +08:00
#include "spdlog/spdlog.h"
2024-03-01 16:00:08 +08:00
MinusRenderer::MinusRenderer(float near, float far, float fov,
float aspect_ratio,
std::vector<Triangle> &&primitives)
: near_(near), far_(far), fov_(fov), aspect_ratio_(aspect_ratio),
height_(calculate_height(fov, near)),
2024-03-06 22:23:48 +08:00
width_(calculate_width(height_, aspect_ratio)), primitives_(primitives) {
spdlog::info("fov: {}, aspect ratio: {}, width: {}, height: {}", fov_,
aspect_ratio_, width_, height_);
}
2024-03-01 21:31:47 +08:00
2024-03-06 22:23:48 +08:00
float MinusRenderer::calculate_height(const float fov, const float near) {
return std::fabs(near) * std::tan(fov * 0.5) * 2;
}
2024-03-01 21:31:47 +08:00
2024-03-06 22:23:48 +08:00
float MinusRenderer::calculate_width(const float height, const float ratio) {
return height * ratio;
}
2024-03-01 16:00:08 +08:00
2024-03-06 22:23:48 +08:00
TransformMatrix MinusRenderer::squish_tranform() {
// Frustum to Cuboid
return TransformMatrix{{near_, 0, 0, 0},
{0, near_, 0, 0},
{0, 0, near_ + far_, -near_ * far_},
{0, 0, 1, 0}};
}
TransformMatrix MinusRenderer::orthographic_tranform() {
const auto right = width_ * 0.5;
const auto left = -right;
const auto top = height_ * 0.5;
const auto bottom = -top;
spdlog::info("near: {}, far: {}, top: {}, bottom: {}, left: {}, right: {}",
near_, far_, top, bottom, left, right);
TransformMatrix m{{1, 0, 0, -0.5 * (right - left)},
{0, 1, 0, -0.5 * (top - bottom)},
{0, 0, 1, -0.5 * (far_ - near_)},
{0, 0, 0, 1}};
m = TransformMatrix{{2 / (right - left), 0, 0, 0},
{0, 2 / (top - bottom), 0, 0},
{0, 0, 2 / std::fabs(far_ - near_), 0},
{0, 0, 0, 1}} *
m;
std::cout << m << '\n';
return m;
}
TransformMatrix MinusRenderer::view_port_transform() {
return TransformMatrix{{width_ * 0.5, 0, 0, width_ * 0.5},
{0, height_ * 0.5, 0, height_ * 0.5},
{0, 0, 1, 0},
{0, 0, 0, 1}};
}
void MinusRenderer::model_transform(const TransformMatrix &m) {
for (auto &t : primitives_) {
t.affine_transform(m);
}
}
2024-03-01 16:00:08 +08:00
cv::Mat MinusRenderer::render(const int resolution_width,
const int resolution_height) {
2024-03-06 22:23:48 +08:00
std::vector<Triangle> primitives;
for (const auto &t : primitives_) {
primitives.push_back(t);
}
for (auto &t : primitives) {
t.projective_transform(squish_tranform());
t.affine_transform(orthographic_tranform());
t.affine_transform(view_port_transform());
}
Rasterizer rasterizer{resolution_width, resolution_height};
2024-03-06 22:23:48 +08:00
const auto &pixels = rasterizer.rasterize(primitives);
assert(!pixels.empty());
cv::Mat color_image(pixels.size(), (pixels[0]).size(), CV_8UC3);
for (int i = 0; i < pixels.size(); ++i) {
const auto &row = pixels[i];
for (int j = 0; j < row.size(); ++j) {
auto &pixel_color = color_image.at<cv::Vec3b>(pixels.size() - i - 1, j);
pixel_color =
cv::Vec3b{static_cast<unsigned char>(
row[j].x() * std::numeric_limits<char>::max()),
static_cast<unsigned char>(
row[j].y() * std::numeric_limits<char>::max()),
static_cast<unsigned char>(
row[j].z() * std::numeric_limits<char>::max())};
}
}
return color_image;
2024-03-01 16:00:08 +08:00
}