Applying barycentric shader to lw2

This commit is contained in:
Andrew Golovashevich 2024-12-25 04:09:46 +03:00
parent fa7f0bd020
commit 0c144f992b
3 changed files with 57 additions and 25 deletions

View File

@ -1,6 +1,8 @@
#include <cmath>
#include <numbers>
#include <QMutex>
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/shapes/triangle.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/shader.hpp>
@ -282,8 +284,30 @@ namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab2 {
receiver(s);
return;
}
case ShaderType::BARYCENTRIC:
case ShaderType::BARYCENTRIC_SEMI_TRANSPARENT:;
case ShaderType::BARYCENTRIC: {
Utilities::Shapes::triangle_barycentric_shader s{
data->pos_rotated_f(data->radius * radius_multiplier, -120.0),
data->pos_rotated_f(data->radius * radius_multiplier, 0.0),
data->pos_rotated_f(data->radius * radius_multiplier, 120.0),
RendererApi::Color{255, 0, 0},
RendererApi::Color{0, 255, 0},
RendererApi::Color{0, 0, 255}
};
receiver(s);
return;
}
case ShaderType::BARYCENTRIC_SEMI_TRANSPARENT: {
Utilities::Shapes::triangle_barycentric_shader s{
data->pos_rotated_f(data->radius * radius_multiplier, -120.0),
data->pos_rotated_f(data->radius * radius_multiplier, 0.0),
data->pos_rotated_f(data->radius * radius_multiplier, 120.0),
RendererApi::Color::Transparent{255, 0, 0, 127},
RendererApi::Color::Transparent{0, 255, 0, 127},
RendererApi::Color::Transparent{0, 0, 255, 127}
};
receiver(s);
return;
}
}
};
public:

View File

@ -28,14 +28,18 @@ namespace BGTU::ComputerGraphicsLabWork::Impl {
private:
[[nodiscard]] inline RendererApi::PointI<2> _rotated(RendererApi::PointI<2>::component_t custom_radius, double base_angle_radians, double angle_degrees) const {
[[nodiscard]] inline RendererApi::PointF<2> _rotated_f(RendererApi::PointI<2>::component_t custom_radius, double base_angle_radians, double angle_degrees) const {
double angle_radians = angle_degrees * (std::numbers::pi_v<double> / 180);
return {
(RendererApi::PointI<2>::component_t) (std::cos(base_angle_radians + angle_radians) * custom_radius),
(RendererApi::PointI<2>::component_t) (std::sin(base_angle_radians + angle_radians) * custom_radius),
(std::cos(base_angle_radians + angle_radians) * custom_radius),
(std::sin(base_angle_radians + angle_radians) * custom_radius),
};
}
[[nodiscard]] inline RendererApi::PointI<2> _rotated(RendererApi::PointI<2>::component_t custom_radius, double base_angle_radians, double angle_degrees) const {
return (RendererApi::PointI<2>) (this->_rotated_f(custom_radius, base_angle_radians, angle_degrees));
}
public:
[[nodiscard]] inline RendererApi::PointI<2> static_rotated(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
@ -48,7 +52,18 @@ namespace BGTU::ComputerGraphicsLabWork::Impl {
[[nodiscard]] inline RendererApi::PointI<2> neg_rotated(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
return this->_rotated(custom_radius, -this->rotation_radians, angle_degrees);
}
[[nodiscard]] inline RendererApi::PointF<2> static_rotated_f(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
return this->_rotated_f(custom_radius, 0, angle_degrees);
}
[[nodiscard]] inline RendererApi::PointF<2> pos_rotated_f(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
return this->_rotated_f(custom_radius, this->rotation_radians, angle_degrees);
}
[[nodiscard]] inline RendererApi::PointF<2> neg_rotated_f(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
return this->_rotated_f(custom_radius, -this->rotation_radians, angle_degrees);
}
};

View File

@ -250,16 +250,11 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
template<class variable_t>
struct triangle_barycentric_interpolator {
public:
struct pole {
RendererApi::PointI<2> coord;
variable_t value;
};
private:
long double full_square;
RendererApi::PointI<2> p0;
RendererApi::PointI<2> p1;
RendererApi::PointI<2> p2;
RendererApi::PointF<2> p0;
RendererApi::PointF<2> p1;
RendererApi::PointF<2> p2;
variable_t v0;
variable_t v1;
variable_t v2;
@ -270,9 +265,9 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
std::conditional_t<std::is_same_v<variable_t, RendererApi::Color::Transparent>, bool, _empty> skip_alpha;
static long double calculate_square_2(
RendererApi::PointI<2> p0,
RendererApi::PointI<2> p1,
RendererApi::PointI<2> p2
RendererApi::PointF<2> p0,
RendererApi::PointF<2> p1,
RendererApi::PointF<2> p2
) noexcept {
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
@ -280,7 +275,7 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
public:
triangle_barycentric_interpolator(
RendererApi::PointI<2> p0, RendererApi::PointI<2> p1, RendererApi::PointI<2> p2,
RendererApi::PointF<2> p0, RendererApi::PointF<2> p1, RendererApi::PointF<2> p2,
variable_t v0, variable_t v1, variable_t v2
) : p0{p0}, p1{p1}, p2{p2}, v0{v0}, v1{v1}, v2{v2}, full_square{calculate_square_2(p0, p1, p2)} {
if constexpr (std::is_same_v<variable_t, RendererApi::Color::Transparent>) {
@ -288,7 +283,7 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
}
}
variable_t interpolate_point(RendererApi::PointI<2> p) const {
variable_t interpolate_point(RendererApi::PointF<2> p) const {
const double k0 = calculate_square_2(p, this->p1, this->p2) / this->full_square;
const double k1 = calculate_square_2(p, this->p2, this->p0) / this->full_square;
const double k2 = calculate_square_2(p, this->p0, this->p1) / this->full_square;
@ -316,25 +311,23 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
}
}
variable_t interpolate_point(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) const {
return this->interpolate_point(RendererApi::PointI<2>{x, y});
variable_t interpolate_point(RendererApi::PointF<2>::component_t x, RendererApi::PointF<2>::component_t y) const {
return this->interpolate_point(RendererApi::PointF<2>{x, y});
}
};
#if 0
class triangle_barycentric_shader : public Shader {
private:
triangle_barycentric_interpolator<RendererApi::Color::Transparent> interpolator;
public:
inline triangle_barycentric_shader(
RendererApi::PointI<2> p0, RendererApi::PointI<2> p1, RendererApi::PointI<2> p2,
RendererApi::PointF<2> p0, RendererApi::PointF<2> p1, RendererApi::PointF<2> p2,
RendererApi::Color::Transparent c0, RendererApi::Color::Transparent c1, RendererApi::Color::Transparent c2
) : interpolator{p0, p1, p2, c0, c1, c2} {}
) noexcept: interpolator{p0, p1, p2, c0, c1, c2} {}
[[nodiscard]] inline RendererApi::Color::Transparent get_color(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) const final {
[[nodiscard]] inline RendererApi::Color::Transparent get_color(RendererApi::PointF<2>::component_t x, RendererApi::PointF<2>::component_t y) const final {
return this->interpolator.interpolate_point(x, y);
}
};
#endif
}