feat: autoresize (extend/shrink) canvas element
This commit is contained in:
parent
b644a76904
commit
0d4838facf
@ -470,6 +470,32 @@ void ImageData::addColor(const ImageData& other, int multiplier) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageData::extend(int newWidth, int newHeight) {
|
||||||
|
size_t comps;
|
||||||
|
switch (format) {
|
||||||
|
case ImageFormat::rgb888: comps = 3; break;
|
||||||
|
case ImageFormat::rgba8888: comps = 4; break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("only unsigned byte formats supported");
|
||||||
|
}
|
||||||
|
auto newData = std::make_unique<ubyte[]>(newWidth * newHeight * comps);
|
||||||
|
for (uint y = 0; y < newHeight; y++) {
|
||||||
|
for (uint x = 0; x < newWidth; x++) {
|
||||||
|
for (size_t c = 0; c < comps; c++) {
|
||||||
|
if (x < width && y < height) {
|
||||||
|
newData[(y * newWidth + x) * comps + c] =
|
||||||
|
data[(y * width + x) * comps + c];
|
||||||
|
} else {
|
||||||
|
newData[(y * newWidth + x) * comps + c] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = std::move(newData);
|
||||||
|
width = newWidth;
|
||||||
|
height = newHeight;
|
||||||
|
}
|
||||||
|
|
||||||
void ImageData::addColor(const glm::ivec4& color, int multiplier) {
|
void ImageData::addColor(const glm::ivec4& color, int multiplier) {
|
||||||
uint comps;
|
uint comps;
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
|||||||
@ -36,6 +36,7 @@ public:
|
|||||||
void mulColor(const ImageData& other);
|
void mulColor(const ImageData& other);
|
||||||
void addColor(const glm::ivec4& color, int multiplier);
|
void addColor(const glm::ivec4& color, int multiplier);
|
||||||
void addColor(const ImageData& other, int multiplier);
|
void addColor(const ImageData& other, int multiplier);
|
||||||
|
void extend(int newWidth, int newHeight);
|
||||||
|
|
||||||
std::unique_ptr<ImageData> cropped(int x, int y, int width, int height) const;
|
std::unique_ptr<ImageData> cropped(int x, int y, int width, int height) const;
|
||||||
|
|
||||||
|
|||||||
@ -44,10 +44,10 @@ void Texture::unbind() const {
|
|||||||
void Texture::reload(const ImageData& image) {
|
void Texture::reload(const ImageData& image) {
|
||||||
width = image.getWidth();
|
width = image.getWidth();
|
||||||
height = image.getHeight();
|
height = image.getHeight();
|
||||||
reload(image.getData());
|
reload(image.getData(), width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::reload(const ubyte* data) {
|
void Texture::reload(const ubyte* data, uint width, uint height) {
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(data));
|
GL_RGBA, GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(data));
|
||||||
|
|||||||
@ -18,7 +18,7 @@ public:
|
|||||||
|
|
||||||
virtual void bind() const;
|
virtual void bind() const;
|
||||||
virtual void unbind() const;
|
virtual void unbind() const;
|
||||||
void reload(const ubyte* data);
|
void reload(const ubyte* data, uint w, uint h);
|
||||||
void reloadPartial(const ImageData& image, uint x, uint y, uint w, uint h);
|
void reloadPartial(const ImageData& image, uint x, uint y, uint w, uint h);
|
||||||
|
|
||||||
void setNearestFilter();
|
void setNearestFilter();
|
||||||
|
|||||||
@ -4,11 +4,11 @@
|
|||||||
#include "graphics/core/DrawContext.hpp"
|
#include "graphics/core/DrawContext.hpp"
|
||||||
#include "graphics/core/Texture.hpp"
|
#include "graphics/core/Texture.hpp"
|
||||||
|
|
||||||
gui::Canvas::Canvas(GUI& gui, ImageFormat inFormat, glm::uvec2 inSize)
|
gui::Canvas::Canvas(GUI& gui, ImageFormat format, glm::uvec2 size)
|
||||||
: UINode(gui, inSize) {
|
: UINode(gui, size) {
|
||||||
auto data = std::make_shared<ImageData>(inFormat, inSize.x, inSize.y);
|
auto data = std::make_shared<ImageData>(format, size.x, size.y);
|
||||||
mTexture = Texture::from(data.get());
|
texture = Texture::from(data.get());
|
||||||
mData = std::move(data);
|
this->data = std::move(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui::Canvas::draw(const DrawContext& pctx, const Assets& assets) {
|
void gui::Canvas::draw(const DrawContext& pctx, const Assets& assets) {
|
||||||
@ -16,6 +16,12 @@ void gui::Canvas::draw(const DrawContext& pctx, const Assets& assets) {
|
|||||||
auto col = calcColor();
|
auto col = calcColor();
|
||||||
|
|
||||||
auto batch = pctx.getBatch2D();
|
auto batch = pctx.getBatch2D();
|
||||||
batch->texture(mTexture.get());
|
batch->texture(texture.get());
|
||||||
batch->rect(pos.x, pos.y, size.x, size.y, 0, 0, 0, {}, false, false, col);
|
batch->rect(pos.x, pos.y, size.x, size.y, 0, 0, 0, {}, false, false, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gui::Canvas::setSize(glm::vec2 size) {
|
||||||
|
UINode::setSize(size);
|
||||||
|
data->extend(size.x, size.y);
|
||||||
|
texture->reload(*data);
|
||||||
|
}
|
||||||
|
|||||||
@ -9,21 +9,23 @@ class Texture;
|
|||||||
namespace gui {
|
namespace gui {
|
||||||
class Canvas final : public UINode {
|
class Canvas final : public UINode {
|
||||||
public:
|
public:
|
||||||
explicit Canvas(GUI& gui, ImageFormat inFormat, glm::uvec2 inSize);
|
explicit Canvas(GUI& gui, ImageFormat format, glm::uvec2 size);
|
||||||
|
|
||||||
~Canvas() override = default;
|
~Canvas() override = default;
|
||||||
|
|
||||||
void draw(const DrawContext& pctx, const Assets& assets) override;
|
void draw(const DrawContext& pctx, const Assets& assets) override;
|
||||||
|
|
||||||
[[nodiscard]] auto texture() const {
|
void setSize(glm::vec2 size) override;
|
||||||
return mTexture;
|
|
||||||
|
[[nodiscard]] auto getTexture() const {
|
||||||
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto data() const {
|
[[nodiscard]] auto getData() const {
|
||||||
return mData;
|
return data;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<::Texture> mTexture;
|
std::shared_ptr<::Texture> texture;
|
||||||
std::shared_ptr<ImageData> mData;
|
std::shared_ptr<ImageData> data;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -380,7 +380,7 @@ static int p_get_region(UINode* node, lua::State* L) {
|
|||||||
|
|
||||||
static int p_get_data(UINode* node, lua::State* L) {
|
static int p_get_data(UINode* node, lua::State* L) {
|
||||||
if (auto canvas = dynamic_cast<Canvas*>(node)) {
|
if (auto canvas = dynamic_cast<Canvas*>(node)) {
|
||||||
return lua::newuserdata<lua::LuaCanvas>(L, canvas->texture(), canvas->data());
|
return lua::newuserdata<lua::LuaCanvas>(L, canvas->getTexture(), canvas->getData());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user