Some beginner questions about Surface and FRect

Hi there,

i am currently learning SDL and i really like it so far. Its a very nice API and as someone who really likes C, i highly appreciate it being written in C.

I home some experience developing games for the MegaDrive which is one of the reasons i decided for SDL (For me, it feels like developing for an MegaDrive without Hardware Limitations (almost :P))

If i am not mistaken, it works like this.

SDL_Surface → Contains the Image (For example an Tilemap) and is in the Main/CPU RAM
SDL_Texture → Contains a copy (or parts) of the Surface and is in the GPU RAM (VRAM)

For example an 2D top down view game, different tilesets are used for the city outside and the inside of buildings. I assume i would create multiple Surfaces, one that holds the tileset for outside and one that holds the tileset for inside and then, depending on where the character currently is and what is supposed to be displayed, create Textures from the Surfaces and use the SDL_Renderer to render and present them on the screen.

I noticed in the examples (because they are not used a second time), they instantly get destroyed after the Texture is created. Because i am a bit unsure about how and what SDL does in the background i want to make sure. As long the Player does not leave the city, there would be no issue leave the Surface as it is and only destroy it, when the city is left, right?

Maybe i am overthinking this because an Tileset is <=150kb so loading from the HDD doesn’t hurt much, but will be slower than just leaving it in RAM and i assume, whatever system is executing my game, has ~1mb for tilesets in RAM to spare :stuck_out_tongue:

I just want to make sure that SDL doesn’t expect me to Destroy them after i created an Texture from them, better be safe than sorry.

The other question is, when i use RenderTexture, i have to use an FRect as Source and Destination, right (or use NULL if i want the whole Texture to be rendered).

The question here is, due to very limited VRAM, the MegaDrive Approach would be to load only the parts into VRAM you want to draw in the scene you are seeing. But looking at the examples, it looks like the better approach would be to load the Whole Tileset (again, 150kb) into VRAM and then use FRect to decide what i want to be shown on screen. Please feel free to point out when i am understanding something fundamentally wrong here.

Example: Create Surface with Outdoor Tiles and a second Surface with Indoor Tiles → Create Texture from Outdoor Tiles Surface → Create an FRect called grass, span over the grass → Create FRect pointing to the position i want the grass → Render → Point the FRect to the next position i want it → Render → When everthing is rendered → Destroy FRect → Present → Player goes inside building → Destroy Outdoor Texture → Create Indoor Texture → and so on and so on

Is that the best practice? Sorry if that is an silly question^^

You can destroy the surfaces whenever you want. You can even skip creating surfaces and just create the textures directly using IMG_LoadTexture (assuming you’re using SDL_image and don’t need the surface for anything).

2 Likes

Thank you very much! In that case, the instant Destroy in the examples is simply because it is never used again and for no other reason. Thanks for clearing that up!

And thanks for the tip with IMG_LoadTexture too =)

For each tileset, just load the whole thing into RAM as an SDL_Surface, create a texture from it, then destroy the SDL_Surface. You don’t need to load tilesets into textures on the fly. It’s OK to have multiple tilesets loaded at once.

So I would do it more like
Load images into textures (via temporary surfaces)
Have some method of determining where each tile type is on the texture
“Create” a source FRect (do not malloc() this!)
Have a destination FRect where to draw the grass
Render it

Reassign source FRect to point to another tile
Set destination FRect accordingly
Render it

SDL_RenderPresent() when everything is done

And when the player goes inside, just switch to using the “inside” tileset and texture. No need to destroy the “outside” texture.

Any computer that SDL 3 supports has plenty of VRAM.

1 Like

Here’s a one liner I use on linux to launch the docs. You may want to spend time with it after you understand the basics, so its less mysterious what’s going on. If you’re using 2 you may want to change the below

7z x ~/sdlwiki.zip && xdg-open file:///tmp/sdlwiki/SDL3/APIByCategory.html

I just want to make sure that SDL doesn’t expect me to Destroy

It’s pretty well documented. There’s generally a destroy function for each create.

what SDL does in the background

I assume it does nothing in the background and I haven’t hit any problems. Most of my surfaces I create from pixel data that is generated one way or another (I deal with font and icon rendering). Once you have a texture you can destroy the surface. IIRC if you made a surface from your pixel data, you’d have to free your data separately. SDL3/SDL_CreateSurfaceFrom - SDL Wiki says “No copy is made of the pixel data. Pixel data is not managed automatically; you must free the surface before you free the pixel data.” so it’s fairly clear what you need to do for most function. Most functions are short and easy to read

@Levo You’re citing SDL_CreateSurfaceFrom but linking to SDL_CreateSurface.

1 Like