Lab5 impl without sorting
This commit is contained in:
parent
9e58b48034
commit
737cb2a23c
@ -21,4 +21,5 @@ add_subdirectory(utilities)
|
||||
add_subdirectory(qt-utilities)
|
||||
add_subdirectory(programs/labs1_2)
|
||||
add_subdirectory(programs/lab3)
|
||||
add_subdirectory(programs/lab4)
|
||||
add_subdirectory(programs/lab4)
|
||||
add_subdirectory(programs/lab5)
|
@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::Impl {
|
||||
class _Lab3SpriteData_Provider;
|
||||
class _Lab5SpriteData_Provider;
|
||||
|
||||
|
||||
struct SpriteData {
|
||||
@ -25,11 +25,11 @@ namespace BGTU::ComputerGraphicsLabWork::Impl {
|
||||
Utilities::Matrix3d planets_transform[9];
|
||||
Utilities::Matrix3d stars_transform;
|
||||
double time_ms;
|
||||
using Provider = _Lab3SpriteData_Provider;
|
||||
using Provider = _Lab5SpriteData_Provider;
|
||||
|
||||
};
|
||||
|
||||
class _Lab3SpriteData_Provider : public QObject, public RendererApi::Sprite<SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>::SpriteDataProvider {
|
||||
class _Lab5SpriteData_Provider : public QObject, public RendererApi::Sprite<SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>::SpriteDataProvider {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QMutex sync;
|
||||
@ -37,7 +37,7 @@ namespace BGTU::ComputerGraphicsLabWork::Impl {
|
||||
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, h;
|
||||
|
||||
public:
|
||||
explicit _Lab3SpriteData_Provider(double radians_per_second) :
|
||||
explicit _Lab5SpriteData_Provider(double radians_per_second) :
|
||||
sync{}, time{},
|
||||
w{0}, h{0} {}
|
||||
|
||||
|
10
programs/lab5/CMakeLists.txt
Normal file
10
programs/lab5/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
add_executable(
|
||||
lab5
|
||||
|
||||
src/main.cpp
|
||||
src/sprite_data.hpp
|
||||
src/model.cpp
|
||||
src/triangle.hpp
|
||||
|
||||
)
|
||||
target_link_libraries(lab5 PRIVATE Qt5::Core Qt5::Widgets renderer_api utilities qt_utilities)
|
82
programs/lab5/src/main.cpp
Normal file
82
programs/lab5/src/main.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <numbers>
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
#include <QGridLayout>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/voxel_painter_exporter_to_packed_array.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/matrix.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/separate_threaded_renderer.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/renderer_widget.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/keyboard_catcher_widget.hpp>
|
||||
#include "sprite_data.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::Impl {
|
||||
int main(int argc, char **argv) {
|
||||
#if 1
|
||||
QApplication qApplication{argc, argv};
|
||||
|
||||
SpriteData::Provider sprites_data_custom{0.1, 0.1, 10};
|
||||
|
||||
QMainWindow w{};
|
||||
|
||||
|
||||
QtUtilities::KeyboardCatcherWidget kbd{&w};
|
||||
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_Left, &sprites_data_custom, &SpriteData::Provider::dec_y_angle);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_Right, &sprites_data_custom, &SpriteData::Provider::inc_y_angle);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_Down, &sprites_data_custom, &SpriteData::Provider::dec_x_angle);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_Up, &sprites_data_custom, &SpriteData::Provider::inc_x_angle);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_A, &sprites_data_custom, &SpriteData::Provider::dec_y_angle);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_D, &sprites_data_custom, &SpriteData::Provider::inc_y_angle);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_S, &sprites_data_custom, &SpriteData::Provider::dec_x_angle);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_W, &sprites_data_custom, &SpriteData::Provider::inc_x_angle);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_PageDown, &sprites_data_custom, &SpriteData::Provider::dec_scale);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_PageUp, &sprites_data_custom, &SpriteData::Provider::inc_scale);
|
||||
QObject::connect(&kbd, &QtUtilities::KeyboardCatcherWidget::key_pressed_P, &sprites_data_custom, &SpriteData::Provider::switch_projection);
|
||||
|
||||
|
||||
|
||||
QtUtilities::SeparateThreadedDefaultRendererLinear<SpriteData> renderer_custom{};
|
||||
renderer_custom.set_sprite_data_provider(&sprites_data_custom);
|
||||
renderer_custom.set_sprites(reinterpret_cast<RendererApi::Sprite <SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl> *const *>(sprites), sprites_count);
|
||||
renderer_custom.set_background(BGTU::ComputerGraphicsLabWork::RendererApi::Color{0, 0, 0});
|
||||
|
||||
|
||||
QGridLayout layout{&kbd};
|
||||
kbd.setLayout(&layout);
|
||||
QtUtilities::RendererWidget<SpriteData> canvas_custom{&renderer_custom, &kbd};
|
||||
layout.addWidget(&canvas_custom, 0, 0);
|
||||
QObject::connect(&canvas_custom, &QtUtilities::_RendererWidget_SignalSlots::resized, &sprites_data_custom, &SpriteData::Provider::set_frame_size);
|
||||
|
||||
|
||||
w.setCentralWidget(&kbd);
|
||||
w.show();
|
||||
|
||||
QApplication::exec();
|
||||
|
||||
return 0;
|
||||
#else
|
||||
auto x = Utilities::Matrix4d{5, 0, 0, 0,
|
||||
0, 5, 0, 0,
|
||||
0, 0, 0, 1,
|
||||
0, 0, -1, 0};
|
||||
|
||||
RendererApi::PointF<3> a{1, 1, 6};
|
||||
RendererApi::PointF<3> b = x * a;
|
||||
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
return BGTU::ComputerGraphicsLabWork::Impl::main(argc, argv);
|
||||
}
|
95
programs/lab5/src/model.cpp
Normal file
95
programs/lab5/src/model.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
#include <utility>
|
||||
#include <numbers>
|
||||
#include <cmath>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/shader.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/shapes/triangle.hpp>
|
||||
|
||||
#include "triangle.hpp"
|
||||
#include "sprite_data.hpp"
|
||||
#include "model.hpp"
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::Impl {
|
||||
namespace {
|
||||
|
||||
Utilities::hsv_sector_shader hsv_shader{0, 0, 0};
|
||||
Utilities::MonoShader transparent_shader{{255, 255, 255, 127}};
|
||||
|
||||
class ChessBoardShader : public Utilities::Shader {
|
||||
private:
|
||||
double w, h;
|
||||
|
||||
public:
|
||||
ChessBoardShader(double w, double h) : w{w}, h{h} {}
|
||||
|
||||
[[nodiscard]] RendererApi::Color::Transparent get_color(double x, double y) const override {
|
||||
if (static_cast<long long>(std::floor(x / this->w) + std::floor(y / this->h)) % 2 == 0)
|
||||
return {0, 0, 0, 255};
|
||||
else
|
||||
return {255, 255, 255, 255};
|
||||
}
|
||||
} chess_board_shader{0.125000000000, 0.125000000000};
|
||||
|
||||
|
||||
RendererApi::PointF<2> rot_n(double degrees, unsigned len) {
|
||||
auto radians = degrees * std::numbers::pi_v<double> / 180;
|
||||
return {std::cos(radians) * len, std::sin(radians) * len};
|
||||
}
|
||||
|
||||
Utilities::Shapes::triangle_barycentric_shader tri_shader_1{
|
||||
{0, 0}, RendererApi::Color{0, 0, 255},
|
||||
{1, 0}, RendererApi::Color{0, 255, 255},
|
||||
{0, 1}, RendererApi::Color{0, 255, 0}
|
||||
};
|
||||
Utilities::Shapes::triangle_barycentric_shader tri_shader_2{
|
||||
{1, 1}, RendererApi::Color{255, 255, 0},
|
||||
{1, 0}, RendererApi::Color{0, 255, 255},
|
||||
{0, 1}, RendererApi::Color{0, 255, 0}
|
||||
};
|
||||
|
||||
Triangle triangles[] = {
|
||||
{{0, 1, 1}, {1, 1, 0}, {1, 0, 1}, rot_n(0, 1), rot_n(240, 1), rot_n(120, 1), &hsv_shader},
|
||||
{{-1, -1, 1}, {-1, 1, 1}, {0, 1, 1}, rot_n(60, 2), rot_n(0, 2), rot_n(0, 1), &hsv_shader},
|
||||
{{-1, -1, 1}, {1, 0, 1}, {0, 1, 1}, rot_n(60, 2), rot_n(120, 1), rot_n(0, 1), &hsv_shader},
|
||||
{{-1, -1, 1}, {1, 0, 1}, {1, -1, 1}, rot_n(60, 2), rot_n(120, 1), rot_n(120, 1), &hsv_shader},
|
||||
{{1, -1, -1}, {1, 1, -1}, {1, 1, 0}, rot_n(180, 2), rot_n(240, 2), rot_n(240, 1), &hsv_shader},
|
||||
{{1, -1, -1}, {1, 0, 1}, {1, 1, 0}, rot_n(180, 2), rot_n(120, 1), rot_n(240, 1), &hsv_shader},
|
||||
{{1, -1, -1}, {1, 0, 1}, {1, -1, 1}, rot_n(180, 2), rot_n(120, 1), rot_n(120, 2), &hsv_shader},
|
||||
{{-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, 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},
|
||||
{{-1, -1, -1}, {-1, -1, 1}, {1, -1, -1}, {1, 1}, {0, 1}, {1, 0}, &tri_shader_2},
|
||||
};
|
||||
|
||||
Triangle *const _sprites[]{
|
||||
&triangles[0],
|
||||
&triangles[1],
|
||||
&triangles[2],
|
||||
&triangles[3],
|
||||
&triangles[4],
|
||||
&triangles[5],
|
||||
&triangles[6],
|
||||
&triangles[7],
|
||||
&triangles[8],
|
||||
&triangles[9],
|
||||
&triangles[10],
|
||||
&triangles[11],
|
||||
&triangles[12],
|
||||
&triangles[13],
|
||||
&triangles[14],
|
||||
&triangles[15],
|
||||
&triangles[16],
|
||||
&triangles[17],
|
||||
&triangles[18],
|
||||
&triangles[19],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Triangle *const *const sprites = _sprites;
|
||||
std::size_t sprites_count = 16;
|
||||
}
|
11
programs/lab5/src/model.hpp
Normal file
11
programs/lab5/src/model.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
#include "sprite_data.hpp"
|
||||
#include "triangle.hpp"
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::Impl {
|
||||
extern Triangle *const *const sprites;
|
||||
extern std::size_t sprites_count;
|
||||
}
|
127
programs/lab5/src/sprite_data.hpp
Normal file
127
programs/lab5/src/sprite_data.hpp
Normal file
@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <numbers>
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <QElapsedTimer>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/matrix.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/zoomed_voxel_painter.hpp>
|
||||
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::Impl {
|
||||
class _Lab5SpriteData_Provider;
|
||||
|
||||
|
||||
struct SpriteData {
|
||||
public:
|
||||
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} {}
|
||||
|
||||
[[nodiscard]] inline RendererApi::PointI<2> project_point(RendererApi::PointF<3> p) const {
|
||||
if (this->is_projection_enabled)
|
||||
return {static_cast<RendererApi::PointI<2>::component_t>((p.x - this->x_radius) / (p.z * (1 / this->x_radius) + 1) + this->x_radius), static_cast<RendererApi::PointI<2>::component_t>((p.y - this->y_radius) / (p.z * (1 / this->y_radius) + 1) + this->y_radius)};
|
||||
else
|
||||
return RendererApi::PointI<2>{static_cast<RendererApi::PointI<2>::component_t>(p.x), static_cast<RendererApi::PointI<2>::component_t>(p.y)};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class _Lab5SpriteData_Provider : public QObject, public RendererApi::Sprite<SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>::SpriteDataProvider {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QMutex sync;
|
||||
double x_angle;
|
||||
double y_angle;
|
||||
double scale;
|
||||
|
||||
double x_angle_step;
|
||||
double y_angle_step;
|
||||
double scale_step;
|
||||
bool is_projection_enabled;
|
||||
|
||||
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, h;
|
||||
|
||||
public:
|
||||
explicit _Lab5SpriteData_Provider(
|
||||
double x_angle_step,
|
||||
double y_angle_step,
|
||||
double scale_step
|
||||
) : x_angle{0}, y_angle{0}, scale{1}, x_angle_step{x_angle_step}, y_angle_step{y_angle_step}, scale_step{scale_step},
|
||||
w{0}, h{0}, is_projection_enabled{false} {}
|
||||
|
||||
SpriteData get_sprite_data() override {
|
||||
this->sync.lock();
|
||||
double radius = (((this->w < this->h) ? this->w : this->h) * 7 / 16.0);
|
||||
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,
|
||||
};
|
||||
this->sync.unlock();
|
||||
return cached;
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
void set_frame_size(RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t ww, RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t hh) {
|
||||
this->sync.lock();
|
||||
this->w = ww;
|
||||
this->h = hh;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
void inc_x_angle() {
|
||||
this->sync.lock();
|
||||
this->x_angle += this->x_angle_step;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
void dec_x_angle() {
|
||||
this->sync.lock();
|
||||
this->x_angle -= this->x_angle_step;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
void inc_y_angle() {
|
||||
this->sync.lock();
|
||||
this->y_angle += this->y_angle_step;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
void dec_y_angle() {
|
||||
this->sync.lock();
|
||||
this->y_angle -= this->y_angle_step;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
void inc_scale() {
|
||||
this->sync.lock();
|
||||
this->scale += this->scale_step;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
void dec_scale() {
|
||||
this->sync.lock();
|
||||
this->scale -= this->scale_step;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
void switch_projection() {
|
||||
this->sync.lock();
|
||||
this->is_projection_enabled = !this->is_projection_enabled;
|
||||
this->sync.unlock();
|
||||
}
|
||||
};
|
||||
}
|
83
programs/lab5/src/triangle.hpp
Normal file
83
programs/lab5/src/triangle.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/matrix.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/shader.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/shapes/triangle.hpp>
|
||||
|
||||
#include "sprite_data.hpp"
|
||||
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::Impl {
|
||||
class Triangle : public RendererApi::Sprite<SpriteData> {
|
||||
public:
|
||||
const RendererApi::PointF<3> triangle_p0;
|
||||
const RendererApi::PointF<3> triangle_p1;
|
||||
const RendererApi::PointF<3> triangle_p2;
|
||||
|
||||
private:
|
||||
const RendererApi::PointF<2> shader_p0;
|
||||
const RendererApi::PointF<2> shader_p1;
|
||||
const RendererApi::PointF<2> shader_p2;
|
||||
Utilities::Shader const *const shader;
|
||||
bool apply_projection_to_shader;
|
||||
|
||||
public:
|
||||
Triangle(
|
||||
RendererApi::PointF<3> triangle_p0,
|
||||
RendererApi::PointF<3> triangle_p1,
|
||||
RendererApi::PointF<3> triangle_p2,
|
||||
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
|
||||
) : 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} {}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
if (this->apply_projection_to_shader) {
|
||||
Utilities::Shapes::triangle_barycentric_interpolator<RendererApi::PointF<3>> interpolator{
|
||||
static_cast<RendererApi::PointF<2>>(pa), {this->shader_p0.x, this->shader_p0.y, ta.z},
|
||||
static_cast<RendererApi::PointF<2>>(pb), {this->shader_p1.x, this->shader_p1.y, tb.z},
|
||||
static_cast<RendererApi::PointF<2>>(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<double> z_interpolator{
|
||||
static_cast<RendererApi::PointF<2>>(pa), ta.z,
|
||||
static_cast<RendererApi::PointF<2>>(pb), tb.z,
|
||||
static_cast<RendererApi::PointF<2>>(pc), tc.z,
|
||||
};
|
||||
Utilities::Shapes::triangle_barycentric_interpolator<RendererApi::PointF<2>> 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)));
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -286,24 +286,18 @@ namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab2 {
|
||||
}
|
||||
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}
|
||||
data->pos_rotated_f(data->radius * radius_multiplier, -120.0), RendererApi::Color{255, 0, 0},
|
||||
data->pos_rotated_f(data->radius * radius_multiplier, 0.0), RendererApi::Color{0, 255, 0},
|
||||
data->pos_rotated_f(data->radius * radius_multiplier, 120.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}
|
||||
data->pos_rotated_f(data->radius * radius_multiplier, -120.0), RendererApi::Color::Transparent{255, 0, 0, 127},
|
||||
data->pos_rotated_f(data->radius * radius_multiplier, 0.0), RendererApi::Color::Transparent{0, 255, 0, 127},
|
||||
data->pos_rotated_f(data->radius * radius_multiplier, 120.0), RendererApi::Color::Transparent{0, 0, 255, 127}
|
||||
};
|
||||
receiver(s);
|
||||
return;
|
||||
|
@ -83,6 +83,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
void key_pressed_S();
|
||||
|
||||
void key_pressed_D();
|
||||
void key_pressed_P();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override {
|
||||
@ -186,6 +187,9 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
case Qt::Key_S:
|
||||
emit this->key_pressed_S();
|
||||
return;
|
||||
case Qt::Key_P:
|
||||
emit this->key_pressed_P();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||
const float sum_f[4]{bg_alpha[0] + fg_alpha[0], bg_alpha[1] + fg_alpha[1], bg_alpha[2] + fg_alpha[2]};
|
||||
|
||||
// divps
|
||||
const float sum_fixed_f[4]{sum_f[0] / 255.f, sum_f[2] / 255.f, sum_f[2] / 255.f};
|
||||
const float sum_fixed_f[4]{sum_f[0] / 255.f, sum_f[1] / 255.f, sum_f[2] / 255.f};
|
||||
|
||||
return {
|
||||
(RendererApi::Color::component_compact_t) sum_fixed_f[0],
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
|
||||
#include "color.hpp"
|
||||
#include "matrix.hpp"
|
||||
|
||||
|
||||
@ -134,6 +135,51 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||
template<RendererApi::Color::Transparent color>
|
||||
constexpr MonoShader::Static<color> const MonoShader::static_{};
|
||||
|
||||
template<RendererApi::Color::Transparent c1, RendererApi::Color::Transparent c2>
|
||||
class RadialShader : public Utilities::Shader {
|
||||
private:
|
||||
RendererApi::PointF<2>::component_t cx, cy;
|
||||
RendererApi::PointF<2>::component_t radius;
|
||||
public:
|
||||
RadialShader(RendererApi::PointF<2>::component_t cx, RendererApi::PointF<2>::component_t cy, RendererApi::PointF<2>::component_t radius) : cx{cx}, cy{cy}, radius{radius} {}
|
||||
|
||||
RadialShader(RendererApi::PointF<2> c, RendererApi::PointF<2>::component_t radius) : cx{c.x}, cy{c.y}, radius{radius} {}
|
||||
|
||||
RadialShader(RendererApi::PointI<2> c, RendererApi::PointF<2>::component_t radius) : cx{(double) c.x}, cy{(double) c.y}, radius{radius} {}
|
||||
|
||||
[[nodiscard]] RendererApi::Color::Transparent get_color(RendererApi::PointF<2>::component_t x, RendererApi::PointF<2>::component_t y) const final {
|
||||
RendererApi::PointF<2>::component_t distance = std::hypot(x - this->cx, y - this->cy);
|
||||
double ratio = distance / this->radius;
|
||||
float c1v;
|
||||
|
||||
if (ratio < 0.5) {
|
||||
c1v = (float) (std::fabs(ratio - 0.25) * 4);
|
||||
} else if (ratio < 1.0) {
|
||||
c1v = (float) (std::fabs(ratio - 0.75) * 4);
|
||||
} else {
|
||||
return c1;
|
||||
}
|
||||
|
||||
return Utilities::colors_gradient(c1, c1v, c2);
|
||||
}
|
||||
};
|
||||
|
||||
class hsv_sector_shader : public Utilities::Shader {
|
||||
private:
|
||||
RendererApi::PointF<2>::component_t cx, cy;
|
||||
double angle_offset_radians;
|
||||
public:
|
||||
hsv_sector_shader(RendererApi::PointF<2>::component_t cx, RendererApi::PointF<2>::component_t cy, double angle_offset_radians) : cx{cx}, cy{cy}, angle_offset_radians{angle_offset_radians} {}
|
||||
|
||||
hsv_sector_shader(RendererApi::PointF<2> c, double angle_offset_radians) : cx{c.x}, cy{c.y}, angle_offset_radians{angle_offset_radians} {}
|
||||
|
||||
hsv_sector_shader(RendererApi::PointI<2> c, double angle_offset_radians) : cx{(double) c.x}, cy{(double) c.y}, angle_offset_radians{angle_offset_radians} {}
|
||||
|
||||
[[nodiscard]] RendererApi::Color::Transparent get_color(RendererApi::PointF<2>::component_t x, RendererApi::PointF<2>::component_t y) const final {
|
||||
double angle = std::atan2(static_cast<double>(y - this->cy), static_cast<double>(x - this->cx)) + this->angle_offset_radians;
|
||||
return Utilities::hsv_to_rgb_360_1_1(std::fmod(std::fmod(angle / std::numbers::pi_v<double> * 180, 360.0) + 360, 360.0), 1.0, 1.0);
|
||||
}
|
||||
};
|
||||
|
||||
class TransformedShader : public Shader {
|
||||
private:
|
||||
|
@ -391,17 +391,17 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
|
||||
private:
|
||||
using point_t = RendererApi::Point<DIMENSIONS, component_t>;
|
||||
|
||||
_triangle_barycentric_interpolator<RendererApi::Color, []<class interpolator_t>(interpolator_t interpolator) {
|
||||
_triangle_barycentric_interpolator<point_t, []<class interpolator_t>(interpolator_t interpolator) {
|
||||
if constexpr (DIMENSIONS == 2)
|
||||
return point_t{
|
||||
static_cast<point_t::component_fast_t>(interpolator([](point_t const &p) { return p.x; })),
|
||||
static_cast<point_t::component_fast_t>(interpolator([](point_t const &p) { return p.y; }))
|
||||
static_cast<point_t::component_t>(interpolator([](point_t const &p) { return p.x; })),
|
||||
static_cast<point_t::component_t>(interpolator([](point_t const &p) { return p.y; }))
|
||||
};
|
||||
else
|
||||
return RendererApi::Point<3, component_t>{
|
||||
static_cast<point_t::component_fast_t>(interpolator([](point_t const &p) { return p.x; })),
|
||||
static_cast<point_t::component_fast_t>(interpolator([](point_t const &p) { return p.y; })),
|
||||
static_cast<point_t::component_fast_t>(interpolator([](point_t const &p) { return p.z; }))
|
||||
return point_t{
|
||||
static_cast<point_t::component_t>(interpolator([](point_t const &p) { return p.x; })),
|
||||
static_cast<point_t::component_t>(interpolator([](point_t const &p) { return p.y; })),
|
||||
static_cast<point_t::component_t>(interpolator([](point_t const &p) { return p.z; }))
|
||||
};
|
||||
}> impl;
|
||||
public:
|
||||
@ -413,11 +413,11 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
|
||||
}
|
||||
|
||||
|
||||
[[nodiscard]] RendererApi::Color interpolate_point(RendererApi::PointF<2> p) const {
|
||||
[[nodiscard]] point_t interpolate_point(RendererApi::PointF<2> p) const {
|
||||
return this->impl.interpolate_point(p);
|
||||
}
|
||||
|
||||
[[nodiscard]] RendererApi::Color interpolate_point(RendererApi::PointF<2>::component_t x, RendererApi::PointF<2>::component_t y) const {
|
||||
[[nodiscard]] point_t interpolate_point(RendererApi::PointF<2>::component_t x, RendererApi::PointF<2>::component_t y) const {
|
||||
return this->impl.interpolate_point(x, y);
|
||||
}
|
||||
};
|
||||
@ -427,8 +427,9 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
|
||||
triangle_barycentric_interpolator<RendererApi::Color::Transparent> interpolator;
|
||||
public:
|
||||
inline triangle_barycentric_shader(
|
||||
RendererApi::PointF<2> p0, RendererApi::PointF<2> p1, RendererApi::PointF<2> p2,
|
||||
RendererApi::Color::Transparent c0, RendererApi::Color::Transparent c1, RendererApi::Color::Transparent c2
|
||||
RendererApi::PointF<2> p0, RendererApi::Color::Transparent c0,
|
||||
RendererApi::PointF<2> p1, RendererApi::Color::Transparent c1,
|
||||
RendererApi::PointF<2> p2, RendererApi::Color::Transparent c2
|
||||
) noexcept: interpolator{p0, c0, p1, c1, p2, c2} {}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user