Drawing square to screen (almost)
This commit is contained in:
parent
4dfbe50bb3
commit
73132bbec5
@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(cg1)
|
project(cg1)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui)
|
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
@ -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)
|
target_link_libraries(lab1 PRIVATE Qt5::Core Qt5::Widgets renderer_api utilities qt_utilities)
|
||||||
|
@ -18,6 +18,8 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
|||||||
|
|
||||||
void key_pressed_PageDown();
|
void key_pressed_PageDown();
|
||||||
|
|
||||||
|
void key_pressed_G();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent *event) override {
|
void keyPressEvent(QKeyEvent *event) override {
|
||||||
switch (event->key()) {
|
switch (event->key()) {
|
||||||
@ -27,6 +29,9 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
|||||||
case Qt::Key_PageDown:
|
case Qt::Key_PageDown:
|
||||||
emit this->key_pressed_PageDown();
|
emit this->key_pressed_PageDown();
|
||||||
return;
|
return;
|
||||||
|
case Qt::Key_G:
|
||||||
|
emit this->key_pressed_G();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
#include <array>
|
||||||
|
#include <iostream>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <array>
|
|
||||||
#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/utilities/voxel_painter_exporter_to_packed_array.hpp>
|
#include <bgtu/computer_graphics_lab_work/utilities/voxel_painter_exporter_to_packed_array.hpp>
|
||||||
@ -11,27 +12,38 @@
|
|||||||
#include "sprite_data.hpp"
|
#include "sprite_data.hpp"
|
||||||
#include "keyboard_catcher_widget.hpp"
|
#include "keyboard_catcher_widget.hpp"
|
||||||
#include "pixel_grid_sprite.hpp"
|
#include "pixel_grid_sprite.hpp"
|
||||||
|
#include "variants.hpp"
|
||||||
|
#include "zoomed_scene_sprite.hpp"
|
||||||
|
|
||||||
namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
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) {
|
int main(int argc, char **argv) {
|
||||||
|
#if 1
|
||||||
QApplication qApplication{argc, argv};
|
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>({
|
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};
|
Lab1SpriteData::Provider sprites_data{1};
|
||||||
sprites_data.set_pixel_size(16);
|
sprites_data.set_pixel_size(16);
|
||||||
|
sprites_data.set_sub_sprites(variant1.sprites, variant1.count);
|
||||||
|
|
||||||
QMainWindow w{};
|
QMainWindow w{};
|
||||||
|
|
||||||
KeyboardCatcherWidget kbd{&w};
|
KeyboardCatcherWidget kbd{&w};
|
||||||
QObject::connect(&kbd, &KeyboardCatcherWidget::key_pressed_PageDown, &sprites_data, &Lab1SpriteData::Provider::decrease_pixel_size);
|
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_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{};
|
QtUtilities::SeparateThreadedDefaultRendererLinear<Lab1SpriteData> renderer{};
|
||||||
renderer.set_sprite_data_provider(&sprites_data);
|
renderer.set_sprite_data_provider(&sprites_data);
|
||||||
@ -46,6 +58,15 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
|||||||
QApplication::exec();
|
QApplication::exec();
|
||||||
|
|
||||||
return 0;
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#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/renderer_api/point.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/renderer_api/sprite.hpp>
|
||||||
|
#include <bgtu/computer_graphics_lab_work/utilities/shapes/rectangle.hpp>
|
||||||
#include "sprite_data.hpp"
|
#include "sprite_data.hpp"
|
||||||
|
|
||||||
|
|
||||||
@ -15,6 +16,9 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
|||||||
PixelGridSprite(RendererApi::Color bg, RendererApi::Color fg) : bg{bg}, fg{fg} {};
|
PixelGridSprite(RendererApi::Color bg, RendererApi::Color fg) : bg{bg}, fg{fg} {};
|
||||||
|
|
||||||
void draw(Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl *frame, const Lab1SpriteData *data) const override {
|
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_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 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();
|
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) {
|
for (long long x = start_x; x < w; x += data->pixel_size, x_flag = !x_flag) {
|
||||||
auto c = x_flag ? this->bg : this->fg;
|
auto c = x_flag ? this->bg : this->fg;
|
||||||
|
|
||||||
for (long long yy = y + data->pixel_size; yy-- > y;) {
|
Utilities::Shapes::fill_rectangle_wh(frame, x, y, data->pixel_size, data->pixel_size, std::numeric_limits<double>::max(), c, c);
|
||||||
for (long long xx = x + data->pixel_size; xx-- > x;) {
|
|
||||||
frame->add_voxel(xx, yy, std::numeric_limits<double>::max(), c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
|
#include <QObject>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
#include <bgtu/computer_graphics_lab_work/renderer_api/point.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/renderer_api/sprite.hpp>
|
||||||
#include <bgtu/computer_graphics_lab_work/utilities/matrix.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/default_renderer_linear.hpp>
|
||||||
|
#include <bgtu/computer_graphics_lab_work/utilities/zoomed_voxel_painter.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
||||||
@ -19,17 +21,37 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
|||||||
struct Lab1SpriteData {
|
struct Lab1SpriteData {
|
||||||
public:
|
public:
|
||||||
struct ShapeData {
|
struct ShapeData {
|
||||||
|
public:
|
||||||
double rotation_radians;
|
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;
|
RendererApi::PointI<2> central_pixel_tl;
|
||||||
std::size_t pixel_size;
|
std::size_t pixel_size;
|
||||||
bool show_grid;
|
bool show_grid;
|
||||||
ShapeData shape_data;
|
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;
|
std::size_t sub_sprites_count;
|
||||||
|
|
||||||
using Provider = _Lab1SpriteData_Provider;
|
using Provider = _Lab1SpriteData_Provider;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class _Lab1SpriteData_Provider : public QObject, public RendererApi::Sprite<Lab1SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>::SpriteDataProvider {
|
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;
|
double radians_per_second;
|
||||||
bool show_grid;
|
bool show_grid;
|
||||||
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, h;
|
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;
|
std::size_t sub_sprites_count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -54,15 +76,18 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
|||||||
|
|
||||||
Lab1SpriteData get_sprite_data() override {
|
Lab1SpriteData get_sprite_data() override {
|
||||||
this->sync.lock();
|
this->sync.lock();
|
||||||
|
RendererApi::PointI<2>::component_t radius = (((this->w < this->h) ? this->w : this->h) * 7 / 16) / this->pixel_size;
|
||||||
Lab1SpriteData cached{
|
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),
|
.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,
|
.pixel_size = this->pixel_size,
|
||||||
.show_grid = this->show_grid,
|
.show_grid = this->show_grid,
|
||||||
.shape_data = {
|
.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 = this->sub_sprites,
|
||||||
.sub_sprites_count = 0
|
.sub_sprites_count = this->sub_sprites_count,
|
||||||
};
|
};
|
||||||
this->sync.unlock();
|
this->sync.unlock();
|
||||||
return cached;
|
return cached;
|
||||||
@ -101,5 +126,18 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 {
|
|||||||
this->show_grid = f;
|
this->show_grid = f;
|
||||||
this->sync.unlock();
|
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();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
83
programs/lab1/src/variants.hpp
Normal file
83
programs/lab1/src/variants.hpp
Normal 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;
|
||||||
|
}
|
29
programs/lab1/src/variants/variant1.cpp
Normal file
29
programs/lab1/src/variants/variant1.cpp
Normal 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{});
|
||||||
|
}
|
0
programs/lab1/src/variants/variant2.cpp
Normal file
0
programs/lab1/src/variants/variant2.cpp
Normal file
0
programs/lab1/src/variants/variant3.cpp
Normal file
0
programs/lab1/src/variants/variant3.cpp
Normal file
0
programs/lab1/src/variants/variant4.cpp
Normal file
0
programs/lab1/src/variants/variant4.cpp
Normal file
0
programs/lab1/src/variants/variant5.cpp
Normal file
0
programs/lab1/src/variants/variant5.cpp
Normal file
0
programs/lab1/src/variants/variant6.cpp
Normal file
0
programs/lab1/src/variants/variant6.cpp
Normal file
0
programs/lab1/src/variants/variant8.cpp
Normal file
0
programs/lab1/src/variants/variant8.cpp
Normal file
0
programs/lab1/src/variants/variant9.cpp
Normal file
0
programs/lab1/src/variants/variant9.cpp
Normal file
25
programs/lab1/src/zoomed_scene_sprite.hpp
Normal file
25
programs/lab1/src/zoomed_scene_sprite.hpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -18,7 +18,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
|||||||
using _SeparateThreadedRenderer_RenderProcedureType = void (renderer_context_t::*)(
|
using _SeparateThreadedRenderer_RenderProcedureType = void (renderer_context_t::*)(
|
||||||
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t,
|
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t,
|
||||||
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t,
|
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t,
|
||||||
Utilities::VoxelPainterExporterToRgb32Array *,
|
Utilities::VoxelPainterExporterToBgr32Array *,
|
||||||
RendererApi::Color,
|
RendererApi::Color,
|
||||||
RendererApi::Sprite<sprite_data_t, renderer_voxel_painter_t> *const *,
|
RendererApi::Sprite<sprite_data_t, renderer_voxel_painter_t> *const *,
|
||||||
std::size_t,
|
std::size_t,
|
||||||
|
@ -158,7 +158,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
|||||||
data_t cached = *const_cast<data_t *>(&this->owner->next_data);
|
data_t cached = *const_cast<data_t *>(&this->owner->next_data);
|
||||||
this->owner->sync.unlock();
|
this->owner->sync.unlock();
|
||||||
|
|
||||||
Utilities::VoxelPainterExporterToRgb32Array img{
|
Utilities::VoxelPainterExporterToBgr32Array img{
|
||||||
cached.width, cached.height,
|
cached.width, cached.height,
|
||||||
new unsigned char[cached.width * cached.height * 4],
|
new unsigned char[cached.width * cached.height * 4],
|
||||||
new RendererApi::SpriteMetadata *[cached.width * cached.height]
|
new RendererApi::SpriteMetadata *[cached.width * cached.height]
|
||||||
@ -206,12 +206,12 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
|
|||||||
|
|
||||||
|
|
||||||
template<class sprite_data_t>
|
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:
|
private:
|
||||||
Utilities::DefaultVoxelDrawerCache context;
|
Utilities::DefaultVoxelDrawerCache context;
|
||||||
public:
|
public:
|
||||||
explicit SeparateThreadedDefaultRendererLinear(QObject *owner = nullptr) :
|
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() {
|
~SeparateThreadedDefaultRendererLinear() {
|
||||||
this->shutdown_thread_blocking();
|
this->shutdown_thread_blocking();
|
||||||
|
@ -19,23 +19,22 @@ namespace BGTU::ComputerGraphicsLabWork::RendererApi {
|
|||||||
|
|
||||||
constexpr Point(component_t x, component_t y) : x{x}, y{y} {}
|
constexpr Point(component_t x, component_t y) : x{x}, y{y} {}
|
||||||
|
|
||||||
[[nodiscard]] constexpr Point<2, _component_t> operator+(Point<2, _component_t> const &other) const noexcept {
|
[[nodiscard]] constexpr Point<2, _component_t> operator+(Point<2, _component_t> const &other) const noexcept {
|
||||||
return Point<2, _component_t>{this->x + other.x, this->y + other.y};
|
return Point<2, _component_t>{this->x + other.x, this->y + other.y};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr Point<2, _component_t> operator-(Point<2, _component_t> const &other) const noexcept {
|
[[nodiscard]] constexpr Point<2, _component_t> operator-(Point<2, _component_t> const &other) const noexcept {
|
||||||
return Point<2, _component_t>{this->x - other.x, this->y - other.y};
|
return Point<2, _component_t>{this->x - other.x, this->y - other.y};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr Point<2, _component_t> operator*(_component_t const &other) const noexcept {
|
[[nodiscard]] constexpr Point<2, _component_t> operator*(_component_t const &other) const noexcept {
|
||||||
return Point<2, _component_t>{this->x * other, this->y * other};
|
return Point<2, _component_t>{this->x * other, this->y * other};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] constexpr Point<2, _component_t> operator/(_component_t const &other) const noexcept {
|
[[nodiscard]] constexpr Point<2, _component_t> operator/(_component_t const &other) const noexcept {
|
||||||
return Point<2, _component_t>{this->x / other, this->y / other};
|
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>
|
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 {
|
[[nodiscard]] constexpr explicit operator Point<2, double>() const noexcept {
|
||||||
return Point<2, double>{(double) this->x, (double) this->y};
|
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 {
|
[[nodiscard]] constexpr explicit operator Point<2, long long>() const noexcept {
|
||||||
return Point<2, long long>{(long long) this->x, (long long) this->y};
|
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>
|
template<class _component_t>
|
||||||
|
@ -1,24 +1,139 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <emmintrin.h>
|
|
||||||
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
|
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||||
inline RendererApi::Color apply_transparent_color(RendererApi::Color bg, RendererApi::Color::Transparent fg) {
|
constexpr RendererApi::Color _apply_transparent_color_pure(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
|
|
||||||
#if 1
|
#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{
|
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.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)),
|
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) {
|
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 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));
|
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.green, fg.green),
|
||||||
calc(bg.blue, fg.blue)
|
calc(bg.blue, fg.blue)
|
||||||
};
|
};
|
||||||
#else
|
#elif 0
|
||||||
static __m128i vec_256 = _mm_set_epi16(256, 256, 256, 0, 0, 0, 0, 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_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_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
|
||||||
|
#endif
|
||||||
namespace PackColor {
|
namespace PackColor {
|
||||||
inline void color_to_rgb32(unsigned char *buffer, std::size_t offset, RendererApi::Color color) noexcept{
|
inline void color_to_rgb32(unsigned char *buffer, std::size_t offset, RendererApi::Color color) noexcept {
|
||||||
buffer[offset] = color.red;
|
buffer[offset] = color.red;
|
||||||
buffer[offset + 1] = color.green;
|
buffer[offset + 1] = color.green;
|
||||||
buffer[offset + 2] = color.blue;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,7 +3,7 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
|
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
|
||||||
|
|
||||||
namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes {
|
||||||
class brezenham_line_iterable {
|
class brezenham_line_iterable {
|
||||||
private:
|
private:
|
||||||
RendererApi::PointI<2>::component_t start_arg, start_ret, end_arg;
|
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;
|
RendererApi::PointI<2>::component_t delta_error, error_threshold;
|
||||||
bool swap_flag;
|
bool swap_flag;
|
||||||
public:
|
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_x = (x1 > x2) ? (x1 - x2) : (x2 - x1);
|
||||||
RendererApi::PointI<2>::component_t delta_y = (y1 > y2) ? (y1 - y2) : (y2 - y1);
|
RendererApi::PointI<2>::component_t delta_y = (y1 > y2) ? (y1 - y2) : (y2 - y1);
|
||||||
if (delta_x > delta_y) {
|
if (delta_x > delta_y) {
|
||||||
@ -33,12 +38,10 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct point {
|
constexpr brezenham_line_iterable(
|
||||||
public:
|
RendererApi::PointI<2> start,
|
||||||
RendererApi::PointI<2>::component_t x, y;
|
RendererApi::PointI<2> end
|
||||||
|
) noexcept: brezenham_line_iterable{start.x, start.y, end.x, end.y} {}
|
||||||
inline point(RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) : x{x}, y{y} {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class iterator {
|
class iterator {
|
||||||
private:
|
private:
|
||||||
@ -47,17 +50,17 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
|||||||
RendererApi::PointI<2>::component_t error, delta_error, error_threshold;
|
RendererApi::PointI<2>::component_t error, delta_error, error_threshold;
|
||||||
bool swap_flag;
|
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 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_ret,
|
||||||
RendererApi::PointI<2>::component_t delta_error, RendererApi::PointI<2>::component_t error_threshold,
|
RendererApi::PointI<2>::component_t delta_error, RendererApi::PointI<2>::component_t error_threshold,
|
||||||
bool swap_flag
|
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;
|
friend class brezenham_line_iterable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline iterator &operator++() {
|
constexpr iterator &operator++() noexcept {
|
||||||
this->arg++;
|
this->arg++;
|
||||||
this->error += this->delta_error;
|
this->error += this->delta_error;
|
||||||
if (this->error >= this->error_threshold) {
|
if (this->error >= this->error_threshold) {
|
||||||
@ -67,29 +70,29 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline iterator operator++(int) {
|
constexpr iterator operator++(int) noexcept {
|
||||||
iterator next = *this;
|
iterator next = *this;
|
||||||
++(*this);
|
++(*this);
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline point operator*() const {
|
constexpr RendererApi::PointI<2> operator*() const noexcept {
|
||||||
if (this->swap_flag)
|
if (this->swap_flag)
|
||||||
return point{this->ret, this->arg};
|
return {this->ret, this->arg};
|
||||||
else
|
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;
|
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;
|
return this->arg <= this->end_arg;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] inline iterator begin() const {
|
[[nodiscard]] constexpr iterator begin() const noexcept {
|
||||||
return iterator{
|
return iterator{
|
||||||
this->start_arg, this->start_ret, this->end_arg,
|
this->start_arg, this->start_ret, this->end_arg,
|
||||||
this->delta_ret,
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -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); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -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); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -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); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <bgtu/computer_graphics_lab_work/renderer_api/point.hpp>
|
#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 {
|
namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
||||||
|
|
||||||
|
@ -29,5 +29,5 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
using VoxelPainterExporterToRgb32Array = VoxelPainterExporterToPackedArray<4, PackColor::color_to_rgb32>;
|
using VoxelPainterExporterToBgr32Array = VoxelPainterExporterToPackedArray<4, PackColor::color_to_bgr32>;
|
||||||
}
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -14,23 +14,24 @@
|
|||||||
|
|
||||||
%macro impl_body 1
|
%macro impl_body 1
|
||||||
%ifidn __OUTPUT_FORMAT__, elf64
|
%ifidn __OUTPUT_FORMAT__, elf64
|
||||||
movd xmm0, edi
|
|
||||||
movd xmm1, esi
|
movd xmm1, esi
|
||||||
|
shr esi, 24
|
||||||
|
cmp r8d, 255
|
||||||
|
je %%not_opaque
|
||||||
|
movd xmm0, edi
|
||||||
mov r8d, esi
|
mov r8d, esi
|
||||||
%elifidn __OUTPUT_FORMAT__, win64
|
%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
|
movd xmm1, r8d
|
||||||
|
shr r8d, 24
|
||||||
|
cmp r8d, 255
|
||||||
|
je %%not_opaque
|
||||||
|
movd xmm0, DWORD [rdx]
|
||||||
%else
|
%else
|
||||||
%error "Unsupported output format"
|
%error "Unsupported output format"
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
pmovzxbd xmm0, xmm0 ; 0-extend 8bit->32bit
|
pmovzxbd xmm0, xmm0 ; 0-extend 8bit->32bit SSE4.1
|
||||||
pmovzxbd xmm1, xmm1 ; 0-extend 8bit->32bit
|
pmovzxbd xmm1, xmm1 ; 0-extend 8bit->32bit SSE4.1
|
||||||
shr r8d, 24
|
|
||||||
%if %1 >= __AVX512F__
|
%if %1 >= __AVX512F__
|
||||||
vpbroadcastd xmm2, r8d ; fill vector with 32bit values
|
vpbroadcastd xmm2, r8d ; fill vector with 32bit values
|
||||||
%elif %1 >= __AVX2__
|
%elif %1 >= __AVX2__
|
||||||
@ -44,12 +45,19 @@
|
|||||||
movd xmm3, r8d
|
movd xmm3, r8d
|
||||||
vpbroadcastd xmm3, xmm3
|
vpbroadcastd xmm3, xmm3
|
||||||
%endif
|
%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
|
subps xmm3, xmm2
|
||||||
pmuludq xmm0, xmm3 ; mul unsigned 32bit integers
|
mulps xmm0, xmm3
|
||||||
pmuludq xmm1, xmm2 ; mul unsigned 32bit integers
|
mulps xmm1, xmm2
|
||||||
paddd xmm0, xmm1 ; add 32bit integers
|
addps xmm0, xmm1
|
||||||
psrld xmm0, 8 ; 0-shift 32bit integers right
|
divps xmm0, xmm4
|
||||||
|
|
||||||
|
cvttps2dq xmm0, xmm0
|
||||||
|
|
||||||
pextrd r9d, xmm0, 0 ; extracts 32 bit integer
|
pextrd r9d, xmm0, 0 ; extracts 32 bit integer
|
||||||
pextrd r10d, xmm0, 1 ; extracts 32 bit integer
|
pextrd r10d, xmm0, 1 ; extracts 32 bit integer
|
||||||
@ -60,11 +68,21 @@
|
|||||||
or r9d, r11d
|
or r9d, r11d
|
||||||
|
|
||||||
%ifidn __OUTPUT_FORMAT__, elf64
|
%ifidn __OUTPUT_FORMAT__, elf64
|
||||||
mov eax, r9d
|
movd eax, r9d
|
||||||
%elifidn __OUTPUT_FORMAT__, win64
|
%elifidn __OUTPUT_FORMAT__, win64
|
||||||
mov DWORD [rcx], r9d
|
mov DWORD [rcx], r9d
|
||||||
%else
|
%else
|
||||||
%error "Unsupported output format"
|
%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
|
%endif
|
||||||
ret
|
ret
|
||||||
%endmacro
|
%endmacro
|
||||||
@ -75,7 +93,10 @@ section .text
|
|||||||
|
|
||||||
; avx2
|
; 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:
|
?_apply_transparent_color_avx2@Utilities@ComputerGraphicsLabWork@BGTU@@YA?AVColor@RendererApi@23@V4523@VTransparent@4523@@Z:
|
||||||
impl_body __AVX2__
|
impl_body __AVX2__
|
Loading…
Reference in New Issue
Block a user