[SDL3.1.1] SDL_Renderer/SDL_Texture or SDL_Surface for sprites

What is the more efficient way when you have multiple sprites as BMP?
If you load an image with SDL_LoadBMP, you get an SDL_Surface. The same with the ttf fonts.

Now the question is, should you take the detour via SDL_Renderer and SDL_Texture or should you use SDL_Surface directly and replace it with SDL_UpdateWindowSurface(window); output directly?

These three links below provide answers that I feel are pretty acceptable, and reading all three gives a pretty solid explanation.
c - Difference between surface and texture (SDL / general) - Stack Overflow
https://www.reddit.com/r/gamedev/comments/6jfzf2/in_sdl2_what_is_the_difference_between_a_texture/
In SDL, what is the difference between using a Surfaces and a Renderer? - Game Development Stack Exchange

Basically, SDL_Texture/SDL_Renderer operations are going to be faster in most cases (especially in a game environment), but there are some instances in which processing a SDL_Surface is faster because it’s held in local RAM instead of in the GPU’s RAM.

  • If you do a lot of per-pixel editing on individual images, accessing pixel data will be potentially faster on an SDL_Surface.

  • On the other hand, if you have a dozen images that make up an animation, or a bunch of images that just need to be drawn in order to build a scene, it is better to use the SDL_Renderer.

Unless you have a specific reason not to, default to using a SDL_Texture.

1 Like

The software renderer is slow, so if you don’t need to constantly modify the contents of the sprites, use the hardware renderer — it is milion times faster, even for 2D rendering.

First, use PNG because they take up less space on the disk. Secondly, all sprites (animation frames of an object) should be in one image (called an atlas). Depending on how many sprites you have, you can have them all in one atlas, you can have one atlas for each type of object, or even several atlases per one type of object. Whatever is more convenient for you, there is a lot of freedom here — there is no one best way.

If I understand correctly, the SDL_Texture is comparable to the OpenGL texture buffers?
And the SDL_Renderer with the OpenGL frame buffer?
And the SDL_Surface is a bitmap processor that is processed with the CPU in RAM?

The software renderer is slow, so if you don’t need to constantly modify the contents of the sprites, use the hardware renderer — it is milion times faster, even for 2D rendering.

A million times is probably a bit exaggerated.

First, use PNG because they take up less space on the disk.

I am aware of this. BMP is an HDD eater.

SDL_Texture is an abstraction per GPU texture, regardless of the backend used by the renderer (DirectX, OpenGL, Vulkan, etc.). The texture is stored in VRAM (on the GPU side) and cannot be accessed directly, meaning you cannot modify it using the CPU.

To make this possible, you must first copy its data from VRAM to general RAM, use the CPU to process it, and then transfer the new content back to VRAM. Such data transfer is expensive. To modify the texture content without copying it from VRAM to RAM and back, you can use shaders, which is extremely effective.

SDL_Renderer is an abstraction to the selected backend and gives access to a set of functions for processing images and rendering them on the back buffer of the selected backend. Again, no matter which backend is chosen (DirectX, OpenGL, Vulkan, Metal, etc.), the same set of functions is used for rendering, which is very convenient. The downside is that this feature set is relatively small and has some computational overhead.

If the type of backend is not important to you and you do not need to render complex scenes, then SDL_Renderer is a very good solution. But if you want to, you can use the API of a specific backend manually (e.g. OpenGL) and not use the SDL renderer at all.

SDL_Surface is a block of memory stored in general RAM containing image data. You can process it normally using the CPU, but this is inefficient compared to the capabilities of the GPU.

Yep, which still does not change the fact that a CPU with even a dozen or so cores, with SSE and AVX, has no chance against a GPU with a thousand cores specialized in image processing. The difference is thousands, if not tens of thousands of times better performance.