[MDX] Creating a texture management class...

Started by
8 comments, last by Moe 17 years, 7 months ago
Something I have been wanting to do for some time now is create a texture management class. The idea behind it is that I don't want to load the same texture more than once into memory - it's just a waste of memory to do so. Suppose that two models share the same texture. In such an event, I only want to load one texture. I have just started looking into this. Since I am using Managed DirectX, I figured I might as well use some of the .Net built in features, rather than code my own Linked List (or something similar). I have come across the Generic List and ArrayList classes. I basically want to use one of these to store a 'list' of textures. Here is how I am thinking that it will work: 1. The user creates an instance of the TextureManager class (which contains the List or ArrayList of textures) 2. The user uses the LoadTexture() function of the TextureManager class to load a texture. The function first searches the list of loaded textures. If the texture does not exist in the list, the texture is loaded, and a reference to it is returned. If the texture does exist in the list, a reference is returned to the already existing texture. 3. The user happily does whatever with the texture. I figure it will centralize all my texture loading, and make it a little more memory efficient (if someone tries to load more than one instance of the same texture). It also provides a central point to reload all the textures if the device is lost and needs to be reset. It could also make it easier to see when the last time a particular texture has been used, as all the textures for the program will be in the list. I am just wondering what you guys think of this. Is this a good or bad idea?
Advertisement
This is absolutely required for any game besides the most basic stuff. The easiest way I have done this in the past is to use create a cache class that uses a hashtable keyed on the filename. If you design it right, you can make it generic enough to handle multiple types of resources (if handling them the same way makes sense in your project).
The hashtable idea above probably is the best choice. I've seen a Map class in C++ a few times, which basically does the same thing, maybe that clears up the concept a bit better. You can make it a bit more fancy by using some generic/parametrized dictionary class in .NET 2.0, but the basic principle of resource retrieval by some key (most likely a filename) remains the same.

In case you're interested, you'll find a hashtable based resource manager over here. I wrote it a while ago, but I still use it for smaller projects, so it might be helpful.
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
In .NET, you typically want to use a Dictionary<> of some sort.

Make sure you normalize the path to the texture, by lower-casing it, and turning it into an absolute path. Else you may get the same texture loaded through different paths ("foo.dds" vs "../DATA/Foo.DDS") loaded twice.

When you do this, I would additionally return a texture wrapper class, rather than the texture pointer directly. If the manager has a reference to all the loaded textures, then it can do cool stuff like unload and reload the tetxure without the user knows it (very handy when changing or even re-creating the device).
enum Bool { True, False, FileNotFound };
Suppose it's not a must, but in my resource manager[since everything is done by one system], I've included a reference counter that automatically unloads the texture[or any other resource] when the counter is decremented to zero. Personally found it rather useful for transitioning between game segments, not having to manually unload the stuff when they are finished.

If you're tricky, and willing to wade through a bit of template soup, you can set the whole thing up to require nothing more than passing a load and unload function into a manager, and having it make a completely new manager for you, but that can get pretty messy. Or you can have one resource manager handle all the different types [which is a much cleaner way of doing it in my personal opinion].
Quote:Original post by hplus0603
When you do this, I would additionally return a texture wrapper class, rather than the texture pointer directly. If the manager has a reference to all the loaded textures, then it can do cool stuff like unload and reload the tetxure without the user knows it (very handy when changing or even re-creating the device).


Just to touch on that, if you load textures into the Managed Pool, aren't they automatically re-loaded when the device is lost and recreated?
Quote:Original post by Maxamor
Quote:Original post by hplus0603
When you do this, I would additionally return a texture wrapper class, rather than the texture pointer directly. If the manager has a reference to all the loaded textures, then it can do cool stuff like unload and reload the tetxure without the user knows it (very handy when changing or even re-creating the device).


Just to touch on that, if you load textures into the Managed Pool, aren't they automatically re-loaded when the device is lost and recreated?

Managed resources survive a device reset, but no resource would survive changing or recreating the device completely [smile]

Regards,
ViLiO
Richard 'ViLiO' Thomasv.net | Twitter | YouTube
Thanks for clearing that up :) I had been letting the resources (textures only, for now) in my project reload themselves... looksl ike I'll need to have a backup plan.
Maxamor: I can't remember off the top of my head.

I am glad to hear that this is a somewhat commonly used architecture. I had originally thought of doing separate managers for Textures, Meshes, and Map data (and possibly a few other things, such as sounds, music, etc).

hplus0603: Good point about cleaning up filenames. I hadn't thought about
Quote:Original post by remigius
In case you're interested, you'll find a hashtable based resource manager over here. I wrote it a while ago, but I still use it for smaller projects, so it might be helpful.

Thanks for the excellent article. I am going to see if I can write my own version using the .Net Dictionary class. Very good article! Thanks for the link.

EDIT - I just had an interesting though (although I haven't thoroughly thought it through, but maybe you can tell me if it makes ense). I could create a generic resource class that contains basically just a filename. From that generic class I could inherit a few new classes - one for a TextureResource, one for a SoundResource, etc. The Dictionary class based ResourceManager class would use the generic resource class. That way, if I need to add a new resource class, all I do is inherit from the generic resource class. The ResourceManager class should then be able to handle any new resource types that I come up with. Would this at all work?

[Edited by - Moe on September 8, 2006 12:57:47 PM]

This topic is closed to new replies.

Advertisement