From 315bf08733f4bc132a23200df26cb2145ac629b3 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 27 Apr 2020 12:27:01 +0200 Subject: [PATCH] render: add wlr_render_subtexture_with_matrix This renders only a subset of the texture, instead of the full texture. --- include/wlr/render/interface.h | 6 +++--- include/wlr/render/wlr_renderer.h | 7 +++++++ render/gles2/renderer.c | 28 +++++++++++++++++++--------- render/wlr_renderer.c | 17 +++++++++++++++-- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h index 6eb6c22f..93c987b7 100644 --- a/include/wlr/render/interface.h +++ b/include/wlr/render/interface.h @@ -32,9 +32,9 @@ struct wlr_renderer_impl { void (*end)(struct wlr_renderer *renderer); void (*clear)(struct wlr_renderer *renderer, const float color[static 4]); void (*scissor)(struct wlr_renderer *renderer, struct wlr_box *box); - bool (*render_texture_with_matrix)(struct wlr_renderer *renderer, - struct wlr_texture *texture, const float matrix[static 9], - float alpha); + bool (*render_subtexture_with_matrix)(struct wlr_renderer *renderer, + struct wlr_texture *texture, const struct wlr_fbox *box, + const float matrix[static 9], float alpha); void (*render_quad_with_matrix)(struct wlr_renderer *renderer, const float color[static 4], const float matrix[static 9]); void (*render_ellipse_with_matrix)(struct wlr_renderer *renderer, diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h index e6140f3e..513f412a 100644 --- a/include/wlr/render/wlr_renderer.h +++ b/include/wlr/render/wlr_renderer.h @@ -54,6 +54,13 @@ bool wlr_render_texture(struct wlr_renderer *r, struct wlr_texture *texture, */ bool wlr_render_texture_with_matrix(struct wlr_renderer *r, struct wlr_texture *texture, const float matrix[static 9], float alpha); +/** + * Renders the requested texture using the provided matrix, after cropping it + * to the provided rectangle. + */ +bool wlr_render_subtexture_with_matrix(struct wlr_renderer *r, + struct wlr_texture *texture, const struct wlr_fbox *box, + const float matrix[static 9], float alpha); /** * Renders a solid rectangle in the specified color. */ diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 9ec9394d..b20c3ac2 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -86,7 +86,8 @@ static void gles2_scissor(struct wlr_renderer *wlr_renderer, POP_GLES2_DEBUG; } -static void draw_quad(void) { +static void draw_quad_with_texcoord(GLfloat x1, GLfloat y1, + GLfloat x2, GLfloat y2) { GLfloat verts[] = { 1, 0, // top right 0, 0, // top left @@ -94,10 +95,10 @@ static void draw_quad(void) { 0, 1, // bottom left }; GLfloat texcoord[] = { - 1, 0, // top right - 0, 0, // top left - 1, 1, // bottom right - 0, 1, // bottom left + x2, y1, // top right + x1, y1, // top left + x2, y2, // bottom right + x1, y2, // bottom left }; glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, verts); @@ -112,8 +113,13 @@ static void draw_quad(void) { glDisableVertexAttribArray(1); } -static bool gles2_render_texture_with_matrix(struct wlr_renderer *wlr_renderer, - struct wlr_texture *wlr_texture, const float matrix[static 9], +static void draw_quad(void) { + draw_quad_with_texcoord(0, 0, 1, 1); +} + +static bool gles2_render_subtexture_with_matrix( + struct wlr_renderer *wlr_renderer, struct wlr_texture *wlr_texture, + const struct wlr_fbox *box, const float matrix[static 9], float alpha) { struct wlr_gles2_renderer *renderer = gles2_get_renderer_in_context(wlr_renderer); @@ -162,7 +168,11 @@ static bool gles2_render_texture_with_matrix(struct wlr_renderer *wlr_renderer, glUniform1i(shader->tex, 0); glUniform1f(shader->alpha, alpha); - draw_quad(); + GLfloat x1 = box->x / wlr_texture->width; + GLfloat y1 = box->y / wlr_texture->height; + GLfloat x2 = (box->x + box->width) / wlr_texture->width; + GLfloat y2 = (box->y + box->height) / wlr_texture->height; + draw_quad_with_texcoord(x1, y1, x2, y2); glBindTexture(texture->target, 0); @@ -492,7 +502,7 @@ static const struct wlr_renderer_impl renderer_impl = { .end = gles2_end, .clear = gles2_clear, .scissor = gles2_scissor, - .render_texture_with_matrix = gles2_render_texture_with_matrix, + .render_subtexture_with_matrix = gles2_render_subtexture_with_matrix, .render_quad_with_matrix = gles2_render_quad_with_matrix, .render_ellipse_with_matrix = gles2_render_ellipse_with_matrix, .formats = gles2_renderer_formats, diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index 016e4d6e..593d165f 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -13,7 +13,7 @@ void wlr_renderer_init(struct wlr_renderer *renderer, assert(impl->begin); assert(impl->clear); assert(impl->scissor); - assert(impl->render_texture_with_matrix); + assert(impl->render_subtexture_with_matrix); assert(impl->render_quad_with_matrix); assert(impl->render_ellipse_with_matrix); assert(impl->formats); @@ -80,8 +80,21 @@ bool wlr_render_texture(struct wlr_renderer *r, struct wlr_texture *texture, bool wlr_render_texture_with_matrix(struct wlr_renderer *r, struct wlr_texture *texture, const float matrix[static 9], float alpha) { + struct wlr_fbox box = { + .x = 0, + .y = 0, + .width = texture->width, + .height = texture->height, + }; + return wlr_render_subtexture_with_matrix(r, texture, &box, matrix, alpha); +} + +bool wlr_render_subtexture_with_matrix(struct wlr_renderer *r, + struct wlr_texture *texture, const struct wlr_fbox *box, + const float matrix[static 9], float alpha) { assert(r->rendering); - return r->impl->render_texture_with_matrix(r, texture, matrix, alpha); + return r->impl->render_subtexture_with_matrix(r, texture, + box, matrix, alpha); } void wlr_render_rect(struct wlr_renderer *r, const struct wlr_box *box,