diff --git a/CMakeLists.txt b/CMakeLists.txt index 17eff28..2479b73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,4 +38,4 @@ qt5_use_modules(cg1 Widgets) add_subdirectory(renderer-api) add_subdirectory(utilities) add_subdirectory(qt-utilities) -add_subdirectory(programs/lab1) \ No newline at end of file +add_subdirectory(programs/labs1_5) \ No newline at end of file diff --git a/programs/lab1/CMakeLists.txt b/programs/lab1/CMakeLists.txt deleted file mode 100644 index d4b6c86..0000000 --- a/programs/lab1/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -add_executable( - lab1 - - src/main.cpp - src/sprite_data.hpp - src/keyboard_catcher_widget.hpp - src/variants.hpp - - src/variants/variant1.cpp - src/variants/variant2.cpp - src/variants/variant3.cpp - src/variants/variant4.cpp - src/variants/variant5.cpp - src/variants/variant6.cpp - src/variants/variant8.cpp - src/variants/variant9.cpp -) -target_link_libraries(lab1 PRIVATE Qt5::Core Qt5::Widgets renderer_api utilities qt_utilities) diff --git a/programs/lab1/src/variants.hpp b/programs/lab1/src/variants.hpp deleted file mode 100644 index 43b2e19..0000000 --- a/programs/lab1/src/variants.hpp +++ /dev/null @@ -1,186 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include "sprite_data.hpp" - -namespace BGTU::ComputerGraphicsLabWork::Lab1 { - struct variant_sprites { - private : - using sprite_t = RendererApi::Sprite>; - public: - - - sprite_t *const *const sprites; - std::size_t const count; - - - constexpr variant_sprites(sprite_t **_sprites, std::size_t _count) : sprites{_sprites}, count{_count} { - - } - - private: - template - struct _make { - }; - - template<> - struct _make<> { - public: - constexpr _make() {}; - - constexpr void export_pointers(sprite_t **dst, std::size_t pos) { - } - }; - - template - struct _make { - public: - e0 value; - - constexpr _make(e0 v) : value{std::move(v)} {}; - - constexpr void export_pointers(sprite_t **dst, std::size_t pos) { - dst[pos] = &this->value; - } - }; - - template - struct _make { - public: - e0 value; - _make next; - - constexpr _make(e0 v, en...nv) : value{std::move(v)}, next{nv...} {}; - - constexpr void export_pointers(sprite_t **dst, std::size_t pos) { - dst[pos] = &this->value; - this->next.export_pointers(dst, pos + 1); - } - }; - - public: - - template - constexpr static variant_sprites make(sprites_t...sprites) { - static _make i{sprites...}; - static sprite_t *p[sizeof...(sprites)]; - - i.export_pointers(p, 0); - return variant_sprites{p, sizeof...(sprites)}; - } - - private: - - template *frame, - Lab1SpriteData::ShapeData const *data)> - struct _make_light : public RendererApi::Sprite> { - }; - - template<> - struct _make_light<> { - public: - constexpr _make_light() {}; - - constexpr void export_pointers(sprite_t **dst, std::size_t pos) { - } - }; - - template *frame, - Lab1SpriteData::ShapeData const *data), - void (...sn)(Utilities::ZoomedVoxelPainter *frame, - Lab1SpriteData::ShapeData const *data)> - struct _make_light : public RendererApi::Sprite> { - public: - _make_light next; - - constexpr _make_light() : next{} {}; - - constexpr void export_pointers(sprite_t **dst, std::size_t pos) { - dst[pos] = this; - this->next.export_pointers(dst, pos + 1); - } - - void draw(Utilities::ZoomedVoxelPainter *frame, const Lab1::Lab1SpriteData::ShapeData *data) const final { - s0(frame, data); - } - - void clicked() final {} - }; - - - public: - template *frame, - Lab1SpriteData::ShapeData const *data)> - constexpr static variant_sprites make_light() { - static _make_light i{}; - static sprite_t *p[sizeof...(sprites)]; - - i.export_pointers(p, 0); - return variant_sprites{p, sizeof...(sprites)}; - } - }; - - - extern variant_sprites variant1; - extern variant_sprites variant2; - extern variant_sprites variant3; - extern variant_sprites variant4; - extern variant_sprites variant5; - extern variant_sprites variant6; - extern variant_sprites variant8; - extern variant_sprites variant9; - - class VariantsManager : public QObject { - Q_OBJECT - signals: - - void set_sprites( - RendererApi::Sprite> *const *sprites, - std::size_t count - ); - - private: - - inline void _set_sprites(variant_sprites sprites) { - emit this->set_sprites(sprites.sprites, sprites.count); - } - - public slots: - - inline void set_variant_1() { - this->_set_sprites(variant1); - }; - - inline void set_variant_2() { - this->_set_sprites(variant2); - }; - - inline void set_variant_3() { - this->_set_sprites(variant3); - }; - - inline void set_variant_4() { - this->_set_sprites(variant4); - }; - - inline void set_variant_5() { - this->_set_sprites(variant5); - }; - - inline void set_variant_6() { - this->_set_sprites(variant6); - }; - - inline void set_variant_8() { - this->_set_sprites(variant8); - }; - - inline void set_variant_9() { - this->_set_sprites(variant9); - }; - }; -} \ No newline at end of file diff --git a/programs/labs1_5/CMakeLists.txt b/programs/labs1_5/CMakeLists.txt new file mode 100644 index 0000000..c3068f5 --- /dev/null +++ b/programs/labs1_5/CMakeLists.txt @@ -0,0 +1,18 @@ +add_executable( + labs + + src/main.cpp + src/variants/sprite_data.hpp + src/keyboard_catcher_widget.hpp + src/variants/variants.hpp + + src/variants/lab1/variant1.cpp + src/variants/lab1/variant2.cpp + src/variants/lab1/variant3.cpp + src/variants/lab1/variant4.cpp + src/variants/lab1/variant5.cpp + src/variants/lab1/variant6.cpp + src/variants/lab1/variant8.cpp + src/variants/lab1/variant9.cpp +) +target_link_libraries(labs PRIVATE Qt5::Core Qt5::Widgets renderer_api utilities qt_utilities) diff --git a/programs/lab1/src/keyboard_catcher_widget.hpp b/programs/labs1_5/src/keyboard_catcher_widget.hpp similarity index 57% rename from programs/lab1/src/keyboard_catcher_widget.hpp rename to programs/labs1_5/src/keyboard_catcher_widget.hpp index a6919f1..d0cb3ce 100644 --- a/programs/lab1/src/keyboard_catcher_widget.hpp +++ b/programs/labs1_5/src/keyboard_catcher_widget.hpp @@ -4,7 +4,7 @@ #include #include -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl { class KeyboardCatcherWidget : public QWidget { Q_OBJECT public: @@ -40,6 +40,30 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { void key_pressed_0(); + void key_pressed_F1(); + + void key_pressed_F2(); + + void key_pressed_F3(); + + void key_pressed_F4(); + + void key_pressed_F5(); + + void key_pressed_F6(); + + void key_pressed_F7(); + + void key_pressed_F8(); + + void key_pressed_F9(); + + void key_pressed_F10(); + + void key_pressed_F11(); + + void key_pressed_F12(); + protected: void keyPressEvent(QKeyEvent *event) override { switch (event->key()) { @@ -82,6 +106,42 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { case Qt::Key_0: emit this->key_pressed_0(); return; + case Qt::Key_F1: + emit this->key_pressed_F1(); + return; + case Qt::Key_F2: + emit this->key_pressed_F2(); + return; + case Qt::Key_F3: + emit this->key_pressed_F3(); + return; + case Qt::Key_F4: + emit this->key_pressed_F4(); + return; + case Qt::Key_F5: + emit this->key_pressed_F5(); + return; + case Qt::Key_F6: + emit this->key_pressed_F6(); + return; + case Qt::Key_F7: + emit this->key_pressed_F7(); + return; + case Qt::Key_F8: + emit this->key_pressed_F8(); + return; + case Qt::Key_F9: + emit this->key_pressed_F9(); + return; + case Qt::Key_F10: + emit this->key_pressed_F10(); + return; + case Qt::Key_F11: + emit this->key_pressed_F11(); + return; + case Qt::Key_F12: + emit this->key_pressed_F12(); + return; } } diff --git a/programs/lab1/src/main.cpp b/programs/labs1_5/src/main.cpp similarity index 61% rename from programs/lab1/src/main.cpp rename to programs/labs1_5/src/main.cpp index 19808ec..57a5078 100644 --- a/programs/lab1/src/main.cpp +++ b/programs/labs1_5/src/main.cpp @@ -9,13 +9,13 @@ #include #include #include -#include "sprite_data.hpp" +#include "variants/sprite_data.hpp" #include "keyboard_catcher_widget.hpp" #include "pixel_grid_sprite.hpp" -#include "variants.hpp" +#include "variants/variants.hpp" #include "zoomed_scene_sprite.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl { volatile RendererApi::Color bg{0, 0, 0}; RendererApi::Color::Transparent fg{255, 255, 255, 127}; @@ -24,45 +24,45 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { #if 1 QApplication qApplication{argc, argv}; - PixelGridSprite pixels_grid_sprite{RendererApi::Color{0, 0, 0}, RendererApi::Color{16, 16, 16}}; ZoomedSceneSprite zoomed_scene_sprite{}; - auto sprites = std::to_array *const>({ - &pixels_grid_sprite, - &zoomed_scene_sprite - }); + auto sprites = std::to_array *const>({ + &pixels_grid_sprite, + &zoomed_scene_sprite + }); - Lab1SpriteData::Provider sprites_data{0.1}; + SpriteData::Provider sprites_data{0.1}; sprites_data.set_pixel_size(16); - sprites_data.set_sub_sprites(variant3.sprites, variant3.count); - VariantsManager vmngr{}; - QObject::connect(&vmngr, &VariantsManager::set_sprites, &sprites_data, &Lab1SpriteData::Provider::set_sub_sprites); + + Variants::VariantsManager vmngr{}; + QObject::connect(&vmngr, &Variants::VariantsManager::set_sprites, &sprites_data, &SpriteData::Provider::set_sub_sprites); + vmngr.set_lab_1(); QMainWindow w{}; KeyboardCatcherWidget kbd{&w}; - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_PageDown, &sprites_data, &Lab1SpriteData::Provider::decrease_pixel_size); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_PageUp, &sprites_data, &Lab1SpriteData::Provider::increase_pixel_size); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_G, &sprites_data, &Lab1SpriteData::Provider::invert_show_grid); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_1, &vmngr, &VariantsManager::set_variant_1); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_2, &vmngr, &VariantsManager::set_variant_2); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_3, &vmngr, &VariantsManager::set_variant_3); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_4, &vmngr, &VariantsManager::set_variant_4); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_5, &vmngr, &VariantsManager::set_variant_5); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_6, &vmngr, &VariantsManager::set_variant_6); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_8, &vmngr, &VariantsManager::set_variant_8); - QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_9, &vmngr, &VariantsManager::set_variant_9); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_PageDown, &sprites_data, &SpriteData::Provider::decrease_pixel_size); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_PageUp, &sprites_data, &SpriteData::Provider::increase_pixel_size); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_G, &sprites_data, &SpriteData::Provider::invert_show_grid); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_1, &vmngr, &Variants::VariantsManager::set_variant_1); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_2, &vmngr, &Variants::VariantsManager::set_variant_2); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_3, &vmngr, &Variants::VariantsManager::set_variant_3); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_4, &vmngr, &Variants::VariantsManager::set_variant_4); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_5, &vmngr, &Variants::VariantsManager::set_variant_5); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_6, &vmngr, &Variants::VariantsManager::set_variant_6); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_8, &vmngr, &Variants::VariantsManager::set_variant_8); + QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_9, &vmngr, &Variants::VariantsManager::set_variant_9); - QtUtilities::SeparateThreadedDefaultRendererLinear renderer{}; + QtUtilities::SeparateThreadedDefaultRendererLinear renderer{}; renderer.set_sprite_data_provider(&sprites_data); renderer.set_sprites(sprites.data(), sprites.size()); renderer.set_background(BGTU::ComputerGraphicsLabWork::RendererApi::Color{0, 0, 0}); - QtUtilities::RendererWidget canvas{&renderer, &kbd}; - QObject::connect(&canvas, &QtUtilities::_RendererWidget_SignalSlots::resized, &sprites_data, &Lab1SpriteData::Provider::set_frame_size); + QtUtilities::RendererWidget canvas{&renderer, &kbd}; + QObject::connect(&canvas, &QtUtilities::_RendererWidget_SignalSlots::resized, &sprites_data, &SpriteData::Provider::set_frame_size); w.setCentralWidget(&canvas); w.show(); @@ -83,5 +83,5 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { int main(int argc, char **argv) { - return BGTU::ComputerGraphicsLabWork::Lab1::main(argc, argv); + return BGTU::ComputerGraphicsLabWork::Impl::main(argc, argv); } \ No newline at end of file diff --git a/programs/lab1/src/pixel_grid_sprite.hpp b/programs/labs1_5/src/pixel_grid_sprite.hpp similarity index 84% rename from programs/lab1/src/pixel_grid_sprite.hpp rename to programs/labs1_5/src/pixel_grid_sprite.hpp index 748f979..ec0fb67 100644 --- a/programs/lab1/src/pixel_grid_sprite.hpp +++ b/programs/labs1_5/src/pixel_grid_sprite.hpp @@ -5,17 +5,17 @@ #include #include #include -#include "sprite_data.hpp" +#include "variants/sprite_data.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { - class PixelGridSprite : public RendererApi::Sprite { +namespace BGTU::ComputerGraphicsLabWork::Impl { + class PixelGridSprite : public RendererApi::Sprite { private: RendererApi::Color bg, fg; public: PixelGridSprite(RendererApi::Color bg, RendererApi::Color fg) : bg{bg}, fg{fg} {}; - void draw(Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl *frame, const Lab1SpriteData *data) const override { + void draw(Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl *frame, const SpriteData *data) const override { if (!data->show_grid) return; diff --git a/programs/lab1/src/variants/common_sprites.hpp b/programs/labs1_5/src/variants/lab1/common_sprites.hpp similarity index 84% rename from programs/lab1/src/variants/common_sprites.hpp rename to programs/labs1_5/src/variants/lab1/common_sprites.hpp index 7425757..21fae15 100644 --- a/programs/lab1/src/variants/common_sprites.hpp +++ b/programs/labs1_5/src/variants/lab1/common_sprites.hpp @@ -7,9 +7,9 @@ #include #include "../sprite_data.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab1 { template - void static_centered_circle_edge(Utilities::ZoomedVoxelPainter *frame, Lab1SpriteData::ShapeData const *data) { + void static_centered_circle_edge(Utilities::ZoomedVoxelPainter *frame, SpriteData::ShapeData const *data) { Utilities::Shapes::draw_circle_edge(frame, {0, 0}, data->radius * radius_multiplier, z, c); } @@ -23,11 +23,11 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { static void apply_radius(RendererApi::PointI<2> *dst, std::size_t i, RendererApi::PointI<2>::component_t radius) {} - static void as_radius_and_angle_pos(RendererApi::PointI<2> *dst, std::size_t i, Lab1SpriteData::ShapeData const *data) {} + static void as_radius_and_angle_pos(RendererApi::PointI<2> *dst, std::size_t i, SpriteData::ShapeData const *data) {} - static void as_radius_and_angle_neg(RendererApi::PointI<2> *dst, std::size_t i, Lab1SpriteData::ShapeData const *data) {} + static void as_radius_and_angle_neg(RendererApi::PointI<2> *dst, std::size_t i, SpriteData::ShapeData const *data) {} - static void as_radius_and_angle_static(RendererApi::PointI<2> *dst, std::size_t i, Lab1SpriteData::ShapeData const *data) {} + static void as_radius_and_angle_static(RendererApi::PointI<2> *dst, std::size_t i, SpriteData::ShapeData const *data) {} }; template p0, RendererApi::PointF<2>... pn> @@ -38,24 +38,24 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { _iter_points::apply_radius(dst, i + 1, radius); } - static void as_radius_and_angle_pos(RendererApi::PointI<2> *dst, std::size_t i, Lab1SpriteData::ShapeData const *data) { + static void as_radius_and_angle_pos(RendererApi::PointI<2> *dst, std::size_t i, SpriteData::ShapeData const *data) { dst[i] = data->pos_rotated(data->radius * p0.x, p0.y); _iter_points::as_radius_and_angle_pos(dst, i + 1, data); } - static void as_radius_and_angle_neg(RendererApi::PointI<2> *dst, std::size_t i, Lab1SpriteData::ShapeData const *data) { + static void as_radius_and_angle_neg(RendererApi::PointI<2> *dst, std::size_t i, SpriteData::ShapeData const *data) { dst[i] = data->neg_rotated(data->radius * p0.x, p0.y); _iter_points::as_radius_and_angle_neg(dst, i + 1, data); } - static void as_radius_and_angle_static(RendererApi::PointI<2> *dst, std::size_t i, Lab1SpriteData::ShapeData const *data) { + static void as_radius_and_angle_static(RendererApi::PointI<2> *dst, std::size_t i, SpriteData::ShapeData const *data) { dst[i] = data->static_rotated(data->radius * p0.x, p0.y); _iter_points::as_radius_and_angle_static(dst, i + 1, data); } }; template... points_m> - void static_polygon_edge(Utilities::ZoomedVoxelPainter *frame, Lab1SpriteData::ShapeData const *data) { + void static_polygon_edge(Utilities::ZoomedVoxelPainter *frame, SpriteData::ShapeData const *data) { union { RendererApi::PointI<2> array[sizeof...(points_m)]; bool nothing; @@ -65,7 +65,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { } template... points_m> - void pos_rotated_polygon_edge(Utilities::ZoomedVoxelPainter *frame, Lab1SpriteData::ShapeData const *data) { + void pos_rotated_polygon_edge(Utilities::ZoomedVoxelPainter *frame, SpriteData::ShapeData const *data) { union { RendererApi::PointI<2> array[sizeof...(points_m)]; bool nothing; @@ -75,7 +75,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { } template... points_m> - void neg_rotated_polygon_edge(Utilities::ZoomedVoxelPainter *frame, Lab1SpriteData::ShapeData const *data) { + void neg_rotated_polygon_edge(Utilities::ZoomedVoxelPainter *frame, SpriteData::ShapeData const *data) { union { RendererApi::PointI<2> array[sizeof...(points_m)]; bool nothing; @@ -85,7 +85,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { } template... points_m> - void static_rotated_polygon_edge(Utilities::ZoomedVoxelPainter *frame, Lab1SpriteData::ShapeData const *data) { + void static_rotated_polygon_edge(Utilities::ZoomedVoxelPainter *frame, SpriteData::ShapeData const *data) { union { RendererApi::PointI<2> array[sizeof...(points_m)]; bool nothing; diff --git a/programs/lab1/src/variants/variant1.cpp b/programs/labs1_5/src/variants/lab1/variant1.cpp similarity index 89% rename from programs/lab1/src/variants/variant1.cpp rename to programs/labs1_5/src/variants/lab1/variant1.cpp index 6fea590..c5abec3 100644 --- a/programs/lab1/src/variants/variant1.cpp +++ b/programs/labs1_5/src/variants/lab1/variant1.cpp @@ -1,7 +1,7 @@ #include "../variants.hpp" #include "common_sprites.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab1 { variant_sprites variant1 = variant_sprites::make_light< static_centered_circle_edge<5.0, {0, 127, 255}, 1.0>, static_rotated_polygon_edge<4.0, {0, 255, 255}, {1, 0}, {1, 90}, {1, 180}, {1, 270}>, diff --git a/programs/lab1/src/variants/variant2.cpp b/programs/labs1_5/src/variants/lab1/variant2.cpp similarity index 88% rename from programs/lab1/src/variants/variant2.cpp rename to programs/labs1_5/src/variants/lab1/variant2.cpp index e32325c..c21b616 100644 --- a/programs/lab1/src/variants/variant2.cpp +++ b/programs/labs1_5/src/variants/lab1/variant2.cpp @@ -1,7 +1,7 @@ #include "../variants.hpp" #include "common_sprites.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab1 { variant_sprites variant2 = variant_sprites::make_light< static_centered_circle_edge<5.0, {127, 127, 127}, 1.0>, static_rotated_polygon_edge<4.0, {127, 127, 127}, {1, 90}, {1, 90-120}, {1, 90+120}>, diff --git a/programs/lab1/src/variants/variant3.cpp b/programs/labs1_5/src/variants/lab1/variant3.cpp similarity index 84% rename from programs/lab1/src/variants/variant3.cpp rename to programs/labs1_5/src/variants/lab1/variant3.cpp index 67ae188..8d8f4ff 100644 --- a/programs/lab1/src/variants/variant3.cpp +++ b/programs/labs1_5/src/variants/lab1/variant3.cpp @@ -1,11 +1,11 @@ -#include +#include "bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp" #include "../variants.hpp" #include "../sprite_data.hpp" #include "common_sprites.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab1 { template - static void _variant3_circle(Utilities::ZoomedVoxelPainter *frame, Lab1SpriteData::ShapeData const *data) { + static void _variant3_circle(Utilities::ZoomedVoxelPainter *frame, SpriteData::ShapeData const *data) { Utilities::Shapes::draw_circle_edge(frame, data->pos_rotated(data->radius * center_distance_multiplier, center_angle_degrees), data->radius * radius_multiplier, z, c); } diff --git a/programs/lab1/src/variants/variant4.cpp b/programs/labs1_5/src/variants/lab1/variant4.cpp similarity index 88% rename from programs/lab1/src/variants/variant4.cpp rename to programs/labs1_5/src/variants/lab1/variant4.cpp index ec58267..c302000 100644 --- a/programs/lab1/src/variants/variant4.cpp +++ b/programs/labs1_5/src/variants/lab1/variant4.cpp @@ -1,7 +1,7 @@ #include "../variants.hpp" #include "common_sprites.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab1 { variant_sprites variant4 = variant_sprites::make_light< static_centered_circle_edge<2.0, {127, 127, 127}, 1.0>, pos_rotated_polygon_edge<1.0, {0, 0, 255}, diff --git a/programs/lab1/src/variants/variant5.cpp b/programs/labs1_5/src/variants/lab1/variant5.cpp similarity index 90% rename from programs/lab1/src/variants/variant5.cpp rename to programs/labs1_5/src/variants/lab1/variant5.cpp index 555425a..5fd98be 100644 --- a/programs/lab1/src/variants/variant5.cpp +++ b/programs/labs1_5/src/variants/lab1/variant5.cpp @@ -1,7 +1,7 @@ #include "../variants.hpp" #include "common_sprites.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab1 { variant_sprites variant5 = variant_sprites::make_light< static_centered_circle_edge<2.0, {127, 127, 127}, 1.0>, neg_rotated_polygon_edge<1.0, {0, 0, 255}, diff --git a/programs/lab1/src/variants/variant6.cpp b/programs/labs1_5/src/variants/lab1/variant6.cpp similarity index 91% rename from programs/lab1/src/variants/variant6.cpp rename to programs/labs1_5/src/variants/lab1/variant6.cpp index 5194834..1ac3b61 100644 --- a/programs/lab1/src/variants/variant6.cpp +++ b/programs/labs1_5/src/variants/lab1/variant6.cpp @@ -1,7 +1,7 @@ #include "../variants.hpp" #include "common_sprites.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab1 { variant_sprites variant6 = variant_sprites::make_light< static_centered_circle_edge<4.0, {127, 127, 127}, 1.0>, //sqrt(5.0)*sqrt(5.0+2.0*sqrt(5.0))/10.0 * sqrt((5.0-sqrt(5.0))/2.0) diff --git a/programs/lab1/src/variants/variant8.cpp b/programs/labs1_5/src/variants/lab1/variant8.cpp similarity index 90% rename from programs/lab1/src/variants/variant8.cpp rename to programs/labs1_5/src/variants/lab1/variant8.cpp index 6305163..0c730f1 100644 --- a/programs/lab1/src/variants/variant8.cpp +++ b/programs/labs1_5/src/variants/lab1/variant8.cpp @@ -1,7 +1,7 @@ #include "../variants.hpp" #include "common_sprites.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab1 { variant_sprites variant8 = variant_sprites::make_light< static_centered_circle_edge<4.0, {127, 127, 127}, 1.0>, static_rotated_polygon_edge<3.0, {0, 0, 255}, diff --git a/programs/lab1/src/variants/variant9.cpp b/programs/labs1_5/src/variants/lab1/variant9.cpp similarity index 85% rename from programs/lab1/src/variants/variant9.cpp rename to programs/labs1_5/src/variants/lab1/variant9.cpp index e303b18..2d93cce 100644 --- a/programs/lab1/src/variants/variant9.cpp +++ b/programs/labs1_5/src/variants/lab1/variant9.cpp @@ -1,11 +1,11 @@ -#include +#include "bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp" #include "../variants.hpp" #include "../sprite_data.hpp" #include "common_sprites.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants::Lab1 { template - static void _variant8_triangle(Utilities::ZoomedVoxelPainter *frame, Lab1SpriteData::ShapeData const *data) { + static void _variant8_triangle(Utilities::ZoomedVoxelPainter *frame, SpriteData::ShapeData const *data) { pos_rotated_polygon_edge(frame, data); } diff --git a/programs/lab1/src/sprite_data.hpp b/programs/labs1_5/src/variants/sprite_data.hpp similarity index 81% rename from programs/lab1/src/sprite_data.hpp rename to programs/labs1_5/src/variants/sprite_data.hpp index 0c4c183..59bc10c 100644 --- a/programs/lab1/src/sprite_data.hpp +++ b/programs/labs1_5/src/variants/sprite_data.hpp @@ -7,18 +7,18 @@ #include #include #include -#include -#include -#include -#include -#include +#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::Lab1 { +namespace BGTU::ComputerGraphicsLabWork::Impl { class _Lab1SpriteData_Provider; - struct Lab1SpriteData { + struct SpriteData { public: struct ShapeData { public: @@ -63,7 +63,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { }; - class _Lab1SpriteData_Provider : public QObject, public RendererApi::Sprite::SpriteDataProvider { + class _Lab1SpriteData_Provider : public QObject, public RendererApi::Sprite::SpriteDataProvider { Q_OBJECT private: QMutex sync; @@ -73,7 +73,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { double radians_per_second; bool show_grid; RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, h; - RendererApi::Sprite> *const *sub_sprites; + RendererApi::Sprite> *const *sub_sprites; std::size_t sub_sprites_count; public: @@ -83,10 +83,10 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { w{0}, h{0}, sub_sprites{nullptr}, sub_sprites_count{0} {} - Lab1SpriteData get_sprite_data() override { + SpriteData get_sprite_data() override { this->sync.lock(); RendererApi::PointI<2>::component_t radius = (((this->w < this->h) ? this->w : this->h) * 7 / 16) / this->pixel_size; - Lab1SpriteData cached{ + SpriteData cached{ .central_pixel_tl = (RendererApi::PointI<2>) (RendererApi::PointF<2>(this->w, this->h) / 2.0 - RendererApi::PointF<2>(this->pixel_size, this->pixel_size) / 2.0), .pixel_size = this->pixel_size, .show_grid = this->show_grid, @@ -142,7 +142,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { this->sync.unlock(); } - void set_sub_sprites(RendererApi::Sprite> *const *s, std::size_t c) { + void set_sub_sprites(RendererApi::Sprite> *const *s, std::size_t c) { this->sync.lock(); this->sub_sprites = s; this->sub_sprites_count = c; diff --git a/programs/labs1_5/src/variants/variants.hpp b/programs/labs1_5/src/variants/variants.hpp new file mode 100644 index 0000000..6406666 --- /dev/null +++ b/programs/labs1_5/src/variants/variants.hpp @@ -0,0 +1,274 @@ +#pragma once + +#include +#include +#include +#include "bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp" +#include "bgtu/computer_graphics_lab_work/utilities/zoomed_voxel_painter.hpp" +#include "sprite_data.hpp" + +namespace BGTU::ComputerGraphicsLabWork::Impl::Variants { + struct variant_sprites { + private : + using sprite_t = RendererApi::Sprite>; + public: + + + sprite_t *const *const sprites; + std::size_t const count; + + + constexpr variant_sprites(sprite_t **_sprites, std::size_t _count) : sprites{_sprites}, count{_count} { + + } + + private: + template + struct _make { + }; + + template<> + struct _make<> { + public: + constexpr _make() {}; + + constexpr void export_pointers(sprite_t **dst, std::size_t pos) { + } + }; + + template + struct _make { + public: + e0 value; + + constexpr _make(e0 v) : value{std::move(v)} {}; + + constexpr void export_pointers(sprite_t **dst, std::size_t pos) { + dst[pos] = &this->value; + } + }; + + template + struct _make { + public: + e0 value; + _make next; + + constexpr _make(e0 v, en...nv) : value{std::move(v)}, next{nv...} {}; + + constexpr void export_pointers(sprite_t **dst, std::size_t pos) { + dst[pos] = &this->value; + this->next.export_pointers(dst, pos + 1); + } + }; + + public: + + template + constexpr static variant_sprites make(sprites_t...sprites) { + static _make i{sprites...}; + static sprite_t *p[sizeof...(sprites)]; + + i.export_pointers(p, 0); + return variant_sprites{p, sizeof...(sprites)}; + } + + private: + + template *frame, + SpriteData::ShapeData const *data)> + struct _make_light : public RendererApi::Sprite> { + }; + + template<> + struct _make_light<> { + public: + constexpr _make_light() {}; + + constexpr void export_pointers(sprite_t **dst, std::size_t pos) { + } + }; + + template *frame, + SpriteData::ShapeData const *data), + void (...sn)(Utilities::ZoomedVoxelPainter *frame, + SpriteData::ShapeData const *data)> + struct _make_light : public RendererApi::Sprite> { + public: + _make_light next; + + constexpr _make_light() : next{} {}; + + constexpr void export_pointers(sprite_t **dst, std::size_t pos) { + dst[pos] = this; + this->next.export_pointers(dst, pos + 1); + } + + void draw(Utilities::ZoomedVoxelPainter *frame, const SpriteData::ShapeData *data) const final { + s0(frame, data); + } + + void clicked() final {} + }; + + + public: + template *frame, + SpriteData::ShapeData const *data)> + constexpr static variant_sprites make_light() { + static _make_light i{}; + static sprite_t *p[sizeof...(sprites)]; + + i.export_pointers(p, 0); + return variant_sprites{p, sizeof...(sprites)}; + } + }; + + + namespace Lab1 { + extern variant_sprites variant1; + extern variant_sprites variant2; + extern variant_sprites variant3; + extern variant_sprites variant4; + extern variant_sprites variant5; + extern variant_sprites variant6; + extern variant_sprites variant8; + extern variant_sprites variant9; + } + + + class VariantsManager : public QObject { + Q_OBJECT + signals: + + void set_sprites( + RendererApi::Sprite> *const *sprites, + std::size_t count + ); + + private: + + enum class LabNo { + L1, L2, L3, L4, L5 + }; + + LabNo _current_lab = LabNo::L1; + QMutex sync; + + inline LabNo get_current_lab() { + this->sync.lock(); + auto copy = this->_current_lab; + this->sync.unlock(); + return copy; + } + + inline void set_current_lab(LabNo no) { + this->sync.lock(); + this->_current_lab = no; + this->sync.unlock(); + } + + inline void _set_sprites(variant_sprites sprites) { + emit this->set_sprites(sprites.sprites, sprites.count); + } + + public slots: + + inline void set_variant_1() { + switch (this->get_current_lab()) { + case LabNo::L1: + this->_set_sprites(Lab1::variant1); + default: + (void) 0; + } + }; + + inline void set_variant_2() { + switch (this->get_current_lab()) { + case LabNo::L1: + this->_set_sprites(Lab1::variant2); + default: + (void) 0; + } + }; + + inline void set_variant_3() { + switch (this->get_current_lab()) { + case LabNo::L1: + this->_set_sprites(Lab1::variant3); + default: + (void) 0; + } + }; + + inline void set_variant_4() { + switch (this->get_current_lab()) { + case LabNo::L1: + this->_set_sprites(Lab1::variant4); + default: + (void) 0; + } + }; + + inline void set_variant_5() { + switch (this->get_current_lab()) { + case LabNo::L1: + this->_set_sprites(Lab1::variant5); + default: + (void) 0; + } + }; + + inline void set_variant_6() { + switch (this->get_current_lab()) { + case LabNo::L1: + this->_set_sprites(Lab1::variant6); + default: + (void) 0; + } + }; + + inline void set_variant_8() { + switch (this->get_current_lab()) { + case LabNo::L1: + this->_set_sprites(Lab1::variant8); + default: + (void) 0; + } + }; + + inline void set_variant_9() { + switch (this->get_current_lab()) { + case LabNo::L1: + this->_set_sprites(Lab1::variant9); + default: + (void) 0; + } + }; + + inline void set_lab_1() { + this->set_current_lab(LabNo::L1); + this->_set_sprites(Lab1::variant3); + }; + + inline void set_lab_2() { + this->set_current_lab(LabNo::L2); + this->_set_sprites(Lab1::variant3); + }; + + inline void set_lab_3() { + this->set_current_lab(LabNo::L3); + this->_set_sprites(Lab1::variant3); + }; + + inline void set_lab_4() { + this->set_current_lab(LabNo::L4); + this->_set_sprites(Lab1::variant3); + }; + + inline void set_lab_5() { + this->set_current_lab(LabNo::L5); + this->_set_sprites(Lab1::variant3); + }; + }; +} \ No newline at end of file diff --git a/programs/lab1/src/zoomed_scene_sprite.hpp b/programs/labs1_5/src/zoomed_scene_sprite.hpp similarity index 74% rename from programs/lab1/src/zoomed_scene_sprite.hpp rename to programs/labs1_5/src/zoomed_scene_sprite.hpp index a246d4f..40b818a 100644 --- a/programs/lab1/src/zoomed_scene_sprite.hpp +++ b/programs/labs1_5/src/zoomed_scene_sprite.hpp @@ -5,16 +5,16 @@ #include #include #include -#include "sprite_data.hpp" +#include "variants/sprite_data.hpp" -namespace BGTU::ComputerGraphicsLabWork::Lab1 { - class ZoomedSceneSprite : public RendererApi::Sprite { +namespace BGTU::ComputerGraphicsLabWork::Impl { + class ZoomedSceneSprite : public RendererApi::Sprite { private: public: ZoomedSceneSprite() = default; - void draw(Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl *frame, const Lab1SpriteData *data) const override { + void draw(Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl *frame, const SpriteData *data) const override { Utilities::ZoomedVoxelPainter zoomed_painter{frame, data->central_pixel_tl, data->pixel_size}; for (std::size_t i = 0; i < data->sub_sprites_count; i++) { diff --git a/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/color.hpp b/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/color.hpp index 27654ef..5429355 100644 --- a/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/color.hpp +++ b/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/color.hpp @@ -50,6 +50,10 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi { constexpr bool operator!=(Color::Transparent const &other) const noexcept { return !(*this == other); } + + [[nodiscard]] constexpr Color without_alpha() const noexcept { + return Color{this->red, this->green, this->blue}; + }; }; }; } \ No newline at end of file diff --git a/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp b/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp index 53c3b32..c213d7e 100644 --- a/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp +++ b/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp @@ -9,14 +9,18 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi { virtual void clicked() {}; }; - template + template class Sprite : public SpriteMetadata { public: - virtual void draw(voxel_painter_t *frame, data_t const *data) const = 0; + using data_t = _data_t; + using voxel_painter_t = _voxel_painter_t; + + + virtual void draw(_voxel_painter_t *frame, _data_t const *data) const = 0; class SpriteDataProvider { public: - virtual data_t get_sprite_data() = 0; + virtual _data_t get_sprite_data() = 0; }; }; } \ No newline at end of file diff --git a/utilities/CMakeLists.txt b/utilities/CMakeLists.txt index 2133519..d94ec2f 100644 --- a/utilities/CMakeLists.txt +++ b/utilities/CMakeLists.txt @@ -1,7 +1,6 @@ add_library( utilities OBJECT - src/shader.cpp src/memory_pages_management.cpp src/default_renderer_linear_implementation.cpp src/default_renderer_linear_shapes_intrinsics.cpp diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/color.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/color.hpp index 4bcb344..3cb33a1 100644 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/color.hpp +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/color.hpp @@ -8,7 +8,9 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { constexpr RendererApi::Color _apply_transparent_color_pure(RendererApi::Color bg, RendererApi::Color::Transparent fg) { #if 1 if (fg.alpha == 255) - return {fg.red, fg.green, fg.blue}; + return fg.without_alpha(); + else if (fg.alpha == 0) + return bg; // pmovzxbd const std::uint_fast32_t bg_i32[4]{bg.red, bg.green, bg.blue}; @@ -31,7 +33,11 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { // divps const float sum_fixed_f[4]{sum_f[0] / 255.f, sum_f[2] / 255.f, sum_f[2] / 255.f}; - return {(RendererApi::Color::component_compact_t) sum_fixed_f[0], (RendererApi::Color::component_compact_t) sum_fixed_f[1], (RendererApi::Color::component_compact_t) sum_fixed_f[2]}; + return { + (RendererApi::Color::component_compact_t) sum_fixed_f[0], + (RendererApi::Color::component_compact_t) sum_fixed_f[1], + (RendererApi::Color::component_compact_t) sum_fixed_f[2] + }; #else return RendererApi::Color{ @@ -172,6 +178,7 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { buffer[offset + 1] = color.green; buffer[offset + 2] = color.blue; } + inline void color_to_bgr32(unsigned char *buffer, std::size_t offset, RendererApi::Color color) noexcept { buffer[offset] = color.blue; buffer[offset + 1] = color.green; diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp index a92fd85..c93f898 100644 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp @@ -165,6 +165,25 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { ) { this->fill_rectangle(left, top, right, bottom, z, fill, this->current_artist); } + + void draw_h_line( + RendererApi::PointI<2>::component_t y, + RendererApi::PointI<2>::component_t left, + RendererApi::PointI<2>::component_t right, + double z, + RendererApi::Color::Transparent color, + RendererApi::SpriteMetadata *owner + ); + + inline void draw_h_line( + RendererApi::PointI<2>::component_t y, + RendererApi::PointI<2>::component_t left, + RendererApi::PointI<2>::component_t right, + double z, + RendererApi::Color::Transparent color + ) { + this->draw_h_line(y, left, right, z, color, this->current_artist); + } }; private: diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shader.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shader.hpp index 01a0806..383ef43 100644 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shader.hpp +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shader.hpp @@ -2,29 +2,138 @@ #include +#include #include "matrix.hpp" namespace BGTU::ComputerGraphicsLabWork::Utilities { class Shader { public: - [[nodiscard]] virtual RendererApi::Color::Transparent get_color(double x, double y) const = 0; + [[nodiscard]] virtual RendererApi::Color::Transparent get_color(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) const = 0; - static Shader const *empty_shader; + [[nodiscard]] inline RendererApi::Color::Transparent get_color(RendererApi::PointI<2> p) const { + return this->get_color(p.x, p.y); + }; + + class Empty; + + static Shader::Empty const empty; }; + class Shader::Empty : public Shader { + public: + constexpr Empty() noexcept = default; + + [[nodiscard]] constexpr RendererApi::Color::Transparent get_color(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) const noexcept final { + return RendererApi::Color::Transparent{0, 0, 0, 0}; + }; + + operator Shader::Empty const *() const noexcept { // NOLINT(*-explicit-constructor) + return this; + } + + Shader::Empty const *operator->() const noexcept { + return this; + } + + }; + + + constexpr bool operator==(Shader::Empty const &, Shader::Empty const &) noexcept { + return true; + } + + constexpr bool operator==(Shader::Empty const &, Shader::Empty const *) noexcept { + return true; + } + + constexpr bool operator==(Shader::Empty const &, Shader const *other) noexcept { + return dynamic_cast(other) != nullptr; + } + + constexpr bool operator!=(Shader::Empty const &, Shader::Empty const &) noexcept { + return false; + } + + constexpr bool operator!=(Shader::Empty const &, Shader::Empty const *) noexcept { + return false; + } + + constexpr bool operator!=(Shader::Empty const &, Shader const *other) noexcept { + return dynamic_cast(other) == nullptr; + } + + constexpr bool operator==(Shader::Empty const *, Shader::Empty const &) noexcept { + return true; + } + + constexpr bool operator==(Shader const *other, Shader::Empty const &) noexcept { + return dynamic_cast(other) != nullptr; + } + + constexpr bool operator!=(Shader::Empty const *, Shader::Empty const &) noexcept { + return false; + } + + constexpr bool operator!=(Shader const *other, Shader::Empty const &) noexcept { + return dynamic_cast(other) == nullptr; + } + + constexpr Shader::Empty const Shader::empty{}; + class MonoShader : public Shader { private: RendererApi::Color::Transparent c; public: - inline explicit MonoShader(RendererApi::Color::Transparent c) : c{c} {} + constexpr explicit MonoShader(RendererApi::Color::Transparent c) noexcept: c{c} {} - [[nodiscard]] inline RendererApi::Color::Transparent get_color(double x, double y) const override { + [[nodiscard]] constexpr RendererApi::Color::Transparent get_color(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) const noexcept final { return this->c; }; + + template + class Static : public Shader { + public: + constexpr Static() noexcept = default; + + static constexpr RendererApi::Color::Transparent const COLOR = _color; + + [[nodiscard]] constexpr RendererApi::Color::Transparent get_color(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) const noexcept final { + return _color; + }; + + private: + static MonoShader::Static<_color> const INSTANCE; + + public: + operator MonoShader::Static<_color> const *() const noexcept { // NOLINT(*-explicit-constructor) + return &INSTANCE; + } + + + MonoShader::Static<_color> const *operator->() const noexcept { + return &INSTANCE; + } + + + template + constexpr bool operator==(MonoShader::Static) const noexcept { + return _color == other_color; + } + }; + + template + static MonoShader::Static const static_; }; + template + constexpr MonoShader::Static const MonoShader::Static::INSTANCE{}; + + template + constexpr MonoShader::Static const MonoShader::static_{}; + + class TransformedShader : public Shader { private: Shader const *shader; @@ -33,7 +142,7 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { public: inline TransformedShader(Shader const *s, Matrix4d t) : shader{s}, transform{t} {} - [[nodiscard]] inline RendererApi::Color::Transparent get_color(double x, double y) const override { + [[nodiscard]] inline RendererApi::Color::Transparent get_color(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) const override { RendererApi::PointF<3> in{x, y, 0}; RendererApi::PointF<3> out = this->transform * in; return this->shader->get_color(out.x, out.y); diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp index 152ba37..a7ec7bb 100644 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp @@ -6,30 +6,109 @@ #include namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes { + template + void iterate_circle_fill_h_lines( + RendererApi::PointI<2>::component_t cx, RendererApi::PointI<2>::component_t cy, + RendererApi::PointI<2>::component_t r, + edger_receiver_t edge_point_receiver, + fill_receiver_t fill_line_receiver + ) { + RendererApi::PointI<2>::component_t x = 0, y = r; + RendererApi::PointI<2>::component_t last_y = r + 1; + RendererApi::PointI<2>::component_t _r2 = r * r; + while (x < y) { + RendererApi::PointI<2>::component_t _x2 = x * x; + RendererApi::PointI<2>::component_t _y_1 = y - 1; + RendererApi::PointI<2>::component_t D1 = _x2 + y * y - _r2; + RendererApi::PointI<2>::component_t D2 = _x2 + _y_1 * _y_1 - _r2; + + if (D1 > -D2) + y--; + + if (y < last_y) { + edge_point_receiver(cx - x, cy + y); + fill_line_receiver(cy + y, cx - x + 1, cx + x); + edge_point_receiver(cx + x, cy + y); + + edge_point_receiver(cx - y, cy + x); + fill_line_receiver(cy + x, cx - y + 1, cx + y); + edge_point_receiver(cx + y, cy + x); + + if (x > 0) { + edge_point_receiver(cx - y, cy - x); + fill_line_receiver(cy - x, cx - y + 1, cx + y); + edge_point_receiver(cx + y, cy - x); + } + + edge_point_receiver(cx - x, cy - y); + fill_line_receiver(cy - y, cx - x + 1, cx + x); + edge_point_receiver(cx + x, cy - y); + + last_y = y; + } else { + edge_point_receiver(cx - x, cy + y); + edge_point_receiver(cx + x, cy + y); + + edge_point_receiver(cx - y, cy + x); + edge_point_receiver(cx + y, cy + x); + + if (x > 0) { + edge_point_receiver(cx - y, cy - x); + edge_point_receiver(cx + y, cy - x); + } + + edge_point_receiver(cx - x, cy - y); + edge_point_receiver(cx + x, cy - y); + } + x++; + } + } + + template + void iterate_circle_fill_h_lines( + RendererApi::PointI<2> c, + RendererApi::PointI<2>::component_t r, + edger_receiver_t edge_point_receiver, + fill_receiver_t fill_line_receiver + ) { + iterate_circle_fill_h_lines(c.x, c.y, r, edge_point_receiver, fill_line_receiver); + } + + template + void iterate_circle_fill( + RendererApi::PointI<2>::component_t cx, RendererApi::PointI<2>::component_t cy, + RendererApi::PointI<2>::component_t r, + receiver_t receiver + ) { + iterate_circle_fill_h_lines( + cx, cy, r, + [&](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { receiver(true, x, y); }, + [&](RendererApi::PointI<2>::component_t y, RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t x2) { + for (RendererApi::PointI<2>::component_t x = x1; x < x2; x++) receiver(x, y); + } + ); + } + + template + void iterate_circle_fill( + RendererApi::PointI<2> c, + RendererApi::PointI<2>::component_t r, + receiver_t receiver + ) { + iterate_circle_fill_lines(c.x, c.y, r, receiver); + } + template void iterate_circle_edge( RendererApi::PointI<2>::component_t cx, RendererApi::PointI<2>::component_t cy, RendererApi::PointI<2>::component_t r, receiver_t receiver ) { - RendererApi::PointI<2>::component_t x = 0, y = r; - while (x < y) { - RendererApi::PointI<2>::component_t D1 = x * x + y * y - r * r; - RendererApi::PointI<2>::component_t D2 = x * x + (y - 1) * (y - 1) - r * r; - - if (D1 > -D2) - y--; - - receiver(cx + x, cy + y); - receiver(cx + x, cy - y); - receiver(cx + y, cy + x); - receiver(cx + y, cy - x); - receiver(cx - x, cy + y); - receiver(cx - x, cy - y); - receiver(cx - y, cy + x); - receiver(cx - y, cy - x); - x++; - } + iterate_circle_fill_h_lines( + cx, cy, r, + receiver, + [](RendererApi::PointI<2>::component_t y, RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t x2) {} + ); } diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/line.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/line.hpp index aeb2435..dd10915 100644 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/line.hpp +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/line.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes { @@ -108,4 +109,66 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes { return nullptr; } }; + + template + void iterate_h_line( + RendererApi::PointI<2>::component_t y, + RendererApi::PointI<2>::component_t x1, + RendererApi::PointI<2>::component_t x2, + receiver_t receiver + ) { + if (x2 < x1) + std::swap(x1, x2); + for (RendererApi::PointI<2>::component_t x = x1; x <= x2; x++) { + receiver(x, y); + } + } + + template + void iterate_v_line( + RendererApi::PointI<2>::component_t x, + RendererApi::PointI<2>::component_t y1, + RendererApi::PointI<2>::component_t y2, + receiver_t receiver + ) { + if (y2 < y1) + std::swap(y1, y2); + for (RendererApi::PointI<2>::component_t y = y1; x <= y2; y++) { + receiver(x, y); + } + } + + template + void iterate_brezenham( + RendererApi::PointI<2>::component_t x1, + RendererApi::PointI<2>::component_t y1, + RendererApi::PointI<2>::component_t x2, + RendererApi::PointI<2>::component_t y2, + receiver_t receiver + ) { + // todo transpose + for (auto p: brezenham_line_iterable{x1, y1, x2, y2}) { + receiver(p.x, p.y); + } + } + + template + void iterate_line( + RendererApi::PointI<2>::component_t x1, + RendererApi::PointI<2>::component_t y1, + RendererApi::PointI<2>::component_t x2, + RendererApi::PointI<2>::component_t y2, + receiver_t receiver + ) { + if (x1 == x2) { + iterate_v_line(x1, y1, y2, receiver); + return; + } + if (y1 == y2) { + iterate_h_line(y1, x1, x2, receiver); + return; + } + + iterate_brezenham(x1, y1, x2, y2, receiver); + } } \ No newline at end of file diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/polygon.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/polygon.hpp index 8b67e62..7c9e6cc 100644 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/polygon.hpp +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/polygon.hpp @@ -66,4 +66,5 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes { [=](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, outline, owner); } ); } + } \ No newline at end of file diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/triangle.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/triangle.hpp new file mode 100644 index 0000000..d41d4e2 --- /dev/null +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/triangle.hpp @@ -0,0 +1,320 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "line.hpp" + +namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes { + + template + void iterate_triangle_fill( + RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, + RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, + RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2, + receiver_t receiver + ); + + class triangle_fill_iterable { + private: + brezenham_line_iterable upper_left; + brezenham_line_iterable lower_left; + brezenham_line_iterable right; + + template + friend + void iterate_triangle_fill( + RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, + RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, + RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2, + receiver_t + ); + + + inline triangle_fill_iterable( + brezenham_line_iterable upper_left, + brezenham_line_iterable lower_left, + brezenham_line_iterable right + ) : upper_left{upper_left}, lower_left{lower_left}, right{right} {} + + struct _pre_constructor { + private: + inline static void sort_points(RendererApi::PointI<2>::component_t *x0, RendererApi::PointI<2>::component_t *y0, RendererApi::PointI<2>::component_t *x1, RendererApi::PointI<2>::component_t *y1, RendererApi::PointI<2>::component_t *x2, RendererApi::PointI<2>::component_t *y2) { + auto _swap = [](RendererApi::PointI<2>::component_t *sx0, RendererApi::PointI<2>::component_t *sy0, RendererApi::PointI<2>::component_t *sx1, RendererApi::PointI<2>::component_t *sy1) { + RendererApi::PointI<2>::component_t tmp; + + tmp = *sx0; + *sx0 = *sx1; + *sx1 = tmp; + + tmp = *sy0; + *sy0 = *sy1; + *sy1 = tmp; + }; + + if (*y0 < *y1) + _swap(x0, y0, x1, y1); + if (*y1 < *y2) + _swap(x1, y1, x2, y2); + if (*y0 < *y1) + _swap(x0, y0, x1, y1); + if (*y0 == *y1 && *x0 < *x1) + _swap(x0, y0, x1, y1); + if (*y1 == *y2 && *x2 < *x1) + _swap(x1, y1, x2, y2); + } + + public: + + static inline triangle_fill_iterable create( + RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, + RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, + RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2 + ) { + _pre_constructor::sort_points(&x0, &y0, &x1, &y1, &x2, &y2); + return triangle_fill_iterable{brezenham_line_iterable{x0, y0, x1, y1}, brezenham_line_iterable{x1, y1, x2, y2}, brezenham_line_iterable{x0, y0, x2, y2}}; + } + }; + + public: + inline triangle_fill_iterable( + RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, + RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, + RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2 + ) : triangle_fill_iterable{_pre_constructor::create(x0, y0, x1, y1, x2, y2)} { + } + +#if 0 + class iterator { + private: + brezenham_line_iterable::iterator upper_left; + brezenham_line_iterable::iterator lower_left; + brezenham_line_iterable::iterator right; + RendererApi::PointI<2>::component_t cx, ex, cy; + + friend class triangle_fill; + + inline iterator( + brezenham_line_iterable const &upper_left, + brezenham_line_iterable const &lower_left, + brezenham_line_iterable const &right + ) : upper_left{upper_left.begin()}, lower_left{lower_left.begin()}, right{right.begin()}, cx{(*this->upper_left).x}, ex{(*this->right).x}, cy{(*this->upper_left).y} {} + + + brezenham_line_iterable::iterator &_left() { + if (this->upper_left == nullptr) + return this->lower_left; + else + return this->upper_left; + } + + public: + inline iterator &operator++() { + if (this->cx < this->ex) { + this->cx++; + return *this; + } + if (this->upper_left != nullptr) { + RendererApi::PointI<2>::component_t sx = (*(this->upper_left)).x; + while (true) { + this->upper_left++; + if (this->upper_left == nullptr) + goto LOWER; + if ((*(this->upper_left)).y < this->cy) + { + this->cy--; + return *this; + + (*++(this->upper_left)).y >= this->cy + if ((*(this->upper_left)).x < sx) + return *this; + } + } else { + LOWER: + RendererApi::PointI<2>::component_t sx = (*(this->upper_left)).x; + } + + while ((*++(this->right)).y >= this->cy) { + if ((*(this->right)).x > this->ex) + return *this; + } + + this->cy--; + + + } + + inline iterator operator++(int) { + iterator next = *this; + ++(*this); + return next; + } + + inline point operator*() const { + if (this->swap_flag) + return point{this->ret, this->arg}; + else + return point{this->arg, this->ret}; + } + + inline bool operator==(std::nullptr_t) const { + return this->arg >= this->end_arg; + } + + inline bool operator!=(std::nullptr_t) const { + return this->arg < this->end_arg; + } + }; +#endif + }; + + + template + void iterate_triangle_fill( + RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, + RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, + RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2, + receiver_t receiver + ) { + triangle_fill_iterable init{x0, y0, x1, y1, x2, y2}; + auto right = init.right.begin(); + RendererApi::PointI<2>::component_t cy = (*right).y; + RendererApi::PointI<2>::component_t sx = std::numeric_limits::component_t>::min(); + RendererApi::PointI<2>::component_t ex = std::numeric_limits::component_t>::max(); + + auto loop = [&](brezenham_line_iterable left) { + + for (auto lp: left) { + if (lp.y == cy) { + receiver(true, lp.x, lp.y); + sx = (lp.x > sx) ? (lp.x) : sx; + continue; + } + + for (; (*right).y > lp.y; right++) { + if ((*right).x > sx) + receiver(true, (*right).x, (*right).y); + ex = ((*right).x < ex) ? ((*right).x) : ex; + } + for (RendererApi::PointI<2>::component_t x = sx + 1; x < ex; x++) + receiver(false, x, cy); + + cy--; + receiver(true, lp.x, lp.y); + } + }; + + loop(init.upper_left); + loop(init.lower_left); + for (; right != nullptr; right++) { + if ((*right).x > sx) + receiver(true, (*right).x, (*right).y); + } + } + + template + void iterate_triangle_fill( + RendererApi::PointI<2> p0, + RendererApi::PointI<2> p1, + RendererApi::PointI<2> p2, + receiver_t receiver + ) { + iterate_triangle_fill( + p0.x, p0.y, + p1.x, p1.y, + p2.x, p2.y, + receiver + ); + } + + template + 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; + variable_t v0; + variable_t v1; + variable_t v2; + + struct _empty { + }; + + std::conditional_t, bool, _empty> skip_alpha; + + static long double calculate_square_2( + RendererApi::PointI<2> p0, + RendererApi::PointI<2> p1, + RendererApi::PointI<2> p2 + ) noexcept { + return (p2.x - p1.x) * (p2.y - p0.y) + (p2.x - p0.x) * (p1.y - p0.y); + } + + + public: + triangle_barycentric_interpolator( + RendererApi::PointI<2> p0, RendererApi::PointI<2> p1, RendererApi::PointI<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) { + this->skip_alpha = v0.alpha == v1.alpha && v0.alpha == v2.alpha; + } + } + + variable_t interpolate_point(RendererApi::PointI<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; + auto f = [&](intermediate_t (variable_t::*offset)) -> intermediate_t { + return static_cast((this->v0.*offset) * k0 + (this->v1.*offset) * k1 + (this->v2.*offset) * k2); + }; + if constexpr (std::is_same_v) { + RendererApi::Color base{ + f(&RendererApi::Color::Transparent::red), + f(&RendererApi::Color::Transparent::green), + f(&RendererApi::Color::Transparent::blue), + }; + return RendererApi::Color::Transparent{ + base.red, base.green, base.blue, + (this->skip_alpha ? this->v0.alpha : f(&RendererApi::Color::Transparent::alpha)) + }; + } else if constexpr (std::is_same_v) { + return RendererApi::Color{ + f(&RendererApi::Color::red), + f(&RendererApi::Color::green), + f(&RendererApi::Color::blue) + }; + } else { + return static_cast(f(&variable_t::variable_t)); + } + } + + 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}); + } + }; + + + class triangle_barycentric_shader : public Shader { + private: + triangle_barycentric_interpolator interpolator; + public: + inline triangle_barycentric_shader( + RendererApi::PointI<2> p0, RendererApi::PointI<2> p1, RendererApi::PointI<2> p2, + RendererApi::Color::Transparent c0, RendererApi::Color::Transparent c1, RendererApi::Color::Transparent c2 + ) : 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 { + return this->interpolator.interpolate_point(x, y); + } + }; +} \ No newline at end of file diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/triangle_fill_iterable.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/triangle_fill_iterable.hpp deleted file mode 100644 index ea10141..0000000 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/triangle_fill_iterable.hpp +++ /dev/null @@ -1,214 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "bgtu/computer_graphics_lab_work/utilities/shapes/line.hpp" - -namespace BGTU::ComputerGraphicsLabWork::Utilities { - - template - void fill_triangle( - RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, - RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, - RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2, - receiver_t receiver - ) noexcept(receiver(static_cast(false), static_cast::component_t>(0), static_cast::component_t>(0))); - class triangle_fill_iterable { - private: - brezenham_line_iterable upper_left; - brezenham_line_iterable lower_left; - brezenham_line_iterable right; - - template - friend - void fill_triangle( - RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, - RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, - RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2, - receiver_t - ) noexcept(std::declval()(static_cast(false), static_cast::component_t>(0), static_cast::component_t>(0))); - - - inline triangle_fill_iterable( - brezenham_line_iterable upper_left, - brezenham_line_iterable lower_left, - brezenham_line_iterable right - ) : upper_left{upper_left}, lower_left{lower_left}, right{right} {} - - struct _pre_constructor { - private: - inline static void sort_points(RendererApi::PointI<2>::component_t *x0, RendererApi::PointI<2>::component_t *y0, RendererApi::PointI<2>::component_t *x1,RendererApi::PointI<2>::component_t *y1, RendererApi::PointI<2>::component_t *x2, RendererApi::PointI<2>::component_t *y2) { - auto _swap = [](RendererApi::PointI<2>::component_t *sx0, RendererApi::PointI<2>::component_t *sy0, RendererApi::PointI<2>::component_t *sx1, RendererApi::PointI<2>::component_t *sy1) { - RendererApi::PointI<2>::component_t tmp; - - tmp = *sx0; - *sx0 = *sx1; - *sx1 = tmp; - - tmp = *sy0; - *sy0 = *sy1; - *sy1 = tmp; - }; - - if (*y0 < *y1) - _swap(x0, y0, x1, y1); - if (*y1 < *y2) - _swap(x1, y1, x2, y2); - if (*y0 < *y1) - _swap(x0, y0, x1, y1); - if (*y0 == *y1 && *x0 < *x1) - _swap(x0, y0, x1, y1); - if (*y1 == *y2 && *x2 < *x1) - _swap(x1, y1, x2, y2); - } - - public: - - static inline triangle_fill_iterable create( - RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, - RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, - RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2 - ) { - _pre_constructor::sort_points(&x0, &y0, &x1, &y1, &x2, &y2); - return triangle_fill_iterable{brezenham_line_iterable{x0, y0, x1, y1}, brezenham_line_iterable{x1, y1, x2, y2}, brezenham_line_iterable{x0, y0, x2, y2}}; - } - }; - - public: - inline triangle_fill_iterable( - RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, - RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, - RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2 - ) : triangle_fill_iterable{_pre_constructor::create(x0, y0, x1, y1, x2, y2)} { - } - -#if 0 - class iterator { - private: - brezenham_line_iterable::iterator upper_left; - brezenham_line_iterable::iterator lower_left; - brezenham_line_iterable::iterator right; - RendererApi::PointI<2>::component_t cx, ex, cy; - - friend class triangle_fill; - - inline iterator( - brezenham_line_iterable const &upper_left, - brezenham_line_iterable const &lower_left, - brezenham_line_iterable const &right - ) : upper_left{upper_left.begin()}, lower_left{lower_left.begin()}, right{right.begin()}, cx{(*this->upper_left).x}, ex{(*this->right).x}, cy{(*this->upper_left).y} {} - - - brezenham_line_iterable::iterator &_left() { - if (this->upper_left == nullptr) - return this->lower_left; - else - return this->upper_left; - } - - public: - inline iterator &operator++() { - if (this->cx < this->ex) { - this->cx++; - return *this; - } - if (this->upper_left != nullptr) { - RendererApi::PointI<2>::component_t sx = (*(this->upper_left)).x; - while (true) { - this->upper_left++; - if (this->upper_left == nullptr) - goto LOWER; - if ((*(this->upper_left)).y < this->cy) - { - this->cy--; - return *this; - - (*++(this->upper_left)).y >= this->cy - if ((*(this->upper_left)).x < sx) - return *this; - } - } else { - LOWER: - RendererApi::PointI<2>::component_t sx = (*(this->upper_left)).x; - } - - while ((*++(this->right)).y >= this->cy) { - if ((*(this->right)).x > this->ex) - return *this; - } - - this->cy--; - - - } - - inline iterator operator++(int) { - iterator next = *this; - ++(*this); - return next; - } - - inline point operator*() const { - if (this->swap_flag) - return point{this->ret, this->arg}; - else - return point{this->arg, this->ret}; - } - - inline bool operator==(std::nullptr_t) const { - return this->arg >= this->end_arg; - } - - inline bool operator!=(std::nullptr_t) const { - return this->arg < this->end_arg; - } - }; -#endif - }; - - - template - void fill_triangle( - RendererApi::PointI<2>::component_t x0, RendererApi::PointI<2>::component_t y0, - RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, - RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2, - receiver_t receiver - ) noexcept(receiver(static_cast(false), static_cast::component_t>(0), static_cast::component_t>(0))) { - triangle_fill_iterable init{x0, y0, x1, y1, x2, y2}; - auto right = init.right.begin(); - RendererApi::PointI<2>::component_t cy = (*right).y; - RendererApi::PointI<2>::component_t sx = std::numeric_limits::component_t>::min(); - RendererApi::PointI<2>::component_t ex = std::numeric_limits::component_t>::max(); - - auto loop = [&](brezenham_line_iterable left) { - - for (auto lp: left) { - if (lp.y == cy) { - receiver(true, lp.x, lp.y); - sx = (lp.x > sx) ? (lp.x) : sx; - continue; - } - - for (; (*right).y > lp.y; right++) { - if ((*right).x > sx) - receiver(true, (*right).x, (*right).y); - ex = ((*right).x < ex) ? ((*right).x) : ex; - } - for (RendererApi::PointI<2>::component_t x = sx + 1; x < ex; x++) - receiver(false, x, cy); - - cy--; - receiver(true, lp.x, lp.y); - } - }; - - loop(init.upper_left); - loop(init.lower_left); - for (; right != nullptr; right++) { - if ((*right).x > sx) - receiver(true, (*right).x, (*right).y); - } - } -} \ No newline at end of file diff --git a/utilities/src/default_renderer_linear_shapes_intrinsics.cpp b/utilities/src/default_renderer_linear_shapes_intrinsics.cpp index 2b198ae..27dfb3f 100644 --- a/utilities/src/default_renderer_linear_shapes_intrinsics.cpp +++ b/utilities/src/default_renderer_linear_shapes_intrinsics.cpp @@ -25,4 +25,22 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { } ); } + + + void DefaultVoxelDrawerCache::VoxelPainterImpl::draw_h_line( + RendererApi::PointI<2>::component_t y, + RendererApi::PointI<2>::component_t left, + RendererApi::PointI<2>::component_t right, + double z, + RendererApi::Color::Transparent color, + RendererApi::SpriteMetadata *owner + ) { + if (y < 0 || y >= this->_height) return; + if (left < 0) left = 0; + if (right >= this->_width) right = this->_width; + + for (RendererApi::PointI<2>::component_t x = left; x < right; x++) { + this->_add_voxel(x, y, z, color, owner); + } + } } \ No newline at end of file diff --git a/utilities/src/shader.cpp b/utilities/src/shader.cpp deleted file mode 100644 index 8b27ca7..0000000 --- a/utilities/src/shader.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include - -namespace BGTU::ComputerGraphicsLabWork::Utilities { - - class EmptyShader : public Shader { - - public: - EmptyShader() = default; - - [[nodiscard]] RendererApi::Color::Transparent get_color(double x, double y) const override { - return RendererApi::Color::Transparent{0, 0, 0, 0}; - } - }; - - static const EmptyShader empty_shader_instance; - - Shader const *Shader::empty_shader = &empty_shader_instance; -} \ No newline at end of file