1
\$\begingroup\$

I've encountered a problem with my game project lately. When I load more than a certain number of textures (around 1000) at startup I recieve an error regarding memory, because I have to use 32-bit in XNA. I am self-taught and so have only basic knowledge of the "correct" ways to program a game. The project itself is getting very big and although I try to compress images together etc, I will have to use more than 1000 textures throughout the project.

My question is this: How can I load textures at other points of time than at startup in XNA, using vb.net? (I'm not using classes at all that I'm aware of, so I hope to stay away from that if possible)

\$\endgroup\$
4
  • \$\begingroup\$ Memory will be an issue no matter when you load it, unless you plan on unloading assets between uses. Have you considered other ways of optimizing? 1000 textures sounds like a lot, perhaps consider clipping them together into fewer larger sprite sheets. \$\endgroup\$
    – William
    Commented Apr 18, 2016 at 12:43
  • \$\begingroup\$ "although I try to compress images together" if the memory issue you have is with the GPU, compressing them further will not solve the issue as they are stored uncompressed in GPU's memory buffers. @WilliamMariager I don't think merging them together will solve the issue as it's a memory issue: merging them will conserve the size used. \$\endgroup\$
    – Vaillancourt
    Commented Apr 18, 2016 at 12:54
  • \$\begingroup\$ Thank's for the answers. By compress I mean having multiple images on the same sheet. I wrote that to avoid hints about "clipping them together into fewer larger sprite sheets" etc. \$\endgroup\$ Commented Apr 18, 2016 at 12:59
  • \$\begingroup\$ William if you are right that I will have the same memoryproblem despite loading them at various times, how can I unload some and load some at a certain time? \$\endgroup\$ Commented Apr 18, 2016 at 13:00

2 Answers 2

0
\$\begingroup\$

First things first: You are free to call the ContentManager at any point in your game cycle (you're not restricted to the use the LoadContent() method created in the main class).

This doesn't solve your memory problem though, so on to part two:

If you run into memory issues because you have too much content loaded at the same time, you should only load the content that you actually need at that point in your game.

To free memory from loaded content, you can use Content.Unload() to release all content that the ContentManager holds. Note: Texture2D.Dispose() does not free up memory for Textures that are loaded via the ContentManager- as the ContentManager is in control of the lifetime of its content! (Sidenote: one should call Dispose() on content that is unmanaged -created without the ContentManager- though!)

A Content.Unload() releases all the content it contains so one might separate "generic" game content from "level specific" game content. Luckily you are able to create your own instance of the ContentManager so you can control what content is kept and what content is unloaded, like so:

C#:

ContentManager levelContentManager = new ContentManager( Game.Services, Content.RootDirectory );

or VB.Net

levelContentManager As New ContentManager(Content.ServiceProvider, Content.RootDirectory)

Now use:

levelContentManager.Unload()

when your level is completed and the level specific content is no longer used.

See also:

An example application would be in a game like Street Fighter (only used as example, Street Fighter wasn't build in XNA). The "Generic ContentManager" holds generic data: the titlescreen, the "Get Ready, Fight!" letters and healthbars. The other "level ContentManager" only loads the sprite info of the selected chars and level.

When the characters and level object are created, have those objects load their content via the "level ContentManager". When the fight is over and the game goes back to the title screen: the "level ContentManager" unloads to free up the resources.

When the players start a new fight, the "level ContentManager" is used again to load the now selected characters and level data and the cycle repeats.

This way, the memory only holds the content it is actually using.

\$\endgroup\$
0
\$\begingroup\$

So the answer seems a lot easier than I expected, if I'm doing it right at the moment(?).

I simply Load the content needed for all "Worlds" in the beginning of the game (in the Protected Overrides Sub LoadContent()) and then Dispose() and Load.Content() depending on what World is loaded later (in any Sub I choose):

TextureName = Content.Load(Of Texture2D)("")
TextureName.Dispose()

If there isn't any problem I'm not yet aware of, this seem to do the trick and does not leave me with the memory error in the start.

\$\endgroup\$
1
  • \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$
    – user1430
    Commented Apr 22, 2016 at 15:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .