Sun sprite

This commit is contained in:
Andrew Golovashevich 2024-12-25 12:50:35 +03:00
parent bcb08b7cc5
commit 4a9ed23ab9
8 changed files with 281 additions and 4 deletions

View File

@ -20,3 +20,4 @@ add_subdirectory(renderer-api)
add_subdirectory(utilities)
add_subdirectory(qt-utilities)
add_subdirectory(programs/labs1_2)
add_subdirectory(programs/lab3)

View File

@ -0,0 +1,9 @@
add_executable(
lab3
src/main.cpp
src/sprite_data.hpp
src/variant1.cpp
)
target_link_libraries(lab3 PRIVATE Qt5::Core Qt5::Widgets renderer_api utilities qt_utilities)

View File

@ -0,0 +1,59 @@
#include <cmath>
#include <array>
#include <iostream>
#include <QApplication>
#include <QMainWindow>
#include <QTimer>
#include <bgtu/computer_graphics_lab_work/renderer_api/color.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/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/matrix.hpp>
#include <bgtu/computer_graphics_lab_work/qt_utilities/separate_threaded_renderer.hpp>
#include <bgtu/computer_graphics_lab_work/qt_utilities/renderer_widget.hpp>
#include <bgtu/computer_graphics_lab_work/qt_utilities/keyboard_catcher_widget.hpp>
#include "sprite_data.hpp"
#include "variant1.hpp"
namespace BGTU::ComputerGraphicsLabWork::Impl {
int main(int argc, char **argv) {
#if 1
QApplication qApplication{argc, argv};
SpriteData::Provider sprites_data{0.1};
QMainWindow w{};
QtUtilities::KeyboardCatcherWidget kbd{&w};
QtUtilities::SeparateThreadedDefaultRendererLinear<SpriteData> renderer{};
renderer.set_sprite_data_provider(&sprites_data);
renderer.set_sprites(sprites, sprites_count);
renderer.set_background(BGTU::ComputerGraphicsLabWork::RendererApi::Color{0, 0, 0});
QtUtilities::RendererWidget<SpriteData> canvas{&renderer, &kbd};
QObject::connect(&canvas, &QtUtilities::_RendererWidget_SignalSlots::resized, &sprites_data, &SpriteData::Provider::set_frame_size);
w.setCentralWidget(&canvas);
w.show();
QApplication::exec();
return 0;
#else
Utilities::Matrix3d x = Utilities::Matrix3d::shift(10, 10);
Utilities::Matrix3d y = x.inversed();
RendererApi::PointF<2> a{0, 0};
RendererApi::PointF<2> b = x * a;
RendererApi::PointF<2> c = y * a;
RendererApi::PointF<2> d = y * b;
return 0;
#endif
}
}
int main(int argc, char **argv) {
return BGTU::ComputerGraphicsLabWork::Impl::main(argc, argv);
}

View File

@ -0,0 +1,81 @@
#pragma once
#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::Impl {
class _Lab3SpriteData_Provider;
struct SpriteData {
public:
RendererApi::PointI<2> central_pixel;
double radius_multiplier;
Utilities::Matrix3d planets_transform[9];
Utilities::Matrix3d stars_transform;
double time_ms;
using Provider = _Lab3SpriteData_Provider;
};
class _Lab3SpriteData_Provider : public QObject, public RendererApi::Sprite<SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl>::SpriteDataProvider {
Q_OBJECT
private:
QMutex sync;
QElapsedTimer time;
RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t w, h;
public:
explicit _Lab3SpriteData_Provider(double radians_per_second) :
sync{}, time{},
w{0}, h{0} {}
SpriteData get_sprite_data() override {
this->sync.lock();
double radius = (((this->w < this->h) ? this->w : this->h) * 5 / 16.0);
Utilities::Matrix3d center_shift = Utilities::Matrix3d::shift(this->w / 2, this->h / 2);
Utilities::Matrix3d scale = Utilities::Matrix3d::scale(radius);
double current_time = this->time.elapsed();
SpriteData cached{
.central_pixel = RendererApi::PointI<2>(this->w, this->h) / 2,
.radius_multiplier = radius,
.planets_transform = {
center_shift * Utilities::Matrix3d::scale(radius),
center_shift * scale * Utilities::Matrix3d::rotate(current_time / 1000.0 * 1.5),
center_shift * scale * Utilities::Matrix3d::rotate(current_time / 1000.0 * 1.2),
center_shift * scale * Utilities::Matrix3d::rotate(current_time / 1000.0 * 1),
center_shift * scale * Utilities::Matrix3d::rotate(current_time / 1000.0 * 0.9),
center_shift * scale * Utilities::Matrix3d::rotate(current_time / 1000.0 * 0.5),
center_shift * scale * Utilities::Matrix3d::rotate(current_time / 1000.0 * 0.45),
center_shift * scale * Utilities::Matrix3d::rotate(current_time / 1000.0 * 0.2),
center_shift * scale * Utilities::Matrix3d::rotate(current_time / 1000.0 * 0.17),
},
.stars_transform = Utilities::Matrix3d::rotate(current_time / 1000.0 * 0.02) * scale * center_shift,
.time_ms = current_time
};
this->sync.unlock();
return cached;
}
public slots:
void set_frame_size(RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t ww, RendererApi::VirtualVoxelPainter::visible_pixel_coordinate_fast_t hh) {
this->sync.lock();
this->w = ww;
this->h = hh;
this->sync.unlock();
}
};
}

View File

