Models with shader parameters fail to load.

I’m trying to convert our XNA game to Monogame, but I’m having difficulties converting the
game content. The game has a lot of 3D models with custom shaders for
backgrounds. The shaders have parameters that can be directly adjusted from the
3D modeling software (so you can see the results before putting the model into
the game). All of our background models are made this way and it works in XNA.
However I get the following error when trying to open those models in Monogame:

An unhandled exception of type ‘System.NotImplementedException’ occurred in
MonoGame.Framework.dll

Additional information: The method or operation is not implemented.

I use Monogame 3.2. Is there any way to fix this or to get around the problem? I know
for a fact that I can create a dummy shader that doesn’t have the parameters
that are assigned in the 3D modeling software and assign a new shader while
manually adjusting the correct parameters to it. However due to the large
amount of content in the game, this isn’t really a viable option.

Hi, good doctor :wink:

It helps to provide the call stack for the exception.

My hunch is that there are no readers/writers for data types that are being added, but I could be completely wrong.

For example, my custom model processor adds quaternions to my compiled models, so I needed to add code to handle writing them to disk and reading them into the game.

public class QuaternionWriter : ContentTypeWriter
{
protected override void Write(ContentWriter output, Quaternion value)
{
output.Write(value.X);
output.Write(value.Y);
output.Write(value.Z);
output.Write(value.W);
}

  public override string GetRuntimeType(TargetPlatform targetPlatform)
  {
  	return typeof(Quaternion).AssemblyQualifiedName;
  }
  public override string GetRuntimeReader(TargetPlatform targetPlatform)
  {
  	return typeof(GameWork.Graphics.QuaternionReader).AssemblyQualifiedName;
  }

}

public class QuaternionReader : ContentTypeReader
{
protected override Quaternion Read(ContentReader input, Quaternion existingInstance)
{
Quaternion output = new Quaternion();
output.X = input.ReadSingle();
output.Y = input.ReadSingle();
output.Z = input.ReadSingle();
output.W = input.ReadSingle();
return output;
}
}

Yes indeed, should’ve done that.

Here’s the stack trace for the problem I specified:

at Microsoft.Xna.Framework.Content.EffectMaterialReader.Read(ContentReader input, EffectMaterial existingInstance)
   at Microsoft.Xna.Framework.Content.ContentTypeReader1.Read(ContentReader input, Object existingInstance)    at Microsoft.Xna.Framework.Content.ContentReader.ReadObject[T](ContentTypeReader typeReader)    at Microsoft.Xna.Framework.Content.ContentReader.ReadSharedResources()    at Microsoft.Xna.Framework.Content.ContentReader.ReadAsset[T]()    at Microsoft.Xna.Framework.Content.ContentManager.ReadAsset[T](String assetName, Action1 recordDisposableObject)
   at Microsoft.Xna.Framework.Content.ContentManager.Load[T](String assetName)

Rest is my code leading to:
meshmodel = content.Load(@“Models/” + modelname);


I just realized I have another different problem too, which is this, something about cubemaps not being implemented:

at Microsoft.Xna.Framework.Graphics.TextureCube.<>c__DisplayClass1.b__0()
   at Microsoft.Xna.Framework.Threading.BlockOnUIThread(Action action)
   at Microsoft.Xna.Framework.Graphics.TextureCube.PlatformConstruct(GraphicsDevice graphicsDevice, Int32 size, Boolean mipMap, SurfaceFormat format, Boolean renderTarget)
   at Microsoft.Xna.Framework.Graphics.TextureCube…ctor(GraphicsDevice graphicsDevice, Int32 size, Boolean mipMap, SurfaceFormat format, Boolean renderTarget)
   at Microsoft.Xna.Framework.Graphics.TextureCube…ctor(GraphicsDevice graphicsDevice, Int32 size, Boolean mipMap, SurfaceFormat format)
   at Microsoft.Xna.Framework.Content.TextureCubeReader.Read(ContentReader reader, TextureCube existingInstance)
   at Microsoft.Xna.Framework.Content.ContentTypeReader1.Read(ContentReader input, Object existingInstance)    at Microsoft.Xna.Framework.Content.ContentReader.ReadObject[T]()    at Microsoft.Xna.Framework.Content.ContentReader.ReadAsset[T]()    at Microsoft.Xna.Framework.Content.ContentManager.ReadAsset[T](String assetName, Action1 recordDisposableObject)
   at Microsoft.Xna.Framework.Content.ContentManager.Load[T](String assetName)
   at Microsoft.Xna.Framework.Content.ContentReader.ReadExternalReferenceT
   at Microsoft.Xna.Framework.Content.ExternalReferenceReader.Read(ContentReader input, Object existingInstance)
   at Microsoft.Xna.Framework.Content.ContentReader.ReadObject[T](ContentTypeReader typeReader)
   at Microsoft.Xna.Framework.Content.DictionaryReader2.Read(ContentReader input, Dictionary2 existingInstance)
   at Microsoft.Xna.Framework.Content.ContentTypeReader1.Read(ContentReader input, Object existingInstance)    at Microsoft.Xna.Framework.Content.ContentReader.ReadObject[T]()    at Microsoft.Xna.Framework.Content.EffectMaterialReader.Read(ContentReader input, EffectMaterial existingInstance)    at Microsoft.Xna.Framework.Content.ContentTypeReader1.Read(ContentReader input, Object existingInstance)
   at Microsoft.Xna.Framework.Content.ContentReader.ReadObject[T](ContentTypeReader typeReader)
   at Microsoft.Xna.Framework.Content.ContentReader.ReadSharedResources()
   at Microsoft.Xna.Framework.Content.ContentReader.ReadAssetT
   at Microsoft.Xna.Framework.Content.ContentManager.ReadAsset[T](String assetName, Action`1 recordDisposableObject)
   at Microsoft.Xna.Framework.Content.ContentManager.Load[T](String assetName)

Rest is my code leading to:
meshmodel = content.Load(@“Models/” + modelname);

@DissidentDan - Are you saying here that MonoGame is missing a ContentTypeWriter<Quaternion>, but MS XNA doesn’t have this problem? If so it is really easy for us to fix… we’ve just never heard of the issue.

I suspect this is the problem…

https://github.com/mono/MonoGame/blob/develop/MonoGame.Framework/Graphics/TextureCube.OpenGL.cs#L61

Looks like no one had implemented support compressed formats in TextureCube under OpenGL.

@DrInfy - Does that sound like your case?

Tom – No, XNA does not supply a writer or reader for Quaternion. I was just giving an example of a custom writer/reader combo from my own experience. Sorry for the confusion.

Turning off compression from the cubemap removed the error relating to TextureCubes. Thank you, that does help a lot, but it still didn’t solve the original problem I started the thread for. Which is Microsoft.Xna.Framework.Content.EffectMaterialReader.Read(ContentReader input, EffectMaterial existingInstance) throwing not implemented exception.