| Summary: | SDL_SetSurfaceBlendMode doesn't function on indexed-colour types | ||
|---|---|---|---|
| Product: | SDL | Reporter: | mattreecebentley |
| Component: | render | Assignee: | Sam Lantinga <slouken> |
| Status: | NEW --- | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | CC: | sylvain.becker |
| Version: | 2.0.4 | ||
| Hardware: | x86_64 | ||
| OS: | Windows 7 | ||
| Attachments: |
test case
input image for the test case |
||
|
Description
mattreecebentley
2016-06-05 00:07:42 UTC
I would suggest you to write a minimal test case. Haven't tested this, but should be close enough
// Create a 32-bit, alpha-channeled SDL_Surface in the appropriate endian order for the given platform:
inline SDL_Surface * create_surface(const int width, const int height)
{
/* SDL interprets each pixel as a 32-bit number, so our masks must depend
on the endianness (byte order) of the machine */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
return SDL_CreateRGBSurface(0, width, height, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
#else
return SDL_CreateRGBSurface(0, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
#endif
}
std::vector <SDL_Texture *> frames;
int add_frames_from_tile(const char *image_filename, const unsigned int number_of_frames, const unsigned int frame_width)
{
SDL_Surface *tiles_surface = IMG_Load(image_filename);
const int total_width = static_cast<int>(number_of_frames * frame_width);
// Create a frame surface for copying the individual frames to:
SDL_Surface *frame_surface = create_surface(frame_width, tiles_surface->h);
SDL_Texture *frame;
SDL_SetSurfaceBlendMode(tiles_surface, SDL_BLENDMODE_NONE);
SDL_SetSurfaceBlendMode(frame_surface, SDL_BLENDMODE_NONE);
SDL_Rect source_rectangle = {0, 0, static_cast<int>(frame_width), tiles_surface->h};
for (; source_rectangle.x != total_width; source_rectangle.x += frame_width)
{
// Sprite tiles will be overlaid without this line:
// SDL_FillRect(frame_surface, NULL, 0x000000);
SDL_BlitSurface(tiles_surface, &source_rectangle, frame_surface, NULL);
frame = SDL_CreateTextureFromSurface(Renderer, frame_surface);
frames.push_back(frame);
}
SDL_FreeSurface(tiles_surface);
SDL_FreeSurface(frame_surface);
return 0;
}
Created attachment 2484 [details]
test case
Created attachment 2485 [details]
input image for the test case
Here's a small test case, just loading and saving surface/image. This issue happens because the *alpha* channel of a palette surface, is in fact a color key. So you don't have to set the "blend mode" to none, but disable the color key, then re-enable it on the output. Since color key is color, you need to retrieve it, convert it from the input pixel_format, to the output pixel_format, to set it back. ( Maybe SDL_SetSurfaceBlendMode could be translated as "disable colorkey" for palette surface ? but to re-activate it, you need the explicit value. |