Drawing square to screen (almost)

This commit is contained in:
Andrew Golovashevich 2024-12-11 09:42:03 +03:00
parent 4dfbe50bb3
commit 73132bbec5
28 changed files with 910 additions and 74 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.25)
project(cg1)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui)
set(CMAKE_AUTOMOC ON)

View File

@ -1,2 +1,16 @@
add_executable(lab1 src/main.cpp src/sprite_data.hpp src/keyboard_catcher_widget.hpp)
add_executable(
lab1
src/main.cpp
src/sprite_data.hpp
src/keyboard_catcher_widget.hpp
src/variants/variant1.cpp
src/variants/variant2.cpp
src/variants/variant3.cpp
src/variants/variant4.cpp
src/variants/variant5.cpp
src/variants/variant6.cpp
src/variants/variant8.cpp
src/variants/variant9.cpp
)
target_link_libraries(lab1 PRIVATE Qt5::Core Qt5::Widgets renderer_api utilities qt_utilities)

View File

@ -18,6 +18,8 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
void key_pressed_PageDown();
void key_pressed_G();
protected:
void keyPressEvent(QKeyEvent *event) override {
switch (event->key()) {
@ -27,6 +29,9 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
case Qt::Key_PageDown:
emit this->key_pressed_PageDown();
return;
case Qt::Key_G:
emit this->key_pressed_G();
return;
}
}

View File

@ -1,7 +1,8 @@
#include <array>
#include <iostream>
#include <QApplication>
#include <QMainWindow>
#include <QTimer>
#include <array>
#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/voxel_painter_exporter_to_packed_array.hpp>
@ -11,27 +12,38 @@
#include "sprite_data.hpp"
#include "keyboard_catcher_widget.hpp"
#include "pixel_grid_sprite.hpp"
#include "variants.hpp"
#include "zoomed_scene_sprite.hpp"
namespace BGTU::ComputerGraphicsLabWork::Lab1 {
volatile RendererApi::Color bg{0, 0, 0};
RendererApi::Color::Transparent fg{255, 255, 255, 127};
int main(int argc, char **argv) {
#if 1
QApplication qApplication{argc, argv};
PixelGridSprite pixels_grid_sprite{RendererApi::Color{0, 0, 0}, RendererApi::Color{32, 32, 32}};
PixelGridSprite pixels_grid_sprite{RendererApi::Color{0, 0, 0}, RendererApi::Color{16, 16, 16}};
ZoomedSceneSprite zoomed_scene_sprite{};
auto sprites = std::to_array<RendererApi::Sprite<Lab1SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl> *const>({
&pixels_grid_sprite
&pixels_grid_sprite,
&zoomed_scene_sprite
});
Lab1SpriteData::Provider sprites_data{1};
sprites_data.set_pixel_size(16);
sprites_data.set_sub_sprites(variant1.sprites, variant1.count);
QMainWindow w{};
KeyboardCatcherWidget kbd{&w};
QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_PageDown, &sprites_data, &Lab1SpriteData::Provider::decrease_pixel_size);
QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_PageUp, &sprites_data, &Lab1SpriteData::Provider::increase_pixel_size);
QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_G, &sprites_data, &Lab1SpriteData::Provider::invert_show_grid);
QtUtilities::SeparateThreadedDefaultRendererLinear<Lab1SpriteData> renderer{};
renderer.set_sprite_data_provider(&sprites_data);
@ -46,6 +58,15 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
QApplication::exec();
return 0;
#else
auto c = Utilities::apply_transparent_color(*(RendererApi::Color*)&bg, fg);
std::cout << c.red << c.green << c.blue << std::endl;
return 0;
#endif
}
}

View File

@ -4,6 +4,7 @@
#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/sprite.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/shapes/rectangle.hpp>
#include "sprite_data.hpp"
@ -15,6 +16,9 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
PixelGridSprite(RendererApi::Color bg, RendererApi::Color fg) : bg{bg}, fg{fg} {};
void draw(Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl *frame, const Lab1SpriteData *data) const override {
if (!data->show_grid)
return;
long long start_x = data->central_pixel_tl.x - ((data->central_pixel_tl.x + data->pixel_size - 1) / data->pixel_size * data->pixel_size);
long long start_y = data->central_pixel_tl.y - ((data->central_pixel_tl.y + data->pixel_size - 1) / data->pixel_size * data->pixel_size);
long long w = frame->width();
@ -26,11 +30,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
for (long long x = start_x; x < w; x += data->pixel_size, x_flag = !x_flag) {
auto c = x_flag ? this->bg : this->fg;
for (long long yy = y + data->pixel_size; yy-- > y;) {
for (long long xx = x + data->pixel_size; xx-- > x;) {
frame->add_voxel(xx, yy, std::numeric_limits<double>::max(), c);
}
}
Utilities::Shapes::fill_rectangle_wh(frame, x, y, data->pixel_size, data->pixel_size, std::numeric_limits<double>::max(), c, c);
}
}
}

View File

