Added the SDL_HINT_RENDER_SCALE_QUALITY hint, which defaults to nearest pixel sampling.
authorSam Lantinga <slouken@libsdl.org>
Sun, 13 Mar 2011 11:18:35 -0700
changeset 5484 e20c93bc9122
parent 5483 ccec742c9b7d
child 5485 4cf1ad60ad47
Added the SDL_HINT_RENDER_SCALE_QUALITY hint, which defaults to nearest pixel sampling.
include/SDL_hints.h
src/render/direct3d/SDL_render_d3d.c
src/render/opengl/SDL_render_gl.c
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
--- a/include/SDL_hints.h	Sun Mar 13 11:17:11 2011 -0700
+++ b/include/SDL_hints.h	Sun Mar 13 11:18:35 2011 -0700
@@ -98,6 +98,18 @@
 #define SDL_HINT_RENDER_OPENGL_SHADERS      "SDL_RENDER_OPENGL_SHADERS"
 
 /**
+ *  \brief  A variable controlling the scaling quality
+ *
+ *  This variable can be set to the following values:
+ *    "0" or "nearest" - Nearest pixel sampling
+ *    "1" or "linear"  - Linear filtering (supported by OpenGL and Direct3D)
+ *    "2" or "best"    - Anisotropic filtering (supported by Direct3D)
+ *
+ *  By default nearest pixel sampling is used
+ */
+#define SDL_HINT_RENDER_SCALE_QUALITY       "SDL_RENDER_SCALE_QUALITY"
+
+/**
  *  \brief  A variable controlling whether updates to the SDL 1.2 screen surface should be synchronized with the vertical refresh, to avoid tearing.
  *
  *  This variable can be set to the following values:
--- a/src/render/direct3d/SDL_render_d3d.c	Sun Mar 13 11:17:11 2011 -0700
+++ b/src/render/direct3d/SDL_render_d3d.c	Sun Mar 13 11:18:35 2011 -0700
@@ -26,6 +26,7 @@
 
 #include "../../core/windows/SDL_windows.h"
 
+#include "SDL_hints.h"
 #include "SDL_loadso.h"
 #include "SDL_syswm.h"
 #include "../SDL_sysrender.h"
@@ -137,11 +138,13 @@
     D3DPRESENT_PARAMETERS pparams;
     SDL_bool updateSize;
     SDL_bool beginScene;
+    D3DTEXTUREFILTERTYPE scaleMode;
 } D3D_RenderData;
 
 typedef struct
 {
     IDirect3DTexture9 *texture;
+    D3DTEXTUREFILTERTYPE scaleMode;
 } D3D_TextureData;
 
 typedef struct
@@ -451,6 +454,7 @@
         return NULL;
     }
     data->beginScene = SDL_TRUE;
+    data->scaleMode = D3DTEXF_FORCE_DWORD;
 
     /* Get presentation parameters to fill info */
     result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
@@ -537,6 +541,20 @@
     }
 }
 
+static D3DTEXTUREFILTERTYPE
+GetScaleQuality(void)
+{
+    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
+
+    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
+        return D3DTEXF_POINT;
+    } else if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) {
+        return D3DTEXF_LINEAR;
+    } else {
+        return D3DTEXF_ANISOTROPIC;
+    }
+}
+
 static int
 D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
@@ -553,6 +571,7 @@
         SDL_OutOfMemory();
         return -1;
     }
+    data->scaleMode = GetScaleQuality();
 
     texture->driverdata = data;
 
@@ -1018,10 +1037,13 @@
 
     D3D_SetBlendMode(data, texture->blendMode);
 
-    IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
-                                     D3DTEXF_LINEAR);
-    IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
-                                     D3DTEXF_LINEAR);
+    if (texturedata->scaleMode != data->scaleMode) {
+        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
+                                         texturedata->scaleMode);
+        IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
+                                         texturedata->scaleMode);
+        data->scaleMode = texturedata->scaleMode;
+    }
 
     result =
         IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
--- a/src/render/opengl/SDL_render_gl.c	Sun Mar 13 11:17:11 2011 -0700
+++ b/src/render/opengl/SDL_render_gl.c	Sun Mar 13 11:18:35 2011 -0700
@@ -393,6 +393,18 @@
     return SDL_TRUE;
 }
 
+static GLenum
+GetScaleQuality(void)
+{
+    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
+
+    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
+        return GL_NEAREST;
+    } else {
+        return GL_LINEAR;
+    }
+}
+
 static int
 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
@@ -455,7 +467,7 @@
 
     data->format = format;
     data->formattype = type;
-    data->scaleMode = GL_LINEAR;
+    data->scaleMode = GetScaleQuality();
     renderdata->glEnable(data->type);
     renderdata->glBindTexture(data->type, data->texture);
     renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
--- a/src/render/opengles/SDL_render_gles.c	Sun Mar 13 11:17:11 2011 -0700
+++ b/src/render/opengles/SDL_render_gles.c	Sun Mar 13 11:18:35 2011 -0700
@@ -23,6 +23,7 @@
 
 #if SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED
 
+#include "SDL_hints.h"
 #include "SDL_opengles.h"
 #include "../SDL_sysrender.h"
 
@@ -292,6 +293,18 @@
     return value;
 }
 
+static GLenum
+GetScaleQuality(void)
+{
+    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
+
+    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
+        return GL_NEAREST;
+    } else {
+        return GL_LINEAR;
+    }
+}
+
 static int
 GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 {
@@ -345,7 +358,7 @@
 
     data->format = format;
     data->formattype = type;
-    data->scaleMode = GL_LINEAR;
+    data->scaleMode = GetScaleQuality();
     glBindTexture(data->type, data->texture);
     glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
--- a/src/render/opengles2/SDL_render_gles2.c	Sun Mar 13 11:17:11 2011 -0700
+++ b/src/render/opengles2/SDL_render_gles2.c	Sun Mar 13 11:18:35 2011 -0700
@@ -24,6 +24,7 @@
 
 #if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED
 
+#include "SDL_hints.h"
 #include "SDL_opengles2.h"
 #include "../SDL_sysrender.h"
 #include "SDL_shaders_gles2.h"
@@ -234,6 +235,18 @@
 static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
                                const void *pixels, int pitch);
 
+static GLenum
+GetScaleQuality(void)
+{
+    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
+
+    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
+        return GL_NEAREST;
+    } else {
+        return GL_LINEAR;
+    }
+}
+
 static int
 GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
 {
@@ -266,7 +279,7 @@
     tdata->texture_type = GL_TEXTURE_2D;
     tdata->pixel_format = format;
     tdata->pixel_type = type;
-    tdata->scaleMode = GL_LINEAR;
+    tdata->scaleMode = GetScaleQuality();
 
     /* Allocate a blob for image data */
     if (texture->access == SDL_TEXTUREACCESS_STREAMING)
@@ -286,8 +299,6 @@
     glGenTextures(1, &tdata->texture);
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(tdata->texture_type, tdata->texture);
-    glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);