Search code examples
c#xnatexturescontent-pipeline

Xna Content Pipeline and Textures


I have tried to get my head around the content processor and textures, but I am a bit confused... I have 2 scenarios:

  • One is a model that contains a texture, the importer loads the xml and passes the texture filename to the processor, but I can only get a TextureContent, which seems to be a compile time reference to a texture, but this doesn't help me populate the Texture2D bit of my model.

  • The 2nd scenario is I want to piggyback of the texture processor to create a spritemap object from a texture file, the spritemap is basically a model which contains a texture and sprite width/height.

The thing that keeps getting me stumped is these ExternalReference and TextureContent, as the model, lets say:

public class SpriteMap
{
    public Texture2D Texture { get; private set; }
    public int SpriteWidth { get; private set; }
    public int SpriteHeight { get; private set; }

    public SpriteMap(Texture2D texture, int spriteWidth, int spriteHeight)
    {
        this.texture = texture;
        this.spriteWidth = spriteWidth;
        this.spriteHeight = spriteHeight;
    }
}

Then I have a content processor like so:

[ContentProcessor(DisplayName = "TextureToSpriteMapProcessor")]
public class TextureToSpriteMapProcessor : ContentProcessor<Texture2D, ISpriteMap>
{
    [DisplayName("Sprite Width")]
    [DefaultValue(64)]
    [Description("The size of each sprite's width within the sprite map.")]
    public virtual int SpriteWidth { get; set; }

    [DisplayName("Sprite Height")]
    [DefaultValue(64)]
    [Description("The size of each sprite's height within the sprite map.")]
    public virtual int SpriteHeight { get; set; }

    public override ISpriteMap Process(Texture2D input, ContentProcessorContext context)
    { return new SpriteMap(input, SpriteWidth, SpriteHeight); }
}

Now it complains that the processor is given a TextureContent, but that isn't a texture... but for some reason a TextureContent seems to magically turn into a Texture when it is loaded via the contentManager... so I am a bit baffled as to how I can get a texture in this instance. As both scenarios are fairly similar I am sure if I solve one I will solve them both, but ideally I want to be able to go:

contentManager.Load<ISpriteMap>("someTextureAsset");

If anyone can explain how to make this seemingly magic process work, I will give you much praise!


Solution

  • My main problem here was that I was trying to use the same model on both sides, the texture content is the compile time representation of the texture from my current understanding. So when I am in the compile-time domain of the Importer/Processor I can only work with these references and content data.

    So to solve my problem I had to revert back to using TextureContent and not Texture2D, then make a model SpriteMapContent which contained the references to the textures in question and the other data required for the model. Then write a content reader/writer to govern how the data was put together in the run-time domain.

    This similar post I made was what made it clearer to me where I was going wrong and what I needed to do to solve the problem.

    https://gamedev.stackexchange.com/questions/22480/contentserializerruntimetype-required-in-content-pipeline/22482#22482