mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-01 23:48:29 +00:00
Added SDL_SCALEMODE_PIXELART
This is based on the algorithm presented by t3ssel8r: https://www.youtube.com/watch?v=d6tp43wZqps
This commit is contained in:
@@ -68,6 +68,7 @@ typedef struct
|
||||
int drawableh;
|
||||
SDL_BlendMode blend;
|
||||
GL_Shader shader;
|
||||
float texel_size[4];
|
||||
const float *shader_params;
|
||||
bool cliprect_enabled_dirty;
|
||||
bool cliprect_enabled;
|
||||
@@ -133,6 +134,7 @@ typedef struct
|
||||
GLenum format;
|
||||
GLenum formattype;
|
||||
GL_Shader shader;
|
||||
float texel_size[4];
|
||||
const float *shader_params;
|
||||
void *pixels;
|
||||
int pitch;
|
||||
@@ -627,6 +629,11 @@ static bool GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
|
||||
data->shader = SHADER_RGB;
|
||||
}
|
||||
|
||||
data->texel_size[2] = texture->w;
|
||||
data->texel_size[3] = texture->h;
|
||||
data->texel_size[0] = 1.0f / data->texel_size[2];
|
||||
data->texel_size[1] = 1.0f / data->texel_size[3];
|
||||
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (data->yuv || data->nv12) {
|
||||
if (data->yuv) {
|
||||
@@ -1081,6 +1088,7 @@ static bool SetTextureScaleMode(GL_RenderData *data, GLenum textype, SDL_ScaleMo
|
||||
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
break;
|
||||
case SDL_SCALEMODE_PIXELART: // Uses linear sampling
|
||||
case SDL_SCALEMODE_LINEAR:
|
||||
data->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
data->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
@@ -1113,8 +1121,24 @@ static bool SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
GL_TextureData *texturedata = (GL_TextureData *)texture->internal;
|
||||
const GLenum textype = data->textype;
|
||||
GL_Shader shader = texturedata->shader;
|
||||
const float *shader_params = texturedata->shader_params;
|
||||
|
||||
SetDrawState(data, cmd, texturedata->shader, texturedata->shader_params);
|
||||
if (cmd->data.draw.texture_scale_mode == SDL_SCALEMODE_PIXELART) {
|
||||
switch (shader) {
|
||||
case SHADER_RGB:
|
||||
shader = SHADER_RGB_PIXELART;
|
||||
shader_params = texturedata->texel_size;
|
||||
break;
|
||||
case SHADER_RGBA:
|
||||
shader = SHADER_RGBA_PIXELART;
|
||||
shader_params = texturedata->texel_size;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetDrawState(data, cmd, shader, shader_params);
|
||||
|
||||
if (texture != data->drawstate.texture) {
|
||||
#ifdef SDL_HAVE_YUV
|
||||
|
@@ -53,6 +53,7 @@ struct GL_ShaderContext
|
||||
PFNGLUNIFORM1IARBPROC glUniform1iARB;
|
||||
PFNGLUNIFORM1FARBPROC glUniform1fARB;
|
||||
PFNGLUNIFORM3FARBPROC glUniform3fARB;
|
||||
PFNGLUNIFORM4FARBPROC glUniform4fARB;
|
||||
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
|
||||
|
||||
bool GL_ARB_texture_rectangle_supported;
|
||||
@@ -261,6 +262,7 @@ static const char *shader_source[NUM_SHADERS][2] = {
|
||||
"varying vec4 v_color;\n"
|
||||
"varying vec2 v_texCoord;\n"
|
||||
"uniform sampler2D tex0;\n"
|
||||
"uniform vec4 texel_size; // texel size (xy: texel size, zw: texture dimensions)\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
@@ -284,6 +286,50 @@ static const char *shader_source[NUM_SHADERS][2] = {
|
||||
" gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n"
|
||||
"}"
|
||||
},
|
||||
|
||||
// SHADER_RGB_PIXELART
|
||||
{
|
||||
// vertex shader
|
||||
TEXTURE_VERTEX_SHADER,
|
||||
// fragment shader
|
||||
"varying vec4 v_color;\n"
|
||||
"varying vec2 v_texCoord;\n"
|
||||
"uniform sampler2D tex0;\n"
|
||||
"uniform vec4 texel_size;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 boxSize = clamp(fwidth(v_texCoord) * texel_size.zw, 1e-5, 1.0);\n"
|
||||
" vec2 tx = v_texCoord * texel_size.zw - 0.5 * boxSize;\n"
|
||||
" vec2 txOffset = smoothstep(vec2(1.0) - boxSize, vec2(1.0), fract(tx));\n"
|
||||
" vec2 uv = (floor(tx) + 0.5 + txOffset) * texel_size.xy;\n"
|
||||
" gl_FragColor = textureGrad(tex0, uv, dFdx(v_texCoord), dFdy(v_texCoord));\n"
|
||||
" gl_FragColor.a = 1.0;\n"
|
||||
" gl_FragColor *= v_color;\n"
|
||||
"}"
|
||||
},
|
||||
|
||||
// SHADER_RGBA_PIXELART
|
||||
{
|
||||
// vertex shader
|
||||
TEXTURE_VERTEX_SHADER,
|
||||
// fragment shader
|
||||
"varying vec4 v_color;\n"
|
||||
"varying vec2 v_texCoord;\n"
|
||||
"uniform sampler2D tex0;\n"
|
||||
"uniform vec4 texel_size;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 boxSize = clamp(fwidth(v_texCoord) * texel_size.zw, 1e-5, 1.0);\n"
|
||||
" vec2 tx = v_texCoord * texel_size.zw - 0.5 * boxSize;\n"
|
||||
" vec2 txOffset = smoothstep(vec2(1.0) - boxSize, vec2(1.0), fract(tx));\n"
|
||||
" vec2 uv = (floor(tx) + 0.5 + txOffset) * texel_size.xy;\n"
|
||||
" gl_FragColor = textureGrad(tex0, uv, dFdx(v_texCoord), dFdy(v_texCoord));\n"
|
||||
" gl_FragColor *= v_color;\n"
|
||||
"}"
|
||||
},
|
||||
|
||||
#ifdef SDL_HAVE_YUV
|
||||
// SHADER_YUV
|
||||
{
|
||||
@@ -466,6 +512,7 @@ GL_ShaderContext *GL_CreateShaderContext(void)
|
||||
ctx->glUniform1iARB = (PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB");
|
||||
ctx->glUniform1fARB = (PFNGLUNIFORM1FARBPROC)SDL_GL_GetProcAddress("glUniform1fARB");
|
||||
ctx->glUniform3fARB = (PFNGLUNIFORM3FARBPROC)SDL_GL_GetProcAddress("glUniform3fARB");
|
||||
ctx->glUniform4fARB = (PFNGLUNIFORM4FARBPROC)SDL_GL_GetProcAddress("glUniform4fARB");
|
||||
ctx->glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB");
|
||||
if (ctx->glGetError &&
|
||||
ctx->glAttachObjectARB &&
|
||||
@@ -511,23 +558,36 @@ void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader, const float *shade
|
||||
ctx->glUseProgramObjectARB(program);
|
||||
|
||||
if (shader_params && shader_params != ctx->shader_params[shader]) {
|
||||
// YUV shader params are Yoffset, 0, Rcoeff, 0, Gcoeff, 0, Bcoeff, 0
|
||||
location = ctx->glGetUniformLocationARB(program, "Yoffset");
|
||||
if (location >= 0) {
|
||||
ctx->glUniform3fARB(location, shader_params[0], shader_params[1], shader_params[2]);
|
||||
if (shader == SHADER_RGB_PIXELART ||
|
||||
shader == SHADER_RGBA_PIXELART) {
|
||||
location = ctx->glGetUniformLocationARB(program, "texel_size");
|
||||
if (location >= 0) {
|
||||
ctx->glUniform4fARB(location, shader_params[0], shader_params[1], shader_params[2], shader_params[3]);
|
||||
}
|
||||
}
|
||||
location = ctx->glGetUniformLocationARB(program, "Rcoeff");
|
||||
if (location >= 0) {
|
||||
ctx->glUniform3fARB(location, shader_params[4], shader_params[5], shader_params[6]);
|
||||
}
|
||||
location = ctx->glGetUniformLocationARB(program, "Gcoeff");
|
||||
if (location >= 0) {
|
||||
ctx->glUniform3fARB(location, shader_params[8], shader_params[9], shader_params[10]);
|
||||
}
|
||||
location = ctx->glGetUniformLocationARB(program, "Bcoeff");
|
||||
if (location >= 0) {
|
||||
ctx->glUniform3fARB(location, shader_params[12], shader_params[13], shader_params[14]);
|
||||
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (shader >= SHADER_YUV) {
|
||||
// YUV shader params are Yoffset, 0, Rcoeff, 0, Gcoeff, 0, Bcoeff, 0
|
||||
location = ctx->glGetUniformLocationARB(program, "Yoffset");
|
||||
if (location >= 0) {
|
||||
ctx->glUniform3fARB(location, shader_params[0], shader_params[1], shader_params[2]);
|
||||
}
|
||||
location = ctx->glGetUniformLocationARB(program, "Rcoeff");
|
||||
if (location >= 0) {
|
||||
ctx->glUniform3fARB(location, shader_params[4], shader_params[5], shader_params[6]);
|
||||
}
|
||||
location = ctx->glGetUniformLocationARB(program, "Gcoeff");
|
||||
if (location >= 0) {
|
||||
ctx->glUniform3fARB(location, shader_params[8], shader_params[9], shader_params[10]);
|
||||
}
|
||||
location = ctx->glGetUniformLocationARB(program, "Bcoeff");
|
||||
if (location >= 0) {
|
||||
ctx->glUniform3fARB(location, shader_params[12], shader_params[13], shader_params[14]);
|
||||
}
|
||||
}
|
||||
#endif // SDL_HAVE_YUV
|
||||
|
||||
ctx->shader_params[shader] = shader_params;
|
||||
}
|
||||
}
|
||||
|
@@ -33,6 +33,8 @@ typedef enum
|
||||
SHADER_SOLID,
|
||||
SHADER_RGB,
|
||||
SHADER_RGBA,
|
||||
SHADER_RGB_PIXELART,
|
||||
SHADER_RGBA_PIXELART,
|
||||
#ifdef SDL_HAVE_YUV
|
||||
SHADER_YUV,
|
||||
SHADER_NV12_RA,
|
||||
|
Reference in New Issue
Block a user