Fps calculator
This commit is contained in:
parent
15c715ad21
commit
003ba2b290
3
.gitignore
vendored
3
.gitignore
vendored
@ -7,4 +7,5 @@
|
||||
*.exe
|
||||
|
||||
/.idea/
|
||||
/*build*/
|
||||
/*build*/
|
||||
/.vs/
|
@ -1,8 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
#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>
|
||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.hpp>
|
||||
@ -10,10 +9,36 @@
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
QApplication qApplication{argc, argv};
|
||||
qRegisterMetaType<BGTU::ComputerGraphicsLabWork::QtUtilities::OwnedQImage>("OwnedQImage");
|
||||
// qRegisterMetaType<BGTU::ComputerGraphicsLabWork::QtUtilities::OwnedQImage>("OwnedQImage");
|
||||
|
||||
QTimer fps_timeout;
|
||||
unsigned frames = 0;
|
||||
fps_timeout.callOnTimeout([&] {
|
||||
qCritical() << (frames * 4) << "\n";
|
||||
qDebug() << (frames * 4) << "\n";
|
||||
frames = 0;
|
||||
});
|
||||
fps_timeout.setInterval(250);
|
||||
fps_timeout.start();
|
||||
QMainWindow w{};
|
||||
class o : public QObject {
|
||||
public:
|
||||
unsigned *frames;
|
||||
|
||||
explicit o(unsigned *f) : QObject{}, frames{f} {}
|
||||
|
||||
public slots:
|
||||
|
||||
void hit() {
|
||||
(*this->frames)++;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
o oo{&frames};
|
||||
|
||||
BGTU::ComputerGraphicsLabWork::QtUtilities::SeparateThreadedDefaultRendererLinear<void> renderer{};
|
||||
QObject::connect(&renderer, &BGTU::ComputerGraphicsLabWork::QtUtilities::_SeparateThreadedRenderer_Signals::frame_rendered, &oo, &o::hit);
|
||||
renderer.set_background(BGTU::ComputerGraphicsLabWork::RendererApi::Color{0, 0, 0});
|
||||
BGTU::ComputerGraphicsLabWork::QtUtilities::RendererWidget<void> canvas{&renderer, &w};
|
||||
w.setCentralWidget(&canvas);
|
||||
|
@ -31,7 +31,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
|
||||
private slots:
|
||||
|
||||
virtual void receive_image(OwnedQImage img) = 0;
|
||||
virtual void receive_image(OwnedQImage *img) = 0;
|
||||
|
||||
};
|
||||
}
|
@ -13,13 +13,16 @@
|
||||
#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 *, 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>
|
||||
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::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *);
|
||||
|
||||
template<class sprite_data_t, class renderer_context_t, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t>>
|
||||
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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t>>
|
||||
friend
|
||||
class SeparateThreadedRenderer;
|
||||
|
||||
@ -27,6 +30,16 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
explicit _SeparateThreadedRenderer_Signals(QObject *owner = nullptr) : QObject{owner} {}
|
||||
|
||||
signals:
|
||||
void frame_rendered(OwnedQImage img);
|
||||
|
||||
void frame_rendered(OwnedQImage *img);
|
||||
|
||||
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_ms_per_frame(std::uint_fast64_t ms) = 0;
|
||||
|
||||
virtual void set_background(RendererApi::Color) = 0;
|
||||
|
||||
};
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <Qt>
|
||||
#include <QObject>
|
||||
#include <QImage>
|
||||
@ -30,6 +31,31 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
|
||||
OwnedQImage() : QImage(), owners{nullptr} {}
|
||||
|
||||
OwnedQImage &operator=(OwnedQImage const ©) {
|
||||
if (this == ©)
|
||||
return *this;
|
||||
if (this->owners != nullptr)
|
||||
delete[] this->owners;
|
||||
if (copy.owners == nullptr) {
|
||||
this->owners = nullptr;
|
||||
} else {
|
||||
this->owners = new RendererApi::SpriteMetadata const *[copy.width() * copy.height()];
|
||||
std::memcpy(this->owners, copy.owners, copy.width() * copy.height() * sizeof(RendererApi::SpriteMetadata const *));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
OwnedQImage(OwnedQImage const ©) : QImage{copy} {
|
||||
*this = copy;
|
||||
}
|
||||
|
||||
OwnedQImage(OwnedQImage &&move) noexcept : QImage{std::move(move)} {
|
||||
if (this->owners != nullptr)
|
||||
delete[] this->owners;
|
||||
this->owners = move.owners;
|
||||
move.owners = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void setPixelOwner(unsigned x, unsigned y, RendererApi::SpriteMetadata const *o) {
|
||||
assert(x < this->width());
|
||||
@ -51,8 +77,10 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
}
|
||||
|
||||
~OwnedQImage() override {
|
||||
if (this->owners != nullptr)
|
||||
if (this->owners != nullptr) {
|
||||
delete[] this->owners;
|
||||
this->owners = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -10,6 +10,8 @@
|
||||
#include <QApplication>
|
||||
#include <QPalette>
|
||||
#include <QStyle>
|
||||
#include <QPaintEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
#include "owned_qimage.hpp"
|
||||
#include "separate_threaded_renderer.hpp"
|
||||
@ -21,15 +23,17 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
class RendererWidget : public _RendererWidget_Slots {
|
||||
private:
|
||||
QMutex sync;
|
||||
OwnedQImage next_image;
|
||||
OwnedQImage current_image;
|
||||
OwnedQImage *next_image;
|
||||
OwnedQImage *current_image;
|
||||
_SeparateThreadedRenderer_Signals *renderer;
|
||||
|
||||
private slots:
|
||||
|
||||
void receive_image(OwnedQImage img) {
|
||||
void receive_image(BGTU::ComputerGraphicsLabWork::QtUtilities::OwnedQImage *img) final {
|
||||
this->sync.lock();
|
||||
std::swap(this->next_image, img);
|
||||
if (this->next_image != nullptr)
|
||||
delete this->next_image;
|
||||
this->next_image = img;
|
||||
this->sync.unlock();
|
||||
this->update();
|
||||
}
|
||||
@ -43,16 +47,26 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) final {
|
||||
this->sync.lock();
|
||||
this->current_image = std::move(this->next_image);
|
||||
if (this->next_image != nullptr) {
|
||||
if (this->current_image != nullptr)
|
||||
delete this->current_image;
|
||||
this->current_image = this->next_image;
|
||||
this->next_image = nullptr;
|
||||
}
|
||||
this->sync.unlock();
|
||||
|
||||
QPainter painter;
|
||||
painter.begin(this);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(QApplication::style()->standardPalette().brush(QPalette::Background));
|
||||
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.drawRect(this->rect().x(), this->rect().y(), this->rect().width() - 1, this->rect().height() - 1);
|
||||
if (this->current_image != nullptr)
|
||||
painter.drawImage(this->current_image->rect(), *this->current_image);
|
||||
painter.end();
|
||||
}
|
||||
|
||||
void resizeEvent(QResizeEvent *event) override {
|
||||
this->renderer->set_frame_size(event->size().width(), event->size().height());
|
||||
}
|
||||
};
|
||||
}
|
@ -15,10 +15,10 @@
|
||||
#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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
class SeparateThreadedRenderer : public _SeparateThreadedRenderer_Signals {
|
||||
private:
|
||||
struct data {
|
||||
struct data_t {
|
||||
public:
|
||||
RendererApi::Sprite<sprite_data_t> *const *sprites;
|
||||
std::size_t sprites_count;
|
||||
@ -44,6 +44,10 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
this->intr.wakeAll();
|
||||
}
|
||||
|
||||
void force_redraw() {
|
||||
this->intr.wakeAll();
|
||||
}
|
||||
|
||||
protected:
|
||||
void run() final;
|
||||
|
||||
@ -57,7 +61,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
};
|
||||
|
||||
|
||||
volatile data next_data;
|
||||
volatile data_t next_data;
|
||||
QMutex sync;
|
||||
RendererThread *thread;
|
||||
QImage *sentinel_img;
|
||||
@ -67,9 +71,9 @@ 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);
|
||||
void set_frame_size(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height) final;
|
||||
|
||||
void set_ms_per_frame(std::uint_fast64_t ms);
|
||||
void set_ms_per_frame(std::uint_fast64_t ms) final;
|
||||
|
||||
void set_sprites(RendererApi::Sprite<sprite_data_t> *const *sprites, std::size_t sprites_count);
|
||||
|
||||
@ -77,14 +81,14 @@ 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);
|
||||
void set_background(RendererApi::Color) final;
|
||||
|
||||
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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::SeparateThreadedRenderer(renderer_context_t *renderer_context, QObject *owner):
|
||||
_SeparateThreadedRenderer_Signals{owner},
|
||||
sync{},
|
||||
@ -103,74 +107,81 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||
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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
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();
|
||||
const_cast<data *>(&this->next_data)->width = width;
|
||||
const_cast<data *>(&this->next_data)->height = height;
|
||||
const_cast<data_t *>(&this->next_data)->width = width;
|
||||
const_cast<data_t *>(&this->next_data)->height = height;
|
||||
this->thread->force_redraw();
|
||||
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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_ms_per_frame(std::uint_fast64_t ms) {
|
||||
this->sync.lock();
|
||||
const_cast<data *>(&this->next_data)->ms_per_frame = ms;
|
||||
const_cast<data_t *>(&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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
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();
|
||||
const_cast<data *>(&this->next_data)->sprites = sprites;
|
||||
const_cast<data *>(&this->next_data)->sprites_count = sprites_count;
|
||||
const_cast<data_t *>(&this->next_data)->sprites = sprites;
|
||||
const_cast<data_t *>(&this->next_data)->sprites_count = sprites_count;
|
||||
this->thread->force_redraw();
|
||||
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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_sprite_data(sprite_data_t const *sprite_data) {
|
||||
this->sync.lock();
|
||||
const_cast<data *>(&this->next_data)->sprite_data = sprite_data;
|
||||
const_cast<data_t *>(&this->next_data)->sprite_data = sprite_data;
|
||||
this->thread->force_redraw();
|
||||
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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
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();
|
||||
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;
|
||||
const_cast<data_t *>(&this->next_data)->sprites = sprites;
|
||||
const_cast<data_t *>(&this->next_data)->sprites_count = sprites_count;
|
||||
const_cast<data_t *>(&this->next_data)->sprite_data = sprite_data;
|
||||
this->thread->force_redraw();
|
||||
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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_background(RendererApi::Color c) {
|
||||
this->sync.lock();
|
||||
const_cast<data *>(&this->next_data)->bg = c;
|
||||
const_cast<data_t *>(&this->next_data)->bg = c;
|
||||
this->thread->force_redraw();
|
||||
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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::RendererThread::run() {
|
||||
try {
|
||||
QElapsedTimer timer;
|
||||
while (!this->isInterruptionRequested()) {
|
||||
timer.start();
|
||||
this->owner->sync.lock();
|
||||
data cached = *const_cast<data *>(&this->owner->next_data);
|
||||
data_t cached = *const_cast<data_t *>(&this->owner->next_data);
|
||||
this->owner->sync.unlock();
|
||||
|
||||
OwnedQImage img{cached.width, cached.height};
|
||||
auto img = new OwnedQImage{cached.width, cached.height};
|
||||
(this->owner->renderer_context->*renderer_procedure)(
|
||||
cached.width, cached.height,
|
||||
&img,
|
||||
img,
|
||||
cached.bg,
|
||||
cached.projection,
|
||||
cached.sprites, cached.sprites_count,
|
||||
cached.sprite_data
|
||||
);
|
||||
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));
|
||||
auto elapsed = timer.elapsed();
|
||||
qCritical() << elapsed << "ms";
|
||||
this->sleepms(std::max<std::int_fast64_t>(static_cast<std::int_fast64_t>(cached.ms_per_frame) - elapsed, 0));
|
||||
}
|
||||
} catch (std::exception const &e) {
|
||||
qCritical() << typeid(e).name() << ": " << e.what() << "\n" << "Renderer thread died" << "\n";
|
||||
@ -178,7 +189,7 @@ 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 *, 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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||
SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::~SeparateThreadedRenderer() {
|
||||
this->thread->requestInterruption();
|
||||
this->thread->wait();
|
||||
|
@ -228,6 +228,10 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
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 (std::int_fast64_t i = w * h - 1; i >= 0; i--) {
|
||||
new(&this->pixel_metadata_cache.buffer[i]) pixel_trace_metadata{};
|
||||
}
|
||||
|
||||
for (; sprites_count-- > 0; sprites++) {
|
||||
painter.current_artist = *sprites;
|
||||
(*sprites)->draw(&painter, projection, sprite_data);
|
||||
@ -237,15 +241,19 @@ namespace BGTU::ComputerGraphicsLabWork {
|
||||
std::uint_fast16_t x = 0;
|
||||
|
||||
for (std::int_fast64_t i = w * h - 1; i >= 0; i--) {
|
||||
this->sorter.clear();
|
||||
for (ZElement *e = this->pixel_metadata_cache.buffer[i].voxels; e != nullptr; e = e->next) {
|
||||
sorter.push_back(e);
|
||||
this->sorter.push_back(e);
|
||||
}
|
||||
std::sort(sorter.rbegin(), sorter.rend(), [](ZElement *l, ZElement *r) { return l->z < r->z; });
|
||||
std::sort(this->sorter.begin(), this->sorter.end(), [](ZElement *l, ZElement *r) { return l->z > r->z; });
|
||||
RendererApi::Color p = bg;
|
||||
for (auto a: sorter) {
|
||||
for (auto a: this->sorter) {
|
||||
p = apply_transparent_color(p, a->color);
|
||||
}
|
||||
frame->set_pixel(x, y, p, sorter[sorter.size() - 1]->owner);
|
||||
if (this->sorter.empty())
|
||||
frame->set_pixel(x, y, p, nullptr);
|
||||
else
|
||||
frame->set_pixel(x, y, p, this->sorter[this->sorter.size() - 1]->owner);
|
||||
|
||||
if (++x >= w) {
|
||||
y++;
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user