Writing pixels to buffer instead of QImage

This commit is contained in:
Andrew Golovashevich 2024-12-10 10:16:40 +03:00
parent 93da247ccc
commit e1154fdf0a
3 changed files with 57 additions and 13 deletions

4
.gitignore vendored
View File

@ -8,4 +8,6 @@
/.idea/
/*build*/
/.vs/
/.vs/
/out/
/CMakeSettings.json

View File

@ -15,10 +15,11 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
class OwnedQImage : public QImage, public RendererApi::VoxelDrawer::Exporter {
private:
RendererApi::SpriteMetadata const **owners;
std::uint_least8_t *pixels_buffer;
bool owns_buffers;
public:
OwnedQImage(unsigned width, unsigned height) :
QImage(width, height, QImage::Format_ARGB32) {
OwnedQImage(unsigned width, unsigned height) : QImage(width, height, QImage::Format_ARGB32), pixels_buffer{nullptr}, owns_buffers{true} {
if (width == 0 || height == 0) {
this->owners = nullptr;
} else {
@ -29,8 +30,22 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
}
}
OwnedQImage() : QImage(), owners{nullptr} {}
OwnedQImage() : QImage(), owners{nullptr}, pixels_buffer{nullptr} {}
OwnedQImage(std::uint_least8_t *data, unsigned width, unsigned height, QImage::Format f, RendererApi::SpriteMetadata const **owners, QImageCleanupFunction destructor, void *destructor_closure) :
QImage(data, width, height, f, destructor, destructor_closure), pixels_buffer{data}, owners{owners}, owns_buffers{false} {}
OwnedQImage(std::uint_least8_t *data, unsigned width, unsigned height, QImage::Format f, RendererApi::SpriteMetadata const **owners) :
QImage(data, width, height, f), pixels_buffer{data}, owners{owners}, owns_buffers{false} {}
enum _DelegateBuffers {
DelegateBuffers
};
OwnedQImage(std::uint_least8_t *data, unsigned width, unsigned height, QImage::Format f, RendererApi::SpriteMetadata const **owners, _DelegateBuffers) :
QImage(data, width, height, f), pixels_buffer{data}, owners{owners}, owns_buffers{true} {}
#if 0
OwnedQImage &operator=(OwnedQImage const &copy) {
if (this == &copy)
return *this;
@ -49,13 +64,13 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
*this = copy;
}
OwnedQImage(OwnedQImage &&move) noexcept : QImage{std::move(move)} {
OwnedQImage(OwnedQImage &&move) noexcept: QImage{std::move(move)} {
if (this->owners != nullptr)
delete[] this->owners;
this->owners = move.owners;
move.owners = nullptr;
}
#endif
void setPixelOwner(unsigned x, unsigned y, RendererApi::SpriteMetadata const *o) {
assert(x < this->width());
@ -64,7 +79,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
this->owners[y * this->width() + x] = o;
}
RendererApi::SpriteMetadata const *getPixelOwner(unsigned x, unsigned y) const {
[[nodiscard]] RendererApi::SpriteMetadata const *getPixelOwner(unsigned x, unsigned y) const {
assert(x < this->width());
assert(y < this->height());
@ -77,9 +92,15 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
}
~OwnedQImage() override {
if (this->owners != nullptr) {
delete[] this->owners;
this->owners = nullptr;
if (this->owns_buffers) {
if (this->owners != nullptr) {
delete[] this->owners;
this->owners = nullptr;
}
if (this->pixels_buffer != nullptr) {
delete[] this->pixels_buffer;
this->pixels_buffer = nullptr;
}
}
}
};

View File

@ -169,16 +169,37 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
data_t cached = *const_cast<data_t *>(&this->owner->next_data);
this->owner->sync.unlock();
auto img = new OwnedQImage{cached.width, cached.height};
struct VoxelDrawerExporterImpl : public RendererApi::VoxelDrawer::Exporter {
public:
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t const w;
RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t const h;
std::uint_least8_t *const pixels_argb;;
RendererApi::SpriteMetadata const **const owners;
VoxelDrawerExporterImpl(RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t w, RendererApi::VoxelDrawer::visible_pixel_coordinate_fast_t h) :
w{w}, h{h},
pixels_argb{new std::uint_least8_t[w * h * 4]},
owners{new RendererApi::SpriteMetadata const *[w * h]} {}
void set_pixel(long long x, long long y, BGTU::ComputerGraphicsLabWork::RendererApi::Color c, const BGTU::ComputerGraphicsLabWork::RendererApi::SpriteMetadata *owner) final {
if (x < 0 || this->w <= x) return;
if (y < 0 || this->h <= y) return;
this->pixels_argb[(y * this->w + x) * 4] = c.red;
this->pixels_argb[(y * this->w + x) * 4 + 1] = c.green;
this->pixels_argb[(y * this->w + x) * 4 + 2] = c.blue;
this->owners[y * this->w + x] = owner;
}
} img{cached.width, cached.height};
(this->owner->renderer_context->*renderer_procedure)(
cached.width, cached.height,
img,
&img,
cached.bg,
cached.projection,
cached.sprites, cached.sprites_count,
cached.sprite_data
);
emit this->owner->frame_rendered(img);
emit this->owner->frame_rendered(new OwnedQImage{img.pixels_argb, img.w, img.h, QImage::Format_RGB32, img.owners, OwnedQImage::DelegateBuffers});
auto elapsed = timer.elapsed();
qCritical() << elapsed << "ms";
this->sleepms(std::max<std::int_fast64_t>(static_cast<std::int_fast64_t>(cached.ms_per_frame) - elapsed, 0));