shithub: choc

Download patch

ref: 893f988ef36da034df99e981de453cd37dd830ba
parent: 1cd9d1136802cbf722d9e0f019a4615027bdbb88
author: Fabian Greffrath <fabian@greffrath.com>
date: Thu Sep 17 13:53:36 EDT 2015

Video: Implement adaptive scaling of the upscaled texture

The texture is always scaled to the next highest integer multiple of
the original resolution whenever the window is resized. If the window
dimensions do not match the original aspect ratio, the rendered area
will be decreased to fit in. Thus, consider the smaller factor for
horizontal and vertical scaling.

Also, allow at least one gametic to pass between two resizes.

--- a/src/i_video.c
+++ b/src/i_video.c
@@ -153,7 +153,6 @@
 // is upscaled by an integer factor UPSCALE using "nearest" scaling and which
 // in turn is finally rendered to screen using "linear" scaling.
 
-#define UPSCALE	2
 static SDL_Surface *screenbuffer = NULL;
 static SDL_Surface *rgbabuffer = NULL;
 static SDL_Texture *texture = NULL;
@@ -1012,6 +1011,41 @@
 */
 }
 
+static void CreateUpscaledTexture(int w, int h)
+{
+    const int w_scale = (w / SCREENWIDTH) + 1;
+    const int h_scale = (h / SCREENHEIGHT) + 1;
+    int upscale;
+
+    if (texture_upscaled)
+    {
+        SDL_DestroyTexture(texture_upscaled);
+    }
+
+    // When the screen or window dimensions do not match the aspect ratio
+    // of the texture, the rendered area is scaled down to fit
+
+    upscale = (w_scale < h_scale) ? w_scale : h_scale;
+
+    // Limit upscaling factor to 6 (1920x1200)
+
+    if (upscale > 6)
+    {
+        upscale = 6;
+    }
+
+    // Set the scaling quality for rendering the upscaled texture to "linear",
+    // which looks much softer and smoother than "nearest" but does a better
+    // job at downscaling from the upscaled texture to screen.
+
+    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+
+    texture_upscaled = SDL_CreateTexture(renderer,
+                                SDL_PIXELFORMAT_ARGB8888,
+                                SDL_TEXTUREACCESS_TARGET,
+                                upscale*SCREENWIDTH, upscale*SCREENHEIGHT);
+}
+
 //
 // I_FinishUpdate
 //
@@ -1031,13 +1065,12 @@
     if (noblit)
         return;
 
-    // TODO: Decrease the forced delay: we are not changing a screen mode
-    // anymore but simply modify the texture scaling factor
-    if (need_resize && SDL_GetTicks() > last_resize_time + 500)
+    if (need_resize && SDL_GetTicks() > last_resize_time + 1000/TICRATE)
     {
 #if 0 // obsolete software scaling reoutines
         ApplyWindowResize(resize_w, resize_h);
 #endif
+        CreateUpscaledTexture(resize_w, resize_h);
         screen_width = resize_w;
         screen_height = resize_h;
         SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
@@ -1884,16 +1917,9 @@
                                 SDL_TEXTUREACCESS_STREAMING,
                                 SCREENWIDTH, SCREENHEIGHT);
 
-    // Set the scaling quality for rendering the upscaled texture to "linear",
-    // which looks much softer and smoother than "nearest" but does a better
-    // job at downscaling from the upscaled texture to screen.
+    // Initially create the upscaled texture for rendering to screen
 
-    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
-
-    texture_upscaled = SDL_CreateTexture(renderer,
-                                SDL_PIXELFORMAT_ARGB8888,
-                                SDL_TEXTUREACCESS_TARGET,
-                                UPSCALE*SCREENWIDTH, UPSCALE*SCREENHEIGHT);
+    CreateUpscaledTexture(w, h);
 
     // Save screen mode.