Shawn Hargreaves Blog
Popular XNA myth #623: "XNA forces me to use the Content Pipeline any time I want to load data into my game".
Not true! The Content Pipeline is (almost) entirely optional. If you prefer to do things some other way, you are most welcome to use any of the varied .NET I/O technologies:
But of course, 'possible' and 'easy' are not the same thing. If you choose not to use our built-in Content Pipeline, you should expect to have to do some work to replace it. Depending on the format of the data you are trying to read, this could range anywhere from trivial to very hard indeed.
It is important to understand that the Content Pipeline has several layers. At the core is an infrastructure which provides generic services for building and loading any type of content:
All that stuff is just regular C# code. If you wanted, you could write your own version from scratch that would do all the same things in the same way. It'd take you a while, but it would be possible.
Layered on top of the generic infrastructure, we provide built-in support for the most important types of content:
Again there is no magic here. You could reimplement all this yourself, given sufficient time, skill, and determination.
So what CAN'T you do yourself?
It all boils down to what runtime type you want to load into. It's no use being able to read whatever you like from whatever files you like, if you then have no way to set the data into its final resting place:
Replacing the built-in Model class is actually a common, sensible, and easy thing to do. Replacing SpriteFont is more work, but still possible. Replacing Song and Video is not really feasible, so you do indeed have to use the Content Pipeline to build music and video data.
Note: this article refers to XNA Game Studio 4.0. Some details varied in previous versions, but the principle remains the same.
I'd really love to see a public constructor for SpriteFont one of these days... :) It's particularly irksome since it's tightly coupled with SpriteBatch.
Also curious about why Texture2D.FromStream might be slower than the Content Pipeline.
I really wish the content pipeline was *truly* optional in the sense it was a layer over top of the public utility classes - internal constructors just make things a nightmare for games that want to support user created content or custom serialization formats. I realize that the internal constructors are there to avoid exposing half-baked public APIs, but we've been waiting years and years for these now.
> curious about why Texture2D.FromStream might be slower than the Content Pipeline
The Content Pipeline has already decoded PNG or JPEG data, converted to DXT format, generated mipmaps, etc, so loading is just a block read into a byte array that can be copied directly into a GPU texture.
FromStream reads from PNG or JPEG, which are nothing like GPU formats, so much more conversion work is required.
> I really wish the content pipeline was *truly* optional in the sense it was a layer over top of the public utility classes
It truly is an optional layer over public APIs, except for the four classes I listed at the end of this article.
In the case of Model, we view that as more of a quick+dirty example to help get beginners started, not the be-all and end-all for more advanced users. It's designed to be easily replaced, and we expect pretty much every expert game dev or engine author to replace it, so we see little value in making it more extensible.
In the case of SpriteFont, we chose not to expose the internal structure because that is somewhat complex and subject to change. We wanted to reserve the right to change implementation details without breaking customer code, which requires a level of encapsulation.
In the case of Song and Video, there's no deep reason for them not to be user constructable. They just aren't :-)
Texture2D.FromStream can be slower because it creates a temporary file to store the stream and then loads the file...
Seems rather stupid, I know...
> Texture2D.FromStream can be slower because it creates a temporary file to store the stream and then loads the file...
Not so. You must be thinking of Texture2D.FromFile in Game Studio <= 3.1.
I thought the content pipeline was one of the best things in XNA (of course after the graphics API that is ;). There is a certain pleasure in writing custom content pipeline extentions and it all fits in together pertty nicely.
> " if you then have no way to set the data into its final resting place:"
You mean, other than by using Reflection, right?
What i don't understand is why you guys don't include the Content Pipeline Assembly within the XNA Redist so that Artist don't have to install GSE and VS just for testing content in a game. I know in windows we just can load textures "FromFile" but i really want to use the content pipeline within my Scene Editor for example. Will we see a change in XNA 4?
Sorry for my English it's not my native language.
PS: Where can i send requests to the XBOX Live Team so we finally can have Avatars on the PC. I Don't understand why i can only create Avatars on XBOX and Phone. Don't forget the PC Guys! It's still a very very important Gaming Platform!
What if I want to create an XNA library, but I want the shaders to be embedded with it? What's the best way to tackle it?
Hey Shawn, not sure if you'll ever read this, but whatever.
Could you shed some light on Mipmap generation with Texture2D.FromStream? I tried it out today and I'm quite happy with the results, but I can't figure out how to get mipmapping working. I'd quite like to precompute it, but I can't figure out how I would embed mipmap data in any of the formats that FromStream can use (it's probably impossible). I suppose I could do it on the fly with a wrapper of FromStream that would automatically generate mipmaps, but they would probably be lower quality so I'd like to hear from you first if I can.