Writing a Custom Importer

You can write a custom importer to convert art assets saved in a particular file format into a form that can be loaded and used within XNA Game Studio Express.

While the Content Pipeline provides standard importers for common file formats, as described in Standard Importers and Processors, XNA Game Studio Express also lets you derive from the ContentImporter class to implement your own custom importer.

An importer accepts as imput a file in a particular format and generates as output one or more managed C# objects for use in your game. Currently, the XNA Game Studio Express Content Document Object Model (DOM) provides support for meshes, materials, textures, sprite-fonts, and animations.

You can import custom types from any kind of file, not just from files containing standard content, but XNA Game Studio Express provides no automatic support for custom objects other than the standard ones previously mentioned. Outside of these, a custom importer can return a ContentItem with custom information in its opaque data, or a custom type you have developed on your own. If you are outputting a custom type of your own, however, you must be sure to provide a custom processor that accepts it as input.

Importer Basics

All importers must derive from the ContentImporter class and be marked with a ContentImporterAttribute. The attribute is used to notify the Content Pipeline of the types of files the importer can read, and set other properties.

For example, the following code creates an importer class named MyImporter for processing any file with an .x extension.

[ContentImporterAttribute( ".x" )]
public class MyImporter : ContentImporter<NodeContent>
{
     public override NodeContent Import( String filename, ContentImporterContext context )
     {
             // implementation here
     }
}   

An importer can be written to handle more than one file format. The following code creates a class that processes files with .bmp, .dds, and .tga extensions.

[ContentImporter (".bmp",".dds",".tga")]
public class MyTextureImporter : ContentImporter<TextureContent>
{
     public override TextureContent Import( String filename, ContentImporterContext context )
     {
             // implementation here
     }
}   

Note

To specify multiple file types, separate file extensions with a comma. Normally, an importer that accepts multiple file formats is specialized to generate one particular kind of output type, such as textures, but there is nothing to prevent a single importer from being written to handle many different content types, aside from difficulties of maintenance.

The Content Pipeline searches for classes matching these requirements in all pipeline assemblies available to the project. When the game is built, the ContentImporter.Import function is called once for each XNA content item in the current project.

When invoked against an input file in the appropriate format, a custom importer is expected to parse the file and produce as output one or more content objects of appropriate types. Since an importer's output is passed directly to a Content Pipeline processor, each type that an importer generates must have at least one processor available that can accept it as input.

Try to Generate Content Pipeline DOM Objects as Output

You can certainly write your importer to produce output in the form of custom objects of your own, as long as you also provide a custom processor for each custom type you produce.

However, you will generally decrease your workload and increase the utility of your importer if you can make it generate standard Content Pipeline DOM objects as output. Producing standard objects ensures interoperability with existing Content Pipeline components, including processors, readers (implemented with ContentTypeReader), and writers (implemented with ContentTypeWriter). It also makes your importer easier for other developers to understand and use. The Content Pipeline Graphics section of the documentation documents classes in the Content Pipeline DOM.

An importer for .gif files, for example, should generally produce TextureContent objects as output, and an importer for 3D files containing scenes made up of meshes, models, and other hierarchical graphics data should generally return NodeContent objects.

Tips for Importing Basic Graphics Objects

These rules are helpful when importing basic graphics objects.

  • Make your coordinate system right-handed. This means that, to the observer, the positive x-axis points to the right, the positive y-axis points up, and the positive z-axis points toward you (out from the screen).
  • Create triangles that have a clockwise winding order. The default culling mode removes triangles that have a counterclockwise winding order. Call SwapWindingOrder to change the winding order of a triangle.
  • Set the scale for graphical objects to 1 unit = 1 meter. Call TransformScene to change the scale of an object.

Take Advantage of Content Pipeline Mesh Classes

There are several properties and classes that are particularly useful when using NodeContent objects to represent a 3D scene or mesh.

The Content Pipeline provides two classes that make it easier to create and work with Pipeline.Graphics.MeshContent objects.

See Also

Overview of the Content Pipeline
Content Pipeline Architecture
Standard Importers and Processors
ContentImporter
MeshContent
MeshBuilder
MeshHelper