I'm trying to convert my emulator to SDL2 (from SDL 1.2).
As I'm drawing pixel per pixel, I follow "If your game just wants to get fully rendered frames to the screen" in the migration guide: https://wiki.libsdl.org/MigrationGuide#If_your_game_just_wants_to_get_fully-rendered_frames_to_the_screen
I basically do:
SDL_CreateWindowAndRenderer(...);
vid = SDL_CreateRGBSurface(..., bpp, ...);
texture = SDL_CreateTextureFromSurface(renderer, vid);
// ... and then later, when "blitting" ...
SDL_UpdateTexture(texture, NULL, vid->pixels, vid->pitch);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
It works fine if I use 32bpp but this doesn't work for other bpp: the colors are not as expected. This is because the surface has a pixel format with the BPP I want but the texture has a different pixel format. This is problematic because:
- I have some (optional) specific scaling algorithms that require 16bpp surfaces
- I'm not sure whether it will behave the same for all users
- When not scaling with my own algorithms, the performance is better if I directly use the bpp of the display
The reason why the bpp doesn't match is that the SDL_UpdateTexture accesses the surface data (pixels) without even looking at the pixel format and SDL_CreateTextureFromSurface creates a texture compatible with the renderer, not caring about the surface format.
So my questions are:
- Is there a simple way to get a surface that is compatible with the renderer? [1]
- Is there a way to blit the surface on the texture that does the color conversion? [2]
[1] I found:
SDL_RendererInfo infos;
SDL_GetRendererInfo(renderer, &infos);
vid = SDL_CreateRGBSurfaceWithFormat(0, w, h, SDL_BITSPERPIXEL(infos.texture_formats[0]), infos.texture_formats[0]);
but it's a bit heavy, there are multiple supported so I'm not sure which one to choose and I also had some display issues that suggest the result is not really what I want.
[2] One idea I had is to have another surface with the format taken from [1] and to blit to it first for the conversion, before copying it to the texture, but I'm surprised there's no simpler way to do it.