@ -4,12 +4,14 @@
#include <cstdlib>
#include <cmath>
#include <numbers>
#include <QObject>
#include <QMutex>
#include <QElapsedTimer>
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/matrix.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/zoomed_voxel_painter.hpp>
namespace BGTU::ComputerGraphicsLabWork::Lab1 {
@ -19,17 +21,37 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
struct Lab1SpriteData {
public:
struct ShapeData {
public:
double rotation_radians;
RendererApi::PointI<2>::component_t radius;
RendererApi::PointI<2>::component_t diameter;
[[nodiscard]] inline RendererApi::PointI<2> pos_rotated(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
double angle_radians = angle_degrees * (std::numbers::pi_v<double> / 180);
return {
(RendererApi::PointI<2>::component_t) (std::cos(this->rotation_radians + angle_radians) * custom_radius),
(RendererApi::PointI<2>::component_t) (std::sin(this->rotation_radians + angle_radians) * custom_radius),
};
}
[[nodiscard]] inline RendererApi::PointI<2> neg_rotated(RendererApi::PointI<2>::component_t custom_radius, double angle_degrees) const {
double angle_radians = angle_degrees * (std::numbers::pi_v<double> / 180);
return {
(RendererApi::PointI<2>::component_t) (std::cos(-this->rotation_radians + angle_radians) * custom_radius),
(RendererApi::PointI<2>::component_t) (std::sin(-this->rotation_radians + angle_radians) * custom_radius),
};
}
};
RendererApi::PointI<2> central_pixel_tl;
std::size_t pixel_size;
bool show_grid;
ShapeData shape_data;
RendererApi::Sprite<ShapeData> **sub_sprites;
RendererApi::Sprite<ShapeData, Utilities::ZoomedVoxelPainter<Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>> *const *sub_sprites;
std::size_t sub_sprites_count;
using Provider = _Lab1SpriteData_Provider;
};
class _Lab1SpriteData_Provider : public QObject, public RendererApi::Sprite<Lab1SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>::SpriteDataProvider {
@ -42,7 +64,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
double radians_per_second;
bool show_grid;
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, h;
RendererApi::Sprite<Lab1SpriteData::ShapeData> **sub_sprites;
RendererApi::Sprite<Lab1SpriteData::ShapeData, Utilities::ZoomedVoxelPainter<Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>> *const *sub_sprites;
std::size_t sub_sprites_count;
public:
@ -54,15 +76,18 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
Lab1SpriteData get_sprite_data() override {
this->sync.lock();
RendererApi::PointI<2>::component_t radius = (((this->w < this->h) ? this->w : this->h) * 7 / 16) / this->pixel_size;
Lab1SpriteData cached{
.central_pixel_tl = (RendererApi::PointI<2>) (RendererApi::PointF<2>(this->w, this->h) / 2.0 - RendererApi::PointF<2>(this->pixel_size, this->pixel_size) / 2.0),
.pixel_size = this->pixel_size,
.show_grid = this->show_grid,
.shape_data = {
.rotation_radians = std::fmod(this->time.elapsed() / 1000.0 * radians_per_second, std::numbers::pi)
.rotation_radians = std::fmod(this->time.elapsed() / 1000.0 * radians_per_second, std::numbers::pi),
.radius = radius,
.diameter = radius * 2
},
.sub_sprites = nullptr,
.sub_sprites_count = 0
.sub_sprites = this->sub_sprites,
.sub_sprites_count = this->sub_sprites_count,
};
this->sync.unlock();
return cached;
@ -101,5 +126,18 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
this->show_grid = f;
this->sync.unlock();
}
void invert_show_grid() {
this->sync.lock();
this->show_grid = !this->show_grid;
this->sync.unlock();
}
void set_sub_sprites(RendererApi::Sprite<Lab1SpriteData::ShapeData, Utilities::ZoomedVoxelPainter<Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>> *const *s, std::size_t c) {
this->sync.lock();
this->sub_sprites = s;
this->sub_sprites_count = c;
this->sync.unlock();
}
};
}

View File

@ -0,0 +1,83 @@
#pragma once
#include <array>
#include <tuple>
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/zoomed_voxel_painter.hpp>
#include "sprite_data.hpp"
namespace BGTU::ComputerGraphicsLabWork::Lab1 {
struct variant_sprites {
private :
using sprite_t = RendererApi::Sprite<Lab1SpriteData::ShapeData, Utilities::ZoomedVoxelPainter<Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>>;
public:
sprite_t *const *const sprites;
std::size_t const count;
constexpr variant_sprites(sprite_t *const *const _sprites, std::size_t _count) : sprites{_sprites}, count{_count}{
}
private:
template<class ...sprites_t>
struct _make {
};
template<>
struct _make<> {
public:
constexpr _make() {};
constexpr void export_pointers(sprite_t **dst, std::size_t pos) {
}
};
template<class e0>
struct _make<e0> {
public:
e0 value;
constexpr _make(e0 v) : value{std::move(v)} {};
constexpr void export_pointers(sprite_t **dst, std::size_t pos) {
dst[pos] = &this->value;
}
};
template<class e0, class ...en>
struct _make<e0, en...> {
public:
e0 value;
_make<en...> next;
constexpr _make(e0 v, en...nv) : value{std::move(v)}, next{nv...} {};
constexpr void export_pointers(sprite_t **dst, std::size_t pos) {
dst[pos] = &this->value;
this->next.export_pointers(dst, pos + 1);
}
};
public:
template<class ...sprites_t>
constexpr static variant_sprites make(sprites_t...sprites) {
static _make<sprites_t...> i{sprites...};
static sprite_t *p[sizeof...(sprites)];
i.export_pointers(p, 0);
return variant_sprites{p, sizeof...(sprites)};
}
};
extern variant_sprites variant1;
extern variant_sprites variant2;
extern variant_sprites variant3;
extern variant_sprites variant4;
extern variant_sprites variant5;
extern variant_sprites variant6;
extern variant_sprites variant8;
extern variant_sprites variant9;
}

View File

