0

I'm trying to make my game load compiled xnb textures outside the main game class, as I usually do with my image files (which are not compiled to xnb format) and it doesn't work.

Texture2D.FromStream returns "unexpected error", and

using (var g = new Game1())
{
    Texture2D t2d = g.Content.Load<Texture2D>(file);
}

says that the file doesn't exist, while File.Exists right next to it shows that it indeed exists.

I can't add those xnb files to my project, because I won't have them at compile time. How do I solve this?


More code:

public void LoadXNA(Microsoft.Xna.Framework.Content.ContentManager cmgr, string path)
{
    string xnaTexturesPath = path.Substring(0, path.LastIndexOf("\\")) + "\\textures xna";

    if (Directory.Exists(xnaTexturesPath))
    {
        var files = Directory.GetFiles(xnaTexturesPath, "*.xnb");

        foreach(var file in files)
        {
            string filename = Path.GetFileNameWithoutExtension(file);

            string ext = Path.GetExtension(file);
            string pathNoext = file.Replace(ext, "");

            var t2d = cmgr.Load < Texture2D > (pathNoext);
        }
    }
}
user1306322
  • 8,561
  • 18
  • 61
  • 122

1 Answers1

1

First of all, you do not need an entire Game. All you need is a GraphicsDevice. Note that the textures are bound to the graphics device - so it must remain in existence while the textures do - and textures cannot be shared between multiple devices.

To get a ContentManager without a Game class, have a look at the XNA WinForms Sample. In particular, it shows how to create a GraphicsDevice bound to a given control (which can be a Form - you can make it a hidden one if you don't need to use it otherwise), how to make a service provider and put a IGraphicsDeviceService in it, and then how to create a ContentManager using that service provider.

Alternately, have a look at this answer which provides some code which you can just use directly (it makes use of some classes in that same WinForms sample). It's XNA 3.1, so it may require minor tweaks for 4.0, but should generally work.

Texture2D.FromStream cannot load XNB files. XNB files need to be run through ContentManager to basically "unwrap" all the XNB stuff.

Possibly the problem you are experiencing with ContentManager.Load is because you are including the file extension in your file name. It adds the .xnb for you, and will get confused if you add it as well.

Community
  • 1
  • 1
Andrew Russell
  • 26,924
  • 7
  • 58
  • 104
  • I think I'm having some other kind of problem here. I have access to my graphics device from where I'm doing this, in fact the method I'm doing this in accepts GD as an argument, but I can't seem to make it work. It either says the file doesn't exist, or if I give it the full absolute path, it says it can't open the file, though it's not being used by any other application. – user1306322 Jan 12 '13 at 23:55
  • @user1306322 Can you edit your question and add more code - particularly where you call each of `FromStream`, `Load` and `Exists` - and the contents of the argument you are passing to each of them (use the debugger, or hard-code the path), as well as the actual path of the file you are expecting to load (can you see it in Windows?), and the exact exceptions you are getting? – Andrew Russell Jan 13 '13 at 05:39
  • I even tried passing the original Content, but it doesn't help. Then I tried loading the file by its full path right inside the `LoadContent` and it doesn't work either! I wonder if I do have to add those files to my content project if I want to load them. – user1306322 Jan 13 '13 at 06:18
  • @user1306322 The `ContentManager` just works on XNB files - it doesn't care where they came from. Note that `ContentManager` loads files relative to `ContentManager.RootDirectory` - so make sure that is set correctly? – Andrew Russell Jan 13 '13 at 08:19
  • 1
    I finally figured this out: the path **must** be relative to `ContentManager.RootDirectory`, even if you give it the absolute path, it will cause an error. Also there must be no extension in the path string (i.e. it must end with the file name, like so: `"textures\\mushroom"`). – user1306322 Jan 17 '13 at 08:45