Utilities module for Qt, default voxel drawer and minor improvements

This commit is contained in:
Andrew Golovashevich 2024-12-09 07:35:04 +03:00
parent cdc8337219
commit 08ced011c6
12 changed files with 619 additions and 21 deletions

View File

@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.29)
cmake_minimum_required(VERSION 3.25)
project(cg1)
set(CMAKE_CXX_STANDARD 20)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui)
set(CMAKE_AUTOMOC ON)
add_executable(
@ -27,3 +27,4 @@ qt5_use_modules(cg1 Widgets)
add_subdirectory(renderer-api)
add_subdirectory(utilities)
add_subdirectory(qt-utilities)

View File

@ -0,0 +1,3 @@
add_library(qt_utilities OBJECT src/separate_threaded_renderer.cpp)
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)

View File

@ -0,0 +1,37 @@
#pragma once
#include <cassert>
#include <Qt>
#include <QObject>
#include <QImage>
#include <bgtu/computer_graphics_lab_work/renderer_api/voxel_drawer.hpp>
#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> {
private:
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;
}
}
void setPixelOwner(unsigned x, unsigned y, RendererApi::Sprite<sprite_data_t> 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 {
assert(x < this->width());
assert(y < this->height());
return this->owners[y * this->width() + x];
}
};
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <Qt>
#include <QObject>
#include <QWidget>
#include <QMutex>
#include "owned_qimage.hpp"
#include "separate_threaded_renderer.hpp"
namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
template<class sprite_data_t>
class RendererWidget : public QWidget {
Q_OBJECT
private:
QMutex sync;
OwnedQImage <sprite_data_t> *next_image;
OwnedQImage <sprite_data_t> *current_image;
SeparateThreadedRenderer
};
}

View File

@ -0,0 +1,143 @@
#pragma once
#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::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t)>
class SeparateThreadedRenderer : public QObject {
private:
struct data {
public:
RendererApi::Sprite<sprite_data_t> *const *sprites;
std::size_t sprites_count;
sprite_data_t const *sprite_data;
std::uint_fast64_t ms_per_frame;
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, height;
RendererApi::Projection *projection;
};
class RendererThread : public QThread {
Q_OBJECT
private:
SeparateThreadedRenderer *owner;
public:
explicit inline RendererThread(SeparateThreadedRenderer *owner) : QThread{owner}, owner{owner} {};
protected:
void run() final;
};
volatile data next_data;
QMutex sync;
RendererThread *thread;
QImage *sentinel_img;
renderer_context_t *renderer_context;
public:
explicit SeparateThreadedRenderer(renderer_context_t *renderer_context, QObject *owner = nullptr);
public slots:
void set_frame_size(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t width, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t height);
void set_ms_per_frame(std::uint_fast64_t ms);
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_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);
};
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)>
SeparateThreadedRenderer<sprite_data_t, renderer_context_t, renderer_procedure>::SeparateThreadedRenderer(renderer_context_t *renderer_context, QObject *owner):
QObject{owner},
sync{},
renderer_context{renderer_context},
sentinel_img{new QImage(0, 0, QImage::Format_ARGB32)},
thread{new RendererThread(this)},
next_data{
.sprites = nullptr,
.sprites_count = 0,
.sprite_data = nullptr,
.ms_per_frame = 1000 / 60,
.width = 0,
.height = 0,
.projection = nullptr
} {
}
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)>
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;
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)>
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)>
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;
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)>
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)>
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;
this->next_data.sprites_count = sprites_count;
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)>
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;
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));
}
} catch (std::exception const &e) {
qCritical() << typeid(e).name() << ": " << e.what() << "\n" << "Renderer thread died" << "\n";
}
}
}

View File

@ -0,0 +1,4 @@
#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>

View File

