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

2
.gitignore vendored
View File

@ -9,3 +9,5 @@
/.idea/ /.idea/
/*build*/ /*build*/
/.vs/ /.vs/
/out/
/CMakeSettings.json

View File

@ -15,10 +15,11 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
class OwnedQImage : public QImage, public RendererApi::VoxelDrawer::Exporter { class OwnedQImage : public QImage, public RendererApi::VoxelDrawer::Exporter {
private: private:
RendererApi::SpriteMetadata const **owners; RendererApi::SpriteMetadata const **owners;
std::uint_least8_t *pixels_buffer;
bool owns_buffers;
public: public:
OwnedQImage(unsigned width, unsigned height) : OwnedQImage(unsigned width, unsigned height) : QImage(width, height, QImage::Format_ARGB32), pixels_buffer{nullptr}, owns_buffers{true} {
QImage(width, height, QImage::Format_ARGB32) {
if (width == 0 || height == 0) { if (width == 0 || height == 0) {
this->owners = nullptr; this->owners = nullptr;
} else { } 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) { OwnedQImage &operator=(OwnedQImage const &copy) {
if (this == &copy) if (this == &copy)
return *this; return *this;
@ -55,7 +70,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
this->owners = move.owners; this->owners = move.owners;
move.owners = nullptr; move.owners = nullptr;
} }
#endif
void setPixelOwner(unsigned x, unsigned y, RendererApi::SpriteMetadata const *o) { void setPixelOwner(unsigned x, unsigned y, RendererApi::SpriteMetadata const *o) {
assert(x < this->width()); assert(x < this->width());
@ -64,7 +79,7 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
this->owners[y * this->width() + x] = o; 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(x < this->width());
assert(y < this->height()); assert(y < this->height());
@ -77,10 +92,16 @@ namespace BGTU::ComputerGraphicsLabWork::QtUtilities {
} }
~OwnedQImage() override { ~OwnedQImage() override {
if (this->owns_buffers) {
if (this->owners != nullptr) { if (this->owners != nullptr) {
delete[] this->owners; delete[] this->owners;
this->owners = nullptr; 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); data_t cached = *const_cast<data_t *>(&this->owner->next_data);
this->owner->sync.unlock(); 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)( (this->owner->renderer_context->*renderer_procedure)(
cached.width, cached.height, cached.width, cached.height,
img, &img,
cached.bg, cached.bg,
cached.projection, cached.projection,
cached.sprites, cached.sprites_count, cached.sprites, cached.sprites_count,
cached.sprite_data 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(); auto elapsed = timer.elapsed();
qCritical() << elapsed << "ms"; qCritical() << elapsed << "ms";
this->sleepms(std::max<std::int_fast64_t>(static_cast<std::int_fast64_t>(cached.ms_per_frame) - elapsed, 0)); this->sleepms(std::max<std::int_fast64_t>(static_cast<std::int_fast64_t>(cached.ms_per_frame) - elapsed, 0));