Resource Managers

Started by
6 comments, last by Biggles 21 years, 4 months ago
OK, I was just going to search the forums for stuff about these, but the search function is unavailable so I''m posting it instead. How does a typical resource manager for a game work? Something like the resource manager for managing textures. When you want to load a texture, you tell the resource manager to give you that texture and supply it with the path and filename of the texture file. The resource manager then returns a pointer to that texture (or something similar). In between, it needs to check if the texture is already loaded and if it isn''t then load it. If it is, it just returns a pointer to that texture. Now, what I''m wondering is how would you store the data internally? Obviously you''d store pointers to dynamically allocated data, but would those be stored in an array or a hashtable or what? It would be nice to be able to search for an existing resource quickly, but if the search is only going to be performed when loading resources that may not be a problem (depending on when resources are loaded). Your thoughts? -------------------- Never eat anything bigger than your own head.
--------------------Never eat anything bigger than your own head.
Advertisement
Well, basicly what I do for my texture manager, is you call LoadTexture(char* filename) and it returns to you an ID, then internally it just increments the ID counter, and stores the texture into a linked list, then when you want to access that texture, you just refer to its ID, eg:

    int ID_CARTEXTURE = CTextureManager.LoadTexture("Data\\car.bmp");IDirect3DTexture8* CarTex = CTextureManager.GetTexture(ID_CARTEXTURE);    

But in my implimentation, you dont actually touch any of the holding the texture ID's, as I have a seperate sprite manager which again handles that in a similer way, (gives you an ID for a created sprite which holds its own texture ID). So in my way you have to load the textures first, and I would assume its alot (well maybe not alot ) faster since your only passing around an int value instead of the whole string everytime you use the function to get access to your texture...

[edited by - elis-cool on November 20, 2002 6:45:31 AM]
[email=esheppard@gmail.com]esheppard@gmail.com[/email]
You only want to check if a texture is already loaded or not in your resource manager ?
Typically the loading time for a resource manager is not of a great consequence when it is before the game start. I suppose you access your textures in game by an index to an array (either an int to a texture array, or use of a STL map).
To me, the most critical part is the in game access to the textures. You can have three ways to ensure you are not loading twice the same texture:
- load up all the textures at the initialization. (if the size and number of textures is small - the control that you will not incorporate twice the same texture is then left to your resource editor)
- store with each texture data in your resource manager a string with the full path and name of the texture file. (you will need to define a check method and to redefine a get texture method to retrieve during the game the right information)
- use the filename as the index to your texture array if you use the STL map container (the path and the extension are not included to the index: they are appended to the filename if the search for map[index] does return nothing)

Hope that helps.
Ghostly yours,
Red.
Ghostly yours,Red.
I''ve got a couple different resource managers, like one for textures, one for models, that kinda thing. Well, mine uses a hash table as an internal method, and uses a linked list to resolve conflicts. It uses two unsigned shorts (2 bytes each), one for the position in the hash table, and the other for the conflict resolution.

It loops through each entry in the specified hash table location, and checks it''s conflict short with the desired one. That way, I can pass strings to the managers like so: Hash( "Filename Here" ).

Unfortunately, this requires that the texture be loaded before hand, but I have the method in each of my Texture objects such as this: Load( char* strPath, char* strFile ) and the object will pass the call up to the main texture manager. This way, if you load a texture in a small function, it will add it to the main ''texture pool''.

I also encapsulate the ID in an object, like the Texture object. That way, the object doesn''t load any data, but only has a reference to it, and the memory usage goes WAY down. This also allows the file to be loaded once in the beginning of the program.

If your program uses archives (like mine), then simply convert all the filenames into hash values when you load the files. This way, if the texture manager doesn''t have the file loaded and you try to get the texture, it can iterate through the open packages and try to find a match. Good Luck!

Chris
~~ <ctoan> ~~
As most of my games are sprite-based (I''ll be old-school ''till death ) I have created a library that allows me to create tiles and sprites from bitmap images. I just load the sprite bitmap on an off-screen surface, lock the surface, load all the sprites with my library, then I can just ditch the off-screen surface and am left with a series of sprites/tiles in arrays which I can apply transformations to. For instance, I can swap pointers around to rapidly animate them, I can apply filters like blurring, tinting...

Basically, I have a function that dynamically creates an array that''ll hold the sprite or tile in question. I then read off the surface (with lock; though since this is usually pre-loading and not in-game stuff it hardly matters; I can just lock once, load everything, and that''s that.). The array contains the sprite''s size (X, Y), the sprite''s actual pixel data, then if I need transparency, the actual pixels to plot (as well as how many "masked" pixels there are).

In the case of tiles, I don''t create a mask (unless they require transparency, like little rocks on the ground or something like that). I can also, optionally, create a palette instead of using 32bit colors, which allows tinting and other color-based functions to perform easier.

It works great and makes things easy to manage. All''s I''d need is a sound/music handler, maybe a string ressource handler.
OK, what I was thinking was that I''d have a resource manager for each kind of resource. Say I want a new texture loaded. I would say to the texture manager, "load me this texture" and provide it with a path and filename. The texture manager would handle all the loading required (or a texture specific resource class would, and the texture manager would create one of these). The texture manager would pass back a resource ID or something similar. When I want to use the texture, I would give it the resource ID and it would give me back a pointer to the texture. I could then use it.
Would the best method of internal storage be a hash table? I guess it would depend on exactly how I use the resources stored in the resource manager. If I got a pointer back at load time and could use that all along, then there would be no searching on use. But if I got a resource ID, I''d have to search on every use.

--------------------
Never eat anything bigger than your own head.
--------------------Never eat anything bigger than your own head.
Biggles, your latest question was answerd earlier in the post.

One thing I''d like to point out, (although pretty ovious), is that for most all computer gaming, you want to try and eliminate as MUCH runtime loading as possible.
Why?
If juggle the numbers for CPU time that it takes to access and read HDD data, you''ll find that you loose about 30% speed that you would have had to compute the game.

Through everything, I try to preload as much as possible. I''m an array junkie, so all my stuff (textures, models, objects) loaded into an array, with everything else simply storing integers, which reference the location of that entity in it''s designated array.
My philosophy, is that if ANYTHING needs to be loaded during run time, it''s bad. Even if it''s a single texture, used for a single instance, and never used again, i either preload it, and take the memory hit, or i decide to use something else in order to accomplish the goal.

Just my input on the situation. Pretty sure everyone already knew that, but i had some time left in my lunch break

~Main

==
Colt "MainRoach" McAnlis
Programmer
www.badheat.com/sinewave
==Colt "MainRoach" McAnlisGraphics Engineer - http://mainroach.blogspot.com
You speak but the truth.
Given the cost of memory these days, having a larger memory footprint is really a small price to pay for the huge savings in load time. I think I shall use an array and make the resource ID the index into the array. That seems to be the method most people here think is best.
--------------------Never eat anything bigger than your own head.

This topic is closed to new replies.

Advertisement