XNA Content.Load() Memory Usage - c#

In XNA, when calling Content.Load() to load in a resource, if you load the same resource into multiple objects (i.e. the texture for a projectile of which there can be many) are you getting a copy for each object, or is the system just internally referencing the same memory for each one?
I was realizing that having a separate Texture2D object in each item may be a memory issue down the line.

The ContentManager will cache the object and return the reference to that object when you try to load it again.

Yes modifying the texture data will change all textures that reference that data.
If you need multiple ones then duplicate the original file and load different versions.

You would need to make a new Texture2D object and simply copy the changed data into the new texture with the SetData method:
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.texture2d.setdata.aspx

Related

XNA C# Dispose() Content

I'm working on a 2D fighting game with XNA (C#). Everything was going well in my game until I added a story mode. There are more than 60 frames. I have a variable whose value changes each time the person presses the spacebar.
I wanted to experiment game state transitions and dispose() (or .Unload()) content when a screen was no longer needed. I have searched about Dispose() and Unload () to save memory that take my textures, but I can not give a value to my variable Texture2D after having called Dispose() for it. (texture.IsDisposed = true).
I have created a ContentManager xContent in a Manager Class.
Texture2D texture;
int image = 0;
____________________
if (Keyboard.GetState().IsKeyDown(Keys.Space))
{
if (image == 0)
{
texture = Manager.xContent.Load<Texture2D>("texture1");
}
else if (image == 1)
{
texture.Dispose();
texture = Manager.xContent.Load<Texture2D>("texture2");
}
}
Draw :
spriteBatch.Begin();
...
spriteBatch.End();
I received an error on spriteBatch.End() of the above paste because I have reloaded the texture. What should I do?
You should not be calling 'Dispose()' on any of the content which was loaded by the XNA content manager. The content manager will manage the lifespan of the content (that's it's job, after all). It ought to make reasonable decisions about when to load/unload specific textures based on usage.
When the content manager itself is disposed then it will dispose all of the content that it's currently managing, so you don't need to dispose individual pieces of content.
Try to to organize it inside your manager. Loading the appropriate texture to the collection as needed and use them and remove if they become do not really need. If the texture will not link it sooner or later pick up the garbage collector.

Properly dispose of non referenced Image without garbage collection C#

I have a C# program which creates a List of Bitmaps from the images in a directory. It'll use the whole list of Bitmaps to generate one new image, which it will then save. When the user loads a new directory to repeat the process, the List of Bitmaps is cleared and refilled. The bitmaps are loaded upon creation of the object, "new Bitmap(path)".
I had a problem which occurred when the user performed the following steps:
Load images from directory 1
Chose not to save and instead load images from directory 2
Tries to save by overwriting an image from directory 1
Program is unable to save due to "A generic error in GDI+", because it is still "using" the image that is being overwritten.
The original List of Bitmaps loaded from directory 1 is indeed cleared and then refilled with images from directory 2. However, Bitmap.Save() refuses to overwrite an image it had previously loaded unless I call System.GC.Collect() after I perform Clear().
I'm pretty sure the problem has something to do with keeping the Bitmaps around even though there are no references, otherwise why would garbage collecting solve the problem? Is this the right way to go about solving this problem, or is there a "proper" way to dispose of Bitmaps in C#? Thanks.
You need to call Dispose on the Bitmap instances.. so they free their file handle.
var bitmap = new Bitmap(path_to_file);
// use it
bitmap.Dispose();
Or, since Bitmap inherits from Image which implements IDisposable, you can do this:
using (var bitmap = new Bitmap(path_to_file)) {
// use it..
}

Game data - arrays of instances or arrays of values?

I'm making a game and need to store a fair bit of animation data. For each frame I have about 15 values to store. My initial idea was to have a list of "frame" objects that contain those values. Then I thought I could also just have separate lists for each of the values and skip the objects altogether. The data will be loaded once from an XML file when the game is started.
I'm just looking for advice here, is either approach at all better (speed, memory usage, ease of use, etc) than the other?
Sorry if this is a dumb question, still pretty new and couldn't find any info on stuff like this.
(PS: this is a 2D game with sprites, so 1 frame != 1 frame of screen time. I estimate somewhere around 500-1000 frames total)
If the animation data is not changing, you could use a struct instead of an class, which combines the "namespacing" of objects with the "value-typeness" of primitives. That will make all the values of a single frame reside in the same space, and save you some memory and page faults.
Just make sure that the size of your arrays doesn't get you into LOH if you intend to allocate and deallocate them often.
you are creating an animation So you should keep in mind a few basic things of.net:
Struct is created on stack. So, it is faster to instantiate (and destroy) a struct than a class.
On the other hand, every time you assign a structure or pass it to a function, it gets copied.
you can still pass struct by reference simply by specifying ref in the function parameter list
So it will be better to keep in mind this things

Does using a static Texture2D with SpriteBatch improve performance?

I am going to have lots of (same looking) zombies in my game.
Is it a good idea to make the texture static, so that SpriteBatch wont need to load a new texture?
I go through the whole zombie list and draw every zombie with the same call, just changing the position. Will SpriteBatch get it? That its exactly the same texture every time? Where could be the disadvantage?
I don't think that the use of static will give you some kind of benefit.
What's sure is that, if you load your Texture2D only once, you save memory and you can draw it how many times you need using the same variable.
Anyway, if you're using only one texture you don't have any problem, because:
Each instance of ContentManager will only load any given resource
once. The second time you ask for a resource, it will return the same
instance that it returned last time.
ContentManager maintains a list of all the content it has loaded
internally. This list prevents the garbage collector from cleaning up
those resources.
Reference here.

Setting Variable to an Instance on disk without calling AssetDatabase.LoadAssetAtPath

Let's say I have two classes, both of which inherit from UnityEngine.ScriptableObject:
-CutScene
-AnimationCollection
The CutScene class holds the dialogue tree, camera cuts, has a public AnimationCollection field. The Animation Collection holds the actual animation data for animations used in a given cut scene.
In our pipeline, CutScene instances are generated by an export process, which saves them as unity .asset files.
An animator uses a unity editor tool to put animations into an AnimationCollection, then saves it out as a unity .asset file. Then, using the unity editor, the animator drags the asset file for the AnimationCollection into the AnimationCollection field for the CutScene that uses it.
When the CutScene is changed and exported, the export code will overwrite the existing .asset file for that CutScene with a new one. We do want to retain the reference to the AnimationCollection that the animator set up. Currently this is done with code like this:
cutScene.AnimationCollection = AssetDatabase.LoadAssetAtPath(pathToAnimCollection, typeof(AnimationCollection)) as AnimationCollection;
The problem is that loading the AnimationCollection can take a long time (12s for some of our bigger cut scenes). If I know the path to the AnimationCollection, can I somehow set the AnimationCollection field of the CutScene without having to actually load the AnimationCollection into memory? The AssetDatabase.AssetPathToGUID seems promising, but I'm not sure what I can do with a GUID string?
In C#, when you set a field's value, one of two things will happen.
If it's a reference type (i.e. a class), a reference to it in memory will be stored. This is a small number that points to a unique location in memory where that item is loaded.
If it's a value type (i.e. structs, int, float, etc), the actual value is stored.
In your case, you're setting an animation collection (a reference type) from an asset loaded by Unity. For your system to work you have to have loaded that whole asset into memory first, so that you can reference it. This means you cannot use GUIDs, or file paths without changing your cutscene system.
To make your system work without loading the files in the interim, consider storing the file path to the animation collection in the cutscene, instead of the animation collection itself. Then load that path when the whole cutscene is loaded.

Categories