Compilable and runnable example
This commit is contained in:
parent
08ced011c6
commit
52561c8004
@ -6,6 +6,16 @@ set(CMAKE_CXX_STANDARD 20)
|
||||
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
enable_language(ASM_NASM)
|
||||
|
||||
option(__AVX2__ "Tells compiler to use AVX2 extension if possible" OFF)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
if (__AVX2__)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:/arch:AVX2>)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
add_executable(
|
||||
cg1
|
||||
|
||||
@ -28,3 +38,4 @@ qt5_use_modules(cg1 Widgets)
|
||||
add_subdirectory(renderer-api)
|
||||
add_subdirectory(utilities)
|
||||
add_subdirectory(qt-utilities)
|
||||
add_subdirectory(programs/lab1)
|
2
programs/lab1/CMakeLists.txt
Normal file
2
programs/lab1/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
add_executable(lab1 src/main.cpp)
|
||||
target_link_libraries(lab1 PRIVATE Qt5::Core Qt5::Widgets renderer_api utilities qt_utilities)
|
19
programs/lab1/src/main.cpp
Normal file
19
programs/lab1/src/main.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include <iostream>
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/color.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/renderer_widget.hpp>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
QApplication qApplication{argc, argv};
|
||||
QMainWindow w{};
|
||||
|
||||
BGTU::ComputerGraphicsLabWork::QtUtilities::SeparateThreadedDefaultRendererLinear<void> renderer{};
|
||||
BGTU::ComputerGraphicsLabWork::QtUtilities::RendererWidget<void> canvas{&renderer, &w};
|
||||
w.setCentralWidget(&canvas);
|
||||
w.show();
|
||||
QApplication::exec();
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
add_library(qt_utilities OBJECT src/separate_threaded_renderer.cpp)
|
||||
add_library(qt_utilities OBJECT include/bgtu/computer_graphics_lab_work/qt_utilities/_separate_threaded_renderer.hpp include/bgtu/computer_graphics_lab_work/qt_utilities/_renderer_widget.hpp)
|
||||
target_include_directories(qt_utilities PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_link_libraries(qt_utilities PUBLIC Qt5::Core Qt5::Widgets Qt5::Gui renderer_api utilities)
|
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <Qt>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QMutex>
|
||||
#include <QPainter>
|
||||
#include <QBrush>
|
||||
#include <QApplication>
|
||||
#include <QPalette>
|
||||
#include <QStyle>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
#include "owned_qimage.hpp"
|
||||
#include "separate_threaded_renderer.hpp"
|
||||
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
template<class sprite_data_t>
|
||||
class RendererWidget;
|
||||
|
||||
class _RendererWidget_Slots : public QWidget {
|
||||
template<class>
|
||||
friend
|
||||
class RendererWidget;
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
inline _RendererWidget_Slots(QWidget *owner) : QWidget{owner} {}
|
||||
|
||||
private slots:
|
||||
|
||||
virtual void receive_image(OwnedQImage<void> img) = 0;
|
||||
|
||||
};
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <Qt>
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QElapsedTimer>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/voxel_drawer.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
|
||||
#include "owned_qimage.hpp"
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
class SeparateThreadedRenderer;
|
||||
|
||||
class _SeparateThreadedRenderer_Signals : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
friend
|
||||
class SeparateThreadedRenderer;
|
||||
|
||||
private:
|
||||
explicit _SeparateThreadedRenderer_Signals(QObject *owner = nullptr) : QObject{owner} {}
|
||||
|
||||
signals:
|
||||
void frame_rendered(OwnedQImage<void> img);
|
||||
};
|
||||
}
|
@ -4,6 +4,9 @@
|
||||
#include <Qt>
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
#include <QColor>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/voxel_drawer.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
|
||||
|
||||
@ -11,15 +14,18 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
template<class sprite_data_t>
|
||||
class OwnedQImage : public QImage, public RendererApi::VoxelDrawer::Exporter<sprite_data_t> {
|
||||
private:
|
||||
RendererApi::Sprite<sprite_data_t> const *owners;
|
||||
RendererApi::Sprite<sprite_data_t> const **owners;
|
||||
|
||||
public:
|
||||
OwnedQImage(unsigned width, unsigned height) : QImage(width, height, QImage::Format_ARGB32), owners{new RendererApi::Sprite<sprite_data_t> const *[width * height]} {
|
||||
for (RendererApi::Sprite<sprite_data_t> const *&e: this->owners) {
|
||||
e = nullptr;
|
||||
for (RendererApi::Sprite<sprite_data_t> const **p = this->owners - 1; p-- >= this->owners;) {
|
||||
*p = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
OwnedQImage() : QImage(), owners{nullptr} {}
|
||||
|
||||
|
||||
void setPixelOwner(unsigned x, unsigned y, RendererApi::Sprite<sprite_data_t> const *o) {
|
||||
assert(x < this->width());
|
||||
assert(y < this->height());
|
||||
@ -33,5 +39,15 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
|
||||
return this->owners[y * this->width() + x];
|
||||
}
|
||||
|
||||
void set_pixel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, RendererApi::Color c, RendererApi::Sprite<sprite_data_t> const *owner) final {
|
||||
this->setPixelColor(x, y, QColor{c.red, c.green, c.blue});
|
||||
this->setPixelOwner(x, y, owner);
|
||||
}
|
||||
|
||||
~OwnedQImage() override {
|
||||
if (this->owners != nullptr)
|
||||
delete[] this->owners;
|
||||
}
|
||||
};
|
||||
}
|
@ -1,22 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <Qt>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
#include <QMutex>
|
||||
#include <QPainter>
|
||||
#include <QBrush>
|
||||
#include <QApplication>
|
||||
#include <QPalette>
|
||||
#include <QStyle>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
#include "owned_qimage.hpp"
|
||||
#include "separate_threaded_renderer.hpp"
|
||||
#include "_renderer_widget.hpp"
|
||||
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
template<class sprite_data_t>
|
||||
class RendererWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
class RendererWidget : public _RendererWidget_Slots {
|
||||
private:
|
||||
QMutex sync;
|
||||
OwnedQImage <sprite_data_t> *next_image;
|
||||
OwnedQImage <sprite_data_t> *current_image;
|
||||
SeparateThreadedRenderer
|
||||
OwnedQImage<void> next_image;
|
||||
OwnedQImage<void> current_image;
|
||||
_SeparateThreadedRenderer_Signals *renderer;
|
||||
|
||||
private slots:
|
||||
|
||||
void receive_image(OwnedQImage<void> img) {
|
||||
this->sync.lock();
|
||||
std::swap(this->next_image, img);
|
||||
this->sync.unlock();
|
||||
this->update();
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
explicit RendererWidget(_SeparateThreadedRenderer_Signals *renderer, QWidget *owner = nullptr) : _RendererWidget_Slots{owner}, sync{}, next_image{}, current_image{}, renderer{renderer} {
|
||||
connect(this->renderer, &_SeparateThreadedRenderer_Signals::frame_rendered, this, &_RendererWidget_Slots::receive_image);
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) final {
|
||||
this->sync.lock();
|
||||
this->current_image = std::move(this->next_image);
|
||||
this->sync.unlock();
|
||||
|
||||
QPainter painter;
|
||||
painter.begin(this);
|
||||
painter.setBrush(QApplication::style()->standardPalette().brush(QPalette::Background));
|
||||
painter.drawRect(this->rect());
|
||||
painter.drawImage(this->current_image.rect(), this->current_image);
|
||||
painter.end();
|
||||
}
|
||||
};
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <Qt>
|
||||
#include <QDebug>
|
||||
#include <QObject>
|
||||
@ -9,10 +11,11 @@
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/voxel_drawer.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
|
||||
#include "owned_qimage.hpp"
|
||||
#include "_separate_threaded_renderer.hpp"
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
|
||||
class SeparateThreadedRenderer : public QObject {
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
class SeparateThreadedRenderer : public _SeparateThreadedRenderer_Signals {
|
||||
private:
|
||||
struct data {
|
||||
public:
|
||||
@ -22,10 +25,10 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
std::uint_fast64_t ms_per_frame;
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, height;
|
||||
RendererApi::Projection *projection;
|
||||
RendererApi::Color bg;
|
||||
};
|
||||
|
||||
class RendererThread : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
SeparateThreadedRenderer *owner;
|
||||
@ -58,14 +61,13 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
|
||||
void set_sprites_and_data(RendererApi::Sprite<sprite_data_t> *const *sprites, std::size_t sprites_count, sprite_data_t const *data);
|
||||
|
||||
signals:
|
||||
|
||||
void frame_rendered(OwnedQImage<sprite_data_t> *img);
|
||||
void set_background(RendererApi::Color);
|
||||
};
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::SeparateThreadedRenderer(renderer_context_t *renderer_context, QObject *owner):
|
||||
QObject{owner},
|
||||
_SeparateThreadedRenderer_Signals{owner},
|
||||
sync{},
|
||||
renderer_context{renderer_context},
|
||||
sentinel_img{new QImage(0, 0, QImage::Format_ARGB32)},
|
||||
@ -81,7 +83,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
} {
|
||||
}
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_frame_size(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height) {
|
||||
this->sync.lock();
|
||||
this->next_data.width = width;
|
||||
@ -89,14 +91,14 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_ms_per_frame(std::uint_fast64_t ms) {
|
||||
this->sync.lock();
|
||||
this->next_data.ms_per_frame = ms;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_sprites(RendererApi::Sprite<sprite_data_t> *const *sprites, std::size_t sprites_count) {
|
||||
this->sync.lock();
|
||||
this->next_data.sprites = sprites;
|
||||
@ -104,14 +106,14 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_sprite_data(sprite_data_t const *data) {
|
||||
this->sync.lock();
|
||||
this->next_data.sprite_data = data;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_sprites_and_data(RendererApi::Sprite<sprite_data_t> *const *sprites, std::size_t sprites_count, sprite_data_t const *data) {
|
||||
this->sync.lock();
|
||||
this->next_data.sprites = sprites;
|
||||
@ -120,20 +122,35 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_background(RendererApi::Color c) {
|
||||
this->sync.lock();
|
||||
this->next_data.bg = c;
|
||||
this->sync.unlock();
|
||||
}
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::RendererThread::run() {
|
||||
try {
|
||||
QElapsedTimer timer;
|
||||
while (true) {
|
||||
timer.start();
|
||||
this->owner->sync.lock();
|
||||
data cached = this->owner->next_data;
|
||||
data cached = *const_cast<data *>(&this->owner->next_data);
|
||||
this->owner->sync.unlock();
|
||||
|
||||
auto img = new OwnedQImage<sprite_data_t>(cached.width, cached.height);
|
||||
(this->owner->renderer_context->*renderer_procedure)(img, cached.sprite_data, cached.sprites, cached.sprites_count);
|
||||
emit this->owner->frame_rendered(img);
|
||||
QThread::msleep(std::max(cached.ms_per_frame - timer.elapsed(), 0));
|
||||
OwnedQImage<sprite_data_t> img{cached.width, cached.height};
|
||||
(this->owner->renderer_context->*renderer_procedure)(
|
||||
cached.width, cached.height,
|
||||
&img,
|
||||
cached.bg,
|
||||
cached.projection,
|
||||
cached.sprites, cached.sprites_count,
|
||||
cached.sprite_data
|
||||
);
|
||||
emit this->owner->frame_rendered(std::move(*reinterpret_cast<OwnedQImage<void> *>(&img)));
|
||||
QThread::msleep(std::max<std::uint_fast64_t>(cached.ms_per_frame - static_cast<std::uint_fast64_t>(timer.elapsed()), 0));
|
||||
}
|
||||
} catch (std::exception const &e) {
|
||||
qCritical() << typeid(e).name() << ": " << e.what() << "\n" << "Renderer thread died" << "\n";
|
||||
|
@ -1,4 +0,0 @@
|
||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/separate_threaded_renderer.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/renderer_widget.hpp>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
@ -7,7 +7,7 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi {
|
||||
template<class data_t>
|
||||
class Sprite {
|
||||
public:
|
||||
virtual void draw(VoxelDrawer *frame, Projection *projection, data_t *data) const = 0;
|
||||
virtual void draw(VoxelDrawer *frame, Projection const *projection, data_t const *data) const = 0;
|
||||
|
||||
virtual void clicked() {};
|
||||
};
|
||||
|
@ -33,6 +33,7 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi {
|
||||
|
||||
template<class sprite_data_t>
|
||||
class Exporter {
|
||||
public:
|
||||
virtual void set_pixel(PointI<2>::component_t x, PointI<2>::component_t y, Color c, Sprite<sprite_data_t> const* owner) = 0;
|
||||
};
|
||||
};
|
||||
|
@ -1,3 +1,3 @@
|
||||
add_library(utilities OBJECT src/shader.cpp src/memory_pages_managment.cpp)
|
||||
add_library(utilities OBJECT src/shader.cpp src/memory_pages_management.cpp src/default_renderer_linear.cpp src/color.asm)
|
||||
target_include_directories(utilities PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_link_libraries(utilities PUBLIC renderer_api)
|
@ -1,13 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <climits>
|
||||
// #include <emmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
|
||||
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||
RendererApi::Color apply_transparent_color(RendererApi::Color bg, RendererApi::Color::Transparent fg) {
|
||||
inline RendererApi::Color apply_transparent_color(RendererApi::Color bg, RendererApi::Color::Transparent fg) {
|
||||
#if defined(__AVX512F__)
|
||||
return _apply_transparent_color_avx512(bg, fg);
|
||||
#elif 0 && defined(__AVX2__)
|
||||
return _apply_transparent_color_avx2(bg, fg);
|
||||
#else
|
||||
#if 1
|
||||
return RendererApi::Color{
|
||||
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.red) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.red) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
|
||||
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.green) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.green) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
|
||||
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.blue) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.blue) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
|
||||
};
|
||||
#elif 1
|
||||
static auto calc = [&](RendererApi::Color::component_fast_t s, RendererApi::Color::component_fast_t o) {
|
||||
auto oo = static_cast<std::uint_fast16_t>(o) * static_cast<std::uint_fast16_t>(fg.alpha);
|
||||
auto ss = static_cast<std::uint_fast16_t>(s) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha));
|
||||
@ -25,14 +36,16 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||
__m128i vec_alpha = _mm_set_epi16(fg.alpha, fg.alpha, fg.alpha, 0, 0, 0, 0, 0);
|
||||
|
||||
union {
|
||||
std::uint_fast64_t packed = static_cast<std::uint_fast64_t>(_mm_cvtsi128_si64(_mm_srli_epi16(_mm_add_epi16(_mm_mullo_epi16(vec_fg, vec_alpha), _mm_mullo_epi16(vec_bg, _mm_sub_epi16(vec_256, vec_alpha))), 8)));
|
||||
__m128i packed;
|
||||
std::uint16_t unpacked[3];
|
||||
} raw;
|
||||
_mm_storel_epi64(&raw.packed, _mm_srli_epi16(_mm_add_epi16(_mm_mullo_epi16(vec_fg, vec_alpha), _mm_mullo_epi16(vec_bg, _mm_sub_epi16(vec_256, vec_alpha))), 8));
|
||||
return RendererApi::Color{
|
||||
static_cast<RendererApi::Color::component_compact_t>(raw.unpacked[0]),
|
||||
static_cast<RendererApi::Color::component_compact_t>(raw.unpacked[1]),
|
||||
static_cast<RendererApi::Color::component_compact_t>(raw.unpacked[2])
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <new>
|
||||
#include <vector>
|
||||
@ -12,10 +13,11 @@
|
||||
#include "color.hpp"
|
||||
#include "matrix.hpp"
|
||||
|
||||
class QObject;
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork {
|
||||
namespace Utilities {
|
||||
class DefaultVoxelDrawerLinear : public RendererApi::VoxelDrawer {
|
||||
class DefaultVoxelDrawerCache {
|
||||
private:
|
||||
class ZElement {
|
||||
public:
|
||||
@ -53,7 +55,7 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
Cell buffer[0];
|
||||
|
||||
public:
|
||||
explicit Page(Page *next, std::size_t capacity) : next{next}, initialized{0}, capacity{capacity} {};
|
||||
explicit Page(Page *next, std::size_t capacity) : next{next}, initialized{0}, capacity{capacity}, buffer{} {};
|
||||
|
||||
Cell *try_allocate();
|
||||
|
||||
@ -93,70 +95,84 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
~ZElementAllocationBuffer();
|
||||
};
|
||||
|
||||
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t _width;
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t _height;
|
||||
|
||||
struct pixel_trace_metadata {
|
||||
public:
|
||||
pixel_trace_metadata() : nearest_z{std::numeric_limits<double>::max()}, voxels{nullptr} {};
|
||||
|
||||
double nearest_z;
|
||||
ZElement *voxels;
|
||||
} *pixels_metadata;
|
||||
|
||||
ZElementAllocationBuffer allocator;
|
||||
RendererApi::Sprite<void> *current_artist;
|
||||
public:
|
||||
inline DefaultVoxelDrawerLinear(std::uint_fast16_t width, std::uint_fast16_t height);
|
||||
|
||||
~DefaultVoxelDrawerLinear();
|
||||
|
||||
template<class data_t>
|
||||
void set_current_artist(RendererApi::Sprite<data_t> *sprite) {
|
||||
this->current_artist = reinterpret_cast<RendererApi::Sprite<void> *>(sprite);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::uint_fast16_t height() const final {
|
||||
return this->_height;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline std::uint_fast16_t width() const final {
|
||||
return this->_width;
|
||||
}
|
||||
template<class sprite_data_t>
|
||||
class VoxelDrawerImpl : public RendererApi::VoxelDrawer {
|
||||
public:
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t _width;
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t _height;
|
||||
|
||||
private:
|
||||
pixel_trace_metadata *pixels_metadata;
|
||||
|
||||
pixel_trace_metadata *at(std::uint_fast16_t x, std::uint_fast16_t y) {
|
||||
return &(this->pixels_metadata[y * this->_width + x]);
|
||||
}
|
||||
ZElementAllocationBuffer *pixel_trace_elements_allocator;
|
||||
RendererApi::Sprite<sprite_data_t> *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);
|
||||
|
||||
[[nodiscard]] RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width() const final {
|
||||
return this->_width;
|
||||
}
|
||||
|
||||
[[nodiscard]] RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height() const final {
|
||||
return this->_height;
|
||||
}
|
||||
|
||||
pixel_trace_metadata *at(std::uint_fast16_t x, std::uint_fast16_t y) {
|
||||
return &(this->pixels_metadata[y * this->_width + x]);
|
||||
}
|
||||
|
||||
void add_voxel(long long x, long long y, double z, RendererApi::Color::Transparent c) final;
|
||||
};
|
||||
|
||||
|
||||
struct {
|
||||
pixel_trace_metadata *buffer;
|
||||
std::size_t size;
|
||||
} pixel_metadata_cache;
|
||||
std::vector<ZElement *> sorter;
|
||||
ZElementAllocationBuffer pixel_trace_elements_allocator;
|
||||
|
||||
public:
|
||||
DefaultVoxelDrawerCache();
|
||||
|
||||
void add_voxel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, double z, RendererApi::Color::Transparent c) final;
|
||||
template<class sprite_data_t>
|
||||
void render(
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w,
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t h,
|
||||
RendererApi::VoxelDrawer::Exporter<sprite_data_t> *frame,
|
||||
RendererApi::Color bg,
|
||||
RendererApi::Projection const *projection,
|
||||
RendererApi::Sprite<sprite_data_t> *const *sprites,
|
||||
std::size_t sprites_count,
|
||||
sprite_data_t const *sprite_data
|
||||
);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
public:
|
||||
|
||||
template<class sdata_t>
|
||||
void export_(RendererApi::Color background, RendererApi::VoxelDrawer::Exporter<sdata_t> *receiver);
|
||||
|
||||
void release_resources();
|
||||
~DefaultVoxelDrawerCache();
|
||||
};
|
||||
|
||||
DefaultVoxelDrawerLinear::ZElementAllocationBuffer::Cell *DefaultVoxelDrawerLinear::ZElementAllocationBuffer::Page::try_allocate() {
|
||||
if (this->initialized < this->capacity) {
|
||||
Cell *cell = &(this->buffer[this->initialized++]);
|
||||
return cell;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
template<class sprite_data_t>
|
||||
DefaultVoxelDrawerCache::VoxelDrawerImpl<sprite_data_t>::VoxelDrawerImpl(
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width,
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height,
|
||||
DefaultVoxelDrawerCache::pixel_trace_metadata *pixels_metadata,
|
||||
DefaultVoxelDrawerCache::ZElementAllocationBuffer *pixel_trace_elements_allocator
|
||||
): _width{width},
|
||||
_height{height},
|
||||
pixels_metadata{pixels_metadata},
|
||||
pixel_trace_elements_allocator{pixel_trace_elements_allocator},
|
||||
current_artist{nullptr} {}
|
||||
|
||||
|
||||
|
||||
template<class... args_t>
|
||||
DefaultVoxelDrawerLinear::ZElement *DefaultVoxelDrawerLinear::ZElementAllocationBuffer::alloc_elem(args_t... args) {
|
||||
DefaultVoxelDrawerCache::ZElement *DefaultVoxelDrawerCache::ZElementAllocationBuffer::alloc_elem(args_t... args) {
|
||||
auto cell = this->next_unallocated;
|
||||
if (cell != nullptr) {
|
||||
this->next_unallocated = cell->empty.next_empty;
|
||||
@ -169,49 +185,8 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
return new(&(cell->allocated)) ZElement{args...};
|
||||
}
|
||||
|
||||
|
||||
void DefaultVoxelDrawerLinear::ZElementAllocationBuffer::free_elem(DefaultVoxelDrawerLinear::ZElement *e) {
|
||||
Cell *cell = reinterpret_cast<Cell *>(e);
|
||||
cell->empty.next_empty = this->next_unallocated;
|
||||
this->next_unallocated = cell;
|
||||
}
|
||||
|
||||
void DefaultVoxelDrawerLinear::ZElementAllocationBuffer::release_resources() {
|
||||
Page *p;
|
||||
while (this->last_page != nullptr) {
|
||||
p = this->last_page;
|
||||
this->last_page = p->next;
|
||||
this->_native_free_page(p);
|
||||
}
|
||||
this->next_unallocated = nullptr;
|
||||
}
|
||||
|
||||
void DefaultVoxelDrawerLinear::ZElementAllocationBuffer::reset_allocations() {
|
||||
Page *p = this->last_page;
|
||||
while (p != nullptr) {
|
||||
p->reset_allocations();
|
||||
p = p->next;
|
||||
}
|
||||
this->next_unallocated = nullptr;
|
||||
}
|
||||
|
||||
DefaultVoxelDrawerLinear::ZElementAllocationBuffer::~ZElementAllocationBuffer() {
|
||||
this->release_resources();
|
||||
}
|
||||
|
||||
|
||||
DefaultVoxelDrawerLinear::DefaultVoxelDrawerLinear(std::uint_fast16_t width, std::uint_fast16_t height) :
|
||||
_width{width},
|
||||
_height{height},
|
||||
pixels_metadata{new pixel_trace_metadata[sizeof(ZElement) * width * height]{}},
|
||||
allocator{},
|
||||
current_artist{nullptr} {}
|
||||
|
||||
DefaultVoxelDrawerLinear::~DefaultVoxelDrawerLinear() {
|
||||
delete[] this->pixels_metadata;
|
||||
}
|
||||
|
||||
void DefaultVoxelDrawerLinear::add_voxel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, double z, RendererApi::Color::Transparent c) {
|
||||
template<class sprite_data_t>
|
||||
void DefaultVoxelDrawerCache::VoxelDrawerImpl<sprite_data_t>::add_voxel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, double z, RendererApi::Color::Transparent c) {
|
||||
if (x < 0 || this->_width <= x) return;
|
||||
if (y < 0 || this->_height <= y) return;
|
||||
if (z < 0) return;
|
||||
@ -224,35 +199,53 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
while (p->voxels != nullptr) {
|
||||
e = p->voxels;
|
||||
p->voxels = e->next;
|
||||
this->allocator.free_elem(e);
|
||||
this->pixel_trace_elements_allocator->free_elem(e);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
p->voxels = this->allocator.alloc_elem(p->voxels, z, c, this->current_artist);
|
||||
p->voxels = this->pixel_trace_elements_allocator->alloc_elem(p->voxels, z, c, this->current_artist);
|
||||
}
|
||||
|
||||
void DefaultVoxelDrawerLinear::release_resources() {
|
||||
this->allocator.release_resources();
|
||||
}
|
||||
template<class sprite_data_t>
|
||||
void DefaultVoxelDrawerCache::render(
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w,
|
||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t h,
|
||||
RendererApi::VoxelDrawer::Exporter<sprite_data_t> *frame,
|
||||
RendererApi::Color bg,
|
||||
RendererApi::Projection const *projection,
|
||||
RendererApi::Sprite<sprite_data_t> *const *sprites,
|
||||
std::size_t sprites_count,
|
||||
sprite_data_t const *sprite_data
|
||||
) {
|
||||
if (this->pixel_metadata_cache.buffer == nullptr || this->pixel_metadata_cache.size < w * h) {
|
||||
this->pixel_metadata_cache.buffer = static_cast<pixel_trace_metadata *>(std::realloc(this->pixel_metadata_cache.buffer, w * h * sizeof(pixel_trace_metadata)));
|
||||
this->pixel_metadata_cache.size = w * h;
|
||||
}
|
||||
|
||||
this->pixel_trace_elements_allocator.reset_allocations();
|
||||
VoxelDrawerImpl<sprite_data_t> painter{w, h, this->pixel_metadata_cache.buffer, &this->pixel_trace_elements_allocator};
|
||||
|
||||
for (; sprites_count-- > 0; sprites++) {
|
||||
painter.current_artist = *sprites;
|
||||
(*sprites)->draw(&painter, projection, sprite_data);
|
||||
}
|
||||
|
||||
template<class sdata_t>
|
||||
void DefaultVoxelDrawerLinear::export_(RendererApi::Color background, RendererApi::VoxelDrawer::Exporter<sdata_t> *receiver) {
|
||||
std::vector<ZElement *> sorter;
|
||||
std::uint_fast16_t y = 0;
|
||||
std::uint_fast16_t x = 0;
|
||||
|
||||
for (std::int_fast64_t i = this->_width * this->_height - 1; i >= 0; i--) {
|
||||
for (ZElement *e = this->pixels_metadata[i].voxels; e != nullptr; e = e->next) {
|
||||
for (std::int_fast64_t i = w * h - 1; i >= 0; i--) {
|
||||
for (ZElement *e = this->pixel_metadata_cache.buffer[i].voxels; e != nullptr; e = e->next) {
|
||||
sorter.push_back(e);
|
||||
}
|
||||
std::sort(sorter.rbegin(), sorter.rend(), [](ZElement *l, ZElement *r) { return l->z < r->z; });
|
||||
RendererApi::Color p = background;
|
||||
RendererApi::Color p = bg;
|
||||
for (auto a: sorter) {
|
||||
p = apply_transparent_color(p, a->color);
|
||||
}
|
||||
receiver->export_pixel(x, y, p, sorter[sorter.size() - 1]->owner);
|
||||
if (++x >= this->_width) {
|
||||
frame->set_pixel(x, y, p, sorter[sorter.size() - 1]->owner);
|
||||
|
||||
if (++x >= w) {
|
||||
y++;
|
||||
x = 0;
|
||||
}
|
||||
@ -261,40 +254,16 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
}
|
||||
|
||||
namespace QtUtilities {
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
|
||||
template<class sprite_data_t, class renderer_context_t, void (renderer_context_t::*renderer_procedure)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
class SeparateThreadedRenderer;
|
||||
|
||||
#if 0
|
||||
template<class sprite_data_t, bool _private_param>
|
||||
class _SeparateThreadedDefaultRendererLinear {
|
||||
};
|
||||
|
||||
template<class sprite_data_t>
|
||||
class _SeparateThreadedDefaultRendererLinear<sprite_data_t, false> {
|
||||
template<class, bool>
|
||||
friend
|
||||
class _SeparateThreadedDefaultRendererLinear;
|
||||
|
||||
|
||||
class SeparateThreadedDefaultRendererLinear : public SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t>> {
|
||||
private:
|
||||
_SeparateThreadedDefaultRendererLinear() = delete;
|
||||
|
||||
class Context : public Utilities::DefaultVoxelDrawerLinear<sprite_data_t> {
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
class _SeparateThreadedDefaultRendererLinear : public SeparateThreadedRenderer<sprite_data_t, SeparateThreadedDefaultRendererLinear < sprite_data_t>, &SeparateThreadedDefaultRendererLinear<sprite_data_t>::render
|
||||
|
||||
> {
|
||||
Utilities::DefaultVoxelDrawerCache context;
|
||||
public:
|
||||
|
||||
void render(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t) {
|
||||
|
||||
}
|
||||
};
|
||||
#endif
|
||||
explicit SeparateThreadedDefaultRendererLinear(QObject *owner = nullptr) : SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t>>{&this->context, owner} {};
|
||||
};
|
||||
}
|
||||
}
|
81
utilities/src/color.asm
Normal file
81
utilities/src/color.asm
Normal file
@ -0,0 +1,81 @@
|
||||
%define __MMX__ 1
|
||||
%define __SSE__ 2
|
||||
%define __SSE2__ 3
|
||||
%define __SSE3__ 4
|
||||
%define __SSSE3__ 5
|
||||
%define __SSE4_1__ 6
|
||||
%define __SSE4_2__ 7
|
||||
%define __AVX__ 8
|
||||
%define __AVX2__ 9
|
||||
%define __FMA3__ 10
|
||||
%define __AVX512F__ 11
|
||||
%define __AMX__ 12
|
||||
|
||||
|
||||
%macro impl_body 1
|
||||
%ifidn __OUTPUT_FORMAT__, elf64
|
||||
movd xmm0, edi
|
||||
movd xmm1, esi
|
||||
mov r8d, esi
|
||||
%elifidn __OUTPUT_FORMAT__, win64
|
||||
; movzx r9d, WORD [rdx]
|
||||
; movzx r10d, BYTE [rdx+2]
|
||||
; shl r10d, 16
|
||||
; or r9d, r10d
|
||||
movd xmm0, DWORD [rdx]
|
||||
movd xmm1, r8d
|
||||
%else
|
||||
%error "Unsupported output format"
|
||||
%endif
|
||||
|
||||
pmovzxbd xmm0, xmm0 ; 0-extend 8bit->32bit
|
||||
pmovzxbd xmm1, xmm1 ; 0-extend 8bit->32bit
|
||||
shr r8d, 24
|
||||
%if %1 >= __AVX512F__
|
||||
vpbroadcastd xmm2, r8d ; fill vector with 32bit values
|
||||
%elif %1 >= __AVX2__
|
||||
movd xmm2, r8d
|
||||
vpbroadcastd xmm2, xmm2
|
||||
%endif
|
||||
mov r8d, 255
|
||||
%if %1 >= __AVX512F__
|
||||
vpbroadcastd xmm3, r8d ; fill vector with 32bit values
|
||||
%elif %1 >= __AVX2__
|
||||
movd xmm3, r8d
|
||||
vpbroadcastd xmm3, xmm3
|
||||
%endif
|
||||
|
||||
psubd xmm3, xmm2 ; sub 32bit integers
|
||||
pmuludq xmm0, xmm3 ; mul unsigned 32bit integers
|
||||
pmuludq xmm1, xmm2 ; mul unsigned 32bit integers
|
||||
paddd xmm0, xmm1 ; add 32bit integers
|
||||
psrld xmm0, 8 ; 0-shift 32bit integers right
|
||||
|
||||
pextrd r9d, xmm0, 0 ; extracts 32 bit integer
|
||||
pextrd r10d, xmm0, 1 ; extracts 32 bit integer
|
||||
pextrd r11d, xmm0, 2 ; extracts 32 bit integer
|
||||
shl r10d, 8
|
||||
shl r11d, 16
|
||||
or r9d, r10d
|
||||
or r9d, r11d
|
||||
|
||||
%ifidn __OUTPUT_FORMAT__, elf64
|
||||
mov eax, r9d
|
||||
%elifidn __OUTPUT_FORMAT__, win64
|
||||
mov DWORD [rcx], r9d
|
||||
%else
|
||||
%error "Unsupported output format"
|
||||
%endif
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
|
||||
section .text
|
||||
|
||||
|
||||
; avx2
|
||||
|
||||
global ?_apply_transparent_color_avx2@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z ; msvc
|
||||
|
||||
?_apply_transparent_color_avx2@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z:
|
||||
impl_body __AVX2__
|
53
utilities/src/default_renderer_linear.cpp
Normal file
53
utilities/src/default_renderer_linear.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include <cstdlib>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||
|
||||
DefaultVoxelDrawerCache::ZElementAllocationBuffer::Cell *DefaultVoxelDrawerCache::ZElementAllocationBuffer::Page::try_allocate() {
|
||||
if (this->initialized < this->capacity) {
|
||||
Cell *cell = &(this->buffer[this->initialized++]);
|
||||
return cell;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DefaultVoxelDrawerCache::ZElementAllocationBuffer::free_elem(DefaultVoxelDrawerCache::ZElement *e) {
|
||||
Cell *cell = reinterpret_cast<Cell *>(e);
|
||||
cell->empty.next_empty = this->next_unallocated;
|
||||
this->next_unallocated = cell;
|
||||
}
|
||||
|
||||
void DefaultVoxelDrawerCache::ZElementAllocationBuffer::release_resources() {
|
||||
Page *p;
|
||||
while (this->last_page != nullptr) {
|
||||
p = this->last_page;
|
||||
this->last_page = p->next;
|
||||
this->_native_free_page(p);
|
||||
}
|
||||
this->next_unallocated = nullptr;
|
||||
}
|
||||
|
||||
void DefaultVoxelDrawerCache::ZElementAllocationBuffer::reset_allocations() {
|
||||
Page *p = this->last_page;
|
||||
while (p != nullptr) {
|
||||
p->reset_allocations();
|
||||
p = p->next;
|
||||
}
|
||||
this->next_unallocated = nullptr;
|
||||
}
|
||||
|
||||
DefaultVoxelDrawerCache::ZElementAllocationBuffer::~ZElementAllocationBuffer() {
|
||||
this->release_resources();
|
||||
}
|
||||
|
||||
DefaultVoxelDrawerCache::DefaultVoxelDrawerCache() : pixel_trace_elements_allocator{}, pixel_metadata_cache{.buffer = nullptr, .size = 0}, sorter{} {}
|
||||
|
||||
DefaultVoxelDrawerCache::~DefaultVoxelDrawerCache() {
|
||||
if (this->pixel_metadata_cache.buffer != nullptr) {
|
||||
std::free(this->pixel_metadata_cache.buffer);
|
||||
this->pixel_metadata_cache.buffer = nullptr;
|
||||
}
|
||||
this->pixel_metadata_cache.size = 0;
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||
DefaultVoxelDrawerLinear::ZElementAllocationBuffer::Page *DefaultVoxelDrawerLinear::ZElementAllocationBuffer::_native_extend() {
|
||||
DefaultVoxelDrawerCache::ZElementAllocationBuffer::Page *DefaultVoxelDrawerCache::ZElementAllocationBuffer::_native_extend() {
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
|
||||
@ -20,7 +20,7 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||
}
|
||||
|
||||
|
||||
void DefaultVoxelDrawerLinear::ZElementAllocationBuffer::_native_free_page(DefaultVoxelDrawerLinear::ZElementAllocationBuffer::Page *p) {
|
||||
void DefaultVoxelDrawerCache::ZElementAllocationBuffer::_native_free_page(DefaultVoxelDrawerCache::ZElementAllocationBuffer::Page *p) {
|
||||
VirtualFree(p, 0, MEM_DECOMMIT | MEM_RELEASE);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user