# The right way to add images to Monogame/Windows

I'm starting out with MonoGame. For now, I'm only targeting Windows (desktop -- not Windows 8 specifically).

I've used a couple of XNA products in the past (raw XNA, FlatRedBall, SilverSprite), so I may have a misunderstanding about how I should add images to my content.

How do I add images to my project?

Currently, I created a new Monogame project, added a folder called "Content," and added images under there; the only caveat is that I need to set the Copy to Output Directory action to one of the Copy ones.

It seems strange, because my "raw" XNA project just last week had a Content project in it (XNA Framework Content Pipeline, according to VS2010), which compiled my images to XNB (I think). It seems like Monogame doesn't use the same content pipeline, but I'm not sure.

Edit: My question is not about "how do I get the XNA content pipeline to work with Monogame." My question is "why would I want to use the XNA content pipeline in Monogame?"

Because there are (at least) two solutions (that I see today):

• Add the images to the Monogame project and set the Copy to Output Directory options to copy.
• Add a XNA content pipeline project and add my images to that instead; reference it from my MOnogame project.

Which solution should I use, and why? I currently have a working version with the first option.

There is, in fact, a way around the Content Pipeline if you can't use it, at least for image dependencies: Use the TitleContainer class to load your dependencies in their raw forms:

// Load a Texture2D from a file
System.IO.Stream stream = TitleContainer.OpenStream("Content/My Sprite.png");
mySpriteTexture = Texture2D.FromFile(GraphicsDevice, stream);

// Load a SoundEffect from a file
// (NOTE: This is NOT in the current version of MonoGame)
stream = TitleContainer.OpenStream("Content/My Sound.wav");
mySound = SoundEffect.FromStream(stream);


These work wherever the Xna Framework can be used, but where the Xna Content Pipeline is not available or is too inconvenient.

What I do, is create an XNA project inside of my MonoGame solution. I set the compile location of this "Dummy" project to point to the same location that MonoGame compiles to.

When you build your project, the XNA Content project will convert your images to XNB files in the same location as your MonoGame binaries.

You need to use the XNA content pipeline in order to get your XNB files, there is currently no way around this if you are writing a MonoGame project.

I then delete the dummy.exe file if I am submitting a release.

• My question is really about whether I should use the content pipeline at all or not; what are the tradeoffs here? I've updated my question accordingly. Nov 28 '12 at 15:30

I have got it to work by having an open XNA solution which i add the jpg's or png's to then rebuild.

I then copy this over to the content folder in the MonoGame solution and set it to a Content type in the properties.

I understand the monogame team are attempting to build a content pipeline but i'm not sure where they are up to it

• My question is really about whether I should use the content pipeline at all or not; what are the tradeoffs here? I've updated my question accordingly. Nov 28 '12 at 15:31

The reason to use the content pipeline can be found in the Microsoft XNA documentation.

The chief reason XNA Game Studio uses a Content Pipeline is to help your game run fast. Without the content pipeline, your game would have to be built with its art assets in their original file format. When the game needs to load its art to draw it on the screen, it would have to determine its format and convert the data into a form it can use more directly. This would have to be performed at run time, for each asset, making the player wait to have fun.

The downside is the extra effort required to setup a content project and manage the process of building your optimized XNB files. Here's a quote taken from the link in your question for clarity.

The trouble using XNA content builder outputs on other platforms is that the XNB files it outputs are platform specific, MonoGame has gotten around this with its own multi-platform builder project allowing the creation of compiled assets for all its target platforms. It’s one deficiency is that it depends on the original XNA content project template which is still only available in VS2010 (express will do). Fear not however there are plans for a more open source version.

As you have already discovered, with MonoGame it's not necessary to use XNB files because you can add the raw content directly to the project. For a smallish project I think that's fine. It's what I've been doing with all of my projects thus far and I haven't had any issues (yet).

A word of caution though, things may change a little once the MonoGame team have finished implementing their own content pipeline. Here's a quote from a forum post I posted a while back.

It's not necessary to use XNB files. They are simply the format that the ContentManager reads (MonoGame's ContentManager currently reads other formats such as JPG, PNG, etc, but that will be removed when we get a Content Build Pipeline going).

The benefit to using XNB is that it is pre-processed into a format that is ready to be used directly by the GPU (in the case of GPU assets). Loading a PNG requires decompression of the PNG, perhaps some channel swapping (red and blue particularly) and then copy that uncompressed data into a Texture2D. If the texture has alpha, you would most likely need to pre-multiply the alpha for every pixel yourself. This is all done at load time. For XNB, the decompression, channel swapping and most importantly, pre-multiplication of alpha is done at build time. You can also optimize further as I have done in some of my games in that I output a dithered 16-bit texture to the XNB to save on memory use and bandwidth rather than the 32-bit default format.

Loading from PNG is fine if it works for you. There are some trade-offs for the convenience, but they won't matter to most developers.

Lastly, if you do decide to go down the Content Pipeline path, this documentation might be helpful.