| Summary: | Should srcRect in SDL_RenderCopy effect SDL_HINT_RENDER_SCALE_QUALITY? | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Diego <diegoacevedo91> |
| Component: | render | Assignee: | 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) | ||
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. |
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; }