diff --git a/src/renderer.cpp b/src/renderer.cpp index 7f038f7..35fbc6c 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -81,6 +81,11 @@ public: return get_rectangle(renderable.screen_position()); } + [[nodiscard]] geom::RectangleD src_bounds() const override + { + return renderable.src_bounds(); + } + [[nodiscard]] std::optional clip_area() const override { auto clip_area_rect = renderable.clip_area(); diff --git a/src/tessellation_helpers.cpp b/src/tessellation_helpers.cpp index 61a961e..0d91a69 100644 --- a/src/tessellation_helpers.cpp +++ b/src/tessellation_helpers.cpp @@ -22,38 +22,51 @@ along with this program. If not, see . namespace mg = mir::graphics; namespace mgl = mir::gl; namespace geom = mir::geometry; + +namespace +{ +struct SrcTexCoords +{ + GLfloat top; + GLfloat bottom; + GLfloat left; + GLfloat right; +}; + +auto tex_coords_from_rect(geom::Size buffer_size, geom::RectangleD sample_rect) -> SrcTexCoords +{ + /* GL Texture coordinates are normalised to the size of the buffer, so (0.0, 0.0) is the top-left + * and (1.0, 1.0) is the bottom-right + */ + SrcTexCoords coords; + coords.top = sample_rect.top() / buffer_size.height; + coords.bottom = sample_rect.bottom() / buffer_size.height; + coords.left = sample_rect.left() / buffer_size.width; + coords.right = sample_rect.right() / buffer_size.width; + return coords; +} +} + mgl::Primitive mgl::tessellate_renderable_into_rectangle( mg::Renderable const& renderable, geom::Displacement const& offset) { auto rect = renderable.screen_position(); rect.top_left = rect.top_left - offset; - GLfloat left = rect.top_left.x.as_int(); - GLfloat right = left + rect.size.width.as_int(); - GLfloat top = rect.top_left.y.as_int(); - GLfloat bottom = top + rect.size.height.as_int(); + GLfloat const left = rect.top_left.x.as_int(); + GLfloat const right = left + rect.size.width.as_int(); + GLfloat const top = rect.top_left.y.as_int(); + GLfloat const bottom = top + rect.size.height.as_int(); mgl::Primitive rectangle; rectangle.type = GL_TRIANGLE_STRIP; - GLfloat const tex_right = 1.0f; - GLfloat const tex_bottom = 1.0f; + auto const [tex_top, tex_bottom, tex_left, tex_right] = + tex_coords_from_rect(renderable.buffer()->size(), renderable.src_bounds()); auto& vertices = rectangle.vertices; - vertices[0] = { - { left, top, 0.0f }, - { 0.0f, 0.0f } - }; - vertices[1] = { - { left, bottom, 0.0f }, - { 0.0f, tex_bottom } - }; - vertices[2] = { - { right, top, 0.0f }, - { tex_right, 0.0f } - }; - vertices[3] = { - { right, bottom, 0.0f }, - { tex_right, tex_bottom } - }; + vertices[0] = {{left, top, 0.0f}, {tex_left, tex_top}}; + vertices[1] = {{left, bottom, 0.0f}, {tex_left, tex_bottom}}; + vertices[2] = {{right, top, 0.0f}, {tex_right, tex_top}}; + vertices[3] = {{right, bottom, 0.0f}, {tex_right, tex_bottom}}; return rectangle; }