Moving Projection from sprite arguments to sprite_data and changing source of sprite_data from field to provider
This commit is contained in:
parent
e1154fdf0a
commit
be82c26b01
@ -3,6 +3,7 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
|
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
|
||||||
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
|
||||||
|
#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/renderer_widget.hpp>
|
||||||
#include <bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.hpp>
|
#include <bgtu/computer_graphics_lab_work/qt_utilities/owned_qimage.hpp>
|
||||||
|
|
||||||
@ -37,10 +38,10 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
o oo{&frames};
|
o oo{&frames};
|
||||||
|
|
||||||
BGTU::ComputerGraphicsLabWork::QtUtilities::SeparateThreadedDefaultRendererLinear<void> renderer{};
|
BGTU::ComputerGraphicsLabWork::QtUtilities::SeparateThreadedDefaultRendererLinear<int> renderer{};
|
||||||
QObject::connect(&renderer, &BGTU::ComputerGraphicsLabWork::QtUtilities::_SeparateThreadedRenderer_Signals::frame_rendered, &oo, &o::hit);
|
QObject::connect(&renderer, &BGTU::ComputerGraphicsLabWork::QtUtilities::_SeparateThreadedRenderer_Signals::frame_rendered, &oo, &o::hit);
|
||||||
renderer.set_background(BGTU::ComputerGraphicsLabWork::RendererApi::Color{0, 0, 0});
|
renderer.set_background(BGTU::ComputerGraphicsLabWork::RendererApi::Color{0, 0, 0});
|
||||||
BGTU::ComputerGraphicsLabWork::QtUtilities::RendererWidget<void> canvas{&renderer, &w};
|
BGTU::ComputerGraphicsLabWork::QtUtilities::RendererWidget<int> canvas{&renderer, &w};
|
||||||
w.setCentralWidget(&canvas);
|
w.setCentralWidget(&canvas);
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||||
template<class sprite_data_t, class renderer_context_t>
|
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 *);
|
using _SeparateThreadedRenderer_RenderProcedureType = void (renderer_context_t::*)(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t, RendererApi::VoxelDrawer::Exporter *, RendererApi::Color, RendererApi::Sprite<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>>
|
template<class sprite_data_t, class renderer_context_t, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t>>
|
||||||
class SeparateThreadedRenderer;
|
class SeparateThreadedRenderer;
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
#include "owned_qimage.hpp"
|
#include "owned_qimage.hpp"
|
||||||
#include "_separate_threaded_renderer.hpp"
|
#include "_separate_threaded_renderer.hpp"
|
||||||
|
|
||||||
|
#define has_BGTU_ComputerGraphicsLabWork_QtUtilities_SeparateThreadedRenderer
|
||||||
|
|
||||||
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
||||||
template<class sprite_data_t, class renderer_context_t, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
template<class sprite_data_t, class renderer_context_t, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
||||||
class SeparateThreadedRenderer : public _SeparateThreadedRenderer_Signals {
|
class SeparateThreadedRenderer : public _SeparateThreadedRenderer_Signals {
|
||||||
@ -22,10 +24,9 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
|||||||
public:
|
public:
|
||||||
RendererApi::Sprite<sprite_data_t> *const *sprites;
|
RendererApi::Sprite<sprite_data_t> *const *sprites;
|
||||||
std::size_t sprites_count;
|
std::size_t sprites_count;
|
||||||
sprite_data_t const *sprite_data;
|
RendererApi::Sprite<sprite_data_t>::SpriteDataProvider *sprite_data_provider;
|
||||||
std::uint_fast64_t ms_per_frame;
|
std::uint_fast64_t ms_per_frame;
|
||||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, height;
|
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, height;
|
||||||
RendererApi::Projection *projection;
|
|
||||||
RendererApi::Color bg;
|
RendererApi::Color bg;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,9 +78,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
|||||||
|
|
||||||
void set_sprites(RendererApi::Sprite<sprite_data_t> *const *sprites, std::size_t sprites_count);
|
void set_sprites(RendererApi::Sprite<sprite_data_t> *const *sprites, std::size_t sprites_count);
|
||||||
|
|
||||||
void set_sprite_data(sprite_data_t const *data);
|
void set_sprite_data_provider(RendererApi::Sprite<sprite_data_t>::SpriteDataProvider *provider);
|
||||||
|
|
||||||
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) final;
|
void set_background(RendererApi::Color) final;
|
||||||
|
|
||||||
@ -98,11 +97,10 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
|||||||
next_data{
|
next_data{
|
||||||
.sprites = nullptr,
|
.sprites = nullptr,
|
||||||
.sprites_count = 0,
|
.sprites_count = 0,
|
||||||
.sprite_data = nullptr,
|
.sprite_data_provider = nullptr,
|
||||||
.ms_per_frame = 1000 / 60,
|
.ms_per_frame = 1000 / 60,
|
||||||
.width = 0,
|
.width = 0,
|
||||||
.height = 0,
|
.height = 0,
|
||||||
.projection = nullptr
|
|
||||||
} {
|
} {
|
||||||
this->thread->start();
|
this->thread->start();
|
||||||
}
|
}
|
||||||
@ -133,24 +131,13 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class sprite_data_t, class renderer_context_t, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
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) {
|
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_sprite_data_provider(RendererApi::Sprite<sprite_data_t>::SpriteDataProvider *provider) {
|
||||||
this->sync.lock();
|
this->sync.lock();
|
||||||
const_cast<data_t *>(&this->next_data)->sprite_data = sprite_data;
|
const_cast<data_t *>(&this->next_data)->sprite_data_provider = provider;
|
||||||
this->thread->force_redraw();
|
this->thread->force_redraw();
|
||||||
this->sync.unlock();
|
this->sync.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
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_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, _SeparateThreadedRenderer_RenderProcedureType<sprite_data_t, renderer_context_t> renderer_procedure>
|
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) {
|
void SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::set_background(RendererApi::Color c) {
|
||||||
this->sync.lock();
|
this->sync.lock();
|
||||||
@ -191,13 +178,24 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
|||||||
}
|
}
|
||||||
} img{cached.width, cached.height};
|
} img{cached.width, cached.height};
|
||||||
|
|
||||||
|
union {
|
||||||
|
sprite_data_t data;
|
||||||
|
bool nothing;
|
||||||
|
} sprite_data_storage;
|
||||||
|
sprite_data_t const *sprite_data;
|
||||||
|
if (cached.sprite_data_provider != nullptr) {
|
||||||
|
sprite_data_storage.data = cached.sprite_data_provider->get_sprite_data();
|
||||||
|
sprite_data = &(sprite_data_storage.data);
|
||||||
|
} else {
|
||||||
|
sprite_data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
(this->owner->renderer_context->*renderer_procedure)(
|
(this->owner->renderer_context->*renderer_procedure)(
|
||||||
cached.width, cached.height,
|
cached.width, cached.height,
|
||||||
&img,
|
&img,
|
||||||
cached.bg,
|
cached.bg,
|
||||||
cached.projection,
|
|
||||||
cached.sprites, cached.sprites_count,
|
cached.sprites, cached.sprites_count,
|
||||||
cached.sprite_data
|
sprite_data
|
||||||
);
|
);
|
||||||
emit this->owner->frame_rendered(new OwnedQImage{img.pixels_argb, img.w, img.h, QImage::Format_RGB32, img.owners, OwnedQImage::DelegateBuffers});
|
emit this->owner->frame_rendered(new OwnedQImage{img.pixels_argb, img.w, img.h, QImage::Format_RGB32, img.owners, OwnedQImage::DelegateBuffers});
|
||||||
auto elapsed = timer.elapsed();
|
auto elapsed = timer.elapsed();
|
||||||
@ -215,4 +213,13 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
|||||||
this->thread->requestInterruption();
|
this->thread->requestInterruption();
|
||||||
this->thread->wait();
|
this->thread->wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class sprite_data_t>
|
||||||
|
class SeparateThreadedDefaultRendererLinear : public SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t>> {
|
||||||
|
private:
|
||||||
|
Utilities::DefaultVoxelDrawerCache context;
|
||||||
|
public:
|
||||||
|
explicit SeparateThreadedDefaultRendererLinear(QObject *owner = nullptr) : SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t>>{&this->context, owner} {};
|
||||||
|
};
|
||||||
}
|
}
|
@ -12,6 +12,11 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi {
|
|||||||
template<class data_t>
|
template<class data_t>
|
||||||
class Sprite : public SpriteMetadata {
|
class Sprite : public SpriteMetadata {
|
||||||
public:
|
public:
|
||||||
virtual void draw(VoxelDrawer *frame, Projection const *projection, data_t const *data) const = 0;
|
virtual void draw(VoxelDrawer *frame, data_t const *data) const = 0;
|
||||||
|
|
||||||
|
class SpriteDataProvider {
|
||||||
|
public:
|
||||||
|
virtual data_t get_sprite_data() = 0;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -15,228 +15,210 @@
|
|||||||
|
|
||||||
class QObject;
|
class QObject;
|
||||||
|
|
||||||
namespace BGTU::ComputerGraphicsLabWork {
|
namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||||
namespace Utilities {
|
class DefaultVoxelDrawerCache {
|
||||||
class DefaultVoxelDrawerCache {
|
private:
|
||||||
private:
|
class ZElement {
|
||||||
class ZElement {
|
|
||||||
public:
|
|
||||||
ZElement *next;
|
|
||||||
double const z;
|
|
||||||
RendererApi::Color::Transparent const color;
|
|
||||||
RendererApi::SpriteMetadata *const 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;
|
|
||||||
this->next = new_next;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ZElementAllocationBuffer {
|
|
||||||
private:
|
|
||||||
union Cell {
|
|
||||||
ZElement allocated;
|
|
||||||
struct Empty {
|
|
||||||
Cell *next_empty;
|
|
||||||
} empty;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Page {
|
|
||||||
public:
|
|
||||||
Page *next;
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::size_t initialized;
|
|
||||||
std::size_t capacity;
|
|
||||||
|
|
||||||
Cell buffer[0];
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Page(Page *next, std::size_t capacity) : next{next}, initialized{0}, capacity{capacity}, buffer{} {};
|
|
||||||
|
|
||||||
Cell *try_allocate();
|
|
||||||
|
|
||||||
static std::size_t calc_capacity(std::size_t bytes) {
|
|
||||||
return (bytes - offsetof(Page, buffer)) / sizeof(Cell);
|
|
||||||
};
|
|
||||||
|
|
||||||
void reset_allocations() {
|
|
||||||
this->initialized = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Cell *next_unallocated;
|
|
||||||
Page *last_page;
|
|
||||||
Page sentinel;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ZElementAllocationBuffer() : next_unallocated{nullptr}, sentinel{nullptr, 0}, last_page{&this->sentinel} {};
|
|
||||||
|
|
||||||
private:
|
|
||||||
Page *_native_extend();
|
|
||||||
|
|
||||||
public:
|
|
||||||
template<class ...args_t>
|
|
||||||
ZElement *alloc_elem(args_t...args);
|
|
||||||
|
|
||||||
void free_elem(ZElement *e);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void _native_free_page(Page *p);
|
|
||||||
|
|
||||||
public:
|
|
||||||
void release_resources();
|
|
||||||
|
|
||||||
void reset_allocations();
|
|
||||||
|
|
||||||
~ZElementAllocationBuffer();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pixel_trace_metadata {
|
|
||||||
public:
|
|
||||||
pixel_trace_metadata() : nearest_z{std::numeric_limits<double>::max()}, voxels{nullptr} {};
|
|
||||||
|
|
||||||
double nearest_z;
|
|
||||||
ZElement *voxels;
|
|
||||||
};
|
|
||||||
|
|
||||||
class VoxelDrawerImpl : public RendererApi::VoxelDrawer {
|
|
||||||
public:
|
|
||||||
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;
|
|
||||||
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);
|
|
||||||
|
|
||||||
[[nodiscard]] inline RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width() const final {
|
|
||||||
return this->_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height() const final {
|
|
||||||
return this->_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline 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;
|
|
||||||
ZElementAllocationBuffer pixel_trace_elements_allocator;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DefaultVoxelDrawerCache();
|
ZElement *next;
|
||||||
|
double const z;
|
||||||
|
RendererApi::Color::Transparent const color;
|
||||||
|
RendererApi::SpriteMetadata *const owner;
|
||||||
|
|
||||||
private:
|
ZElement(ZElement *next, double z, RendererApi::Color::Transparent color, RendererApi::SpriteMetadata *owner) : next{next}, z{z}, color{color}, owner{owner} {}
|
||||||
static ZElement *sort_zelements_desc(DefaultVoxelDrawerCache::ZElement *start) noexcept;
|
|
||||||
|
|
||||||
public:
|
void link_after(ZElement *new_next) {
|
||||||
template<class sprite_data_t>
|
new_next->next = this->next;
|
||||||
void render(
|
this->next = new_next;
|
||||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w,
|
}
|
||||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t h,
|
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
~DefaultVoxelDrawerCache();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class... args_t>
|
class ZElementAllocationBuffer {
|
||||||
DefaultVoxelDrawerCache::ZElement *DefaultVoxelDrawerCache::ZElementAllocationBuffer::alloc_elem(args_t... args) {
|
private:
|
||||||
auto cell = this->next_unallocated;
|
union Cell {
|
||||||
if (cell != nullptr) {
|
ZElement allocated;
|
||||||
this->next_unallocated = cell->empty.next_empty;
|
struct Empty {
|
||||||
return &(cell->allocated);
|
Cell *next_empty;
|
||||||
|
} empty;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Page {
|
||||||
|
public:
|
||||||
|
Page *next;
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::size_t initialized;
|
||||||
|
std::size_t capacity;
|
||||||
|
|
||||||
|
Cell buffer[0];
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Page(Page *next, std::size_t capacity) : next{next}, initialized{0}, capacity{capacity}, buffer{} {};
|
||||||
|
|
||||||
|
Cell *try_allocate();
|
||||||
|
|
||||||
|
static std::size_t calc_capacity(std::size_t bytes) {
|
||||||
|
return (bytes - offsetof(Page, buffer)) / sizeof(Cell);
|
||||||
|
};
|
||||||
|
|
||||||
|
void reset_allocations() {
|
||||||
|
this->initialized = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Cell *next_unallocated;
|
||||||
|
Page *last_page;
|
||||||
|
Page sentinel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZElementAllocationBuffer() : next_unallocated{nullptr}, sentinel{nullptr, 0}, last_page{&this->sentinel} {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Page *_native_extend();
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<class ...args_t>
|
||||||
|
ZElement *alloc_elem(args_t...args);
|
||||||
|
|
||||||
|
void free_elem(ZElement *e);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _native_free_page(Page *p);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void release_resources();
|
||||||
|
|
||||||
|
void reset_allocations();
|
||||||
|
|
||||||
|
~ZElementAllocationBuffer();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pixel_trace_metadata {
|
||||||
|
public:
|
||||||
|
pixel_trace_metadata() : nearest_z{std::numeric_limits<double>::max()}, voxels{nullptr} {};
|
||||||
|
|
||||||
|
double nearest_z;
|
||||||
|
ZElement *voxels;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VoxelDrawerImpl : public RendererApi::VoxelDrawer {
|
||||||
|
public:
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
|
||||||
|
[[nodiscard]] inline RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width() const final {
|
||||||
|
return this->_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((cell = this->last_page->try_allocate()) == nullptr)
|
[[nodiscard]] inline RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height() const final {
|
||||||
this->_native_extend();
|
return this->_height;
|
||||||
|
}
|
||||||
|
|
||||||
return new(&(cell->allocated)) ZElement{args...};
|
inline 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;
|
||||||
|
ZElementAllocationBuffer pixel_trace_elements_allocator;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DefaultVoxelDrawerCache();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ZElement *sort_zelements_desc(DefaultVoxelDrawerCache::ZElement *start) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
template<class sprite_data_t>
|
template<class sprite_data_t>
|
||||||
void DefaultVoxelDrawerCache::render(
|
void render(
|
||||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w,
|
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w,
|
||||||
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t h,
|
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t h,
|
||||||
RendererApi::VoxelDrawer::Exporter *frame,
|
RendererApi::VoxelDrawer::Exporter *frame,
|
||||||
RendererApi::Color bg,
|
RendererApi::Color bg,
|
||||||
RendererApi::Projection const *projection,
|
|
||||||
RendererApi::Sprite<sprite_data_t> *const *sprites,
|
RendererApi::Sprite<sprite_data_t> *const *sprites,
|
||||||
std::size_t sprites_count,
|
std::size_t sprites_count,
|
||||||
sprite_data_t const *sprite_data
|
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) {
|
~DefaultVoxelDrawerCache();
|
||||||
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;
|
|
||||||
|
template<class... args_t>
|
||||||
|
DefaultVoxelDrawerCache::ZElement *DefaultVoxelDrawerCache::ZElementAllocationBuffer::alloc_elem(args_t... args) {
|
||||||
|
auto cell = this->next_unallocated;
|
||||||
|
if (cell != nullptr) {
|
||||||
|
this->next_unallocated = cell->empty.next_empty;
|
||||||
|
return &(cell->allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((cell = this->last_page->try_allocate()) == nullptr)
|
||||||
|
this->_native_extend();
|
||||||
|
|
||||||
|
return new(&(cell->allocated)) ZElement{args...};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 *frame,
|
||||||
|
RendererApi::Color bg,
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pixel_trace_elements_allocator.reset_allocations();
|
||||||
|
VoxelDrawerImpl 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, sprite_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint_fast16_t y = 0;
|
||||||
|
std::uint_fast16_t x = 0;
|
||||||
|
|
||||||
|
for (std::int_fast64_t i = w * h - 1; i >= 0; i--) {
|
||||||
|
this->pixel_metadata_cache.buffer[i].voxels = sort_zelements_desc(this->pixel_metadata_cache.buffer[i].voxels);
|
||||||
|
RendererApi::Color cc = bg;
|
||||||
|
RendererApi::SpriteMetadata *owner = nullptr;
|
||||||
|
for (auto p = this->pixel_metadata_cache.buffer[i].voxels; p != nullptr; p = p->next) {
|
||||||
|
cc = apply_transparent_color(cc, p->color);
|
||||||
|
owner = p->owner;
|
||||||
}
|
}
|
||||||
|
frame->set_pixel(x, y, cc, owner);
|
||||||
|
|
||||||
this->pixel_trace_elements_allocator.reset_allocations();
|
if (++x >= w) {
|
||||||
VoxelDrawerImpl painter{w, h, this->pixel_metadata_cache.buffer, &this->pixel_trace_elements_allocator};
|
y++;
|
||||||
|
x = 0;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint_fast16_t y = 0;
|
|
||||||
std::uint_fast16_t x = 0;
|
|
||||||
|
|
||||||
for (std::int_fast64_t i = w * h - 1; i >= 0; i--) {
|
|
||||||
this->pixel_metadata_cache.buffer[i].voxels = sort_zelements_desc(this->pixel_metadata_cache.buffer[i].voxels);
|
|
||||||
RendererApi::Color cc = bg;
|
|
||||||
RendererApi::SpriteMetadata *owner = nullptr;
|
|
||||||
for (auto p = this->pixel_metadata_cache.buffer[i].voxels; p != nullptr; p = p->next) {
|
|
||||||
cc = apply_transparent_color(cc, p->color);
|
|
||||||
owner = p->owner;
|
|
||||||
}
|
|
||||||
frame->set_pixel(x, y, cc, owner);
|
|
||||||
|
|
||||||
if (++x >= w) {
|
|
||||||
y++;
|
|
||||||
x = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *, RendererApi::Color, RendererApi::Projection const *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t, sprite_data_t const *)>
|
|
||||||
class SeparateThreadedRenderer;
|
|
||||||
|
|
||||||
|
|
||||||
template<class sprite_data_t>
|
|
||||||
class SeparateThreadedDefaultRendererLinear : public SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t>> {
|
|
||||||
private:
|
|
||||||
Utilities::DefaultVoxelDrawerCache context;
|
|
||||||
public:
|
|
||||||
explicit SeparateThreadedDefaultRendererLinear(QObject *owner = nullptr) : SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t>>{&this->context, owner} {};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user