Commit a19e2587 authored by Sam Lantinga's avatar Sam Lantinga

Added the SDL_HINT_RENDER_SCALE_QUALITY hint, which defaults to nearest pixel sampling.

parent fbc49bee
...@@ -97,6 +97,18 @@ extern "C" { ...@@ -97,6 +97,18 @@ extern "C" {
*/ */
#define SDL_HINT_RENDER_OPENGL_SHADERS "SDL_RENDER_OPENGL_SHADERS" #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. * \brief A variable controlling whether updates to the SDL 1.2 screen surface should be synchronized with the vertical refresh, to avoid tearing.
* *
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_windows.h"
#include "SDL_hints.h"
#include "SDL_loadso.h" #include "SDL_loadso.h"
#include "SDL_syswm.h" #include "SDL_syswm.h"
#include "../SDL_sysrender.h" #include "../SDL_sysrender.h"
...@@ -137,11 +138,13 @@ typedef struct ...@@ -137,11 +138,13 @@ typedef struct
D3DPRESENT_PARAMETERS pparams; D3DPRESENT_PARAMETERS pparams;
SDL_bool updateSize; SDL_bool updateSize;
SDL_bool beginScene; SDL_bool beginScene;
D3DTEXTUREFILTERTYPE scaleMode;
} D3D_RenderData; } D3D_RenderData;
typedef struct typedef struct
{ {
IDirect3DTexture9 *texture; IDirect3DTexture9 *texture;
D3DTEXTUREFILTERTYPE scaleMode;
} D3D_TextureData; } D3D_TextureData;
typedef struct typedef struct
...@@ -451,6 +454,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) ...@@ -451,6 +454,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
return NULL; return NULL;
} }
data->beginScene = SDL_TRUE; data->beginScene = SDL_TRUE;
data->scaleMode = D3DTEXF_FORCE_DWORD;
/* Get presentation parameters to fill info */ /* Get presentation parameters to fill info */
result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
...@@ -537,6 +541,20 @@ D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) ...@@ -537,6 +541,20 @@ D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
} }
} }
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 static int
D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
...@@ -553,6 +571,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -553,6 +571,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
SDL_OutOfMemory(); SDL_OutOfMemory();
return -1; return -1;
} }
data->scaleMode = GetScaleQuality();
texture->driverdata = data; texture->driverdata = data;
...@@ -1018,10 +1037,13 @@ D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, ...@@ -1018,10 +1037,13 @@ D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
D3D_SetBlendMode(data, texture->blendMode); D3D_SetBlendMode(data, texture->blendMode);
if (texturedata->scaleMode != data->scaleMode) {
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER, IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
D3DTEXF_LINEAR); texturedata->scaleMode);
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER, IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
D3DTEXF_LINEAR); texturedata->scaleMode);
data->scaleMode = texturedata->scaleMode;
}
result = result =
IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *) IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
......
...@@ -393,6 +393,18 @@ convert_format(GL_RenderData *renderdata, Uint32 pixel_format, ...@@ -393,6 +393,18 @@ convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
return SDL_TRUE; 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 static int
GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
...@@ -455,7 +467,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -455,7 +467,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
data->format = format; data->format = format;
data->formattype = type; data->formattype = type;
data->scaleMode = GL_LINEAR; data->scaleMode = GetScaleQuality();
renderdata->glEnable(data->type); renderdata->glEnable(data->type);
renderdata->glBindTexture(data->type, data->texture); renderdata->glBindTexture(data->type, data->texture);
renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#if SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED #if SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED
#include "SDL_hints.h"
#include "SDL_opengles.h" #include "SDL_opengles.h"
#include "../SDL_sysrender.h" #include "../SDL_sysrender.h"
...@@ -292,6 +293,18 @@ power_of_2(int input) ...@@ -292,6 +293,18 @@ power_of_2(int input)
return value; 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 static int
GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ {
...@@ -345,7 +358,7 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ...@@ -345,7 +358,7 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
data->format = format; data->format = format;
data->formattype = type; data->formattype = type;
data->scaleMode = GL_LINEAR; data->scaleMode = GetScaleQuality();
glBindTexture(data->type, data->texture); glBindTexture(data->type, data->texture);
glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED #if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED
#include "SDL_hints.h"
#include "SDL_opengles2.h" #include "SDL_opengles2.h"
#include "../SDL_sysrender.h" #include "../SDL_sysrender.h"
#include "SDL_shaders_gles2.h" #include "SDL_shaders_gles2.h"
...@@ -234,6 +235,18 @@ static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture); ...@@ -234,6 +235,18 @@ static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
const void *pixels, int pitch); 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 static int
GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{ {
...@@ -266,7 +279,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) ...@@ -266,7 +279,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
tdata->texture_type = GL_TEXTURE_2D; tdata->texture_type = GL_TEXTURE_2D;
tdata->pixel_format = format; tdata->pixel_format = format;
tdata->pixel_type = type; tdata->pixel_type = type;
tdata->scaleMode = GL_LINEAR; tdata->scaleMode = GetScaleQuality();
/* Allocate a blob for image data */ /* Allocate a blob for image data */
if (texture->access == SDL_TEXTUREACCESS_STREAMING) if (texture->access == SDL_TEXTUREACCESS_STREAMING)
...@@ -286,8 +299,6 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) ...@@ -286,8 +299,6 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
glGenTextures(1, &tdata->texture); glGenTextures(1, &tdata->texture);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(tdata->texture_type, tdata->texture); 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_S, GL_CLAMP_TO_EDGE);
glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, 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); glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment