It’s been a long time since I’ve posted on XNA on this blog. In fact, a long time since I posted on anything! After a re-shuffle of projects I have been undertaking in my own personal time, I’ve managed to make far more time to play around with XNA, my real passion.
When I first started playing with XNA, I was intrigued as to how XNA allows developers to get their game assets into XNA. Out-of-the box, XNA allows you to easily include certain graphics formats such as .PNG or .JPEG images and 3D file formats such as .X (DirectX) or .FBX (3D Studio Max). Great if your 3D modelling package exports these formats but not so convenient if it does not. I want to import from Blender but this is not supported directly by XNA….
However, XNA does have one pretty clever trick up its sleeve:
The Content Pipeline
This is a customisable process in which XNA can read source file formats and convert them into binary files for distribution with your game in a format that your game can then read in at run-time. Drop an FBX 3D model file into the content folder in your project and Visual C# Express will use the appropriate Content Pipeline class to parse it and package it into a binary file (an XNB file) during the build process. For your game to use it, you simple have to call the Load method in the XNA run-time content manager to pull the data in and populate a nice, clean runtime Model class.
Things get even more interesting when you realise that you can write your own Content Pipeline components to customise things to your liking. And if I want to import Blender models into my games and use them, I need to understand them.
So in this article, and subsequent ones to follow I am going to look at using the Content Pipeline to import Blender 3D models and render them in an XNA game. As this article is published, I am about 2 or 3 blog-posts ahead of what I am describing – and I’m still working it out as I go along!
What I’d like to share is what I’ve needed to learn in order to accomplish this, plus how I overcame any problems along the way. If you too are looking to create your own Content Pipeline plugins, this may be of use to you. Even if you are not, learning more about the Pipeline could open up some avenues in your game development that hadn’t really occurred to you. Let’s take a look at the Content Pipeline and its fundamental components.
The pipeline consists of 4 distinct parts:
ContentImporter, ContentProcessor, ContentTypeWriter, and ContentTypeReader.
In Visual C# Express, when you add content you can specify which Content Importer and Content Processor it should us to compile that data into your project. If you wanted to, you could create just a ContentImporter and bolt that onto an existing ContentProcessor in order to support a new file format that XNA does not support already. The flexibility is there though if you wish to go one stage further and customise the entire pipeline for a particular type of game asset.
I’ll briefly run through the components mentioned above to explain what they do.
ContentImporter
The ContentImporter parses the content file and fills a set of appropriate classes with the data it contains. XNA provides a set of content classes ready to store such data. For example, if your file contained 3D geometry, you would populate a MeshContent class. For 2D bitmap graphics, you would use a TextureContent class. These content classes can be arranged in a hierarchy so you could pull in multiple images or multiple 3D meshes and arrange them in a parent-child configuration. The important thing to remember about a Content Importer is that it does not care about what the final use of the data will be. Its job is simply to retrive information from the file the content is contained in and make it available to the rest of the Pipeline to do with as it pleases.
ContentProcessor
A ContentProcessor converts those standard data types mentioned above into something that resembles the run-time data structure. If you simply wished to support a new fileformat that XNA does not natively support, a ContentImporter would be all you needed, you could then use the built-in XNA Processors to prepare that content into one of the built-in types, such as Model . So if you wanted to support the ILBM format for textures (showing my age there), then a ContentImporter would do just fine providing it populated a TextureContent class properly ready for processing by the built-in XNA texture processor.
Conversely, if you wanted to ditch the standard XNA runtime classes, such as Model and use your own, you would need to create a ContentProcessor to spit out your custom class. You could still take advantage of the built-in ContentImporters to save you having to write a class to parse FBX files, for example.
Using your own class instead of the built-in XNA-provided ones might seem risky but it’s positively encouraged. And if Shawn Hargreaves, one of lead developers of the XNA framework endorses that approach , you shouldn’t feel too worried about going down that route also.
A moment ago I said that the ContentProcessor creates something that “resembles the run-time data structure “. I don’t want to confuse the reader too much right now, but I’ll give one example of why this is necessary or useful:
You might wish to specify a particular shader or texture for your model when you import the model itself. That same shader or texture might well be used again in other models in your project. Without going into too much detail too soon, the pipeline allows you to put a placeholder in your content to refer to this other asset. The pipeline will then pull this particular asset in at runtime and plug it into every class that needs it. This ensures that you do not pull the same dependencies in more than once.
ContentTypeWriter
You only need to implement a ContentTypeWriter when you are going to use your own custom runtime class to hold your content asset. This is a surprisingly simple class to write as it simply dumps the intermediary class output from your ContentProcessor to an XNB file. An XNB file is what every item of content in the XNA framework is stored in after the project is built. You don’t need to understand what the exact format of the file is because ….. it doesn’t have one !
If you want to store 10 3D meshes in your XNB file, you can. You would simple write out the number of meshes and then follow that by writing out the meshes themselves. XNA looks after the hard part of serialising these objects into a binary format and your code just looks something like this:
output.Write(Meshes.Count);
output.WriteObject(listOfVertices1);
output.WriteObject(listOfTriangles1);
..
..
output.WriteObject(listOfVertices10);
output.WriteObject(listOfTriangles10);
I’ve simplified the above but it illustrates that you can just dump out whatever you please, providing you write the part that reads it in to use the same order. That brings us nicely to the final part:
ContentTypeReader
Again, like ContentTypeWriter, you only need to implement a ContentTypeReader class if you are not going to be using the built-in run-time classes such as Model or Texture and instead plan to use your own custom class. Using the pseudo-code above as an example, the complementary ContentTypeReader would do something like:
meshCount = input.ReadInt32();
for (i=0; i < meshCount; i++)
{
listOfVertices[i] = input.ReadObject();
listOfTrangles[i] = input.ReadObject();
}
The ContentReader creates an instance of your run-time custom class that will hold your game asset, populates it and returns it. When you ask the ContentManager in your game to load in your asset, the ContentManagers load method calls this ContentTypeReader and returns your custom content class ready to use in your game at runtime.
Next time…
In my next article, I am going to explain why I decided to use Blender for my game content generation and discuss the various ways to get content out of Blender. I’ll explain why I chose the export method I did and we’ll look at the file format directly so you can better understand how we actually go about pulling the data it contains into the XNA environment.

Very nice! I look forward to reading your blog, for I as well am using Blender as the sole DCC tool for my endeavors. Five months ago I gained an interest in XNA. Having no programming experience whatsoever didn’t scare me (I once heard that a pre-req for programming was math skills, and I have a few …). Since, I’ve learned the basics of C# and am able to peruse code and know what the programmer is intending, as well as determine my intentions and materialize them with XNA. For DCC, I chose Blender because, well … -$$$$! I’m learning Python now to help with the interaction between XNA and Blender and, maybe one day, streamline the two and continue showing what Blender is capable of (BTW … all should try Blender … it’s like with anything in life … you don’t know how until you learn how … are you willing to learn?
) Imagine the possibilities!!!
Anyway, hope to hear more soon. Keep me posted …
[...] be continuing the Blender and XNA series soon which should help those who wonder how I have achieved the above. March 16th, 2008 | [...]
Trackback this post | Subscribe to the comments via RSS Feed