Refactor ui::painter interface: gather draw_image options into a struct

This commit is contained in:
Nikita Lisitsa 2022-05-19 11:38:09 +03:00
parent f21fa3c2d6
commit 35eaf17a3b
6 changed files with 33 additions and 16 deletions

View file

@ -10,12 +10,28 @@
namespace psemek::ui namespace psemek::ui
{ {
namespace detail
{
// Have to define this struct outside of ui::painter to workaround
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88165
struct image_options
{
gfx::color_rgba color{0, 0, 0, 0};
float rotation{0.f};
};
}
struct painter struct painter
{ {
virtual void draw_rect(geom::box<float, 2> const & rect, gfx::color_rgba const & color) = 0; virtual void draw_rect(geom::box<float, 2> const & rect, gfx::color_rgba const & color) = 0;
virtual void draw_triangle(geom::triangle<geom::point<float, 2>> const & tri, gfx::color_rgba const & color) = 0; virtual void draw_triangle(geom::triangle<geom::point<float, 2>> const & tri, gfx::color_rgba const & color) = 0;
using image_options = detail::image_options;
virtual void draw_glyph(font const & f, char32_t c, geom::box<float, 2> const & rect, gfx::color_rgba const & color) = 0; virtual void draw_glyph(font const & f, char32_t c, geom::box<float, 2> const & rect, gfx::color_rgba const & color) = 0;
virtual void draw_image(geom::box<float, 2> const & rect, gfx::texture_view_2d const & tex, gfx::color_rgba const & color = {0, 0, 0, 0}, float rotation = 0.f) = 0; virtual void draw_image(geom::box<float, 2> const & rect, gfx::texture_view_2d const & tex, image_options const & opts = image_options{}) = 0;
virtual void begin_stencil() = 0; virtual void begin_stencil() = 0;
virtual void commit_stencil() = 0; virtual void commit_stencil() = 0;

View file

@ -17,8 +17,9 @@ namespace psemek::ui
void draw_rect(geom::box<float, 2> const & rect, gfx::color_rgba const & color) override; void draw_rect(geom::box<float, 2> const & rect, gfx::color_rgba const & color) override;
void draw_triangle(geom::triangle<geom::point<float, 2>> const & tri, gfx::color_rgba const & color) override; void draw_triangle(geom::triangle<geom::point<float, 2>> const & tri, gfx::color_rgba const & color) override;
void draw_glyph(font const & f, char32_t c, geom::box<float, 2> const & rect, gfx::color_rgba const & color) override; void draw_glyph(font const & f, char32_t c, geom::box<float, 2> const & rect, gfx::color_rgba const & color) override;
void draw_image(geom::box<float, 2> const & rect, gfx::texture_view_2d const & tex, gfx::color_rgba const & color = {0, 0, 0, 0}, float rotation = 0.f) override; void draw_image(geom::box<float, 2> const & rect, gfx::texture_view_2d const & tex, image_options const & opts) override;
void begin_stencil() override; void begin_stencil() override;
void commit_stencil() override; void commit_stencil() override;

View file

@ -85,7 +85,7 @@ namespace psemek::ui
} }
} }
p.draw_image(box, image_, color_); p.draw_image(box, image_, {color_});
} }
} }

View file

@ -111,12 +111,12 @@ namespace psemek::ui
auto const offset = geom::cast<float>(*st->text_shadow_offset); auto const offset = geom::cast<float>(*st->text_shadow_offset);
for (auto const & batch : cached_state_->batches) for (auto const & batch : cached_state_->batches)
for (auto const & image : batch.images) for (auto const & image : batch.images)
p.draw_image(image.position + offset, gfx::texture_view_2d{batch.texture, image.texcoords}, *st->shadow_color); p.draw_image(image.position + offset, gfx::texture_view_2d{batch.texture, image.texcoords}, {*st->shadow_color});
} }
for (auto const & batch : cached_state_->batches) for (auto const & batch : cached_state_->batches)
for (auto const & image : batch.images) for (auto const & image : batch.images)
p.draw_image(image.position, gfx::texture_view_2d{batch.texture, image.texcoords}, *st->text_color); p.draw_image(image.position, gfx::texture_view_2d{batch.texture, image.texcoords}, {*st->text_color});
} }
void label::on_state_changed() void label::on_state_changed()

View file

@ -342,7 +342,7 @@ void main()
impl().draw_bbox |= rect; impl().draw_bbox |= rect;
} }
void painter_impl::draw_image(geom::box<float, 2> const & rect, gfx::texture_view_2d const & tex, gfx::color_rgba const & color, float rotation) void painter_impl::draw_image(geom::box<float, 2> const & rect, gfx::texture_view_2d const & tex, image_options const & options)
{ {
auto & batch = impl().batch<textured_batch>(textured_batch{tex.texture}); auto & batch = impl().batch<textured_batch>(textured_batch{tex.texture});
@ -354,20 +354,20 @@ void main()
auto p01 = rect.corner(0.f, 1.f); auto p01 = rect.corner(0.f, 1.f);
auto p11 = rect.corner(1.f, 1.f); auto p11 = rect.corner(1.f, 1.f);
if (rotation != 0.f) if (options.rotation != 0.f)
{ {
auto const c = rect.center(); auto const c = rect.center();
p00 = c + geom::rotate(p00 - c, rotation); p00 = c + geom::rotate(p00 - c, options.rotation);
p10 = c + geom::rotate(p10 - c, rotation); p10 = c + geom::rotate(p10 - c, options.rotation);
p01 = c + geom::rotate(p01 - c, rotation); p01 = c + geom::rotate(p01 - c, options.rotation);
p11 = c + geom::rotate(p11 - c, rotation); p11 = c + geom::rotate(p11 - c, options.rotation);
} }
batch.vertices.push_back({p00, depth, color, tex.part.corner(0.f, 0.f)}); batch.vertices.push_back({p00, depth, options.color, tex.part.corner(0.f, 0.f)});
batch.vertices.push_back({p10, depth, color, tex.part.corner(1.f, 0.f)}); batch.vertices.push_back({p10, depth, options.color, tex.part.corner(1.f, 0.f)});
batch.vertices.push_back({p01, depth, color, tex.part.corner(0.f, 1.f)}); batch.vertices.push_back({p01, depth, options.color, tex.part.corner(0.f, 1.f)});
batch.vertices.push_back({p11, depth, color, tex.part.corner(1.f, 1.f)}); batch.vertices.push_back({p11, depth, options.color, tex.part.corner(1.f, 1.f)});
batch.indices.insert(batch.indices.end(), {base + 0, base + 1, base + 2, base + 2, base + 1, base + 3}); batch.indices.insert(batch.indices.end(), {base + 0, base + 1, base + 2, base + 2, base + 1, base + 3});

View file

@ -177,7 +177,7 @@ namespace psemek::ui
if (*st->shadow_offset != geom::vector{0, 0}) if (*st->shadow_offset != geom::vector{0, 0})
p.draw_rect(box + geom::cast<float>(*st->shadow_offset), *st->shadow_color); p.draw_rect(box + geom::cast<float>(*st->shadow_offset), *st->shadow_color);
p.draw_image(box, {image_.get(), reg}, color_); p.draw_image(box, {image_.get(), reg}, {color_});
} }
} }