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
This commit is contained in:
Pascal Massimino 2016-09-29 07:30:03 +02:00
parent f79450ca02
commit 9310d19258

View File

@ -64,6 +64,7 @@ static struct {
WebPIterator curr_frame; WebPIterator curr_frame;
WebPIterator prev_frame; WebPIterator prev_frame;
WebPChunkIterator iccp; WebPChunkIterator iccp;
int viewport_width, viewport_height;
} kParams; } kParams;
static void ClearPreviousPic(void) { 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) { static void HandleReshape(int width, int height) {
// TODO(skal): proper handling of resize, esp. for large pictures. // TODO(skal): should we preserve aspect ratio?
// + key control of the zoom. // Also: handle larger-than-screen pictures correctly.
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
kParams.viewport_width = width;
kParams.viewport_height = height;
} }
static void PrintString(const char* const text) { static void PrintString(const char* const text) {
@ -299,7 +302,8 @@ static void HandleDisplay(void) {
GLfloat xoff, yoff; GLfloat xoff, yoff;
if (pic == NULL) return; if (pic == NULL) return;
glPushMatrix(); 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); xoff = (GLfloat)(2. * curr->x_offset / kParams.canvas_width);
yoff = (GLfloat)(2. * curr->y_offset / kParams.canvas_height); yoff = (GLfloat)(2. * curr->y_offset / kParams.canvas_height);
glRasterPos2f(-1.f + xoff, 1.f - yoff); glRasterPos2f(-1.f + xoff, 1.f - yoff);
@ -308,8 +312,6 @@ static void HandleDisplay(void) {
if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND || if (prev->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND ||
curr->blend_method == WEBP_MUX_NO_BLEND) { 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). // glScissor() takes window coordinates (0,0 at bottom left).
int window_x, window_y; int window_x, window_y;
int frame_w, frame_h; int frame_w, frame_h;
@ -329,6 +331,10 @@ static void HandleDisplay(void) {
} }
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
// Only update the requested area, not the whole canvas. // 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); glScissor(window_x, window_y, frame_w, frame_h);
glClear(GL_COLOR_BUFFER_BIT); // use clear color glClear(GL_COLOR_BUFFER_BIT); // use clear color
@ -371,6 +377,7 @@ static void StartDisplay(void) {
glutInitWindowSize(width, height); glutInitWindowSize(width, height);
glutCreateWindow("WebP viewer"); glutCreateWindow("WebP viewer");
glutDisplayFunc(HandleDisplay); glutDisplayFunc(HandleDisplay);
glutReshapeFunc(HandleReshape);
glutIdleFunc(NULL); glutIdleFunc(NULL);
glutKeyboardFunc(HandleKey); glutKeyboardFunc(HandleKey);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 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, 8),
GetColorf(kParams.bg_color, 16), GetColorf(kParams.bg_color, 16),
GetColorf(kParams.bg_color, 24)); GetColorf(kParams.bg_color, 24));
HandleReshape(width, height);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
DrawCheckerBoard(); DrawCheckerBoard();
} }