diff --git a/programs/lab1/src/main.cpp b/programs/lab1/src/main.cpp index 2827030..a30ecd0 100644 --- a/programs/lab1/src/main.cpp +++ b/programs/lab1/src/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { PixelGridSprite pixels_grid_sprite{RendererApi::Color{0, 0, 0}, RendererApi::Color{32, 32, 32}}; - auto sprites = std::to_array *const>({ + auto sprites = std::to_array *const>({ &pixels_grid_sprite }); diff --git a/programs/lab1/src/pixel_grid_sprite.hpp b/programs/lab1/src/pixel_grid_sprite.hpp index 6f0bba8..56e357e 100644 --- a/programs/lab1/src/pixel_grid_sprite.hpp +++ b/programs/lab1/src/pixel_grid_sprite.hpp @@ -8,21 +8,18 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { - class PixelGridSprite : public RendererApi::Sprite { + class PixelGridSprite : public RendererApi::Sprite { private: RendererApi::Color bg, fg; public: PixelGridSprite(RendererApi::Color bg, RendererApi::Color fg) : bg{bg}, fg{fg} {}; - void draw(BGTU::ComputerGraphicsLabWork::RendererApi::VoxelDrawer *frame, const BGTU::ComputerGraphicsLabWork::Lab1::Lab1SpriteData *data) const override { - auto centerd = (data->transform * RendererApi::PointF<2>{0, 0}); - auto center = RendererApi::PointI<2>{static_cast(centerd.x), static_cast(centerd.y)}; - - long long start_x = center.x - ((center.x + data->pixel_size - 1) / data->pixel_size * data->pixel_size); - long long start_y = center.y - ((center.y + data->pixel_size - 1) / data->pixel_size * data->pixel_size); + void draw(Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl *frame, const Lab1SpriteData *data) const override { + long long start_x = data->central_pixel_tl.x - ((data->central_pixel_tl.x + data->pixel_size - 1) / data->pixel_size * data->pixel_size); + long long start_y = data->central_pixel_tl.y - ((data->central_pixel_tl.y + data->pixel_size - 1) / data->pixel_size * data->pixel_size); long long w = frame->width(); long long h = frame->height(); - bool y_flag = ((center.x - start_x) / data->pixel_size + (center.y - start_y) / data->pixel_size) % 2 != 0; + bool y_flag = ((data->central_pixel_tl.x - start_x) / data->pixel_size + (data->central_pixel_tl.y - start_y) / data->pixel_size) % 2 == 0; bool x_flag; for (long long y = start_y; y < h; y += data->pixel_size, y_flag = !y_flag) { x_flag = y_flag; diff --git a/programs/lab1/src/sprite_data.hpp b/programs/lab1/src/sprite_data.hpp index 6c835fb..aa8a3ee 100644 --- a/programs/lab1/src/sprite_data.hpp +++ b/programs/lab1/src/sprite_data.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace BGTU::ComputerGraphicsLabWork::Lab1 { @@ -31,7 +32,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { using Provider = _Lab1SpriteData_Provider; }; - class _Lab1SpriteData_Provider : public QObject, public RendererApi::Sprite::SpriteDataProvider { + class _Lab1SpriteData_Provider : public QObject, public RendererApi::Sprite::SpriteDataProvider { Q_OBJECT private: QMutex sync; @@ -39,18 +40,22 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { std::size_t pixel_size; double radians_per_second; - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w, h; bool show_grid; + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, h; RendererApi::Sprite **sub_sprites; std::size_t sub_sprites_count; public: - explicit _Lab1SpriteData_Provider(double radians_per_second) : sync{}, time{}, pixel_size{1}, radians_per_second{radians_per_second}, show_grid{false} {} + explicit _Lab1SpriteData_Provider(double radians_per_second) : + sync{}, time{}, + pixel_size{1}, radians_per_second{radians_per_second}, show_grid{false}, + w{0}, h{0}, + sub_sprites{nullptr}, sub_sprites_count{0} {} Lab1SpriteData get_sprite_data() override { this->sync.lock(); Lab1SpriteData cached{ - .central_pixel_tl = static_cast>(RendererApi::PointF<2>(this->w, this->h) / 2.0 - RendererApi::PointF<2>(this->pixel_size, this->pixel_size) / 2.0), + .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, .shape_data = { @@ -64,6 +69,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { } public slots: + void set_pixel_size(std::size_t s) { this->sync.lock(); this->pixel_size = s; @@ -83,7 +89,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { this->sync.unlock(); } - void set_frame_size(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t ww, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t hh) { + 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; diff --git a/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/_separate_threaded_renderer.hpp b/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/_separate_threaded_renderer.hpp index 20b672b..749c78f 100644 --- a/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/_separate_threaded_renderer.hpp +++ b/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/_separate_threaded_renderer.hpp @@ -8,21 +8,30 @@ #include #include #include -#include +#include #include +#include #include "owned_qimage.hpp" namespace BGTU::ComputerGraphicsLabWork::QtUtilities { - template - using _SeparateThreadedRenderer_RenderProcedureType = void (renderer_context_t::*)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter *, RendererApi::Color, RendererApi::Sprite *const *, std::size_t, sprite_data_t const *); + template + using _SeparateThreadedRenderer_RenderProcedureType = void (renderer_context_t::*)( + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t, + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t, + Utilities::VoxelPainterExporterToRgb32Array *, + RendererApi::Color, + RendererApi::Sprite *const *, + std::size_t, + sprite_data_t const * + ); - template> + template> class SeparateThreadedRenderer; class _SeparateThreadedRenderer_Signals : public QObject { Q_OBJECT - template> + template> friend class SeparateThreadedRenderer; @@ -35,11 +44,10 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { public slots: - virtual void set_frame_size(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height) = 0; + virtual void set_frame_size(RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t width, RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t height) = 0; virtual void set_ms_per_frame(std::uint_fast64_t ms) = 0; virtual void set_background(RendererApi::Color) = 0; - }; } \ No newline at end of file diff --git a/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.hpp b/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.hpp index 322b5df..be546b2 100644 --- a/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.hpp +++ b/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.hpp @@ -8,14 +8,14 @@ #include #include #include -#include +#include #include namespace BGTU::ComputerGraphicsLabWork::QtUtilities { - class OwnedQImage : public QImage, public RendererApi::VoxelDrawer::Exporter { + class OwnedQImage : public QImage, public RendererApi::VirtualVoxelPainter::Exporter { private: - RendererApi::SpriteMetadata const **owners; - std::uint_least8_t *pixels_buffer; + RendererApi::SpriteMetadata **owners; + unsigned char *pixels_buffer; bool owns_buffers; public: @@ -23,8 +23,8 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { if (width == 0 || height == 0) { this->owners = nullptr; } else { - this->owners = new RendererApi::SpriteMetadata const *[width * height]; - for (RendererApi::SpriteMetadata const **p = this->owners - 1; p-- >= this->owners;) { + this->owners = new RendererApi::SpriteMetadata *[width * height]; + for (RendererApi::SpriteMetadata **p = this->owners - 1; p-- >= this->owners;) { *p = nullptr; } } @@ -32,17 +32,17 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { OwnedQImage() : QImage(), owners{nullptr}, pixels_buffer{nullptr} {} - OwnedQImage(std::uint_least8_t *data, unsigned width, unsigned height, QImage::Format f, RendererApi::SpriteMetadata const **owners, QImageCleanupFunction destructor, void *destructor_closure) : + OwnedQImage(std::uint_least8_t *data, unsigned width, unsigned height, QImage::Format f, RendererApi::SpriteMetadata **owners, QImageCleanupFunction destructor, void *destructor_closure) : QImage(data, width, height, f, destructor, destructor_closure), pixels_buffer{data}, owners{owners}, owns_buffers{false} {} - OwnedQImage(std::uint_least8_t *data, unsigned width, unsigned height, QImage::Format f, RendererApi::SpriteMetadata const **owners) : + OwnedQImage(std::uint_least8_t *data, unsigned width, unsigned height, QImage::Format f, RendererApi::SpriteMetadata **owners) : QImage(data, width, height, f), pixels_buffer{data}, owners{owners}, owns_buffers{false} {} enum _DelegateBuffers { DelegateBuffers }; - OwnedQImage(std::uint_least8_t *data, unsigned width, unsigned height, QImage::Format f, RendererApi::SpriteMetadata const **owners, _DelegateBuffers) : + OwnedQImage(std::uint_least8_t *data, unsigned width, unsigned height, QImage::Format f, RendererApi::SpriteMetadata **owners, _DelegateBuffers) : QImage(data, width, height, f), pixels_buffer{data}, owners{owners}, owns_buffers{true} {} #if 0 @@ -72,7 +72,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { } #endif - void setPixelOwner(unsigned x, unsigned y, RendererApi::SpriteMetadata const *o) { + void setPixelOwner(unsigned x, unsigned y, RendererApi::SpriteMetadata *o) { assert(x < this->width()); assert(y < this->height()); diff --git a/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/separate_threaded_renderer.hpp b/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/separate_threaded_renderer.hpp index bf4b017..200706e 100644 --- a/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/separate_threaded_renderer.hpp +++ b/qt-utilities/include/bgtu/computer_graphics_lab_work/qt_utilities/separate_threaded_renderer.hpp @@ -9,24 +9,24 @@ #include #include #include -#include +#include #include +#include #include "owned_qimage.hpp" #include "_separate_threaded_renderer.hpp" -#define has_BGTU_ComputerGraphicsLabWork_QtUtilities_SeparateThreadedRenderer namespace BGTU::ComputerGraphicsLabWork::QtUtilities { - template renderer_procedure> + template renderer_procedure> class SeparateThreadedRenderer : public _SeparateThreadedRenderer_Signals { private: struct data_t { public: - RendererApi::Sprite *const *sprites; + RendererApi::Sprite *const *sprites; std::size_t sprites_count; - RendererApi::Sprite::SpriteDataProvider *sprite_data_provider; + RendererApi::Sprite::SpriteDataProvider *sprite_data_provider; std::uint_fast64_t ms_per_frame; - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, height; + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t width, height; RendererApi::Color bg; }; @@ -72,23 +72,25 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { public slots: - void set_frame_size(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height) final; + void set_frame_size(RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t width, RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t height) final; void set_ms_per_frame(std::uint_fast64_t ms) final; - void set_sprites(RendererApi::Sprite *const *sprites, std::size_t sprites_count); + void set_sprites(RendererApi::Sprite *const *sprites, std::size_t sprites_count); - void set_sprite_data_provider(RendererApi::Sprite::SpriteDataProvider *provider); + void set_sprite_data_provider(RendererApi::Sprite::SpriteDataProvider *provider); void set_background(RendererApi::Color) final; + void shutdown_thread_blocking(); + public: - ~SeparateThreadedRenderer(); + ~SeparateThreadedRenderer() override; }; - template renderer_procedure> - SeparateThreadedRenderer::SeparateThreadedRenderer(renderer_context_t *renderer_context, QObject *owner): + template renderer_procedure> + SeparateThreadedRenderer::SeparateThreadedRenderer(renderer_context_t *renderer_context, QObject *owner): _SeparateThreadedRenderer_Signals{owner}, sync{}, renderer_context{renderer_context}, @@ -105,8 +107,8 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { this->thread->start(); } - template renderer_procedure> - void SeparateThreadedRenderer::set_frame_size(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height) { + template renderer_procedure> + void SeparateThreadedRenderer::set_frame_size(RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t width, RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t height) { this->sync.lock(); const_cast(&this->next_data)->width = width; const_cast(&this->next_data)->height = height; @@ -114,15 +116,15 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { this->sync.unlock(); } - template renderer_procedure> - void SeparateThreadedRenderer::set_ms_per_frame(std::uint_fast64_t ms) { + template renderer_procedure> + void SeparateThreadedRenderer::set_ms_per_frame(std::uint_fast64_t ms) { this->sync.lock(); const_cast(&this->next_data)->ms_per_frame = ms; this->sync.unlock(); } - template renderer_procedure> - void SeparateThreadedRenderer::set_sprites(RendererApi::Sprite *const *sprites, std::size_t sprites_count) { + template renderer_procedure> + void SeparateThreadedRenderer::set_sprites(RendererApi::Sprite *const *sprites, std::size_t sprites_count) { this->sync.lock(); const_cast(&this->next_data)->sprites = sprites; const_cast(&this->next_data)->sprites_count = sprites_count; @@ -130,24 +132,24 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { this->sync.unlock(); } - template renderer_procedure> - void SeparateThreadedRenderer::set_sprite_data_provider(RendererApi::Sprite::SpriteDataProvider *provider) { + template renderer_procedure> + void SeparateThreadedRenderer::set_sprite_data_provider(RendererApi::Sprite::SpriteDataProvider *provider) { this->sync.lock(); const_cast(&this->next_data)->sprite_data_provider = provider; this->thread->force_redraw(); this->sync.unlock(); } - template renderer_procedure> - void SeparateThreadedRenderer::set_background(RendererApi::Color c) { + template renderer_procedure> + void SeparateThreadedRenderer::set_background(RendererApi::Color c) { this->sync.lock(); const_cast(&this->next_data)->bg = c; this->thread->force_redraw(); this->sync.unlock(); } - template renderer_procedure> - void SeparateThreadedRenderer::RendererThread::run() { + template renderer_procedure> + void SeparateThreadedRenderer::RendererThread::run() { try { QElapsedTimer timer; while (!this->isInterruptionRequested()) { @@ -156,27 +158,11 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { data_t cached = *const_cast(&this->owner->next_data); this->owner->sync.unlock(); - struct VoxelDrawerExporterImpl : public RendererApi::VoxelDrawer::Exporter { - public: - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t const w; - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t const h; - std::uint_least8_t *const pixels_argb;; - RendererApi::SpriteMetadata const **const owners; - - VoxelDrawerExporterImpl(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t h) : - w{w}, h{h}, - pixels_argb{new std::uint_least8_t[w * h * 4]}, - owners{new RendererApi::SpriteMetadata const *[w * h]} {} - - void set_pixel(long long x, long long y, BGTU::ComputerGraphicsLabWork::RendererApi::Color c, BGTU::ComputerGraphicsLabWork::RendererApi::SpriteMetadata *owner) final { - if (x < 0 || this->w <= x) return; - if (y < 0 || this->h <= y) return; - this->pixels_argb[(y * this->w + x) * 4] = c.red; - this->pixels_argb[(y * this->w + x) * 4 + 1] = c.green; - this->pixels_argb[(y * this->w + x) * 4 + 2] = c.blue; - this->owners[y * this->w + x] = owner; - } - } img{cached.width, cached.height}; + Utilities::VoxelPainterExporterToRgb32Array img{ + cached.width, cached.height, + new unsigned char[cached.width * cached.height * 4], + new RendererApi::SpriteMetadata *[cached.width * cached.height] + }; union { sprite_data_t data; @@ -197,7 +183,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { cached.sprites, cached.sprites_count, sprite_data ); - emit this->owner->frame_rendered(new OwnedQImage{img.pixels_argb, img.w, img.h, QImage::Format_RGB32, img.owners, OwnedQImage::DelegateBuffers}); + emit this->owner->frame_rendered(new OwnedQImage{img.pixels_packed, img.w, img.h, QImage::Format_RGB32, img.pixel_owners, OwnedQImage::DelegateBuffers}); auto elapsed = timer.elapsed(); qCritical() << elapsed << "ms"; this->sleepms(std::max(static_cast(cached.ms_per_frame) - elapsed, 0)); @@ -207,19 +193,28 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities { } } - - template renderer_procedure> - SeparateThreadedRenderer::~SeparateThreadedRenderer() { + template renderer_procedure> + void SeparateThreadedRenderer::shutdown_thread_blocking() { this->thread->requestInterruption(); this->thread->wait(); } + template renderer_procedure> + SeparateThreadedRenderer::~SeparateThreadedRenderer() { + this->shutdown_thread_blocking(); + } + template - class SeparateThreadedDefaultRendererLinear : public SeparateThreadedRenderer> { + class SeparateThreadedDefaultRendererLinear : public SeparateThreadedRenderer> { private: Utilities::DefaultVoxelDrawerCache context; public: - explicit SeparateThreadedDefaultRendererLinear(QObject *owner = nullptr) : SeparateThreadedRenderer>{&this->context, owner}, context{} {}; + explicit SeparateThreadedDefaultRendererLinear(QObject *owner = nullptr) : + SeparateThreadedRenderer>{&this->context, owner}, context{} {}; + + ~SeparateThreadedDefaultRendererLinear() { + this->shutdown_thread_blocking(); + } }; } \ No newline at end of file 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 bc00996..2562c67 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 @@ -15,9 +15,9 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi { component_compact_t green; component_compact_t blue; - inline Color() : red{0}, green{0}, blue{0} {} + constexpr Color() : red{0}, green{0}, blue{0} {} - inline Color(component_fast_t red, component_fast_t green, component_fast_t blue) : red{red}, green{green}, blue{blue} {} + constexpr Color(component_fast_t red, component_fast_t green, component_fast_t blue) : red{red}, green{green}, blue{blue} {} class Transparent { public: @@ -26,13 +26,13 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi { component_compact_t blue; component_compact_t alpha; - inline Transparent() : red{component_min_value}, green{component_min_value}, blue{component_min_value}, alpha{component_max_value} {} + constexpr Transparent() : red{component_min_value}, green{component_min_value}, blue{component_min_value}, alpha{component_max_value} {} - inline Transparent(component_fast_t red, component_fast_t green, component_fast_t blue) : red{red}, green{green}, blue{blue}, alpha{component_max_value} {} + constexpr Transparent(component_fast_t red, component_fast_t green, component_fast_t blue) : red{red}, green{green}, blue{blue}, alpha{component_max_value} {} - inline Transparent(component_fast_t red, component_fast_t green, component_fast_t blue, component_fast_t alpha) : red{red}, green{green}, blue{blue}, alpha{alpha} {} + constexpr Transparent(component_fast_t red, component_fast_t green, component_fast_t blue, component_fast_t alpha) : red{red}, green{green}, blue{blue}, alpha{alpha} {} - inline Transparent(Color c) : red{c.red}, green{c.green}, blue{c.blue}, alpha{component_max_value} {} + constexpr Transparent(Color c) : red{c.red}, green{c.green}, blue{c.blue}, alpha{component_max_value} {} }; }; } \ No newline at end of file diff --git a/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/point.hpp b/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/point.hpp index 9f1aa80..ede8036 100644 --- a/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/point.hpp +++ b/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/point.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace BGTU::ComputerGraphicsLabWork::RendererApi { template @@ -16,28 +17,34 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi { component_t x; component_t y; - inline Point(component_t x, component_t y) : x{x}, y{y} {} + constexpr Point(component_t x, component_t y) : x{x}, y{y} {} - template - explicit operator Point<2, new_component_t>() const { - return Point<2, new_component_t>{converter(this->x), converter(this->y)}; - } - - Point<2, _component_t> operator+(Point<2, _component_t> const &other) const { + [[nodiscard]] constexpr Point<2, _component_t> operator+(Point<2, _component_t> const &other) const noexcept { return Point<2, _component_t>{this->x + other.x, this->y + other.y}; } - Point<2, _component_t> operator-(Point<2, _component_t> const &other) const { + [[nodiscard]] constexpr Point<2, _component_t> operator-(Point<2, _component_t> const &other) const noexcept { return Point<2, _component_t>{this->x - other.x, this->y - other.y}; } - Point<2, _component_t> operator*(_component_t const &other) const { + [[nodiscard]] constexpr Point<2, _component_t> operator*(_component_t const &other) const noexcept { return Point<2, _component_t>{this->x * other, this->y * other}; } - Point<2, _component_t> operator/(_component_t const &other) const { + [[nodiscard]] constexpr Point<2, _component_t> operator/(_component_t const &other) const noexcept { return Point<2, _component_t>{this->x / other, this->y / other}; } + + + template, void>::type> + [[nodiscard]] constexpr explicit operator Point<2, double>() const noexcept { + return Point<2, double>{(double) this->x, (double) this->y}; + } + + template, void>::type> + [[nodiscard]] constexpr explicit operator Point<2, long long>() const noexcept { + return Point<2, long long>{(long long) this->x, (long long) this->y}; + } }; template 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 abdabd7..53c3b32 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 @@ -1,6 +1,6 @@ #pragma once -#include "voxel_drawer.hpp" +#include "voxel_painter.hpp" #include "projection.hpp" namespace BGTU::ComputerGraphicsLabWork::RendererApi { @@ -9,10 +9,10 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi { virtual void clicked() {}; }; - template + template class Sprite : public SpriteMetadata { public: - virtual void draw(VoxelDrawer *frame, data_t const *data) const = 0; + virtual void draw(voxel_painter_t *frame, data_t const *data) const = 0; class SpriteDataProvider { public: diff --git a/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/voxel_drawer.hpp b/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/voxel_painter.hpp similarity index 98% rename from renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/voxel_drawer.hpp rename to renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/voxel_painter.hpp index 367bc71..73e7625 100644 --- a/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/voxel_drawer.hpp +++ b/renderer-api/include/bgtu/computer_graphics_lab_work/renderer_api/voxel_painter.hpp @@ -9,7 +9,7 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi { class SpriteMetadata; - class VoxelDrawer { + class VirtualVoxelPainter { public: using visible_pixel_coordinate_fast_t = std::uint_fast16_t; using visible_pixel_coordinate_compact_t = std::uint_least16_t; 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 9b9cf68..7a6e491 100644 --- a/utilities/include/bgtu/computer_graphics_lab_work/utilities/color.hpp +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/color.hpp @@ -48,4 +48,13 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { #endif #endif } + + + namespace PackColor { + inline void color_to_rgb32(unsigned char *buffer, std::size_t offset, RendererApi::Color color) noexcept{ + buffer[offset] = color.red; + buffer[offset + 1] = color.green; + buffer[offset + 2] = color.blue; + } + } } \ No newline at end of file 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 7c0d3ae..4581613 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 @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include "color.hpp" #include "matrix.hpp" @@ -106,36 +106,43 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { ZElement *voxels; }; - class VoxelDrawerImpl : public RendererApi::VoxelDrawer { - public: - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t _width; - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t _height; + public: + class VoxelPainterImpl : public RendererApi::VirtualVoxelPainter { + friend + class DefaultVoxelDrawerCache; + + private: + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t _width; + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t _height; pixel_trace_metadata *pixels_metadata; ZElementAllocationBuffer *pixel_trace_elements_allocator; RendererApi::SpriteMetadata *current_artist; - VoxelDrawerImpl(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height, pixel_trace_metadata *pixels_metadata, ZElementAllocationBuffer *pixel_trace_elements_allocator); + VoxelPainterImpl(RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t width, RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t height, pixel_trace_metadata *pixels_metadata, ZElementAllocationBuffer *pixel_trace_elements_allocator); - [[nodiscard]] inline RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width() const final { + public: + [[nodiscard]] inline RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t width() const final { return this->_width; } - [[nodiscard]] inline RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height() const final { + [[nodiscard]] inline RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t height() const final { return this->_height; } + private: inline pixel_trace_metadata *at(std::uint_fast16_t x, std::uint_fast16_t y) { return &(this->pixels_metadata[y * this->_width + x]); } + public: void add_voxel(long long x, long long y, double z, RendererApi::Color::Transparent c) final; void add_voxel(long long x, long long y, double z, RendererApi::Color::Transparent c, RendererApi::SpriteMetadata *owner) final; }; - + private: struct { pixel_trace_metadata *buffer; std::size_t size; @@ -149,13 +156,13 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { static ZElement *sort_zelements_desc(DefaultVoxelDrawerCache::ZElement *start) noexcept; public: - template + template void render( - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w, - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t h, - RendererApi::VoxelDrawer::Exporter *frame, + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t h, + voxel_exporter_t *frame, RendererApi::Color bg, - RendererApi::Sprite *const *sprites, + RendererApi::Sprite *const *sprites, std::size_t sprites_count, sprite_data_t const *sprite_data ); @@ -182,13 +189,13 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { } - template + template void DefaultVoxelDrawerCache::render( - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w, - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t h, - RendererApi::VoxelDrawer::Exporter *frame, + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t h, + voxel_exporter_t *frame, RendererApi::Color bg, - RendererApi::Sprite *const *sprites, + RendererApi::Sprite *const *sprites, std::size_t sprites_count, sprite_data_t const *sprite_data ) { @@ -201,7 +208,7 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { } this->pixel_trace_elements_allocator.reset_allocations(); - VoxelDrawerImpl painter{w, h, this->pixel_metadata_cache.buffer, &this->pixel_trace_elements_allocator}; + VoxelPainterImpl painter{w, h, this->pixel_metadata_cache.buffer, &this->pixel_trace_elements_allocator}; for (std::int_fast64_t i = w * h - 1; i >= 0; i--) { new(&this->pixel_metadata_cache.buffer[i]) pixel_trace_metadata{}; diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/voxel_painter_exporter_to_packed_array.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/voxel_painter_exporter_to_packed_array.hpp new file mode 100644 index 0000000..7f15eba --- /dev/null +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/voxel_painter_exporter_to_packed_array.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include "color.hpp" + +namespace BGTU::ComputerGraphicsLabWork::Utilities { + template + class VoxelPainterExporterToPackedArray : public RendererApi::VirtualVoxelPainter::Exporter { + public: + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w; + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t h; + unsigned char *pixels_packed; + RendererApi::SpriteMetadata **pixel_owners; + + constexpr VoxelPainterExporterToPackedArray( + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t h, + unsigned char *pixels_packed, + RendererApi::SpriteMetadata **pixel_owners + ) noexcept: w{w}, h{h}, pixels_packed{pixels_packed}, pixel_owners{pixel_owners} {} + + constexpr void set_pixel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, RendererApi::Color c, RendererApi::SpriteMetadata *owner) noexcept final { + assert(x < this->w); + assert(y < this->h); + std::size_t offset = y * this->w + x; + this->pixel_owners[offset] = owner; + pack_color(this->pixels_packed, offset * bytes_per_pixel, c); + }; + }; + + using VoxelPainterExporterToRgb32Array = VoxelPainterExporterToPackedArray<4, PackColor::color_to_rgb32>; +} \ No newline at end of file diff --git a/utilities/src/default_renderer_linear.cpp b/utilities/src/default_renderer_linear.cpp index 757da96..0b27b81 100644 --- a/utilities/src/default_renderer_linear.cpp +++ b/utilities/src/default_renderer_linear.cpp @@ -123,9 +123,9 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { } - DefaultVoxelDrawerCache::VoxelDrawerImpl::VoxelDrawerImpl( - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, - RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height, + DefaultVoxelDrawerCache::VoxelPainterImpl::VoxelPainterImpl( + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t width, + RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t height, DefaultVoxelDrawerCache::pixel_trace_metadata *pixels_metadata, DefaultVoxelDrawerCache::ZElementAllocationBuffer *pixel_trace_elements_allocator ) : _width{width}, @@ -135,10 +135,10 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities { current_artist{nullptr} {} - void DefaultVoxelDrawerCache::VoxelDrawerImpl::add_voxel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, double z, RendererApi::Color::Transparent c) { + void DefaultVoxelDrawerCache::VoxelPainterImpl::add_voxel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, double z, RendererApi::Color::Transparent c) { return this->add_voxel(x, y, z, c, this->current_artist); } - void DefaultVoxelDrawerCache::VoxelDrawerImpl::add_voxel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, double z, RendererApi::Color::Transparent c, RendererApi::SpriteMetadata *owner) { + void DefaultVoxelDrawerCache::VoxelPainterImpl::add_voxel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, double z, RendererApi::Color::Transparent c, RendererApi::SpriteMetadata *owner) { if (x < 0 || this->_width <= x) return; if (y < 0 || this->_height <= y) return; if (z < 0) return;