@ -7,6 +7,9 @@
#include "point.hpp"
namespace BGTU::ComputerGraphicsLabWork::RendererApi {
template<class>
class Sprite;
class VoxelDrawer {
public:
using visible_pixel_coordinate_fast_t = std::uint_fast16_t;
@ -22,10 +25,15 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi {
[[nodiscard]] virtual visible_pixel_coordinate_fast_t height() const = 0;
virtual void update_pixel(PointI<2>::component_t x, PointI<2>::component_t y, double z, Color::Transparent c) = 0;
virtual void add_voxel(PointI<2>::component_t x, PointI<2>::component_t y, double z, Color::Transparent c) = 0;
inline void update_pixel(PointI<2> p, double z, Color::Transparent c) {
return this->update_pixel(p.x, p.y, z, c);
inline void add_voxel(PointI<2> p, double z, Color::Transparent c) {
return this->add_voxel(p.x, p.y, z, c);
}
template<class sprite_data_t>
class Exporter {
virtual void set_pixel(PointI<2>::component_t x, PointI<2>::component_t y, Color c, Sprite<sprite_data_t> const* owner) = 0;
};
};
}

View File

@ -1,3 +1,3 @@
add_library(utilities OBJECT src/shader.cpp)
add_library(utilities OBJECT src/shader.cpp src/memory_pages_managment.cpp)
target_include_directories(utilities PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(utilities PUBLIC renderer_api)

View File

@ -0,0 +1,38 @@
#pragma once
#include <climits>
// #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) {
#if 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));
return static_cast<std::uint_fast8_t >((oo + ss) / 256);
};
return RendererApi::Color{
calc(bg.red, fg.red),
calc(bg.green, fg.green),
calc(bg.blue, fg.blue)
};
#else
static __m128i vec_256 = _mm_set_epi16(256, 256, 256, 0, 0, 0, 0, 0);
__m128i vec_bg = _mm_set_epi16(bg.red, bg.green, bg.blue, 0, 0, 0, 0, 0);
__m128i vec_fg = _mm_set_epi16(fg.red, fg.green, fg.blue, 0, 0, 0, 0, 0);
__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)));
std::uint16_t unpacked[3];
} raw;
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
}
}

View File

@ -0,0 +1,300 @@
#pragma once
#include <cstddef>
#include <limits>
#include <new>
#include <vector>
#include <algorithm>
#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>
#include "color.hpp"
#include "matrix.hpp"
namespace BGTU::ComputerGraphicsLabWork {
namespace Utilities {
class DefaultVoxelDrawerLinear : public RendererApi::VoxelDrawer {
private:
class ZElement {
public:
ZElement *next;
double const z;
RendererApi::Color::Transparent const color;
RendererApi::Sprite<void> *const owner;
ZElement(ZElement *next, double z, RendererApi::Color::Transparent color, RendererApi::Sprite<void> *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} {};
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();
};
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;
}
private:
pixel_trace_metadata *at(std::uint_fast16_t x, std::uint_fast16_t y) {
return &(this->pixels_metadata[y * this->_width + x]);
}
public:
void add_voxel(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y, double z, RendererApi::Color::Transparent c) final;
private:
public:
template<class sdata_t>
void export_(RendererApi::Color background, RendererApi::VoxelDrawer::Exporter<sdata_t> *receiver);
void release_resources();
};
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... args_t>
DefaultVoxelDrawerLinear::ZElement *DefaultVoxelDrawerLinear::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...};
}
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) {
if (x < 0 || this->_width <= x) return;
if (y < 0 || this->_height <= y) return;
if (z < 0) return;
auto p = this->at(x, y);
if (z <= p->nearest_z) {
p->nearest_z = z;
#if 1
if (c.alpha == 255) {
ZElement *e;
while (p->voxels != nullptr) {
e = p->voxels;
p->voxels = e->next;
this->allocator.free_elem(e);
}
}
#endif
}
p->voxels = this->allocator.alloc_elem(p->voxels, z, c, this->current_artist);
}
void DefaultVoxelDrawerLinear::release_resources() {
this->allocator.release_resources();
}
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) {
sorter.push_back(e);
}
std::sort(sorter.rbegin(), sorter.rend(), [](ZElement *l, ZElement *r) { return l->z < r->z; });
RendererApi::Color p = background;
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) {
y++;
x = 0;
}
}
}
}
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)>
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;
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
> {
public:
void render(RendererApi::VoxelDrawer::Exporter<sprite_data_t> *, sprite_data_t *, RendererApi::Sprite<sprite_data_t> *const *, std::size_t) {
}
};
#endif
}
}