@ -0,0 +1,29 @@
#include <tuple>
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/shapes/polygon.hpp>
#include "../variants.hpp"
#include "../sprite_data.hpp"
namespace BGTU::ComputerGraphicsLabWork::Lab1{
namespace Variant1 {
class S1 : public RendererApi::Sprite<Lab1SpriteData::ShapeData, Utilities::ZoomedVoxelPainter<Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>> {
public:
void draw(
BGTU::ComputerGraphicsLabWork::Utilities::ZoomedVoxelPainter<BGTU::ComputerGraphicsLabWork::Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl> *frame,
const BGTU::ComputerGraphicsLabWork::Lab1::Lab1SpriteData::ShapeData *data
) const final {
Utilities::Shapes::draw_polygon_edge(
frame,
{data->neg_rotated(data->radius / 2, 0), data->neg_rotated(data->radius / 2, 90), data->neg_rotated(data->radius / 2, 180), data->neg_rotated(data->radius / 2, 270),},
1,
{255, 0, 0}
);
}
};
}
variant_sprites variant1 = variant_sprites::make(Variant1::S1{});
}

View File

View File

View File

View File

View File

View File

View File

View File

@ -0,0 +1,25 @@
#pragma once
#include <limits>
#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/sprite.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/default_renderer_linear.hpp>
#include "sprite_data.hpp"
namespace BGTU::ComputerGraphicsLabWork::Lab1 {
class ZoomedSceneSprite : public RendererApi::Sprite<Lab1SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl> {
private:
public:
ZoomedSceneSprite() = default;
void draw(Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl *frame, const Lab1SpriteData *data) const override {
Utilities::ZoomedVoxelPainter<Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl> zoomed_painter{frame, data->central_pixel_tl, data->pixel_size};
for (std::size_t i = 0; i < data->sub_sprites_count; i++) {
data->sub_sprites[i]->draw(&zoomed_painter, &data->shape_data);
}
}
};
}

View File