@ -0,0 +1,76 @@
#include <utility>
#include <bgtu/computer_graphics_lab_work/utilities/shader.hpp>
#include <bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp>
#include "variant1.hpp"
namespace BGTU::ComputerGraphicsLabWork::Impl {
namespace {
template<class real_shader_t>
class TransformedShader : public Utilities::Shader {
private:
Utilities::Matrix3d transform;
real_shader_t real_shader;
public:
TransformedShader(Utilities::Matrix3d transform, real_shader_t real_shader) : transform{transform}, real_shader{real_shader} {};
[[nodiscard]] RendererApi::Color::Transparent get_color(RendererApi::PointF<2>::component_t x, RendererApi::PointF<2>::component_t y) const final {
auto p = this->transform * RendererApi::PointF<2>{x, y};
return this->real_shader.get_color(p.x, p.y);
}
};
template<double radius>
class SunShader : public Utilities::Shader {
private:
public:
SunShader() = default;
[[nodiscard]] RendererApi::Color::Transparent get_color(RendererApi::PointF<2>::component_t x, RendererApi::PointF<2>::component_t y) const final {
RendererApi::PointF<2>::component_t distance = std::hypot(x, y) / radius;
if (distance > 1)
return RendererApi::Color::Transparent{255, 255, 0, 0};
if (distance > 0.8)
return Utilities::colors_gradient(RendererApi::Color::Transparent{255, 255, 0, 0}, (distance - 0.8) * 5, RendererApi::Color::Transparent{255, 255, 0, 255});
else if (distance > 0.3)
return Utilities::colors_gradient(RendererApi::Color::Transparent{255, 255, 0, 255}, (distance - 0.3) * 10 / 5, RendererApi::Color::Transparent{255, 255, 200, 255});
else
return RendererApi::Color::Transparent{255, 255, 200, 255};
}
};
template<double z, double radius>
class SunSprite : public RendererApi::Sprite<SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl> {
private:
public:
SunSprite() = default;
void draw(BGTU::ComputerGraphicsLabWork::Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl *frame, const BGTU::ComputerGraphicsLabWork::Impl::SpriteData *data) const final {
TransformedShader<SunShader<radius>> shader{data->planets_transform[0].inversed(), SunShader<radius>{}};
Utilities::Shapes::iterate_circle_fill(
static_cast< RendererApi::PointI<2>>(data->planets_transform[0] * RendererApi::PointF<2>{0, 0}),
data->radius_multiplier * radius,
[&](bool, RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) {
frame->add_voxel(x, y, z, shader.get_color(x, y));
}
);
}
};
SunSprite<1.0, 0.1> sun_sprite{};
RendererApi::Sprite<SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl> *_sprites[]{
&sun_sprite
};
}
RendererApi::Sprite<SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl> **const sprites = _sprites;
std::size_t sprites_count = 1;
}

View File

@ -0,0 +1,10 @@
#pragma once
#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::Impl {
extern RendererApi::Sprite<SpriteData, Utilities::DefaultVoxelDrawerCache::VoxelPainterImpl> ** const sprites;
extern std::size_t sprites_count;
}

View File

@ -16,10 +16,6 @@
#include "zoomed_scene_sprite.hpp"
namespace BGTU::ComputerGraphicsLabWork::Impl {
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};

View File

@ -94,6 +94,12 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
0, 0, 1};
}
static Matrix3<elem_t> scale(elem_t s) {
return Matrix3<elem_t>{s, 0, 0,
0, s, 0,
0, 0, 1};
}
static Matrix3<elem_t> rotate(elem_t radians) {
auto s = std::sin(radians);
auto c = std::cos(radians);
@ -114,6 +120,38 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
this->data[1][0] * other.x + this->data[1][1] * other.y + this->data[1][2],
};
}
elem_t det() const {
return this->data[0][0] * (this->data[1][1] * this->data[2][2] - this->data[1][2] * this->data[2][1]) -
this->data[0][1] * (this->data[1][0] * this->data[2][2] - this->data[1][2] * this->data[2][0]) +
this->data[0][2] * (this->data[1][0] * this->data[2][1] - this->data[1][1] * this->data[2][0]);
}
Matrix3<elem_t> adj() const {
return Matrix3<elem_t>{
this->data[1][1] * this->data[2][2] - this->data[1][2] * this->data[2][1],
-(this->data[1][0] * this->data[2][2] - this->data[1][2] * this->data[2][0]),
this->data[1][0] * this->data[2][1] - this->data[1][1] * this->data[2][0],
-(this->data[0][1] * this->data[2][2] - this->data[0][2] * this->data[2][1]),
this->data[0][0] * this->data[2][2] - this->data[0][2] * this->data[2][0],
-(this->data[0][0] * this->data[2][1] - this->data[0][1] * this->data[2][0]),
this->data[0][1] * this->data[1][2] - this->data[0][2] * this->data[1][1],
-(this->data[0][0] * this->data[1][2] - this->data[0][2] * this->data[1][0]),
this->data[0][0] * this->data[1][1] - this->data[0][1] * this->data[1][0]
};
}
Matrix3<elem_t> transposed() const {
return Matrix3<elem_t>{
this->data[0][0], this->data[1][0], this->data[2][0],
this->data[0][2], this->data[1][1], this->data[2][1],
this->data[0][1], this->data[1][2], this->data[2][2]
};
}
Matrix3<elem_t> inversed() const {
return this->adj().transposed() / this->det();
}
};
using Matrix3i = Matrix3<int>;
@ -221,6 +259,13 @@ namespace BGTU::ComputerGraphicsLabWork::Utilities {
0, 0, 0, 1};
}
static Matrix4<elem_t> scale(elem_t s) {
return Matrix4<elem_t>{s, 0, 0, 0,
0, s, 0, 0,
0, 0, s, 0,
0, 0, 0, 1};
}
static Matrix4<elem_t> rotate_x(elem_t radians) {
auto s = std::sin(radians);