From 3d152d77f89ce5144db27367eb3a89e6aa4d4ce0 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Fri, 14 Mar 2025 12:11:16 +0300 Subject: [PATCH] Draft of matrix projections --- programs/lab5/src/main.cpp | 5 +- programs/lab5/src/model.cpp | 4 +- programs/lab5/src/sprite_data.hpp | 17 ++---- programs/lab5/src/triangle.hpp | 55 ++++++------------- .../utilities/matrix.hpp | 15 +++++ 5 files changed, 38 insertions(+), 58 deletions(-) diff --git a/programs/lab5/src/main.cpp b/programs/lab5/src/main.cpp index 476958d..0af8606 100644 --- a/programs/lab5/src/main.cpp +++ b/programs/lab5/src/main.cpp @@ -64,10 +64,7 @@ namespace BGTU::ComputerGraphicsLabWork::Impl { return 0; #else - auto x = Utilities::Matrix4d{5, 0, 0, 0, - 0, 5, 0, 0, - 0, 0, 0, 1, - 0, 0, -1, 0}; + auto x = Utilities::Matrix4d::projection_orto(-2, 2, -1, 1, 0, 2); RendererApi::PointF<3> a{1, 1, 6}; RendererApi::PointF<3> b = x * a; diff --git a/programs/lab5/src/model.cpp b/programs/lab5/src/model.cpp index 3aa8a1f..df6a347 100644 --- a/programs/lab5/src/model.cpp +++ b/programs/lab5/src/model.cpp @@ -57,8 +57,8 @@ namespace BGTU::ComputerGraphicsLabWork::Impl { {{-1, 1, -1}, {1, 1, -1}, {1, 1, 0}, rot_n(300, 2), rot_n(240, 2), rot_n(240, 1), &hsv_shader}, {{-1, 1, -1}, {0, 1, 1}, {1, 1, 0}, rot_n(300, 2), rot_n(0, 1), rot_n(240, 1), &hsv_shader}, {{-1, 1, -1}, {0, 1, 1}, {-1, 1, 1}, rot_n(300, 2), rot_n(0, 1), rot_n(0, 2), &hsv_shader}, - {{-1, -1, 1}, {-1, -1, -1}, {-1, 1, 1}, {0, 0}, {0, 1}, {1, 0}, &chess_board_shader, false}, - {{-1, 1, -1}, {-1, -1, -1}, {-1, 1, 1}, {1, 1}, {0, 1}, {1, 0}, &chess_board_shader, false}, + {{-1, -1, 1}, {-1, -1, -1}, {-1, 1, 1}, {0, 0}, {0, 1}, {1, 0}, &chess_board_shader}, + {{-1, 1, -1}, {-1, -1, -1}, {-1, 1, 1}, {1, 1}, {0, 1}, {1, 0}, &chess_board_shader}, {{-1, -1, -1}, {-1, 1, -1}, {1, 1, -1}, {0, 0}, {0, 1}, {1, 1}, &transparent_shader}, {{-1, -1, -1}, {1, -1, -1}, {1, 1, -1}, {0, 0}, {1, 0}, {1, 1}, &transparent_shader}, {{1, -1, 1}, {-1, -1, 1}, {1, -1, -1}, {0, 0}, {0, 1}, {1, 0}, &tri_shader_1}, diff --git a/programs/lab5/src/sprite_data.hpp b/programs/lab5/src/sprite_data.hpp index c8d4c46..ff133f8 100644 --- a/programs/lab5/src/sprite_data.hpp +++ b/programs/lab5/src/sprite_data.hpp @@ -23,19 +23,10 @@ namespace BGTU::ComputerGraphicsLabWork::Impl { using Provider = _Lab5SpriteData_Provider; Utilities::Matrix4d transform; - bool is_projection_enabled; - double x_radius; - double y_radius; - explicit SpriteData(Utilities::Matrix4d transform, bool is_projection_enabled, double x_radius, double y_radius) : - transform{transform}, is_projection_enabled{is_projection_enabled}, x_radius{x_radius}, y_radius{y_radius} {} + explicit SpriteData(Utilities::Matrix4d transform) : + transform{transform} {} - [[nodiscard]] inline RendererApi::PointI<2> project_point(RendererApi::PointF<3> p) const { - if (this->is_projection_enabled) - return {static_cast::component_t>((p.x - this->x_radius) / (p.z * (1 / this->x_radius) + 1) + this->x_radius), static_cast::component_t>((p.y - this->y_radius) / (p.z * (1 / this->y_radius) + 1) + this->y_radius)}; - else - return RendererApi::PointI<2>{static_cast::component_t>(p.x), static_cast::component_t>(p.y)}; - }; }; @@ -65,9 +56,9 @@ namespace BGTU::ComputerGraphicsLabWork::Impl { SpriteData get_sprite_data() override { this->sync.lock(); double radius = (((this->w < this->h) ? this->w : this->h) * 7 / 16.0); + auto projection = this->is_projection_enabled ? Utilities::Matrix4d::projection_central(-2, 2, -2, 2, this->scale - 2, this->scale + 2) * Utilities::Matrix4d::shift(0, 0, this->scale) : Utilities::Matrix4d::projection_orto(-2, 2, -2, 2, -2, 2); SpriteData cached{ - Utilities::Matrix4d::shift(0, 0, this->scale) * Utilities::Matrix4d::shift(this->w / 2, this->h / 2, radius * 2) * Utilities::Matrix4d::rotate_x(this->x_angle) * Utilities::Matrix4d::rotate_y(this->y_angle) * Utilities::Matrix4d::scale(radius), - this->is_projection_enabled, this->w * 7 / 16.0, this->h * 7 / 16.0, + Utilities::Matrix4d::shift(this->w / 2, this->h / 2, 2) * Utilities::Matrix4d::scale(radius) * projection * Utilities::Matrix4d::rotate_x(this->x_angle) * Utilities::Matrix4d::rotate_y(this->y_angle), }; this->sync.unlock(); return cached; diff --git a/programs/lab5/src/triangle.hpp b/programs/lab5/src/triangle.hpp index 31e1672..7b05cf5 100644 --- a/programs/lab5/src/triangle.hpp +++ b/programs/lab5/src/triangle.hpp @@ -21,7 +21,6 @@ namespace BGTU::ComputerGraphicsLabWork::Impl { const RendererApi::PointF<2> shader_p1; const RendererApi::PointF<2> shader_p2; Utilities::Shader const *const shader; - bool apply_projection_to_shader; public: Triangle( @@ -31,53 +30,31 @@ namespace BGTU::ComputerGraphicsLabWork::Impl { RendererApi::PointF<2> shader_p0, RendererApi::PointF<2> shader_p1, RendererApi::PointF<2> shader_p2, - Utilities::Shader const *shader, - bool apply_projection_to_shader = true + Utilities::Shader const *shader ) : triangle_p0{triangle_p0}, triangle_p1{triangle_p1}, triangle_p2{triangle_p2}, - shader_p0{shader_p0}, shader_p1{shader_p1}, shader_p2{shader_p2}, shader{shader}, apply_projection_to_shader{apply_projection_to_shader} {} + shader_p0{shader_p0}, shader_p1{shader_p1}, shader_p2{shader_p2}, shader{shader} {} void draw(BGTU::ComputerGraphicsLabWork::RendererApi::VirtualVoxelPainter *frame, SpriteData const *data) const override { auto ta = data->transform * this->triangle_p0; auto tb = data->transform * this->triangle_p1; auto tc = data->transform * this->triangle_p2; - RendererApi::PointI<2> pa = data->project_point(ta); - RendererApi::PointI<2> pb = data->project_point(tb); - RendererApi::PointI<2> pc = data->project_point(tc); + Utilities::Shapes::triangle_barycentric_interpolator> interpolator{ + {ta.x, ta.y}, {this->shader_p0.x, this->shader_p0.y, ta.z}, + {tb.x, tb.y}, {this->shader_p1.x, this->shader_p1.y, tb.z}, + {tc.x, tc.y}, {this->shader_p2.x, this->shader_p2.y, tc.z}, + }; + Utilities::Shapes::iterate_triangle_fill( + {static_cast::component_t>(ta.x), static_cast::component_t>(ta.y)}, + {static_cast::component_t>(tb.x), static_cast::component_t>(tb.y)}, + {static_cast::component_t>(tc.x), static_cast::component_t>(tc.y)}, + [&, this](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { + RendererApi::PointF<3> _tmp = interpolator.interpolate_point(x, y); + frame->add_voxel(x, y, _tmp.z, this->shader->get_color(_tmp.x, _tmp.y)); + } + ); - if (this->apply_projection_to_shader) { - Utilities::Shapes::triangle_barycentric_interpolator> interpolator{ - static_cast>(pa), {this->shader_p0.x, this->shader_p0.y, ta.z}, - static_cast>(pb), {this->shader_p1.x, this->shader_p1.y, tb.z}, - static_cast>(pc), {this->shader_p2.x, this->shader_p2.y, tc.z}, - }; - - Utilities::Shapes::iterate_triangle_fill( - pa, pb, pc, - [&, this](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { - RendererApi::PointF<3> _tmp = interpolator.interpolate_point(x, y); - frame->add_voxel(x, y, _tmp.z, this->shader->get_color(_tmp.x, _tmp.y)); - } - ); - } else { - Utilities::Shapes::triangle_barycentric_interpolator z_interpolator{ - static_cast>(pa), ta.z, - static_cast>(pb), tb.z, - static_cast>(pc), tc.z, - }; - Utilities::Shapes::triangle_barycentric_interpolator> shader_interpolator{ - {ta.x, ta.y}, this->shader_p0, - {tb.x, tb.y}, this->shader_p1, - {tc.x, tc.y}, this->shader_p2, - }; - Utilities::Shapes::iterate_triangle_fill( - pa, pb, pc, - [&, this](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { - frame->add_voxel(x, y, z_interpolator.interpolate_point(x, y), this->shader->get_color(shader_interpolator.interpolate_point(x, y))); - } - ); - } } }; } \ No newline at end of file diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/matrix.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/matrix.hpp index 79aa54c..b13a9b4 100644 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/matrix.hpp +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/matrix.hpp @@ -308,6 +308,21 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { this->data[2][0] * other.x + this->data[2][1] * other.y + this->data[2][2] * other.z + this->data[2][3], }; } + + + static Matrix4 projection_orto(elem_t l, elem_t r, elem_t b, elem_t t, elem_t n, elem_t f) { + return Matrix4{static_cast(2.0 / (r - l)), 0, 0, static_cast(-(r + l) * (r - l)), + 0, static_cast(2.0 / (t - b)), 0, static_cast(-(t + b) * (t - b)), + 0, 0, static_cast(2.0 / (f - n)), static_cast(-(f + n) * (f - n)), + 0, 0, 0, 1}; + } + + static Matrix4 projection_central(elem_t l, elem_t r, elem_t b, elem_t t, elem_t n, elem_t f) { + return Matrix4{static_cast(2.0 * n / (r - l)), 0, static_cast((r + l) * (r - l)), 0, + 0, static_cast(2.0 * n / (t - b)), static_cast((t + b) * (t - b)), 0, + 0, 0, static_cast(-(f + n) * (f - n)), static_cast(-2.0 * n * f * (f - n)), + 0, 0, -1, 0}; + } }; template