We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2573

Summary: Should srcRect in SDL_RenderCopy effect SDL_HINT_RENDER_SCALE_QUALITY?
Product: SDL Reporter: Diego <diegoacevedo91>
Component: renderAssignee: Sam Lantinga <slouken>
Status: RESOLVED WONTFIX QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: HG 2.0   
Hardware: x86_64   
OS: Mac OS X (All)   

Description Diego 2014-06-05 19:09:55 UTC
Currently, when using SDL_HINT_RENDER_SCALE_QUALITY linear, a texture is filtered with respect to the pixels outside of the source rectangle. I don't know how rational this is, but in my opinion when using a srcRect, the linear filter should not blend with pixels of the texture outside the srcRect.
The following code demonstrates this effect.
A half red and half blue square is created. The srcRect is set on just the red half. Using SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear") still shows blending with the blue half. Commenting out the hint obviously shows the nearest pixel sampling method. This is how I would expect the result to look when using a srcRect regardless of the SDL_HINT_RENDER_SCALE_QUALITY value.

/////CODE
#include <stdio.h>
#include "SDL.h"

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
static Uint32 rmask = 0xff000000;
static Uint32 gmask = 0x00ff0000;
static Uint32 bmask = 0x0000ff00;
static Uint32 amask = 0x000000ff;
#else
static Uint32 rmask = 0x000000ff;
static Uint32 gmask = 0x0000ff00;
static Uint32 bmask = 0x00ff0000;
static Uint32 amask = 0xff000000;
#endif

int main(int argc, char *argv[]) {
    
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
        printf("Could not initialize SDL\n");
        return 1;
    }
    
    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
    
    SDL_Window *window = SDL_CreateWindow("Title", SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,500,500, SDL_WINDOW_SHOWN);
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
    
    SDL_Surface *surface = SDL_CreateRGBSurface(0, 10, 10, 32, rmask, gmask, bmask, amask);
    SDL_FillRect(surface, &(SDL_Rect){0,0,5,10}, SDL_MapRGBA(surface->format, 255, 0, 0, 255));
    SDL_FillRect(surface, &(SDL_Rect){5,0,5,10}, SDL_MapRGBA(surface->format, 0, 0, 255, 255));
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_FreeSurface(surface);
    
    SDL_Rect src = {0,0,5,10};
    SDL_Rect dst = {0,0,250,500};
    
    SDL_bool running = SDL_TRUE;
    while (running) {
        
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, &src, &dst);
        SDL_RenderPresent(renderer);
        
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                running = SDL_FALSE;
                break;
            }
        }
        
        SDL_Delay(100);
    }
    
    return 0;
}
Comment 1 Sam Lantinga 2014-06-22 16:53:21 UTC
I don't know of a way to specify the behavior you're looking for that works across video APIs, without using compute shaders. If you find one, please let me know!

In the meantime, if you're using tiled sprites or something similar, make sure you put a transparent pixel between animation frames.