Xbox LIVE Indie Games
Sort Discussions: Previous Discussion Next Discussion
Page 1 of 1 (16 posts)

XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

Last post 12/7/2009 1:47 PM by Sergiusz. 15 replies.
  • 3/15/2009 5:17 PM

    XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    Hello guys,

    I am using XNA 3.0 for some time. Now I need to properly handle LoadContent, UnloadContent, reset of
    graphics device, etc. And all this even if game has more levels/sectors.

    So let me write down the questions:

    1) If our game has more levels and in each we need to load different content (e.g. in level 1 we use models XX,
       but in level 2 we use model YY, etc). I guess, all we need to do is: don't load this models at application
       LoadContent (because at that time we don't know which level player will run), but later during loading each level.
       Question is: who will destroy/dispose this content after player switches to different level? Will it be still
       in memory?

    2) Seconds thing is, we have problems when switching application on/off using ALT+TAB. Graphics device is disposed
       (probably by XNA), and application fails. I can give you more details, but I was assuming, XNA is maintaining
       this things even if device is lost or reset... So how it is? Do we need to handle every lost/reset event and
       initialize/load our objects again (effects, vertex buffers, etc)?


    Thanks,
    Marek
  • 3/16/2009 3:22 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    To answer your first question, to the best of my knowledge, there's no way to unload data from content managers after it's been loaded. Once you load a model or a texture into a manager, the only way to free it is to dispose of the actual content manager it was associated with. I hear that a lot of people basically use individual content managers per level to manage this sort of thing.
  • 3/16/2009 3:37 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    flimflam:
    To answer your first question, to the best of my knowledge, there's no way to unload data from content managers after it's been loaded. Once you load a model or a texture into a manager, the only way to free it is to dispose of the actual content manager it was associated with. I hear that a lot of people basically use individual content managers per level to manage this sort of thing.
    Almost. You don't have to dispose of the ContentManager; just call Unload on it and it will unload everything it loaded. You obviously still need to be careful since you can't pick and choose what's unloaded. It's all or nothing.
  • 3/16/2009 3:59 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    flimflam:
    I hear that a lot of people basically use individual content managers per level to manage this sort of thing.


    Yeah, it's the most simple and effective way of managing per-level content that I've come across.  Make a ContentManager that's member of your Level class, use that to load all level-specific content, and then when the level goes out of scope the content all goes with it.  Just make sure you either call GC.Collect when you're done with the level or make it implement IDisposable, so that you can make sure all the content is cleared out of memory before you load your next level. 
  • 3/16/2009 4:06 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    In answer to your second question, you don't need to handle the lost/reset events directly, the framework will call the LoadContent() method on the game class and all the components in the games Component collection, all you need to do is ensure all your game objects (ones that are not in the game Components collection) have their content reloaded aswell, usually via the game.LoadContent() method.

    class MyGameObject
    {
        public void LoadContent()
        {
           // load this objects content
        }
    }

    class MyGame : Game
    {
       List<MyGameObject> objects;

      // this is called on a device lost/reset event
      protected override void LoadContent()
      {
           base.LoadContent();

           // make sure my proprietry objects reload their content
           foreach (MyGameObject object in objects) object.LoadContent();
      }
    }
  • 3/16/2009 4:19 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    Actually it doesn't. LoadContent is called once when the game starts up. Make a new project, put a Console.WriteLine in LoadContent, and run it. Then Alt-Tab back and forth between your game and VS. You'll never see it write your message again. Same goes for minimizing the window and bringing it back up.

    The GraphicsDevice is all virtualized in XNA. The framework should take care of everything for you. This functionality was added in 2.0 and still exists. Shawn has a great blog post (as usual) on the subject. Note that there are a few resource types that are not automatically taken care of, but he also mentions that most people won't notice anyway.

    If you can share more details about exactly what error you're getting maybe we can try to help you out.
  • 3/16/2009 5:15 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    Ah thanks Nick, I am way behind the times on this! :D
  • 3/16/2009 8:12 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    flimflam:
    To answer your first question, to the best of my knowledge, there's no way to unload data from content managers after it's been loaded. Once you load a model or a texture into a manager, the only way to free it is to dispose of the actual content manager it was associated with. I hear that a lot of people basically use individual content managers per level to manage this sort of thing.


    There is actually a way to unload individual content items. However, you do have to create a custom ContentManager. This is my ContentTracker class if you want to go down that path: http://www.ziggyware.com/readarticle.php?article_id=231
  • 3/16/2009 12:37 PM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    Very nice Roonda! I'd somehow missed that before, I'm considering dropping your ContentTracker into my own projects now (or read the whole thing and implement it myself, better for me since I'll understand what it's all doing!). I especially like how you handled the Asynchronous loading too, that's probably one of the main reasons I'd like to use it.
  • 3/17/2009 2:15 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    Martin Caine:
    Very nice Roonda! I'd somehow missed that before, I'm considering dropping your ContentTracker into my own projects now (or read the whole thing and implement it myself, better for me since I'll understand what it's all doing!). I especially like how you handled the Asynchronous loading too, that's probably one of the main reasons I'd like to use it.


    Thank you Martin. Please feel free to use it as you like.

    One warning for if you want to use ContentTracker's async loading on the XBox: since writing that article, I've purchased an XBox and discovered that one small (but critical) feature doesn't work. The CallGenericLoad() method uses MakeGenericMethod which doesn't behave properly on the compact CLR. I have a patch (actually quite a hack) that fixes it which I will post as a comment to the article ASAP. I emailed an updated download to Ziggy, but haven't heard back yet.
  • 3/17/2009 9:20 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    Thanks for the heads up, I'm rewriting my engine at the moment to make more use of game components and services and I'm really thinking of using this to handle the content loading.

    If possible could you email me a copy of the latest version with the hack? (to martin@bytrix.org) Thanks
  • 3/18/2009 2:53 AM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

         Hey guys, I hope this  is a decent place to post this:   I am having trouble with my LoadContent Method.  Specifically when I am trying to use abstract classes.  For example, I have a base class I am calling "GameImage". I have a few derived classes, "Spaceship", "Laserbeam", "Enemy".  I am using the GameStateManagement Sample to call about 4 - 5 different "GameplayScreens" , they represent 1 level each. the game has 5 levels and then you win or whatever. So, when I try to tell the Program to load the artwork for the three classes I am going into the LoadContent Method for "GameplayScreen1", and the code that I would use before I started messing with multiple "GameImage" derived classes is not working at all. I hope this is not only posted in a good spot, but that I have explained my issue clearly. Thanks to any and all that might get me going. I might also wanna add that where I first encountered this problem was trying to use the 2D extra credit Particle Explosions with the GameStateManagement Sample. Hope this helps as well.
  • 3/18/2009 5:19 PM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    Vicious Gaming:
    the code that I would use before I started messing with multiple "GameImage" derived classes is not working at all. I hope this is not only posted in a good spot, but that I have explained my issue clearly.


    Not really...  Without seeing what code you are using, and without knowing what you mean by "not working at all", it's impossible to guess what the problem might be!

    What exactly is the code you are using?

    What exactly goes wrong?
  • 6/21/2009 9:38 PM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    Hi,

    so this problem gets solved after we upgraded from XNA 3.0 to 3.1. Now I can switch from fullscreen to desktop, minimize all,
    switch back and do these things ten times and everything is OK. In log I can see reset event is made each time, but that's OK.

    Bye,
    Marek
  • 12/6/2009 9:22 PM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    Hi guys, I'd like to get back to this for a second. I have a simple XNA app that runs in windowed mode. It survives alt-tabbing perfectly but fails when I do show desktop. When I switch back to XNA window again all I can see is CornflowerBlue :)

    This is my Game.Initialize:

                spriteBatch = new SpriteBatch(GraphicsDevice);  
     
                this.effDefault = this.Content.Load<Effect>(@"Effects\default");  
                this.effDefault.CurrentTechnique = this.effDefault.Techniques[0];  
                this.effParamWVP = this.effDefault.Parameters["mxWVP"];  
     
                this.tp = new TestGame.Graphics.TestPrimitive(this.graphics.GraphicsDevice); 

    this is Game.Update:

                Matrix world = Matrix.Identity;  
     
                // cam is a instance of a simple camera class that  
                // handles mouse movement and calculates matricies accordingly  
     
                this.effParamWVP.SetValue(this.cam.GetWorldViewProjection(ref world)); 

    and Game.Draw:

                GraphicsDevice.Clear(Color.CornflowerBlue);  
     
                this.tp.Draw(this.effDefault);  
     
                base.Draw(gameTime); 


    TestPrimitive guy is a simple class with Initialize and Draw methods. I pass GraphicsDevice to it's ctor and initialize VertexDeclaration for VertexPositionColor.

    Then in TestPrimitive.Initialize I create some triangles:

                List<VertexPositionColor> t = new List<VertexPositionColor>();  
                  
                t.Add(new VertexPositionColor(new Vector3(-5.0f, 0.0f, 0.0f), Color.Green));  
                t.Add(new VertexPositionColor(new Vector3(0.0f, 5.0f, 0.0f), Color.Red));  
                t.Add(new VertexPositionColor(new Vector3(0.0f, 5.0f, 0.0f), Color.Red));  
                /* ... */ 
     
                this.verts = t.ToArray();  
                t = null

    and Draw'em:

                GraphicsDevice gdv = this.vd.GraphicsDevice;  
     
                gdv.VertexDeclaration = this.vd;  
     
                // eff is a CustomEffect passed as parameter do Draw method  
                eff.Begin();  
                eff.CurrentTechnique.Passes[0].Begin();  
     
                gdv.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, this.verts, 0, this.verts.Length / 3);  
     
                eff.CurrentTechnique.Passes[0].End();  
                eff.End(); 

    I hooked'up into DeviceReset events and tried to recreate various things there, like re-initialize VertexDeclaration and verticies for TestPrimitive or re-load and setup effDefault - nothing helped.

    I'm probably doing something wrong, that's for sure :) but what?
  • 12/7/2009 1:47 PM In reply to

    Re: XNA 3.0 - Proper use of LoadContent, UnloadContent, graphics device reset or lost

    OK, solved!

    It had nothing to do with device reseting though :)
Page 1 of 1 (16 posts) Previous Discussion Next Discussion
var gDomain='m.webtrends.com'; var gDcsId='dcschd84w10000w4lw9hcqmsz_8n3x'; var gTrackEvents=1; var gFpc='WT_FPC'; /*<\/scr"+"ipt>");} /*]]>*/
DCSIMG