From 9310d192581872c97bb9e29099ac4d9257d30929 Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Thu, 29 Sep 2016 07:30:03 +0200 Subject: [PATCH] vwebp: handle window resizing properly The image is scaled to fit the whole viewport. Avoid some oddities with offsets, etc. removes some TODO. Change-Id: I52fae9ca80a2feed234f32261c7f6358d7594e21 --- examples/vwebp.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/vwebp.c b/examples/vwebp.c index 6da5b9c0..6bcdcf7f 100644 --- a/examples/vwebp.c +++ b/examples/vwebp.c @@ -64,6 +64,7 @@ static struct { WebPIterator curr_frame; WebPIterator prev_frame; WebPChunkIterator iccp; + int viewport_width, viewport_height; } kParams; static void ClearPreviousPic(void) { @@ -251,13 +252,15 @@ static void HandleKey(unsigned char key, int pos_x, int pos_y) { } static void HandleReshape(int width, int height) { - // TODO(skal): proper handling of resize, esp. for large pictures. - // + key control of the zoom. + // TODO(skal): should we preserve aspect ratio? + // Also: handle larger-than-screen pictures correctly. glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + kParams.viewport_width = width; + kParams.viewport_height = height; } static void PrintString(const char* const text) { @@ -299,7 +302,8 @@ static void HandleDisplay(void) { GLfloat xoff, yoff; if (pic == NULL) return; glPushMatrix(); - glPixelZoom(1, -1); + glPixelZoom((GLfloat)(+1. / kParams.canvas_width * kParams.viewport_width), + (GLfloat)(-1. / kParams.canvas_height * kParams.viewport_height)); xoff = (GLfloat)(2. * curr->x_offset / kParams.canvas_width); yoff = (GLfloat)(2. * curr->y_offset / kParams.canvas_height); glRasterPos2f(-1.f + xoff, 1.f - yoff); @@ -308,8 +312,6 @@ static void HandleDisplay(void) { if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND || curr->blend_method == WEBP_MUX_NO_BLEND) { - // TODO(later): these offsets and those above should factor in window size. - // they will be incorrect if the window is resized. // glScissor() takes window coordinates (0,0 at bottom left). int window_x, window_y; int frame_w, frame_h; @@ -329,6 +331,10 @@ static void HandleDisplay(void) { } glEnable(GL_SCISSOR_TEST); // Only update the requested area, not the whole canvas. + window_x = window_x * kParams.viewport_width / kParams.canvas_width; + window_y = window_y * kParams.viewport_height / kParams.canvas_height; + frame_w = frame_w * kParams.viewport_width / kParams.canvas_width; + frame_h = frame_h * kParams.viewport_height / kParams.canvas_height; glScissor(window_x, window_y, frame_w, frame_h); glClear(GL_COLOR_BUFFER_BIT); // use clear color @@ -371,6 +377,7 @@ static void StartDisplay(void) { glutInitWindowSize(width, height); glutCreateWindow("WebP viewer"); glutDisplayFunc(HandleDisplay); + glutReshapeFunc(HandleReshape); glutIdleFunc(NULL); glutKeyboardFunc(HandleKey); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -379,7 +386,6 @@ static void StartDisplay(void) { GetColorf(kParams.bg_color, 8), GetColorf(kParams.bg_color, 16), GetColorf(kParams.bg_color, 24)); - HandleReshape(width, height); glClear(GL_COLOR_BUFFER_BIT); DrawCheckerBoard(); }