View File

@ -17,11 +17,9 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
elem_t e20, elem_t e21, elem_t e22
) : data{e00, e01, e02, e10, e11, e12, e20, e21, e22} {}
static inline const Matrix3<elem_t> I{1, 0, 0,
0, 1, 0,
0, 0, 1};
static const Matrix3<elem_t> I;
private:
static inline const Matrix3<elem_t> _tmp{};
static const Matrix3<elem_t> _tmp;
template<class operator_t>
@ -143,17 +141,14 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
elem_t e30, elem_t e31, elem_t e32, elem_t e33
) : data{e00, e01, e02, e03, e10, e11, e12, e13, e20, e21, e22, e23, e30, e31, e32, e33} {}
static inline const Matrix4<elem_t> I{1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
static const Matrix4<elem_t> I;
private:
static inline const Matrix4<elem_t> _tmp{};
static const Matrix4<elem_t> _tmp;
template<class operator_t>
Matrix4<elem_t> _zipmap_matrix(Matrix4<elem_t> const *other, operator_t op) const {
Matrix4<elem_t> dst;
Matrix4 < elem_t > dst;
auto _map_row = [&](std::size_t row_index) {
dst.data[row_index][0] = op(row_index, 0, this->data[row_index][0], other->data[row_index][0]);
dst.data[row_index][1] = op(row_index, 1, this->data[row_index][1], other->data[row_index][1]);
@ -216,10 +211,10 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
}
static Matrix4<elem_t> scale(elem_t x, elem_t y, elem_t z) {
return Matrix4<elem_t>{x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1};
return Matrix4 < elem_t > {x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1};
}
@ -266,6 +261,24 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
}
};
template<class elem_t>
const Matrix3<elem_t> Matrix3<elem_t>::I{1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
template<class elem_t>
const Matrix3<elem_t> Matrix3<elem_t>::_tmp{};
template<class elem_t>
const Matrix4<elem_t> Matrix4<elem_t>::I{1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
template<class elem_t>
const Matrix4<elem_t> Matrix4<elem_t>::_tmp{};
using Matrix4i = Matrix4<int>;
using Matrix4l = Matrix4<long>;
using Matrix4f = Matrix4<float>;

View File

@ -0,0 +1,29 @@
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
#if defined(_WIN32)
#include <cstdlib>
#include <cassert>
#include <new>
#include <Windows.h>
namespace BGTU::ComputerGraphicsLabWork::Utilities {
DefaultVoxelDrawerLinear::ZElementAllocationBuffer::Page *DefaultVoxelDrawerLinear::ZElementAllocationBuffer::_native_extend() {
SYSTEM_INFO si;
GetSystemInfo(&si);
std::size_t size = max(si.dwPageSize, si.dwAllocationGranularity);
void *raw = VirtualAlloc(nullptr, max(si.dwPageSize, si.dwAllocationGranularity), MEM_COMMIT, PAGE_READWRITE);
if (raw != nullptr) throw std::bad_alloc{};
return this->last_page = new(raw)Page(this->last_page, Page::calc_capacity(size));
}
void DefaultVoxelDrawerLinear::ZElementAllocationBuffer::_native_free_page(DefaultVoxelDrawerLinear::ZElementAllocationBuffer::Page *p) {
VirtualFree(p, 0, MEM_DECOMMIT | MEM_RELEASE);
}
}
#else
# error ""
#endif