@ -18,7 +18,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
using _SeparateThreadedRenderer_RenderProcedureType = void (renderer_context_t::*)(
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t,
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t,
Utilities::VoxelPainterExporterToRgb32Array *,
Utilities::VoxelPainterExporterToBgr32Array *,
RendererApi::Color,
RendererApi::Sprite<sprite_data_t, renderer_voxel_painter_t> *const *,
std::size_t,

View File

@ -158,7 +158,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
data_t cached = *const_cast<data_t *>(&this->owner->next_data);
this->owner->sync.unlock();
Utilities::VoxelPainterExporterToRgb32Array img{
Utilities::VoxelPainterExporterToBgr32Array img{
cached.width, cached.height,
new unsigned char[cached.width * cached.height * 4],
new RendererApi::SpriteMetadata *[cached.width * cached.height]
@ -206,12 +206,12 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
template<class sprite_data_t>
class SeparateThreadedDefaultRendererLinear : public SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t, Utilities::VoxelPainterExporterToRgb32Array>> {
class SeparateThreadedDefaultRendererLinear : public SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t, Utilities::VoxelPainterExporterToBgr32Array>> {
private:
Utilities::DefaultVoxelDrawerCache context;
public:
explicit SeparateThreadedDefaultRendererLinear(QObject *owner = nullptr) :
SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t, Utilities::VoxelPainterExporterToRgb32Array>>{&this->context, owner}, context{} {};
SeparateThreadedRenderer<sprite_data_t, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl, Utilities::DefaultVoxelDrawerCache, &Utilities::DefaultVoxelDrawerCache::render<sprite_data_t, Utilities::VoxelPainterExporterToBgr32Array>>{&this->context, owner}, context{} {};
~SeparateThreadedDefaultRendererLinear() {
this->shutdown_thread_blocking();

View File

@ -35,7 +35,6 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi {
return Point<2, _component_t>{this->x / other, this->y / other};
}
template<class _self_component_t = _component_t, class sfinae = std::enable_if<std::is_same_v<_self_component_t, long long>, void>::type>
[[nodiscard]] constexpr explicit operator Point<2, double>() const noexcept {
return Point<2, double>{(double) this->x, (double) this->y};
@ -45,6 +44,14 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi {
[[nodiscard]] constexpr explicit operator Point<2, long long>() const noexcept {
return Point<2, long long>{(long long) this->x, (long long) this->y};
}
[[nodiscard]] constexpr bool operator==(Point<2, _component_t> const &other) const noexcept {
return this->x == other.x && this->y == other.y;
}
[[nodiscard]] constexpr bool operator!=(Point<2, _component_t> const &other) const noexcept {
return this->x != other.x || this->y != other.y;
}
};
template<class _component_t>

View File

@ -1,24 +1,139 @@
#pragma once
#include <climits>
#include <emmintrin.h>
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
namespace BGTU::ComputerGraphicsLabWork::Utilities {
inline RendererApi::Color apply_transparent_color(RendererApi::Color bg, RendererApi::Color::Transparent fg) {
#if defined(__AVX512F__)
return _apply_transparent_color_avx512(bg, fg);
#elif 0 && defined(__AVX2__)
return _apply_transparent_color_avx2(bg, fg);
#else
constexpr RendererApi::Color _apply_transparent_color_pure(RendererApi::Color bg, RendererApi::Color::Transparent fg) {
#if 1
if (fg.alpha == 255)
return {fg.red, fg.green, fg.blue};
// pmovzxbd
const std::uint_fast32_t bg_i32[4]{bg.red, bg.green, bg.blue};
const std::uint_fast32_t fg_i32[4]{fg.red, fg.green, fg.blue};
// cvtdq2pd
const float bg_f[4]{(float) bg_i32[0], (float) bg_i32[1], (float) bg_i32[2]};
const float fg_f[4]{(float) fg_i32[0], (float) fg_i32[1], (float) fg_i32[2]};
const float alpha_f = fg.alpha;
const float neg_alpha_f = 255.f - alpha_f;
// mulps
const float bg_alpha[4]{bg_f[0] * neg_alpha_f, bg_f[1] * neg_alpha_f, bg_f[1] * neg_alpha_f};
const float fg_alpha[4]{fg_f[0] * alpha_f, fg_f[1] * alpha_f, fg_f[1] * alpha_f};
// addps
const float sum_f[4]{bg_alpha[0] + fg_alpha[0], bg_alpha[1] + fg_alpha[1], bg_alpha[2] + fg_alpha[2]};
// divps
const float sum_fixed_f[4]{sum_f[0] / 255.f, sum_f[2] / 255.f, sum_f[2] / 255.f};
return {(RendererApi::Color::component_compact_t) sum_fixed_f[0], (RendererApi::Color::component_compact_t) sum_fixed_f[1], (RendererApi::Color::component_compact_t) sum_fixed_f[2]};
#else
return RendererApi::Color{
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.red) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.red) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
static_cast<RendererApi::Color::component_fast_t>(((static_cast<float>(fg.red) * static_cast<float>(fg.alpha) + static_cast<float>(bg.red) * (static_cast<float>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.green) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.green) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.blue) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.blue) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
};
#elif 1
#endif
}
#if defined(_MSC_VER)
# if defined(__AVX512F__)
extern RendererApi::Color _apply_transparent_color_avx512f(RendererApi::Color bg, RendererApi::Color::Transparent fg);
inline RendererApi::Color apply_transparent_color(RendererApi::Color bg, RendererApi::Color::Transparent fg) {
return _apply_transparent_color_avx512f(bg, fg);
}
# pragma comment(linker, "/alternatename:?_apply_transparent_color_avx512f@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z=?_apply_transparent_color_pure@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z")
# elif defined(__AVX2__)
extern RendererApi::Color _apply_transparent_color_avx2(RendererApi::Color bg, RendererApi::Color::Transparent fg);
inline RendererApi::Color apply_transparent_color(RendererApi::Color bg, RendererApi::Color::Transparent fg) {
return _apply_transparent_color_avx2(bg, fg);
}
# pragma comment(linker, "/alternatename:?_apply_transparent_color_avx2@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z=?_apply_transparent_color_pure@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z")
# else
inline RendererApi::Color apply_transparent_color(RendererApi::Color bg, RendererApi::Color::Transparent fg) {
return _apply_transparent_color_pure(bg, fg);
}
# endif
#endif
//?_apply_transparent_color_avx2@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z
// ?apply_transparent_color@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z
#if 0
#if 0
RendererApi::Color apply_transparent_color(RendererApi::Color bg, RendererApi::Color::Transparent fg) {
return _apply_transparent_color_avx2(bg, fg);
if (fg.alpha == 255)
return {fg.red, fg.green, fg.blue};
// pmovzxbd
const std::uint_fast32_t bg_i32[4]{bg.red, bg.green, bg.blue};
const std::uint_fast32_t fg_i32[4]{fg.red, fg.green, fg.blue};
// cvtdq2pd
const float bg_f[4]{(float) bg_i32[0], (float) bg_i32[1], (float) bg_i32[2]};
const float fg_f[4]{(float) fg_i32[0], (float) fg_i32[1], (float) fg_i32[2]};
const float alpha_f = fg.alpha;
const float neg_alpha_f = 255.f - alpha_f;
// mulps
const float bg_alpha[4]{bg_f[0] * neg_alpha_f, bg_f[1] * neg_alpha_f, bg_f[1] * neg_alpha_f};
const float fg_alpha[4]{fg_f[0] * alpha_f, fg_f[1] * alpha_f, fg_f[1] * alpha_f};
// addps
const float sum_f[4]{bg_alpha[0] + fg_alpha[0], bg_alpha[1] + fg_alpha[1], bg_alpha[2] + fg_alpha[2]};
// divps
const float sum_fixed_f[4]{sum_f[0] / 255.f, sum_f[2] / 255.f, sum_f[2] / 255.f};
return {(RendererApi::Color::component_compact_t) sum_fixed_f[0], (RendererApi::Color::component_compact_t) sum_fixed_f[1], (RendererApi::Color::component_compact_t) sum_fixed_f[2]};
#else
return RendererApi::Color{
static_cast<RendererApi::Color::component_fast_t>(((static_cast<float>(fg.red) * static_cast<float>(fg.alpha) + static_cast<float>(bg.red) * (static_cast<float>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.green) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.green) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.blue) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.blue) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
};
/*__m128i bg_vec = _mm_cvtsi32_si128(*(std::int32_t *) &bg);
__m128i fg_vec = _mm_cvtsi32_si128(*(std::int32_t *) &fg);
bg_vec = _mm_cvtepu8_epi16(bg_vec);
fg_vec = _mm_cvtepu8_epi16(fg_vec);
// bg_vec = _mm_cvtepi16_ph(bg_vec);
// fg_vec = _mm_cvtepi16_ph(fg_vec);*/
#if defined(__AVX512F__)
return _apply_transparent_color_avx512(bg, fg);
#elif defined(__AVX2__)
return _apply_transparent_color_avx2(bg, fg);
#else
#if 0
return RendererApi::Color{
static_cast<RendererApi::Color::component_fast_t>(((static_cast<float>(fg.red) * static_cast<float>(fg.alpha) + static_cast<float>(bg.red) * (static_cast<float>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.green) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.green) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
static_cast<RendererApi::Color::component_fast_t>(((static_cast<std::uint_fast16_t>(fg.blue) * static_cast<std::uint_fast16_t>(fg.alpha) + static_cast<std::uint_fast16_t>(bg.blue) * (static_cast<std::uint_fast16_t>(255) - static_cast<std::uint_fast16_t>(fg.alpha))) / 255)),
};
#elif 0
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));
@ -29,7 +144,7 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
calc(bg.green, fg.green),
calc(bg.blue, fg.blue)
};
#else
#elif 0
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);
@ -49,12 +164,18 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
#endif
}
#endif
#endif
namespace PackColor {
inline void color_to_rgb32(unsigned char *buffer, std::size_t offset, RendererApi::Color color) noexcept {
buffer[offset] = color.red;
buffer[offset + 1] = color.green;
buffer[offset + 2] = color.blue;
}
inline void color_to_bgr32(unsigned char *buffer, std::size_t offset, RendererApi::Color color) noexcept {
buffer[offset] = color.blue;
buffer[offset + 1] = color.green;
buffer[offset + 2] = color.red;
}
}
}

View File

@ -3,7 +3,7 @@
#include <cstdlib>
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
namespace BGTU::ComputerGraphicsLabWork::Utilities {
namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
class brezenham_line_iterable {
private:
RendererApi::PointI<2>::component_t start_arg, start_ret, end_arg;
@ -11,7 +11,12 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
RendererApi::PointI<2>::component_t delta_error, error_threshold;
bool swap_flag;
public:
inline brezenham_line_iterable(RendererApi::PointI<2>::component_t x1, RendererApi::PointI<2>::component_t y1, RendererApi::PointI<2>::component_t x2, RendererApi::PointI<2>::component_t y2) {
constexpr brezenham_line_iterable(
RendererApi::PointI<2>::component_t x1,
RendererApi::PointI<2>::component_t y1,
RendererApi::PointI<2>::component_t x2,
RendererApi::PointI<2>::component_t y2
) noexcept {
RendererApi::PointI<2>::component_t delta_x = (x1 > x2) ? (x1 - x2) : (x2 - x1);
RendererApi::PointI<2>::component_t delta_y = (y1 > y2) ? (y1 - y2) : (y2 - y1);
if (delta_x > delta_y) {
@ -33,12 +38,10 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
}
}
struct point {
public:
RendererApi::PointI<2>::component_t x, y;
inline point(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) : x{x}, y{y} {}
};
constexpr brezenham_line_iterable(
RendererApi::PointI<2> start,
RendererApi::PointI<2> end
) noexcept: brezenham_line_iterable{start.x, start.y, end.x, end.y} {}
class iterator {
private:
@ -47,17 +50,17 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
RendererApi::PointI<2>::component_t error, delta_error, error_threshold;
bool swap_flag;
inline iterator(
constexpr iterator(
RendererApi::PointI<2>::component_t arg, RendererApi::PointI<2>::component_t ret, RendererApi::PointI<2>::component_t end_arg,
RendererApi::PointI<2>::component_t delta_ret,
RendererApi::PointI<2>::component_t delta_error, RendererApi::PointI<2>::component_t error_threshold,
bool swap_flag
) : arg{arg}, ret{ret}, end_arg{end_arg}, delta_ret{delta_ret}, error{0}, delta_error{delta_error}, swap_flag{swap_flag}, error_threshold{error_threshold} {}
) noexcept: arg{arg}, ret{ret}, end_arg{end_arg}, delta_ret{delta_ret}, error{0}, delta_error{delta_error}, swap_flag{swap_flag}, error_threshold{error_threshold} {}
friend class brezenham_line_iterable;
public:
inline iterator &operator++() {
constexpr iterator &operator++() noexcept {
this->arg++;
this->error += this->delta_error;
if (this->error >= this->error_threshold) {
@ -67,29 +70,29 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
return *this;
}
inline iterator operator++(int) {
constexpr iterator operator++(int) noexcept {
iterator next = *this;
++(*this);
return next;
}
inline point operator*() const {
constexpr RendererApi::PointI<2> operator*() const noexcept {
if (this->swap_flag)
return point{this->ret, this->arg};
return {this->ret, this->arg};
else
return point{this->arg, this->ret};
return {this->arg, this->ret};
}
inline bool operator==(std::nullptr_t) const {
constexpr bool operator==(std::nullptr_t) const noexcept {
return this->arg > this->end_arg;
}
inline bool operator!=(std::nullptr_t) const {
constexpr bool operator!=(std::nullptr_t) const noexcept {
return this->arg <= this->end_arg;
}
};
[[nodiscard]] inline iterator begin() const {
[[nodiscard]] constexpr iterator begin() const noexcept {
return iterator{
this->start_arg, this->start_ret, this->end_arg,
this->delta_ret,
@ -98,7 +101,7 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
};
}
[[nodiscard]] inline std::nullptr_t end() const {
[[nodiscard]] constexpr std::nullptr_t end() const noexcept {
return nullptr;
}
};

View File

@ -0,0 +1,69 @@
#pragma once
#include <cstdlib>
#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_painter.hpp>
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
#include "../color.hpp"
#include "brezenham.hpp"
namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
template<class receiver_t, std::size_t points_count>
void iterate_polygon_edge(
RendererApi::PointI<2> (&&points)[points_count],
receiver_t receiver
) {
if constexpr (points_count == 0) {
return;
} else if constexpr (points_count == 1) {
receiver(points[0].x, points[0].y);
return;
} else {
receiver(points[0].x, points[0].y);
for (std::size_t i = 1; i < points_count; i++) {
if (points[i - 1] == points[i])
continue;
auto it = brezenham_line_iterable{points[i - 1], points[i]}.begin();
it++;
for (; it != nullptr; it++) {
receiver((*it).x, (*it).y);
}
}
if (points[0] != points[points_count - 1]) {
auto it = brezenham_line_iterable{points[points_count - 1], points[0]}.begin();
it++;
for (; it != nullptr; it++) {
receiver((*it).x, (*it).y);
}
}
}
}
template<std::size_t points_count, class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void draw_polygon_edge(
voxel_painter_t *painter,
RendererApi::PointI<2> (&&points)[points_count],
double z,
RendererApi::Color::Transparent outline
) {
iterate_polygon_edge(
std::move(points),
[=](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, outline); }
);
}
template<std::size_t points_count, class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void draw_polygon_edge(
voxel_painter_t *painter,
RendererApi::PointI<2> (&&points)[points_count],
double z,
RendererApi::Color::Transparent outline,
RendererApi::SpriteMetadata *owner
) {
iterate_polygon_edge(
std::move(points),
[=](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, outline, owner); }
);
}
}

View File

@ -0,0 +1,62 @@
#pragma once
#include <cstdlib>
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
#include <bgtu/computer_graphics_lab_work/renderer_api/voxel_painter.hpp>
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
#include "../color.hpp"
#include "brezenham.hpp"
namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
template<class receiver_t, std::size_t points_count>
void iterate_polyline(
RendererApi::PointI<2> (&&points)[points_count],
receiver_t receiver
) {
if constexpr (points_count == 0) {
return;
} else if constexpr (points_count == 1) {
receiver(points[0].x, points[0].y);
return;
} else {
receiver(points[0].x, points[0].y);
for (std::size_t i = 1; i < points_count; i++) {
if (points[i - 1] == points[i])
continue;
auto it = brezenham_line_iterable{points[i - 1], points[i]}.begin();
it++;
for (; it != nullptr; it++) {
receiver((*it).x, (*it).y);
}
}
}
}
template<std::size_t points_count, class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void draw_polyline_edge(
voxel_painter_t *painter,
RendererApi::PointI<2> (&&points)[points_count],
double z,
RendererApi::Color::Transparent outline
) {
iterate_polyline(
points,
[=](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, outline); }
);
}
template<std::size_t points_count, class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void draw_polyline_edge(
voxel_painter_t *painter,
RendererApi::PointI<2> (&&points)[points_count],
double z,
RendererApi::Color::Transparent outline,
RendererApi::SpriteMetadata *owner
) {
iterate_polyline(
points,
[=](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, outline, owner); }
);
}
}

View File

@ -0,0 +1,272 @@
#pragma once
#include <cstdlib>
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
#include <bgtu/computer_graphics_lab_work/renderer_api/voxel_painter.hpp>
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/color.hpp>
namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
class rectangle_fill_iterable {
private:
RendererApi::PointI<2>::component_t x_start, y_start, x_end, y_end;
constexpr rectangle_fill_iterable(
RendererApi::PointI<2>::component_t x0,
RendererApi::PointI<2>::component_t y0,
RendererApi::PointI<2>::component_t x1,
RendererApi::PointI<2>::component_t y1
) noexcept: x_start{x0}, y_start{y0}, x_end{x1}, y_end{y1} {}
public:
static constexpr rectangle_fill_iterable from_wh(
RendererApi::PointI<2>::component_t x,
RendererApi::PointI<2>::component_t y,
RendererApi::PointI<2>::component_t w,
RendererApi::PointI<2>::component_t h
) noexcept {
return {x, y, x + w, y + h};
}
static constexpr rectangle_fill_iterable from_edges(
RendererApi::PointI<2>::component_t left,
RendererApi::PointI<2>::component_t top,
RendererApi::PointI<2>::component_t right,
RendererApi::PointI<2>::component_t bottom
) noexcept {
return {left, top, right, bottom};
}
class iterator {
private:
RendererApi::PointI<2>::component_t x_start, x_end, y_end;
RendererApi::PointI<2>::component_t x, y;
constexpr iterator(
RendererApi::PointI<2>::component_t x0,
RendererApi::PointI<2>::component_t y0,
RendererApi::PointI<2>::component_t x1,
RendererApi::PointI<2>::component_t y1
) noexcept: x_start{x0}, x_end{x1}, y_end{y1}, x{x0}, y{y0} {}
friend class rectangle_fill_iterable;
public:
constexpr iterator &operator++() noexcept {
if (++this->x > this->x_end) {
if (this->y < this->y_end) {
this->y++;
}
this->x = x_start;
}
return *this;
}
constexpr iterator operator++(int) noexcept {
iterator next = *this;
++(*this);
return next;
}
constexpr RendererApi::PointI<2> operator*() const noexcept {
return {this->x, this->y};
}
constexpr bool operator==(std::nullptr_t) const noexcept {
return this->y >= this->y_end;
}
constexpr bool operator!=(std::nullptr_t) const noexcept {
return this->y < this->y_end;
}
};
[[nodiscard]] constexpr iterator begin() const noexcept {
return iterator{
this->x_start, this->y_start,
this->x_end, this->y_end
};
}
[[nodiscard]] constexpr std::nullptr_t end() const noexcept {
return nullptr;
}
};
template<class receiver_t>
void iterate_rectangle_fill_edges(
RendererApi::PointI<2>::component_t left,
RendererApi::PointI<2>::component_t top,
RendererApi::PointI<2>::component_t right,
RendererApi::PointI<2>::component_t bottom,
receiver_t receiver
) {
for (RendererApi::PointI<2>::component_t x = left; x < right; x++) {
receiver(true, x, top);
}
right--;
bottom--;
for (RendererApi::PointI<2>::component_t y = top; y < bottom; y++) {
RendererApi::PointI<2>::component_t x = left;
receiver(true, x, y);
for (x++; x < right; x++) {
receiver(false, x, y);
}
receiver(true, x, y);
}
bottom++;
for (RendererApi::PointI<2>::component_t x = left; x <= right; x++) {
receiver(true, x, bottom);
}
}
template<class receiver_t>
void iterate_rectangle_fill_wh(
RendererApi::PointI<2>::component_t x,
RendererApi::PointI<2>::component_t y,
RendererApi::PointI<2>::component_t width,
RendererApi::PointI<2>::component_t height,
receiver_t receiver
) {
return iterate_rectangle_fill_edges<receiver_t>(x, y, x + width, y + height, receiver);
}
template<class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void draw_rectangle_edges(
voxel_painter_t *painter,
RendererApi::PointI<2>::component_t left,
RendererApi::PointI<2>::component_t top,
RendererApi::PointI<2>::component_t right,
RendererApi::PointI<2>::component_t bottom,
double z,
RendererApi::Color::Transparent outline
) {
iterate_rectangle_fill_edges(
left, top, right, bottom,
[=](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { if (is_edge) painter->add_voxel(x, y, z, outline); }
);
}
template<class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void draw_rectangle_wh(
voxel_painter_t *painter,
RendererApi::PointI<2>::component_t x,
RendererApi::PointI<2>::component_t y,
RendererApi::PointI<2>::component_t width,
RendererApi::PointI<2>::component_t height,
double z,
RendererApi::Color::Transparent outline
) {
iterate_rectangle_fill_wh(
x, y, width, height,
[=](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { if (is_edge) painter->add_voxel(x, y, z, outline); }
);
}
template<class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void fill_rectangle_edges(
voxel_painter_t *painter,
RendererApi::PointI<2>::component_t left,
RendererApi::PointI<2>::component_t top,
RendererApi::PointI<2>::component_t right,
RendererApi::PointI<2>::component_t bottom,
double z,
RendererApi::Color::Transparent outline,
RendererApi::Color::Transparent fill
) {
iterate_rectangle_fill_edges(
left, top, right, bottom,
[=](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, is_edge ? outline : fill); }
);
}
template<class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void fill_rectangle_wh(
voxel_painter_t *painter,
RendererApi::PointI<2>::component_t x,
RendererApi::PointI<2>::component_t y,
RendererApi::PointI<2>::component_t width,
RendererApi::PointI<2>::component_t height,
double z,
RendererApi::Color::Transparent outline,
RendererApi::Color::Transparent fill
) {
iterate_rectangle_fill_wh(
x, y, width, height,
[=](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, is_edge ? outline : fill); }
);
}
template<class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void draw_rectangle_edges(
voxel_painter_t *painter,
RendererApi::PointI<2>::component_t left,
RendererApi::PointI<2>::component_t top,
RendererApi::PointI<2>::component_t right,
RendererApi::PointI<2>::component_t bottom,
double z,
RendererApi::Color::Transparent outline,
RendererApi::SpriteMetadata *owner
) {
iterate_rectangle_fill_edges(
left, top, right, bottom,
[=](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { if (is_edge) painter->add_voxel(x, y, z, outline, owner); }
);
}
template<class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void draw_rectangle_wh(
voxel_painter_t *painter,
RendererApi::PointI<2>::component_t x,
RendererApi::PointI<2>::component_t y,
RendererApi::PointI<2>::component_t width,
RendererApi::PointI<2>::component_t height,
double z,
RendererApi::Color::Transparent outline,
RendererApi::SpriteMetadata *owner
) {
iterate_rectangle_fill_wh(
x, y, width, height,
[=](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { if (is_edge) painter->add_voxel(x, y, z, outline, owner); }
);
}
template<class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void fill_rectangle_edges(
voxel_painter_t *painter,
RendererApi::PointI<2>::component_t left,
RendererApi::PointI<2>::component_t top,
RendererApi::PointI<2>::component_t right,
RendererApi::PointI<2>::component_t bottom,
double z,
RendererApi::Color::Transparent outline,
RendererApi::Color::Transparent fill,
RendererApi::SpriteMetadata *owner
) {
iterate_rectangle_fill_edges(
left, top, right, bottom,
[=](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, (is_edge ? outline : fill), owner); }
);
}
template<class voxel_painter_t = RendererApi::VirtualVoxelPainter>
void fill_rectangle_wh(
voxel_painter_t *painter,
RendererApi::PointI<2>::component_t x,
RendererApi::PointI<2>::component_t y,
RendererApi::PointI<2>::component_t width,
RendererApi::PointI<2>::component_t height,
double z,
RendererApi::Color::Transparent outline,
RendererApi::Color::Transparent fill,
RendererApi::SpriteMetadata *owner
) {
iterate_rectangle_fill_wh(
x, y, width, height,
[=](bool is_edge, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, (is_edge ? outline : fill), owner); }
);
}
}

View File

@ -4,7 +4,7 @@
#include <utility>
#include <limits>
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
#include "brezenham.hpp"
#include "bgtu/computer_graphics_lab_work/utilities/shapes/brezenham.hpp"
namespace BGTU::ComputerGraphicsLabWork::Utilities {

View File

@ -29,5 +29,5 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
};
};
using VoxelPainterExporterToRgb32Array = VoxelPainterExporterToPackedArray<4, PackColor::color_to_rgb32>;
using VoxelPainterExporterToBgr32Array = VoxelPainterExporterToPackedArray<4, PackColor::color_to_bgr32>;
}

View File

@ -0,0 +1,66 @@
#pragma once
#include <cstdlib>
#include <exception>
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
#include <bgtu/computer_graphics_lab_work/renderer_api/voxel_painter.hpp>
#include <bgtu/computer_graphics_lab_work/renderer_api/sprite.hpp>
#include "shapes/rectangle.hpp"
namespace BGTU::ComputerGraphicsLabWork::Utilities {
template<class unzoomed_painter_t = RendererApi::VirtualVoxelPainter>
class ZoomedVoxelPainter : public RendererApi::VirtualVoxelPainter {
private:
unzoomed_painter_t *dst;
RendererApi::PointI<2>::component_t cx, cy;
std::size_t pixel_size;
public:
constexpr ZoomedVoxelPainter(
unzoomed_painter_t *dst,
RendererApi::PointI<2>::component_t cx,
RendererApi::PointI<2>::component_t cy,
std::size_t pixel_size
) noexcept: dst{dst}, cx{cx}, cy{cy}, pixel_size{pixel_size} {}
constexpr ZoomedVoxelPainter(
unzoomed_painter_t *dst,
RendererApi::PointI<2> center_tl,
std::size_t pixel_size
) noexcept: dst{dst}, cx{center_tl.x}, cy{center_tl.y}, pixel_size{pixel_size} {}
void add_voxel(long long x, long long y, double z, RendererApi::Color::Transparent c) final {
Shapes::fill_rectangle_wh<unzoomed_painter_t>(
this->dst,
this->cx + x * this->pixel_size,
this->cy + y * this->pixel_size,
this->pixel_size,
this->pixel_size,
z,
c, c
);
}
void add_voxel(long long x, long long y, double z, RendererApi::Color::Transparent c, RendererApi::SpriteMetadata *owner) final {
Shapes::fill_rectangle_wh<unzoomed_painter_t>(
this->dst,
this->cx + x * this->pixel_size,
this->cy + y * this->pixel_size,
this->pixel_size,
this->pixel_size,
z,
c, c,
owner
);
}
[[nodiscard]] constexpr visible_pixel_coordinate_fast_t width() const override {
throw std::exception{"This wrapper doesn't provides such information"};
return 0;
}
[[nodiscard]] constexpr visible_pixel_coordinate_fast_t height() const override {
throw std::exception{"This wrapper doesn't provides such information"};
return 0;
}
};
}

View File

@ -14,23 +14,24 @@
%macro impl_body 1
%ifidn __OUTPUT_FORMAT__, elf64
movd xmm0, edi
movd xmm1, esi
shr esi, 24
cmp r8d, 255
je %%not_opaque
movd xmm0, edi
mov r8d, esi
%elifidn __OUTPUT_FORMAT__, win64
; movzx r9d, WORD [rdx]
; movzx r10d, BYTE [rdx+2]
; shl r10d, 16
; or r9d, r10d
movd xmm0, DWORD [rdx]
movd xmm1, r8d
shr r8d, 24
cmp r8d, 255
je %%not_opaque
movd xmm0, DWORD [rdx]
%else
%error "Unsupported output format"
%endif
pmovzxbd xmm0, xmm0 ; 0-extend 8bit->32bit
pmovzxbd xmm1, xmm1 ; 0-extend 8bit->32bit
shr r8d, 24
pmovzxbd xmm0, xmm0 ; 0-extend 8bit->32bit SSE4.1
pmovzxbd xmm1, xmm1 ; 0-extend 8bit->32bit SSE4.1
%if %1 >= __AVX512F__
vpbroadcastd xmm2, r8d ; fill vector with 32bit values
%elif %1 >= __AVX2__
@ -44,12 +45,19 @@
movd xmm3, r8d
vpbroadcastd xmm3, xmm3
%endif
cvtdq2ps xmm0, xmm0 ; i32 -> float SSE2
cvtdq2ps xmm1, xmm1 ; i32 -> float SSE2
cvtdq2ps xmm2, xmm2 ; i32 -> float SSE2
cvtdq2ps xmm3, xmm3 ; i32 -> float SSE2
movups xmm4, xmm3
psubd xmm3, xmm2 ; sub 32bit integers
pmuludq xmm0, xmm3 ; mul unsigned 32bit integers
pmuludq xmm1, xmm2 ; mul unsigned 32bit integers
paddd xmm0, xmm1 ; add 32bit integers
psrld xmm0, 8 ; 0-shift 32bit integers right
subps xmm3, xmm2
mulps xmm0, xmm3
mulps xmm1, xmm2
addps xmm0, xmm1
divps xmm0, xmm4
cvttps2dq xmm0, xmm0
pextrd r9d, xmm0, 0 ; extracts 32 bit integer
pextrd r10d, xmm0, 1 ; extracts 32 bit integer
@ -60,11 +68,21 @@
or r9d, r11d
%ifidn __OUTPUT_FORMAT__, elf64
mov eax, r9d
movd eax, r9d
%elifidn __OUTPUT_FORMAT__, win64
mov DWORD [rcx], r9d
%else
%error "Unsupported output format"
%endif
ret
%%not_opaque:
%ifidn __OUTPUT_FORMAT__, elf64
movd eax, xmm1
%elifidn __OUTPUT_FORMAT__, win64
movd DWORD [rcx], xmm1
%else
%error "Unsupported output format"
%endif
ret
%endmacro
@ -75,7 +93,10 @@ section .text
; avx2
global ?_apply_transparent_color_avx2@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z ; msvc
global ?_apply_transparent_color_avx512f@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z ; msvc
?_apply_transparent_color_avx512f@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z:
impl_body __AVX512F__
global ?_apply_transparent_color_avx2@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z ; msvc
?_apply_transparent_color_avx2@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z:
impl_body __AVX2__