So, i don’t know how graphics hardware works, but from SDL knowledge i know that a texture uses the memory of the GPU for faster performance. So every time i use CreateTextureFromSurface() i will probably exhaust the memory of the GPU, or if someone else makes sure to handle this i will still probably cause some performance issues.
In my game engine i have a sprite class that can have the following rules:
- You can make clones of this sprite.
- On scene initialization, multiple sprites can load a texture from the same path (image).
So what if n sprites load the same image? I will have n copies of the same texture? This applies also when i clone the sprite.
So this is my solution:
I will create a tree (in main memory) that will use the path (of an image) as the key. This tree will store 3 things, the path , a reference to the texture and a reference counter.
Every time a sprite tries to load a texture, first it will search in the tree to see if the path of the image is already registered. If it is then it will take a copy of the texture’s reference and it will increase the ref counter, else it will load the texture and add a new node into the tree.
Also each sprite object will have a reference to its relative node so when the sprite object is destroyed, will decrease the ref counter. When the ref counter reaches zero we delete the node from the tree and we also call SDL_DestroyTexture() to destroy the texture.
So if we have 500 sprites that uses the same image, only one texture will be rendered!
This might be similar to garbage collection but its a lot faster!!!
The only think i’m loosing is Ram (for the tree) and some speed (when i search in the tree) but still if i make sure that this tree is balanced the search algorithm will be very fast.
Also all of this will probably only happen at scene loading except when at run time the player creates clones of a sprite (like bullets from a gun).
I think this is a good solution, but because i don’t really know how textures and graphics hardware works, i want your advice.
This is (kind of) how I do it in my own render library.
I have an asset manager object, containing a texture list (std::vector) of texture object pointers. Each texture object contains a reference counter to keep track of how many objects that’s using that specific texture. Whenever an object loads a texture, the list is checked to see if that specific texture is already loaded, and if it is, that specific texture object is returned and the reference counter is increased by 1. If that specific texture doesn’t exist in the texture list, a new texture object is created, added into the texture list and finally returned to the object that loaded the texture in the first place.
At shutdown of the game / application, the reference counter for each texture object is decreased, for each object that’s using that texture, and when the reference counter is at zero (0), the texture object is destroyed and removed from the texture list.
The common term for this is texture pooling, shader pooling etc and it’s a good approach in my opinion.
A side note: when creating a game that’s using multiple objects of the same type (bullets, particles etc), don’t create the bullets during run time. What you can do instead, at the startup of the game, is creating a list of bullet object pointers. Then, whenever the player is supposed to shoot a bullet, check the list for a free bullet (by checking a bool named ‘Used’ for example, which is set to true whenever the bullet is shot), return the free bullet and render it on the screen. Whenever the bullet is destroyed, i.e when the bullet hits an enemy, a wall etc, set ‘Used’ back to false, which let’s the code know that the specific bullet can be used next time the player is supposed to shoot a bullet.
By keeping a list of bullets, you don’t have to call ‘new’ and ‘delete’ whenever the player is supposed to shoot a bullet, which saves performance of your game.
Thank you!!! You’re tip about the bullets is actually quite clever! I’m gonna apply the same technique for my rendering system but i will use a tree instead (to increase the search speed).