Search code examples
c#iosxnatexturesmonogame

Workaround for Texture2D.GetData method


I’m converting a game from XNA to iOS with Monogame.
In the code snippet below, smallDeform is a Texture2D on which I call the GetData method.

smallDeform = Game.Content.Load<Texture2D>("Terrain/...");
smallDeform.GetData(smallDeformData, 0, smallDeform.Width * smallDeform.Height);

I’m having some problem with Monogame because the feature in iOS has not been implemented yet because it returns this exception.

#if IOS 
   throw new NotImplementedException();
#elif ANDROID

I tried to serialize the data in a XML file from Windows to load the whole file from iOS. The serialized files weight more than 100MB each, that is quite unacceptable to parse.

Basically, I’m looking for a workaround to get the data (for instance a uint[] or Color[]) from a texture without using the GetData method.

PS: I'm on Mac, so I can't use the Monogame SharpDX library.

Thanks in advance.


Solution

  • I answer my own question, if someone will have the same problem.

    Following craftworkgame's suggestion, I saved my data using byte streams, but due to the absence of File class, I had to use WinRT functions:

    private async void SaveColorArray(string filename, Color[] array)
    {
        StorageFile sampleFile = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(filename + ".dat", CreationCollisionOption.ReplaceExisting);
        IRandomAccessStream writeStream = await sampleFile.OpenAsync(FileAccessMode.ReadWrite);
        IOutputStream outputSteam = writeStream.GetOutputStreamAt(0);
        DataWriter dataWriter = new DataWriter(outputSteam);
        for (int i = 0; i < array.Length; i++)
        {
            dataWriter.WriteByte(array[i].R);
            dataWriter.WriteByte(array[i].G);
            dataWriter.WriteByte(array[i].B);
            dataWriter.WriteByte(array[i].A);
        }
    
        await dataWriter.StoreAsync();
        await outputSteam.FlushAsync();
    }
    
    protected async Task<Color[]> LoadColorArray(string filename)
    {
        StorageFile sampleFile = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(filename + ".dat", CreationCollisionOption.OpenIfExists);
        IRandomAccessStream readStream = await sampleFile.OpenAsync(FileAccessMode.Read);
        IInputStream inputSteam = readStream.GetInputStreamAt(0);
        DataReader dataReader = new DataReader(inputSteam);
        await dataReader.LoadAsync((uint)readStream.Size);
    
        Color[] levelArray = new Color[dataReader.UnconsumedBufferLength / 4];
        int i = 0;
        while (dataReader.UnconsumedBufferLength > 0)
        {
            byte[] colorArray = new byte[4];
            dataReader.ReadBytes(colorArray);
            levelArray[i++] = new Color(colorArray[0], colorArray[1], colorArray[2], colorArray[3]);
        }
    
        return levelArray;
    }