Minor improvements
This commit is contained in:
parent
52561c8004
commit
15c715ad21
@ -5,15 +5,19 @@
|
||||
#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>
|
||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.hpp>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
QApplication qApplication{argc, argv};
|
||||
QMainWindow w{};
|
||||
qRegisterMetaType<BGTU::ComputerGraphicsLabWork::QtUtilities::OwnedQImage>("OwnedQImage");
|
||||
|
||||
QMainWindow w{};
|
||||
BGTU::ComputerGraphicsLabWork::QtUtilities::SeparateThreadedDefaultRendererLinear<void> renderer{};
|
||||
renderer.set_background(BGTU::ComputerGraphicsLabWork::RendererApi::Color{0, 0, 0});
|
||||
BGTU::ComputerGraphicsLabWork::QtUtilities::RendererWidget<void> canvas{&renderer, &w};
|
||||
w.setCentralWidget(&canvas);
|
||||
w.show();
|
||||
|
||||
QApplication::exec();
|
||||
}
|
@ -1,3 +1,9 @@
|
||||
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)
|
||||
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
|
||||
include/bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.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)
|
@ -31,7 +31,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
|
||||
private slots:
|
||||
|
||||
virtual void receive_image(OwnedQImage<void> img) = 0;
|
||||
virtual void receive_image(OwnedQImage img) = 0;
|
||||
|
||||
};
|
||||
}
|
@ -13,13 +13,13 @@
|
||||
#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 *)>
|
||||
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 *, 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 *)>
|
||||
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 *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
friend
|
||||
class SeparateThreadedRenderer;
|
||||
|
||||
@ -27,6 +27,6 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
explicit _SeparateThreadedRenderer_Signals(QObject *owner = nullptr) : QObject{owner} {}
|
||||
|
||||
signals:
|
||||
void frame_rendered(OwnedQImage<void> img);
|
||||
void frame_rendered(OwnedQImage img);
|
||||
};
|
||||
}
|
@ -11,36 +11,41 @@
|
||||
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
template<class sprite_data_t>
|
||||
class OwnedQImage : public QImage, public RendererApi::VoxelDrawer::Exporter<sprite_data_t> {
|
||||
class OwnedQImage : public QImage, public RendererApi::VoxelDrawer::Exporter {
|
||||
private:
|
||||
RendererApi::Sprite<sprite_data_t> const **owners;
|
||||
RendererApi::SpriteMetadata 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 **p = this->owners - 1; p-- >= this->owners;) {
|
||||
*p = nullptr;
|
||||
OwnedQImage(unsigned width, unsigned height) :
|
||||
QImage(width, height, QImage::Format_ARGB32) {
|
||||
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;) {
|
||||
*p = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OwnedQImage() : QImage(), owners{nullptr} {}
|
||||
|
||||
|
||||
void setPixelOwner(unsigned x, unsigned y, RendererApi::Sprite<sprite_data_t> const *o) {
|
||||
void setPixelOwner(unsigned x, unsigned y, RendererApi::SpriteMetadata const *o) {
|
||||
assert(x < this->width());
|
||||
assert(y < this->height());
|
||||
|
||||
this->owners[y * this->width() + x] = o;
|
||||
}
|
||||
|
||||
RendererApi::Sprite<sprite_data_t> const *getPixelOwner(unsigned x, unsigned y) const {
|
||||
RendererApi::SpriteMetadata const *getPixelOwner(unsigned x, unsigned y) const {
|
||||
assert(x < this->width());
|
||||
assert(y < this->height());
|
||||
|
||||
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 {
|
||||
void set_pixel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, RendererApi::Color c, RendererApi::SpriteMetadata const *owner) final {
|
||||
this->setPixelColor(x, y, QColor{c.red, c.green, c.blue});
|
||||
this->setPixelOwner(x, y, owner);
|
||||
}
|
||||
|
@ -21,13 +21,13 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
class RendererWidget : public _RendererWidget_Slots {
|
||||
private:
|
||||
QMutex sync;
|
||||
OwnedQImage<void> next_image;
|
||||
OwnedQImage<void> current_image;
|
||||
OwnedQImage next_image;
|
||||
OwnedQImage current_image;
|
||||
_SeparateThreadedRenderer_Signals *renderer;
|
||||
|
||||
private slots:
|
||||
|
||||
void receive_image(OwnedQImage<void> img) {
|
||||
void receive_image(OwnedQImage img) {
|
||||
this->sync.lock();
|
||||
std::swap(this->next_image, img);
|
||||
this->sync.unlock();
|
||||
@ -48,8 +48,9 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
|
||||
QPainter painter;
|
||||
painter.begin(this);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(QApplication::style()->standardPalette().brush(QPalette::Background));
|
||||
painter.drawRect(this->rect());
|
||||
painter.drawRect(this->rect().x(), this->rect().y(), this->rect().width()-1, this->rect().height()-1);
|
||||
painter.drawImage(this->current_image.rect(), this->current_image);
|
||||
painter.end();
|
||||
}
|
||||
|
@ -8,13 +8,14 @@
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QElapsedTimer>
|
||||
#include <QWaitCondition>
|
||||
#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::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 *)>
|
||||
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 *, 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 {
|
||||
@ -32,12 +33,27 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
|
||||
private:
|
||||
SeparateThreadedRenderer *owner;
|
||||
|
||||
QWaitCondition intr;
|
||||
public:
|
||||
explicit inline RendererThread(SeparateThreadedRenderer *owner) : QThread{owner}, owner{owner} {};
|
||||
|
||||
explicit inline RendererThread(SeparateThreadedRenderer *owner) : QThread{owner}, owner{owner}, intr{} {
|
||||
};
|
||||
|
||||
void requestInterruption() {
|
||||
QThread::requestInterruption();
|
||||
this->intr.wakeAll();
|
||||
}
|
||||
|
||||
protected:
|
||||
void run() final;
|
||||
|
||||
private:
|
||||
void sleepms(std::uint_fast64_t ms) {
|
||||
QMutex m{};
|
||||
m.lock();
|
||||
this->intr.wait(&m, ms);
|
||||
m.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -62,10 +78,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);
|
||||
|
||||
void set_background(RendererApi::Color);
|
||||
|
||||
public:
|
||||
~SeparateThreadedRenderer();
|
||||
};
|
||||
|
||||
|
||||
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 *)>
|
||||
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 *, 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):
|
||||
_SeparateThreadedRenderer_Signals{owner},
|
||||
sync{},
|
||||
@ -81,66 +100,67 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
.height = 0,
|
||||
.projection = nullptr
|
||||
} {
|
||||
this->thread->start();
|
||||
}
|
||||
|
||||
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 *)>
|
||||
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 *, 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;
|
||||
this->next_data.height = height;
|
||||
const_cast<data *>(&this->next_data)->width = width;
|
||||
const_cast<data *>(&this->next_data)->height = height;
|
||||
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 *)>
|
||||
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 *, 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;
|
||||
const_cast<data *>(&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::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 *)>
|
||||
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 *, 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;
|
||||
this->next_data.sprites_count = sprites_count;
|
||||
const_cast<data *>(&this->next_data)->sprites = sprites;
|
||||
const_cast<data *>(&this->next_data)->sprites_count = sprites_count;
|
||||
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>::set_sprite_data(sprite_data_t const *data) {
|
||||
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 *, 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 *sprite_data) {
|
||||
this->sync.lock();
|
||||
this->next_data.sprite_data = data;
|
||||
const_cast<data *>(&this->next_data)->sprite_data = sprite_data;
|
||||
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>::set_sprites_and_data(RendererApi::Sprite<sprite_data_t> *const *sprites, std::size_t sprites_count, sprite_data_t const *data) {
|
||||
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 *, 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 *sprite_data) {
|
||||
this->sync.lock();
|
||||
this->next_data.sprites = sprites;
|
||||
this->next_data.sprites_count = sprites_count;
|
||||
this->next_data.sprite_data = data;
|
||||
const_cast<data *>(&this->next_data)->sprites = sprites;
|
||||
const_cast<data *>(&this->next_data)->sprites_count = sprites_count;
|
||||
const_cast<data *>(&this->next_data)->sprite_data = sprite_data;
|
||||
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 *)>
|
||||
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 *, 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;
|
||||
const_cast<data *>(&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 *)>
|
||||
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 *, 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) {
|
||||
while (!this->isInterruptionRequested()) {
|
||||
timer.start();
|
||||
this->owner->sync.lock();
|
||||
data cached = *const_cast<data *>(&this->owner->next_data);
|
||||
this->owner->sync.unlock();
|
||||
|
||||
OwnedQImage<sprite_data_t> img{cached.width, cached.height};
|
||||
OwnedQImage img{cached.width, cached.height};
|
||||
(this->owner->renderer_context->*renderer_procedure)(
|
||||
cached.width, cached.height,
|
||||
&img,
|
||||
@ -149,12 +169,18 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
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));
|
||||
emit this->owner->frame_rendered(img);
|
||||
this->sleepms(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";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 *, 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() {
|
||||
this->thread->requestInterruption();
|
||||
this->thread->wait();
|
||||
}
|
||||
}
|
@ -4,11 +4,14 @@
|
||||
#include "projection.hpp"
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::RendererApi {
|
||||
template<class data_t>
|
||||
class Sprite {
|
||||
class SpriteMetadata {
|
||||
public:
|
||||
virtual void draw(VoxelDrawer *frame, Projection const *projection, data_t const *data) const = 0;
|
||||
|
||||
virtual void clicked() {};
|
||||
};
|
||||
|
||||
template<class data_t>
|
||||
class Sprite : public SpriteMetadata {
|
||||
public:
|
||||
virtual void draw(VoxelDrawer *frame, Projection const *projection, data_t const *data) const = 0;
|
||||
};
|
||||
}
|
@ -7,8 +7,7 @@
|
||||
#include "point.hpp"
|
||||
|
||||
namespace BGTU::ComputerGraphicsLabWork::RendererApi {
|
||||
template<class>
|
||||
class Sprite;
|
||||
class SpriteMetadata;
|
||||
|
||||
class VoxelDrawer {
|
||||
public:
|
||||
@ -31,10 +30,9 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi {
|
||||
return this->add_voxel(p.x, p.y, z, c);
|
||||
}
|
||||
|
||||
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;
|
||||
virtual void set_pixel(PointI<2>::component_t x, PointI<2>::component_t y, Color c, SpriteMetadata const* owner) = 0;
|
||||
};
|
||||
};
|
||||
}
|
@ -24,9 +24,9 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
ZElement *next;
|
||||
double const z;
|
||||
RendererApi::Color::Transparent const color;
|
||||
RendererApi::Sprite<void> *const owner;
|
||||
RendererApi::SpriteMetadata *const owner;
|
||||
|
||||
ZElement(ZElement *next, double z, RendererApi::Color::Transparent color, RendererApi::Sprite<void> *owner) : next{next}, z{z}, color{color}, owner{owner} {}
|
||||
ZElement(ZElement *next, double z, RendererApi::Color::Transparent color, RendererApi::SpriteMetadata *owner) : next{next}, z{z}, color{color}, owner{owner} {}
|
||||
|
||||
void link_after(ZElement *new_next) {
|
||||
new_next->next = this->next;
|
||||
@ -112,7 +112,7 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
pixel_trace_metadata *pixels_metadata;
|
||||
|
||||
ZElementAllocationBuffer *pixel_trace_elements_allocator;
|
||||
RendererApi::Sprite<sprite_data_t> *current_artist;
|
||||
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);
|
||||
|
||||
@ -146,7 +146,7 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
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::VoxelDrawer::Exporter *frame,
|
||||
RendererApi::Color bg,
|
||||
RendererApi::Projection const *projection,
|
||||
RendererApi::Sprite<sprite_data_t> *const *sprites,
|
||||
@ -170,7 +170,6 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
current_artist{nullptr} {}
|
||||
|
||||
|
||||
|
||||
template<class... args_t>
|
||||
DefaultVoxelDrawerCache::ZElement *DefaultVoxelDrawerCache::ZElementAllocationBuffer::alloc_elem(args_t... args) {
|
||||
auto cell = this->next_unallocated;
|
||||
@ -211,13 +210,16 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
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::VoxelDrawer::Exporter *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 (w == 0 || h == 0)
|
||||
return;
|
||||
|
||||
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;
|
||||
@ -254,7 +256,7 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
}
|
||||
|
||||
namespace 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 *)>
|
||||
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 *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
||||
class SeparateThreadedRenderer;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user