A friend of mine was a little confused about the best way to use XNA's LoadGraphicsContent API, so I thought I'd try to clarify it a bit here.
In general, your XNA Game object (or DrawableGameComponent object) will experience the following calls:
- Constructor
- Initialize()
- LoadGraphicsContent()
- Update / Draw repeatedly
- UnloadGraphicsContent()
- (maybe) goto 3
- Dispose()
In your constructor, you don't want to do much of anything. Assign values to things that aren't allowed to be null later, and maybe cache some constructor parameters into private fields of your object. Constructors in C# as a rule should avoid throwing exceptions. Try not to call any system APIs or anything that uses a resource, since that's a good way to encounter an exception. You can and should set your graphics preferences on the graphics object here.
In Initialize you have a lot more freedom. Your graphics object has been initialized and you should have a valid device. This is a good place for all the object creation and system calls that you wanted to make in your constructor. Don't load any Textures or Models yet though.
Load your Textures and Models in LoadGraphicsContent instead. This will get called every time the graphics card is reset (e.g. if the application moves from one monitor to another) and if you load a Texture in Initialize you'll be in for a nasty surprise after the device resets and you didn't reload it in LoadGraphicsContent. This is also where you want to create new RenderTargets.
UnloadGraphicsContent gets called when the device is being reset, or your application is ending. If you've loaded anything that needs explicit disposal, do that here. You'll notice the boilerplate telling the Content Manager to dump what it's loaded. If the device is being reset this call should be followed by a LoadGraphicsContent with the new graphics device settings.
You will rarely need to override Dispose. If you load something in Initialize that requires disposal you should do it here.
Update: One thing I forgot to mention about Initalize - if you are making a
GameComponent, you don't want to make any assumptions about whether you are
going to be drawn or receive updates soon. It could be a while between the
time an application initializes a component and when it actually gets to update
or draw. Some of the XNA documention samples do things in Initialize they probably shouldn't - for example, one of the audio
samples plays a sound in Initialize (that gaffe in the docs is my
fault, actually). While you can get away with that in a Game object it's a
bad habit in general.
Update2: If you want to control when LoadGraphicsContent is called, call Initialize on your Game's base class.
Labels: XNA