diff options
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/gl_video.c | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 25b1547327..1f140b040d 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -132,7 +132,7 @@ struct fbotex { GLuint fbo; GLuint texture; int tex_w, tex_h; // size of .texture - int vp_w, vp_h; // viewport of fbo / used part of the texture + int vp_x, vp_y, vp_w, vp_h; // viewport of fbo / used part of the texture }; struct gl_video { @@ -397,10 +397,12 @@ static bool fbotex_init(struct gl_video *p, struct fbotex *fbo, int w, int h, assert(!fbo->fbo); assert(!fbo->texture); - tex_size(p, w, h, &fbo->tex_w, &fbo->tex_h); + *fbo = (struct fbotex) { + .vp_w = w, + .vp_h = h, + }; - fbo->vp_w = w; - fbo->vp_h = h; + tex_size(p, w, h, &fbo->tex_w, &fbo->tex_h); mp_msg(MSGT_VO, MSGL_V, "[gl] Create FBO: %dx%d\n", fbo->tex_w, fbo->tex_h); @@ -505,7 +507,7 @@ static void update_uniforms(struct gl_video *p, GLuint program) gl->Uniform1i(gl->GetUniformLocation(program, textures_n), n); gl->Uniform2f(gl->GetUniformLocation(program, textures_size_n), - p->image.planes[n].w, p->image.planes[n].h); + p->image.planes[n].tex_w, p->image.planes[n].tex_h); } gl->Uniform2f(gl->GetUniformLocation(program, "dither_size"), @@ -1055,7 +1057,7 @@ static void reinit_rendering(struct gl_video *p) update_all_uniforms(p); if (p->indirect_program && !p->indirect_fbo.fbo) - fbotex_init(p, &p->indirect_fbo, p->texture_w, p->texture_h, + fbotex_init(p, &p->indirect_fbo, p->image_w, p->image_h, p->opts.fbo_format); recreate_osd(p); @@ -1214,17 +1216,17 @@ static void change_dither_trafo(struct gl_video *p) gl->UseProgram(0); } -static void render_to_fbo(struct gl_video *p, struct fbotex *fbo, int w, int h, - int tex_w, int tex_h) +static void render_to_fbo(struct gl_video *p, struct fbotex *fbo, + int x, int y, int w, int h, int tex_w, int tex_h) { GL *gl = p->gl; - gl->Viewport(0, 0, fbo->vp_w, fbo->vp_h); + gl->Viewport(fbo->vp_x, fbo->vp_y, fbo->vp_w, fbo->vp_h); gl->BindFramebuffer(GL_FRAMEBUFFER, fbo->fbo); struct vertex vb[VERTICES_PER_QUAD]; write_quad(vb, -1, -1, 1, 1, - 0, 0, w, h, + x, y, x + w, y + h, tex_w, tex_h, NULL, false); draw_triangles(p, vb, VERTICES_PER_QUAD); @@ -1244,7 +1246,8 @@ static void handle_pass(struct gl_video *p, struct fbotex **source, gl->BindTexture(GL_TEXTURE_2D, (*source)->texture); gl->UseProgram(program); - render_to_fbo(p, fbo, (*source)->vp_w, (*source)->vp_h, + render_to_fbo(p, fbo, (*source)->vp_x, (*source)->vp_y, + (*source)->vp_w, (*source)->vp_h, (*source)->tex_w, (*source)->tex_h); *source = fbo; } @@ -1272,23 +1275,37 @@ void gl_video_render_frame(struct gl_video *p) set_image_textures(p, vimg); struct fbotex dummy = { - .vp_w = p->image_w, .vp_h = p->image_h, - .tex_w = p->texture_w, .tex_h = p->texture_h, + .vp_w = p->image_w, + .vp_h = p->image_h, + .tex_w = p->texture_w, + .tex_h = p->texture_h, .texture = vimg->planes[0].gl_texture, }; struct fbotex *source = &dummy; handle_pass(p, &source, &p->indirect_fbo, p->indirect_program); + + // Clip to visible height so that separate scaling scales the visible part + // only (and the target FBO texture can have a bounded size). + // Don't clamp width; too hard to get correct final scaling on l/r borders. + dummy = *source; + source = &dummy; + source->vp_y = p->src_rect.y0, + source->vp_h = p->src_rect.y1 - p->src_rect.y0, + handle_pass(p, &source, &p->scale_sep_fbo, p->scale_sep_program); gl->BindTexture(GL_TEXTURE_2D, source->texture); gl->UseProgram(p->final_program); - float final_texw = p->image_w * source->tex_w / (float)source->vp_w; - float final_texh = p->image_h * source->tex_h / (float)source->vp_h; + float final_texw = source->tex_w; + float final_texh = source->tex_h; + + struct mp_rect src = {p->src_rect.x0, source->vp_y, + p->src_rect.x1, source->vp_y + source->vp_h}; if (p->opts.stereo_mode) { - int w = p->src_rect.x1 - p->src_rect.x0; + int w = src.x1 - src.x0; int imgw = p->image_w; glEnable3DLeft(gl, p->opts.stereo_mode); @@ -1296,8 +1313,8 @@ void gl_video_render_frame(struct gl_video *p) write_quad(vb, p->dst_rect.x0, p->dst_rect.y0, p->dst_rect.x1, p->dst_rect.y1, - p->src_rect.x0 / 2, p->src_rect.y0, - p->src_rect.x0 / 2 + w / 2, p->src_rect.y1, + src.x0 / 2, src.y0, + src.x0 / 2 + w / 2, src.y1, final_texw, final_texh, NULL, is_flipped); draw_triangles(p, vb, VERTICES_PER_QUAD); @@ -1307,8 +1324,8 @@ void gl_video_render_frame(struct gl_video *p) write_quad(vb, p->dst_rect.x0, p->dst_rect.y0, p->dst_rect.x1, p->dst_rect.y1, - p->src_rect.x0 / 2 + imgw / 2, p->src_rect.y0, - p->src_rect.x0 / 2 + imgw / 2 + w / 2, p->src_rect.y1, + src.x0 / 2 + imgw / 2, src.y0, + src.x0 / 2 + imgw / 2 + w / 2, src.y1, final_texw, final_texh, NULL, is_flipped); draw_triangles(p, vb, VERTICES_PER_QUAD); @@ -1318,8 +1335,8 @@ void gl_video_render_frame(struct gl_video *p) write_quad(vb, p->dst_rect.x0, p->dst_rect.y0, p->dst_rect.x1, p->dst_rect.y1, - p->src_rect.x0, p->src_rect.y0, - p->src_rect.x1, p->src_rect.y1, + src.x0, src.y0, + src.x1, src.y1, final_texw, final_texh, NULL, is_flipped); draw_triangles(p, vb, VERTICES_PER_QUAD); |